1 /*=============================================================================
2     Copyright (c) 2011 Eric Niebler
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED)
8 #define BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED
9 
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/mpl/bool.hpp>
12 #include <boost/fusion/sequence/intrinsic_fwd.hpp>
13 #include <boost/fusion/iterator/iterator_facade.hpp>
14 #include <boost/fusion/iterator/deref.hpp>
15 #include <boost/fusion/iterator/deref_data.hpp>
16 #include <boost/fusion/iterator/key_of.hpp>
17 #include <boost/fusion/iterator/value_of.hpp>
18 #include <boost/fusion/iterator/value_of_data.hpp>
19 #include <boost/fusion/iterator/detail/segmented_equal_to.hpp>
20 
21 namespace boost { namespace fusion
22 {
23     struct nil_;
24 
25     namespace detail
26     {
27         template <typename Stack>
28         struct segmented_next_impl;
29     }
30 
31     // A segmented iterator wraps a "context", which is a cons list
32     // of ranges, the frontmost is range over values and the rest
33     // are ranges over internal segments.
34     template <typename Context>
35     struct segmented_iterator
36       : iterator_facade<segmented_iterator<Context>, forward_traversal_tag>
37     {
segmented_iteratorboost::fusion::segmented_iterator38         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED explicit segmented_iterator(Context const& ctx)
39           : context(ctx)
40         {}
41 
42         //auto deref(it)
43         //{
44         //  return deref(begin(car(it.context)))
45         //}
46         template <typename It>
47         struct deref
48         {
49             typedef
50                 typename result_of::deref<
51                     typename It::context_type::car_type::begin_type
52                 >::type
53             type;
54 
55             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::segmented_iterator::deref56             static type call(It const& it)
57             {
58                 return *it.context.car.first;
59             }
60         };
61 
62         //auto deref_data(it)
63         //{
64         //  return deref_data(begin(car(it.context)))
65         //}
66         template <typename It>
67         struct deref_data
68         {
69             typedef
70                 typename result_of::deref_data<
71                     typename It::context_type::car_type::begin_type
72                 >::type
73             type;
74 
75             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::segmented_iterator::deref_data76             static type call(It const& it)
77             {
78                 return fusion::deref_data(it.context.car.first);
79             }
80         };
81 
82         //auto key_of(it)
83         //{
84         //  return key_of(begin(car(it.context)))
85         //}
86         template <typename It>
87         struct key_of
88           : result_of::key_of<typename It::context_type::car_type::begin_type>
89         {};
90 
91         //auto value_of(it)
92         //{
93         //  return value_of(begin(car(it.context)))
94         //}
95         template <typename It>
96         struct value_of
97           : result_of::value_of<typename It::context_type::car_type::begin_type>
98         {};
99 
100         //auto value_of_data(it)
101         //{
102         //  return value_of_data(begin(car(it.context)))
103         //}
104         template <typename It>
105         struct value_of_data
106           : result_of::value_of_data<typename It::context_type::car_type::begin_type>
107         {};
108 
109         // Compare all the segment iterators in each stack, starting with
110         // the bottom-most.
111         template <
112             typename It1
113           , typename It2
114           , int Size1 = It1::context_type::size::value
115           , int Size2 = It2::context_type::size::value
116         >
117         struct equal_to
118           : mpl::false_
119         {};
120 
121         template <typename It1, typename It2, int Size>
122         struct equal_to<It1, It2, Size, Size>
123           : detail::segmented_equal_to<
124                 typename It1::context_type
125               , typename It2::context_type
126             >
127         {};
128 
129         template <typename It>
130         struct next
131         {
132             typedef detail::segmented_next_impl<typename It::context_type> impl;
133             typedef segmented_iterator<typename impl::type> type;
134 
135             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
callboost::fusion::segmented_iterator::next136             static type call(It const& it)
137             {
138                 return type(impl::call(it.context));
139             }
140         };
141 
142         typedef Context context_type;
143         context_type context;
144     };
145 
146 }}
147 
148 #endif
149