]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // cons.hpp | |
3 | // | |
4 | // Copyright 2008 Eric Niebler. Distributed under the Boost | |
5 | // Software License, Version 1.0. (See accompanying file | |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 | |
9 | #define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 | |
10 | ||
11 | #include <boost/version.hpp> | |
12 | ||
13 | #if BOOST_VERSION >= 103300 | |
14 | ||
15 | // In Boost 1.33+, we have a cons list in Fusion, so just include it. | |
16 | ||
17 | # if BOOST_VERSION >= 103500 | |
18 | # include <boost/fusion/include/cons.hpp> // Boost 1.35+ has Fusion2 | |
19 | # else | |
20 | # include <boost/spirit/fusion/sequence/cons.hpp> // Fusion1 | |
21 | # endif | |
22 | ||
23 | #else | |
24 | ||
25 | // For earlier versions of Boost, put the definition of cons here | |
26 | # include <boost/call_traits.hpp> | |
27 | # include <boost/mpl/if.hpp> | |
28 | # include <boost/mpl/eval_if.hpp> | |
29 | # include <boost/mpl/identity.hpp> | |
30 | # include <boost/type_traits/is_const.hpp> | |
31 | # include <boost/type_traits/add_const.hpp> | |
32 | # include <boost/type_traits/add_reference.hpp> | |
33 | # include <boost/spirit/fusion/detail/config.hpp> | |
34 | # include <boost/spirit/fusion/detail/access.hpp> | |
35 | # include <boost/spirit/fusion/iterator/next.hpp> | |
36 | # include <boost/spirit/fusion/iterator/equal_to.hpp> | |
37 | # include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp> | |
38 | # include <boost/spirit/fusion/iterator/detail/iterator_base.hpp> | |
39 | # include <boost/spirit/fusion/sequence/begin.hpp> | |
40 | # include <boost/spirit/fusion/sequence/end.hpp> | |
41 | # include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp> | |
42 | # include <boost/spirit/fusion/sequence/detail/sequence_base.hpp> | |
43 | ||
44 | namespace boost { namespace fusion | |
45 | { | |
46 | struct nil; | |
47 | ||
48 | struct cons_tag; | |
49 | ||
50 | template <typename Car, typename Cdr> | |
51 | struct cons; | |
52 | ||
53 | struct cons_iterator_tag; | |
54 | ||
55 | template <typename Cons> | |
56 | struct cons_iterator; | |
57 | ||
58 | namespace cons_detail | |
59 | { | |
60 | template <typename Iterator> | |
61 | struct deref_traits_impl | |
62 | { | |
63 | typedef typename Iterator::cons_type cons_type; | |
64 | typedef typename cons_type::car_type value_type; | |
65 | ||
66 | typedef typename mpl::eval_if< | |
67 | is_const<cons_type> | |
68 | , add_reference<typename add_const<value_type>::type> | |
69 | , add_reference<value_type> >::type | |
70 | type; | |
71 | ||
72 | static type | |
73 | call(Iterator const& i) | |
74 | { | |
75 | return detail::ref(i.cons.car); | |
76 | } | |
77 | }; | |
78 | ||
79 | template <typename Iterator> | |
80 | struct next_traits_impl | |
81 | { | |
82 | typedef typename Iterator::cons_type cons_type; | |
83 | typedef typename cons_type::cdr_type cdr_type; | |
84 | ||
85 | typedef cons_iterator< | |
86 | typename mpl::eval_if< | |
87 | is_const<cons_type> | |
88 | , add_const<cdr_type> | |
89 | , mpl::identity<cdr_type> | |
90 | >::type> | |
91 | type; | |
92 | ||
93 | static type | |
94 | call(Iterator const& i) | |
95 | { | |
96 | return type(detail::ref(i.cons.cdr)); | |
97 | } | |
98 | }; | |
99 | ||
100 | template <typename Iterator> | |
101 | struct value_traits_impl | |
102 | { | |
103 | typedef typename Iterator::cons_type cons_type; | |
104 | typedef typename cons_type::car_type type; | |
105 | }; | |
106 | ||
107 | template <typename Cons> | |
108 | struct begin_traits_impl | |
109 | { | |
110 | typedef cons_iterator<Cons> type; | |
111 | ||
112 | static type | |
113 | call(Cons& t) | |
114 | { | |
115 | return type(t); | |
116 | } | |
117 | }; | |
118 | ||
119 | template <typename Cons> | |
120 | struct end_traits_impl | |
121 | { | |
122 | typedef cons_iterator< | |
123 | typename mpl::if_<is_const<Cons>, nil const, nil>::type> | |
124 | type; | |
125 | ||
126 | static type | |
127 | call(Cons& t) | |
128 | { | |
129 | FUSION_RETURN_DEFAULT_CONSTRUCTED; | |
130 | } | |
131 | }; | |
132 | } // namespace cons_detail | |
133 | ||
134 | namespace meta | |
135 | { | |
136 | template <typename Tag> | |
137 | struct deref_impl; | |
138 | ||
139 | template <> | |
140 | struct deref_impl<cons_iterator_tag> | |
141 | { | |
142 | template <typename Iterator> | |
143 | struct apply : cons_detail::deref_traits_impl<Iterator> {}; | |
144 | }; | |
145 | ||
146 | template <typename Tag> | |
147 | struct next_impl; | |
148 | ||
149 | template <> | |
150 | struct next_impl<cons_iterator_tag> | |
151 | { | |
152 | template <typename Iterator> | |
153 | struct apply : cons_detail::next_traits_impl<Iterator> {}; | |
154 | }; | |
155 | ||
156 | template <typename Tag> | |
157 | struct value_impl; | |
158 | ||
159 | template <> | |
160 | struct value_impl<cons_iterator_tag> | |
161 | { | |
162 | template <typename Iterator> | |
163 | struct apply : cons_detail::value_traits_impl<Iterator> {}; | |
164 | }; | |
165 | ||
166 | template <typename Tag> | |
167 | struct begin_impl; | |
168 | ||
169 | template <> | |
170 | struct begin_impl<cons_tag> | |
171 | { | |
172 | template <typename Sequence> | |
173 | struct apply : cons_detail::begin_traits_impl<Sequence> | |
174 | {}; | |
175 | }; | |
176 | ||
177 | template <typename Tag> | |
178 | struct end_impl; | |
179 | ||
180 | template <> | |
181 | struct end_impl<cons_tag> | |
182 | { | |
183 | template <typename Sequence> | |
184 | struct apply : cons_detail::end_traits_impl<Sequence> | |
185 | {}; | |
186 | }; | |
187 | } // namespace meta | |
188 | ||
189 | template <typename Cons = nil> | |
190 | struct cons_iterator : iterator_base<cons_iterator<Cons> > | |
191 | { | |
192 | typedef cons_iterator_tag tag; | |
193 | typedef Cons cons_type; | |
194 | ||
195 | explicit cons_iterator(cons_type& cons_) | |
196 | : cons(cons_) {} | |
197 | ||
198 | cons_type& cons; | |
199 | }; | |
200 | ||
201 | template <> | |
202 | struct cons_iterator<nil> : iterator_base<cons_iterator<nil> > | |
203 | { | |
204 | typedef cons_iterator_tag tag; | |
205 | typedef nil cons_type; | |
206 | cons_iterator() {} | |
207 | explicit cons_iterator(nil const&) {} | |
208 | }; | |
209 | ||
210 | template <> | |
211 | struct cons_iterator<nil const> : iterator_base<cons_iterator<nil const> > | |
212 | { | |
213 | typedef cons_iterator_tag tag; | |
214 | typedef nil const cons_type; | |
215 | cons_iterator() {} | |
216 | explicit cons_iterator(nil const&) {} | |
217 | }; | |
218 | ||
219 | struct nil : sequence_base<nil> | |
220 | { | |
221 | typedef cons_tag tag; | |
222 | typedef void_t car_type; | |
223 | typedef void_t cdr_type; | |
224 | }; | |
225 | ||
226 | template <typename Car, typename Cdr = nil> | |
227 | struct cons : sequence_base<cons<Car,Cdr> > | |
228 | { | |
229 | typedef cons_tag tag; | |
230 | typedef typename call_traits<Car>::value_type car_type; | |
231 | typedef Cdr cdr_type; | |
232 | ||
233 | cons() | |
234 | : car(), cdr() {} | |
235 | ||
236 | explicit cons( | |
237 | typename call_traits<Car>::param_type car_ | |
238 | , typename call_traits<Cdr>::param_type cdr_ = Cdr()) | |
239 | : car(car_), cdr(cdr_) {} | |
240 | ||
241 | car_type car; | |
242 | cdr_type cdr; | |
243 | }; | |
244 | ||
245 | template <typename Car> | |
246 | inline cons<Car> | |
247 | make_cons(Car const& car) | |
248 | { | |
249 | return cons<Car>(car); | |
250 | } | |
251 | ||
252 | template <typename Car, typename Cdr> | |
253 | inline cons<Car, Cdr> | |
254 | make_cons(Car const& car, Cdr const& cdr) | |
255 | { | |
256 | return cons<Car, Cdr>(car, cdr); | |
257 | } | |
258 | }} // namespace boost::fusion | |
259 | ||
260 | namespace boost { namespace mpl | |
261 | { | |
262 | template <typename Tag> | |
263 | struct begin_impl; | |
264 | ||
265 | template <typename Tag> | |
266 | struct end_impl; | |
267 | ||
268 | template <> | |
269 | struct begin_impl<fusion::cons_tag> | |
270 | : fusion::meta::begin_impl<fusion::cons_tag> | |
271 | { | |
272 | }; | |
273 | ||
274 | template <> | |
275 | struct end_impl<fusion::cons_tag> | |
276 | : fusion::meta::end_impl<fusion::cons_tag> | |
277 | { | |
278 | }; | |
279 | ||
280 | }} // namespace boost::mpl | |
281 | ||
282 | #endif | |
283 | ||
284 | // Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences. | |
285 | #if BOOST_VERSION < 103301 | |
286 | namespace boost { namespace mpl | |
287 | { | |
288 | template<typename Iterator> | |
289 | struct next; | |
290 | ||
291 | template<typename Cons> | |
292 | struct next<fusion::cons_iterator<Cons> > | |
293 | : fusion::cons_detail::next_traits_impl<fusion::cons_iterator<Cons> > | |
294 | { | |
295 | }; | |
296 | ||
297 | template<typename Iterator> | |
298 | struct deref; | |
299 | ||
300 | template<typename Cons> | |
301 | struct deref<fusion::cons_iterator<Cons> > | |
302 | : fusion::cons_detail::value_traits_impl<fusion::cons_iterator<Cons> > | |
303 | { | |
304 | }; | |
305 | ||
306 | }} // namespace boost::mpl | |
307 | #endif | |
308 | ||
309 | #endif |