| /*============================================================================= |
| Copyright (c) 2011 Eric Niebler |
| |
| 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) |
| ==============================================================================*/ |
| #if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED) |
| #define BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED |
| |
| #include <boost/fusion/support/config.hpp> |
| #include <boost/mpl/bool.hpp> |
| #include <boost/fusion/sequence/intrinsic_fwd.hpp> |
| #include <boost/fusion/iterator/iterator_facade.hpp> |
| #include <boost/fusion/iterator/deref.hpp> |
| #include <boost/fusion/iterator/deref_data.hpp> |
| #include <boost/fusion/iterator/key_of.hpp> |
| #include <boost/fusion/iterator/value_of.hpp> |
| #include <boost/fusion/iterator/value_of_data.hpp> |
| #include <boost/fusion/iterator/detail/segmented_equal_to.hpp> |
| |
| namespace boost { namespace fusion |
| { |
| struct nil_; |
| |
| namespace detail |
| { |
| template <typename Stack> |
| struct segmented_next_impl; |
| } |
| |
| // A segmented iterator wraps a "context", which is a cons list |
| // of ranges, the frontmost is range over values and the rest |
| // are ranges over internal segments. |
| template <typename Context> |
| struct segmented_iterator |
| : iterator_facade<segmented_iterator<Context>, forward_traversal_tag> |
| { |
| BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED explicit segmented_iterator(Context const& ctx) |
| : context(ctx) |
| {} |
| |
| //auto deref(it) |
| //{ |
| // return deref(begin(car(it.context))) |
| //} |
| template <typename It> |
| struct deref |
| { |
| typedef |
| typename result_of::deref< |
| typename It::context_type::car_type::begin_type |
| >::type |
| type; |
| |
| BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| static type call(It const& it) |
| { |
| return *it.context.car.first; |
| } |
| }; |
| |
| //auto deref_data(it) |
| //{ |
| // return deref_data(begin(car(it.context))) |
| //} |
| template <typename It> |
| struct deref_data |
| { |
| typedef |
| typename result_of::deref_data< |
| typename It::context_type::car_type::begin_type |
| >::type |
| type; |
| |
| BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| static type call(It const& it) |
| { |
| return fusion::deref_data(it.context.car.first); |
| } |
| }; |
| |
| //auto key_of(it) |
| //{ |
| // return key_of(begin(car(it.context))) |
| //} |
| template <typename It> |
| struct key_of |
| : result_of::key_of<typename It::context_type::car_type::begin_type> |
| {}; |
| |
| //auto value_of(it) |
| //{ |
| // return value_of(begin(car(it.context))) |
| //} |
| template <typename It> |
| struct value_of |
| : result_of::value_of<typename It::context_type::car_type::begin_type> |
| {}; |
| |
| //auto value_of_data(it) |
| //{ |
| // return value_of_data(begin(car(it.context))) |
| //} |
| template <typename It> |
| struct value_of_data |
| : result_of::value_of_data<typename It::context_type::car_type::begin_type> |
| {}; |
| |
| // Compare all the segment iterators in each stack, starting with |
| // the bottom-most. |
| template < |
| typename It1 |
| , typename It2 |
| , int Size1 = It1::context_type::size::value |
| , int Size2 = It2::context_type::size::value |
| > |
| struct equal_to |
| : mpl::false_ |
| {}; |
| |
| template <typename It1, typename It2, int Size> |
| struct equal_to<It1, It2, Size, Size> |
| : detail::segmented_equal_to< |
| typename It1::context_type |
| , typename It2::context_type |
| > |
| {}; |
| |
| template <typename It> |
| struct next |
| { |
| typedef detail::segmented_next_impl<typename It::context_type> impl; |
| typedef segmented_iterator<typename impl::type> type; |
| |
| BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| static type call(It const& it) |
| { |
| return type(impl::call(it.context)); |
| } |
| }; |
| |
| typedef Context context_type; |
| context_type context; |
| }; |
| |
| }} |
| |
| #endif |