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 | { |
38 | 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 |
56 | 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 |
76 | 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 |
136 | 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 | |