/*////////////////////////////////////////////////////////////////////////////// Copyright (c) 2013 Jamboree Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) //////////////////////////////////////////////////////////////////////////////*/ #ifndef BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED #define BOOST_FUSION_FLATTEN_VIEW_HPP_INCLUDED #include #include #include #include #include #include #include #include #include namespace boost { namespace fusion { struct forward_traversal_tag; struct flatten_view_tag; template struct flatten_view : sequence_base > { typedef flatten_view_tag fusion_tag; typedef fusion_sequence_tag tag; // this gets picked up by MPL typedef mpl::true_ is_view; typedef forward_traversal_tag category; typedef Sequence sequence_type; typedef typename result_of::begin::type first_type; typedef typename result_of::end::type last_type; explicit flatten_view(Sequence& seq) : seq(seq) {} first_type first() const { return fusion::begin(seq); } last_type last() const { return fusion::end(seq); } typename mpl::if_, Sequence, Sequence&>::type seq; }; }} namespace boost { namespace fusion { namespace extension { template<> struct begin_impl { template struct apply { typedef typename Sequence::first_type first_type; typedef typename result_of::begin< mpl::single_view< typename Sequence::sequence_type> >::type root_iterator; typedef detail::seek_descent seek_descent; typedef typename seek_descent::type type; static inline type call(Sequence& seq) { return seek_descent::apply(root_iterator(), seq.first()); } }; }; template<> struct end_impl { template struct apply { typedef typename Sequence::last_type last_type; typedef typename result_of::end< mpl::single_view< typename Sequence::sequence_type> >::type type; static inline type call(Sequence&) { return type(); } }; }; template<> struct size_impl { template struct apply : result_of::distance < typename result_of::begin::type , typename result_of::end::type > {}; }; template<> struct empty_impl { template struct apply : result_of::empty {}; }; }}} #endif