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