/*============================================================================== 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_ITERATOR_HPP_INCLUDED #define BOOST_FUSION_FLATTEN_VIEW_ITERATOR_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include namespace boost { namespace fusion { struct forward_traversal_tag; struct flatten_view_iterator_tag; template struct flatten_view_iterator : iterator_base > { typedef flatten_view_iterator_tag fusion_tag; typedef forward_traversal_tag category; typedef convert_iterator first_converter; typedef typename first_converter::type first_type; typedef Base base_type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED flatten_view_iterator(First const& first, Base const& base) : first(first), base(base) {} first_type first; base_type base; }; }} namespace boost { namespace fusion { namespace detail { template struct make_descent_cons { typedef cons type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(Iterator const& it) { return type(it); } }; template struct make_descent_cons::type> >::type> { // we use 'value_of' above for convenience, assuming the value won't be reference, // while we must use the regular 'deref' here for const issues... typedef typename remove_reference::type>::type sub_sequence; typedef typename result_of::begin::type sub_begin; typedef cons::type> type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(Iterator const& it) { return type(it, make_descent_cons::apply( fusion::begin(*it))); } }; template struct build_flatten_view_iterator; template struct build_flatten_view_iterator, Base> { typedef flatten_view_iterator type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(cons const& cons, Base const& base) { return type(cons.car, base); } }; template struct build_flatten_view_iterator, Base> { typedef flatten_view_iterator next_base; typedef build_flatten_view_iterator next; typedef typename next::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(cons const& cons, Base const& base) { return next::apply(cons.cdr, next_base(cons.car, base)); } }; template struct seek_descent { typedef make_descent_cons make_descent_cons_; typedef typename make_descent_cons_::type cons_type; typedef build_flatten_view_iterator build_flatten_view_iterator_; typedef typename build_flatten_view_iterator_::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(Base const& base, Iterator const& it) { return build_flatten_view_iterator_::apply( make_descent_cons_::apply(it), base); } }; template struct seek_descent::type>::type> >::type> { typedef typename result_of::next::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type apply(Base const& base, Iterator const&) { return fusion::next(base); } }; }}} namespace boost { namespace fusion { namespace extension { template<> struct next_impl { template struct apply { typedef typename Iterator::first_type first_type; typedef typename Iterator::base_type base_type; typedef typename result_of::next::type next_type; typedef detail::seek_descent seek_descent; typedef typename seek_descent::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type call(Iterator const& it) { return seek_descent::apply(it.base, fusion::next(it.first)); } }; }; template<> struct deref_impl { template struct apply { typedef typename result_of::deref::type type; BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED static inline type call(Iterator const& it) { return *it.first; } }; }; template<> struct value_of_impl { template struct apply { typedef typename result_of::value_of::type type; }; }; }}} #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408 namespace std { template struct iterator_traits< ::boost::fusion::flatten_view_iterator > { }; } #endif #endif