Chris@102
|
1 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 // lazy prelude.hpp
|
Chris@102
|
3 //
|
Chris@102
|
4 // Build lazy operations for Phoenix equivalents for FC++
|
Chris@102
|
5 //
|
Chris@102
|
6 // These are equivalents of the Boost FC++ functoids in prelude.hpp
|
Chris@102
|
7 //
|
Chris@102
|
8 // Usage: All of these are functors which need various numbers of arguments.
|
Chris@102
|
9 // Those can be supplied as real arguments or as Phoenix arguments.
|
Chris@102
|
10 // Execution will happen when all the arguments are supplied.
|
Chris@102
|
11 // e.g.
|
Chris@102
|
12 // take(2,list)() or take(2,arg1)(list)
|
Chris@102
|
13 //
|
Chris@102
|
14 // Implemented so far:
|
Chris@102
|
15 //
|
Chris@102
|
16 // id (moved back to operators.hpp)
|
Chris@102
|
17 //
|
Chris@102
|
18 // A lot of what comes here uses the list type, so that will be needed first.
|
Chris@102
|
19 //
|
Chris@102
|
20 // Now that list<T> is available I can start to build things here.
|
Chris@102
|
21 //
|
Chris@102
|
22 //
|
Chris@102
|
23 // until(pred,f,start) - if pred(start) is true, return start
|
Chris@102
|
24 // apply value = f(start)
|
Chris@102
|
25 // apply value = f(value)
|
Chris@102
|
26 // until pred(value) is true
|
Chris@102
|
27 // return value
|
Chris@102
|
28 //
|
Chris@102
|
29 // The predicate argument pred must be a lazy function taking one argument
|
Chris@102
|
30 // and returning bool.
|
Chris@102
|
31 // This can be a lazy function with an argument already.
|
Chris@102
|
32 // This has to be declared before the call to until.
|
Chris@102
|
33 // The type can be declated using Predicate as in this example:
|
Chris@102
|
34 //
|
Chris@102
|
35 // Predicate<int>::type f(greater(arg1,10));
|
Chris@102
|
36 // std::cout << until(f, inc, 1)() << std::endl;
|
Chris@102
|
37 //
|
Chris@102
|
38 // until2(pred,f,start,value2) - if pred(start,value2) is true, return start
|
Chris@102
|
39 // apply value1 = f(start)
|
Chris@102
|
40 // apply value1 = f(value1)
|
Chris@102
|
41 // until pred(value1,value2) is true
|
Chris@102
|
42 // return value1
|
Chris@102
|
43 //
|
Chris@102
|
44 // NOTE: until2 has been defined because this code does not support
|
Chris@102
|
45 // FC++ currying, so that a partial function cannot be passed
|
Chris@102
|
46 // as an argument. This provides a way of passing a second parameter.
|
Chris@102
|
47 // There is now the option to use Predicate<T> as shown above.
|
Chris@102
|
48 //
|
Chris@102
|
49 // odd(n) true if n is odd
|
Chris@102
|
50 // even(n) true if n is even
|
Chris@102
|
51 //
|
Chris@102
|
52 // last(list)
|
Chris@102
|
53 // all_but_last(list)
|
Chris@102
|
54 // at(list,n)
|
Chris@102
|
55 // length(list)
|
Chris@102
|
56 // filter(pred,list)
|
Chris@102
|
57 // iterate(function,value)
|
Chris@102
|
58 // repeat(value)
|
Chris@102
|
59 // take(n,list)
|
Chris@102
|
60 // drop(n,list)
|
Chris@102
|
61 // enum_from(x)
|
Chris@102
|
62 // enum_from_to(x,y)
|
Chris@102
|
63 //
|
Chris@102
|
64 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
65 // Interdependence:
|
Chris@102
|
66 // The old Boost FC++ has a set of headers which interelate and call each
|
Chris@102
|
67 // other in a complicated way. I am going to document the interdependence
|
Chris@102
|
68 // of the files here. I will then make sure that they are called correctly
|
Chris@102
|
69 // starting from this file. John Fletcher. February 2015.
|
Chris@102
|
70 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
71 // BoostFC++ header sequence:
|
Chris@102
|
72 //
|
Chris@102
|
73 // prelude.hpp -> list.hpp (optinally monad.hpp at end)
|
Chris@102
|
74 // list.hpp -> reuse.hpp
|
Chris@102
|
75 // reuse.hpp -> function.hpp
|
Chris@102
|
76 // function.hpp -> ref_count.hpp operator.hpp
|
Chris@102
|
77 // ref_count.hpp -> config.hpp boost headers and RefCountType definition
|
Chris@102
|
78 // operator.hpp -> lambda.hpp
|
Chris@102
|
79 // lambda.hpp -> full.hpp (use of lambda internals is optional)
|
Chris@102
|
80 // full.hpp -> smart.hpp curry.hpp pre_lambda.hpp (optionally full4.hpp)
|
Chris@102
|
81 // smart.hpp -> signature.hpp
|
Chris@102
|
82 // curry.hpp -> signature.hpp
|
Chris@102
|
83 // signature.hpp -> config.hpp
|
Chris@102
|
84 //
|
Chris@102
|
85 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
86 // Proposed order in lazy_prelude.hpp
|
Chris@102
|
87 // on the basis that files need what they call.
|
Chris@102
|
88 //
|
Chris@102
|
89 // lazy_config.hpp (If needed)* probably not needed.
|
Chris@102
|
90 // lazy_signature.hpp (If needed)*
|
Chris@102
|
91 // lazy_smart.hpp (If needed)*
|
Chris@102
|
92 // lazy_curry.hpp (If needed)*
|
Chris@102
|
93 // lazy_full.hpp (If needed)*
|
Chris@102
|
94 // lazy_operator.hpp (absorb definition of RefCountType)
|
Chris@102
|
95 // lazy_function.hpp (may not now be needed)
|
Chris@102
|
96 // lazy_reuse.hpp (implemented without use of FC++ functions)
|
Chris@102
|
97 // lazy_list.hpp
|
Chris@102
|
98 //
|
Chris@102
|
99 // * file does not yet exist.
|
Chris@102
|
100 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
101 // This is implemented such that no other lazy_ file calls other lazy_ files.
|
Chris@102
|
102 // They do call their own external files, which may well be duplicates.
|
Chris@102
|
103 // That can be sorted out later.
|
Chris@102
|
104 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
105 // Notes: full and curry operations should be covered by Phoenix.
|
Chris@102
|
106 // The lambda operations are quite different from Phoenix lambda
|
Chris@102
|
107 // and will be omitted.
|
Chris@102
|
108 // The implementation monad can be postponed.
|
Chris@102
|
109 // Some of function and reuse are needed for the list type.
|
Chris@102
|
110 // I will review later whether they are part of the external interface.
|
Chris@102
|
111 //
|
Chris@102
|
112 // John Fletcher February 2015.
|
Chris@102
|
113 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
114 /*=============================================================================
|
Chris@102
|
115 Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
|
Chris@102
|
116 Copyright (c) 2001-2007 Joel de Guzman
|
Chris@102
|
117 Copyright (c) 2015 John Fletcher
|
Chris@102
|
118
|
Chris@102
|
119 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
120 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
121 ==============================================================================*/
|
Chris@102
|
122
|
Chris@102
|
123
|
Chris@102
|
124 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE
|
Chris@102
|
125 #define BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE
|
Chris@102
|
126
|
Chris@102
|
127 #include <exception>
|
Chris@102
|
128 #include <vector>
|
Chris@102
|
129 #include <boost/phoenix/core.hpp>
|
Chris@102
|
130 #include <boost/phoenix/function.hpp>
|
Chris@102
|
131 #include <boost/phoenix/scope.hpp>
|
Chris@102
|
132 #include <boost/phoenix/operator.hpp>
|
Chris@102
|
133 #include <boost/phoenix/function/lazy_operator.hpp>
|
Chris@102
|
134 #include <boost/phoenix/function/lazy_reuse.hpp>
|
Chris@102
|
135 #include <boost/phoenix/function/lazy_list.hpp>
|
Chris@102
|
136
|
Chris@102
|
137 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
138 // To come here, the Haskell Prelude things which need list<T>.
|
Chris@102
|
139 // Things which do not need list<T> are in lazy_operator.hpp.
|
Chris@102
|
140 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
141
|
Chris@102
|
142 namespace boost {
|
Chris@102
|
143
|
Chris@102
|
144 namespace phoenix {
|
Chris@102
|
145
|
Chris@102
|
146 // These are in fcpp namespace as they introduce an FC++ style.
|
Chris@102
|
147 namespace fcpp {
|
Chris@102
|
148
|
Chris@102
|
149 template <typename T>
|
Chris@102
|
150 struct Predicate {
|
Chris@102
|
151 typedef typename boost::function1<bool,T> fun1_bool_T;
|
Chris@102
|
152 typedef typename boost::phoenix::function<fun1_bool_T> bool_F_T;
|
Chris@102
|
153 typedef bool_F_T type;
|
Chris@102
|
154 };
|
Chris@102
|
155
|
Chris@102
|
156 template <typename R>
|
Chris@102
|
157 struct Function0 {
|
Chris@102
|
158 typedef typename boost::function0<R> fun0_R;
|
Chris@102
|
159 typedef typename boost::phoenix::function<fun0_R> R_F;
|
Chris@102
|
160 typedef R_F type;
|
Chris@102
|
161 };
|
Chris@102
|
162
|
Chris@102
|
163 template <typename R,typename A0>
|
Chris@102
|
164 struct Function1 {
|
Chris@102
|
165 typedef typename boost::function1<R,A0> fun1_R_A0;
|
Chris@102
|
166 typedef typename boost::phoenix::function<fun1_R_A0> R_F_A0;
|
Chris@102
|
167 typedef R_F_A0 type;
|
Chris@102
|
168 };
|
Chris@102
|
169
|
Chris@102
|
170 template <typename R, typename A0, typename A1>
|
Chris@102
|
171 struct Function2 {
|
Chris@102
|
172 typedef typename boost::function2<R,A0,A1> fun2_R_A0_A1;
|
Chris@102
|
173 typedef typename boost::phoenix::function<fun2_R_A0_A1> R_F_A0_A1;
|
Chris@102
|
174 typedef R_F_A0_A1 type;
|
Chris@102
|
175 };
|
Chris@102
|
176
|
Chris@102
|
177 }
|
Chris@102
|
178
|
Chris@102
|
179 namespace impl {
|
Chris@102
|
180 using fcpp::INV;
|
Chris@102
|
181 using fcpp::VAR;
|
Chris@102
|
182 using fcpp::reuser1;
|
Chris@102
|
183 using fcpp::reuser2;
|
Chris@102
|
184 using fcpp::reuser3;
|
Chris@102
|
185 using boost::phoenix::arg_names::arg1;
|
Chris@102
|
186
|
Chris@102
|
187 struct Pow {
|
Chris@102
|
188
|
Chris@102
|
189 template <typename Sig>
|
Chris@102
|
190 struct result;
|
Chris@102
|
191
|
Chris@102
|
192 template <typename This, typename N, typename A0>
|
Chris@102
|
193 struct result<This(N,A0)>
|
Chris@102
|
194 : boost::remove_reference<A0>
|
Chris@102
|
195 {};
|
Chris@102
|
196
|
Chris@102
|
197 template <typename N, typename A0>
|
Chris@102
|
198 A0 operator()(N n, const A0 & a0,
|
Chris@102
|
199 reuser2<INV,VAR,INV,Pow,N,A0> r = NIL ) const {
|
Chris@102
|
200 if ( n <= 0 )
|
Chris@102
|
201 return A0(1);
|
Chris@102
|
202 else if ( n==1 )
|
Chris@102
|
203 return a0;
|
Chris@102
|
204 else {
|
Chris@102
|
205 A0 a1 = r( Pow(), n-1, a0)();
|
Chris@102
|
206 return a0*a1;
|
Chris@102
|
207 }
|
Chris@102
|
208 }
|
Chris@102
|
209
|
Chris@102
|
210 };
|
Chris@102
|
211
|
Chris@102
|
212 struct Apply {
|
Chris@102
|
213
|
Chris@102
|
214 template <typename Sig>
|
Chris@102
|
215 struct result;
|
Chris@102
|
216
|
Chris@102
|
217 template <typename This, typename N, typename F,typename A0>
|
Chris@102
|
218 struct result<This(N,F,A0)>
|
Chris@102
|
219 : boost::remove_reference<A0>
|
Chris@102
|
220 {};
|
Chris@102
|
221
|
Chris@102
|
222 template <typename N, typename F, typename A0>
|
Chris@102
|
223 A0 operator()(N n, const F &f, const A0 & a0,
|
Chris@102
|
224 reuser3<INV,VAR,INV,INV,Apply,N,F,A0> r = NIL ) const {
|
Chris@102
|
225 if ( n <= 0 )
|
Chris@102
|
226 return a0;
|
Chris@102
|
227 else if ( n==1 )
|
Chris@102
|
228 return f(arg1)(a0);
|
Chris@102
|
229 else {
|
Chris@102
|
230 A0 a1 = r( Apply(), n-1, f, a0)();
|
Chris@102
|
231 return f(a1)();
|
Chris@102
|
232 }
|
Chris@102
|
233 }
|
Chris@102
|
234
|
Chris@102
|
235 };
|
Chris@102
|
236
|
Chris@102
|
237 struct Odd {
|
Chris@102
|
238 template <typename Sig>
|
Chris@102
|
239 struct result;
|
Chris@102
|
240
|
Chris@102
|
241 template <typename This, typename T>
|
Chris@102
|
242 struct result<This(T)>
|
Chris@102
|
243 {
|
Chris@102
|
244 typedef bool type;
|
Chris@102
|
245 };
|
Chris@102
|
246
|
Chris@102
|
247 template <class T>
|
Chris@102
|
248 typename result<Odd(T)>::type operator()( const T& x ) const {
|
Chris@102
|
249 return x%2==1;
|
Chris@102
|
250 }
|
Chris@102
|
251 };
|
Chris@102
|
252
|
Chris@102
|
253 struct Even {
|
Chris@102
|
254 template <typename Sig>
|
Chris@102
|
255 struct result;
|
Chris@102
|
256
|
Chris@102
|
257 template <typename This, typename T>
|
Chris@102
|
258 struct result<This(T)>
|
Chris@102
|
259 {
|
Chris@102
|
260 typedef bool type;
|
Chris@102
|
261 };
|
Chris@102
|
262
|
Chris@102
|
263 template <class T>
|
Chris@102
|
264 typename result<Even(T)>::type operator()( const T& x ) const {
|
Chris@102
|
265 return x%2==0;
|
Chris@102
|
266 }
|
Chris@102
|
267 };
|
Chris@102
|
268
|
Chris@102
|
269 }
|
Chris@102
|
270 typedef boost::phoenix::function<impl::Pow> Pow;
|
Chris@102
|
271 typedef boost::phoenix::function<impl::Apply> Apply;
|
Chris@102
|
272 typedef boost::phoenix::function<impl::Odd> Odd;
|
Chris@102
|
273 typedef boost::phoenix::function<impl::Even> Even;
|
Chris@102
|
274 Pow pow;
|
Chris@102
|
275 Apply apply;
|
Chris@102
|
276 Odd odd;
|
Chris@102
|
277 Even even;
|
Chris@102
|
278
|
Chris@102
|
279 namespace impl {
|
Chris@102
|
280 using fcpp::INV;
|
Chris@102
|
281 using fcpp::VAR;
|
Chris@102
|
282 using fcpp::reuser1;
|
Chris@102
|
283 using fcpp::reuser2;
|
Chris@102
|
284 using fcpp::reuser3;
|
Chris@102
|
285 using boost::phoenix::arg_names::arg1;
|
Chris@102
|
286
|
Chris@102
|
287 // I cannot yet do currying to pass e.g. greater(9,arg1)
|
Chris@102
|
288 // as a function. This can be done using Predicate<T>::type.
|
Chris@102
|
289 struct Until {
|
Chris@102
|
290
|
Chris@102
|
291 template <typename Sig> struct result;
|
Chris@102
|
292
|
Chris@102
|
293 template <typename This, typename Pred, typename Unary, typename T>
|
Chris@102
|
294 struct result<This(Pred,Unary,T)>
|
Chris@102
|
295 : boost::remove_reference<T> {};
|
Chris@102
|
296
|
Chris@102
|
297 template <class Pred, class Unary, class T>
|
Chris@102
|
298 T operator()( const Pred& p,const Unary& op,const T &start) const
|
Chris@102
|
299 {
|
Chris@102
|
300 T tmp = start;
|
Chris@102
|
301 while( !p(tmp)() ) {
|
Chris@102
|
302 tmp = apply(1,op,tmp)();
|
Chris@102
|
303 }
|
Chris@102
|
304 return tmp;
|
Chris@102
|
305 }
|
Chris@102
|
306
|
Chris@102
|
307 };
|
Chris@102
|
308
|
Chris@102
|
309 struct Until2 {
|
Chris@102
|
310
|
Chris@102
|
311 template <typename Sig> struct result;
|
Chris@102
|
312
|
Chris@102
|
313 template <typename This, typename Binary, typename Unary,
|
Chris@102
|
314 typename T, typename X>
|
Chris@102
|
315 struct result<This(Binary,Unary,T,X)>
|
Chris@102
|
316 : boost::remove_reference<T> {};
|
Chris@102
|
317
|
Chris@102
|
318 template <class Binary, class Unary, class T, class X>
|
Chris@102
|
319 typename result<Until2(Binary,Unary,T,X)>::type
|
Chris@102
|
320 operator()( const Binary& p, const Unary& op, const T & start,
|
Chris@102
|
321 const X & check ) const
|
Chris@102
|
322 {
|
Chris@102
|
323 T tmp1 = start;
|
Chris@102
|
324 T tmp2;
|
Chris@102
|
325 while( !p(tmp1,check)() ) {
|
Chris@102
|
326 tmp2 = apply(1,op,tmp1)();
|
Chris@102
|
327 tmp1 = tmp2;
|
Chris@102
|
328
|
Chris@102
|
329 }
|
Chris@102
|
330 return tmp1;
|
Chris@102
|
331 }
|
Chris@102
|
332 };
|
Chris@102
|
333
|
Chris@102
|
334 struct Last {
|
Chris@102
|
335 template <typename Sig> struct result;
|
Chris@102
|
336
|
Chris@102
|
337 template <typename This, typename L>
|
Chris@102
|
338 struct result<This(L)>
|
Chris@102
|
339 {
|
Chris@102
|
340 typedef typename result_of::ListType<L>::value_type type;
|
Chris@102
|
341 };
|
Chris@102
|
342
|
Chris@102
|
343 template <class L>
|
Chris@102
|
344 typename result<Last(L)>::type
|
Chris@102
|
345 operator()( const L& ll ) const {
|
Chris@102
|
346 size_t x = 0;
|
Chris@102
|
347 typename result_of::ListType<L>::delay_result_type l = delay(ll);
|
Chris@102
|
348 while( !null( tail(l)() )() ) {
|
Chris@102
|
349 l = tail(l)();
|
Chris@102
|
350 ++x;
|
Chris@102
|
351 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
352 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
353 break;
|
Chris@102
|
354 #endif
|
Chris@102
|
355 }
|
Chris@102
|
356 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
357 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
358 throw lazy_exception("Your list is too long!!");
|
Chris@102
|
359 #endif
|
Chris@102
|
360 return head(l)();
|
Chris@102
|
361 }
|
Chris@102
|
362 };
|
Chris@102
|
363
|
Chris@102
|
364 struct Init {
|
Chris@102
|
365
|
Chris@102
|
366 template <typename Sig> struct result;
|
Chris@102
|
367
|
Chris@102
|
368 template <typename This, typename L>
|
Chris@102
|
369 struct result<This(L)>
|
Chris@102
|
370 {
|
Chris@102
|
371 typedef typename result_of::ListType<L>::force_result_type type;
|
Chris@102
|
372 };
|
Chris@102
|
373
|
Chris@102
|
374 template <class L>
|
Chris@102
|
375 typename result<Init(L)>::type
|
Chris@102
|
376 operator()( const L& l,
|
Chris@102
|
377 reuser1<INV,VAR,Init,
|
Chris@102
|
378 typename result_of::ListType<L>::delay_result_type>
|
Chris@102
|
379 r = NIL ) const {
|
Chris@102
|
380 if( null( tail( l )() )() )
|
Chris@102
|
381 return NIL;
|
Chris@102
|
382 else
|
Chris@102
|
383 return cons( head(l)(), r( Init(), tail(l)() )() )();
|
Chris@102
|
384 }
|
Chris@102
|
385 };
|
Chris@102
|
386
|
Chris@102
|
387 struct Length {
|
Chris@102
|
388 template <typename Sig> struct result;
|
Chris@102
|
389
|
Chris@102
|
390 template <typename This, typename L>
|
Chris@102
|
391 struct result<This(L)>
|
Chris@102
|
392 {
|
Chris@102
|
393 typedef size_t type;
|
Chris@102
|
394 };
|
Chris@102
|
395
|
Chris@102
|
396 template <class L>
|
Chris@102
|
397 size_t operator()( const L& ll ) const {
|
Chris@102
|
398 typename L::delay_result_type l = delay(ll);
|
Chris@102
|
399 size_t x = 0;
|
Chris@102
|
400 while( !null(l)() ) {
|
Chris@102
|
401 l = tail(l);
|
Chris@102
|
402 ++x;
|
Chris@102
|
403 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
404 break;
|
Chris@102
|
405 }
|
Chris@102
|
406 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
407 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
408 throw lazy_exception("Your list is too long!!");
|
Chris@102
|
409 #endif
|
Chris@102
|
410 return x;
|
Chris@102
|
411 }
|
Chris@102
|
412 };
|
Chris@102
|
413
|
Chris@102
|
414 // at is Haskell's operator (!!)
|
Chris@102
|
415 // This is zero indexed. at(l,0)() returns the first element.
|
Chris@102
|
416 struct At {
|
Chris@102
|
417 template <typename Sig> struct result;
|
Chris@102
|
418
|
Chris@102
|
419 template <typename This, typename L, typename N>
|
Chris@102
|
420 struct result<This(L,N)>
|
Chris@102
|
421 {
|
Chris@102
|
422 typedef typename result_of::ListType<L>::value_type type;
|
Chris@102
|
423 };
|
Chris@102
|
424
|
Chris@102
|
425 template <class L>
|
Chris@102
|
426 typename result<At(L,size_t)>::type
|
Chris@102
|
427 operator()( L l, size_t n ) const {
|
Chris@102
|
428 while( n!=0 ) {
|
Chris@102
|
429 l = tail(l);
|
Chris@102
|
430 --n;
|
Chris@102
|
431 }
|
Chris@102
|
432 return head(l)();
|
Chris@102
|
433 }
|
Chris@102
|
434 };
|
Chris@102
|
435
|
Chris@102
|
436 template <class P,class L>
|
Chris@102
|
437 struct FilterH
|
Chris@102
|
438 {
|
Chris@102
|
439 P p;
|
Chris@102
|
440 L l;
|
Chris@102
|
441 FilterH( const P& pp, const L& ll) : p(pp), l(ll) {}
|
Chris@102
|
442 template <typename Sig> struct result;
|
Chris@102
|
443
|
Chris@102
|
444 template <typename This, class PP, class LL>
|
Chris@102
|
445 struct result<This(PP,LL)>
|
Chris@102
|
446 {
|
Chris@102
|
447 typedef typename boost::phoenix::result_of::
|
Chris@102
|
448 ListType<LL>::delay_result_type type;
|
Chris@102
|
449 };
|
Chris@102
|
450 typename result<FilterH(P,L)>::type operator()() const {
|
Chris@102
|
451 typedef typename result_of::ListType<L>::
|
Chris@102
|
452 delay_result_type result_type;
|
Chris@102
|
453 typedef boost::function0<result_type> Fun2_R_P_L;
|
Chris@102
|
454 typedef boost::phoenix::function<Fun2_R_P_L> FilterH_R_P_L;
|
Chris@102
|
455 if (null(l)() )
|
Chris@102
|
456 return NIL;
|
Chris@102
|
457 Fun2_R_P_L fun2_R_P_L = FilterH<P,L>(p,tail(l));
|
Chris@102
|
458 FilterH_R_P_L filterh_R_P_L(fun2_R_P_L);
|
Chris@102
|
459 if( p(head(l))() )
|
Chris@102
|
460 return cons( head(l)(), filterh_R_P_L() );
|
Chris@102
|
461 else
|
Chris@102
|
462 return filterh_R_P_L();
|
Chris@102
|
463 }
|
Chris@102
|
464 };
|
Chris@102
|
465
|
Chris@102
|
466 struct Filter {
|
Chris@102
|
467 template <typename Sig> struct result;
|
Chris@102
|
468
|
Chris@102
|
469 template <typename This, typename P, typename L>
|
Chris@102
|
470 struct result<This(P,L)>
|
Chris@102
|
471 {
|
Chris@102
|
472 typedef typename result_of::ListType<L>::delay_result_type
|
Chris@102
|
473 type;
|
Chris@102
|
474 };
|
Chris@102
|
475
|
Chris@102
|
476 template <class P, class L>
|
Chris@102
|
477 typename result<Filter(P,L)>::type
|
Chris@102
|
478 operator()( const P& p, const L& ll) const
|
Chris@102
|
479 {
|
Chris@102
|
480 typename result_of::ListType<L>::delay_result_type
|
Chris@102
|
481 l = delay(ll);
|
Chris@102
|
482 typedef typename result_of::ListType<L>::
|
Chris@102
|
483 delay_result_type result_type;
|
Chris@102
|
484 typedef boost::function0<result_type> Fun2_R_P_L;
|
Chris@102
|
485 typedef boost::phoenix::function<Fun2_R_P_L> FilterH_R_P_L;
|
Chris@102
|
486 Fun2_R_P_L fun2_R_P_L = FilterH<P,L>(p,l);
|
Chris@102
|
487 FilterH_R_P_L filterh_R_P_L(fun2_R_P_L);
|
Chris@102
|
488 return filterh_R_P_L();
|
Chris@102
|
489 }
|
Chris@102
|
490 };
|
Chris@102
|
491
|
Chris@102
|
492 template <class F,class T>
|
Chris@102
|
493 struct IterateH
|
Chris@102
|
494 {
|
Chris@102
|
495 F f;
|
Chris@102
|
496 T t;
|
Chris@102
|
497 IterateH( const F& ff, const T& tt) : f(ff), t(tt) {}
|
Chris@102
|
498 template <typename Sig> struct result;
|
Chris@102
|
499
|
Chris@102
|
500 template <typename This,class F2,class T2>
|
Chris@102
|
501 struct result<This(F2,T2)>
|
Chris@102
|
502 {
|
Chris@102
|
503 typedef typename boost::remove_reference<T2>::type TT;
|
Chris@102
|
504 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
505 typedef typename UseList::template List<TTT>::type LType;
|
Chris@102
|
506 typedef typename result_of::ListType<LType>::
|
Chris@102
|
507 delay_result_type type;
|
Chris@102
|
508 };
|
Chris@102
|
509
|
Chris@102
|
510 typename result<IterateH(F,T)>::type operator()() const {
|
Chris@102
|
511 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
512 typedef typename result_of::ListType<LType>::
|
Chris@102
|
513 delay_result_type result_type;
|
Chris@102
|
514 typedef boost::function0<result_type> Fun2_R_F_T;
|
Chris@102
|
515 typedef boost::phoenix::function<Fun2_R_F_T> IterateH_R_F_T;
|
Chris@102
|
516 Fun2_R_F_T fun2_R_F_T = IterateH<F,T>(f,f(t)());
|
Chris@102
|
517 IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T);
|
Chris@102
|
518 return cons( t, iterateh_R_F_T() );
|
Chris@102
|
519 }
|
Chris@102
|
520 };
|
Chris@102
|
521
|
Chris@102
|
522
|
Chris@102
|
523 struct Iterate {
|
Chris@102
|
524 // Note: this does always return an odd_list; iterate() takes no ListLike
|
Chris@102
|
525 // parameter, and it requires that its result be lazy.
|
Chris@102
|
526 template <typename Sig> struct result;
|
Chris@102
|
527
|
Chris@102
|
528 template <typename This, typename F, typename T>
|
Chris@102
|
529 struct result<This(F,T)>
|
Chris@102
|
530 {
|
Chris@102
|
531 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
532 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
533 typedef typename UseList::template List<TTT>::type LType;
|
Chris@102
|
534 typedef typename result_of::ListType<LType>::
|
Chris@102
|
535 delay_result_type type;
|
Chris@102
|
536 };
|
Chris@102
|
537
|
Chris@102
|
538 template <class F, class T>
|
Chris@102
|
539 typename result<Iterate(F,T)>::type operator()
|
Chris@102
|
540 (const F& f, const T& t) const {
|
Chris@102
|
541 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
542 typedef typename result_of::ListType<LType>::
|
Chris@102
|
543 delay_result_type result_type;
|
Chris@102
|
544 typedef boost::function0<result_type> Fun2_R_F_T;
|
Chris@102
|
545 typedef boost::phoenix::function<Fun2_R_F_T> IterateH_R_F_T;
|
Chris@102
|
546 Fun2_R_F_T fun2_R_F_T = IterateH<F,T>(f,f(t)());
|
Chris@102
|
547 IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T);
|
Chris@102
|
548 return iterateh_R_F_T();
|
Chris@102
|
549 }
|
Chris@102
|
550 };
|
Chris@102
|
551
|
Chris@102
|
552 }
|
Chris@102
|
553
|
Chris@102
|
554 typedef boost::phoenix::function<impl::Until> Until;
|
Chris@102
|
555 typedef boost::phoenix::function<impl::Until2> Until2;
|
Chris@102
|
556 typedef boost::phoenix::function<impl::Last> Last;
|
Chris@102
|
557 typedef boost::phoenix::function<impl::Init> Init;
|
Chris@102
|
558 typedef boost::phoenix::function<impl::Length> Length;
|
Chris@102
|
559 typedef boost::phoenix::function<impl::At> At;
|
Chris@102
|
560 typedef boost::phoenix::function<impl::Filter> Filter;
|
Chris@102
|
561 typedef boost::phoenix::function<impl::Iterate> Iterate;
|
Chris@102
|
562 Until until;
|
Chris@102
|
563 Until2 until2;
|
Chris@102
|
564 Last last;
|
Chris@102
|
565 Init all_but_last; // renamed from init which is not available.
|
Chris@102
|
566 Length length;
|
Chris@102
|
567 At at_; //Renamed from at.
|
Chris@102
|
568 Filter filter;
|
Chris@102
|
569 Iterate iterate;
|
Chris@102
|
570
|
Chris@102
|
571 namespace impl {
|
Chris@102
|
572
|
Chris@102
|
573 struct Repeat {
|
Chris@102
|
574 // See note for iterate()
|
Chris@102
|
575 template <typename Sig> struct result;
|
Chris@102
|
576
|
Chris@102
|
577 template <typename This, typename T>
|
Chris@102
|
578 struct result<This(T)>
|
Chris@102
|
579 {
|
Chris@102
|
580 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
581 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
582 typedef typename UseList::template List<TTT>::type LType;
|
Chris@102
|
583 typedef typename result_of::ListType<LType>::
|
Chris@102
|
584 delay_result_type type;
|
Chris@102
|
585 };
|
Chris@102
|
586
|
Chris@102
|
587 template <class T>
|
Chris@102
|
588 typename result<Repeat(T)>::type operator()( const T& x) const
|
Chris@102
|
589 {
|
Chris@102
|
590 return iterate(id,x);
|
Chris@102
|
591 }
|
Chris@102
|
592 };
|
Chris@102
|
593
|
Chris@102
|
594 struct Take {
|
Chris@102
|
595
|
Chris@102
|
596 template <typename Sig> struct result;
|
Chris@102
|
597
|
Chris@102
|
598 template <typename This, typename N, typename L>
|
Chris@102
|
599 struct result<This(N,L)>
|
Chris@102
|
600 {
|
Chris@102
|
601 typedef typename result_of::ListType<L>::force_result_type type;
|
Chris@102
|
602 };
|
Chris@102
|
603
|
Chris@102
|
604 template <class N,class L>
|
Chris@102
|
605 typename result<Take(N,L)>::type
|
Chris@102
|
606 operator()( N n, const L& l,
|
Chris@102
|
607 reuser2<INV,VAR,VAR,Take,N,
|
Chris@102
|
608 typename result_of::ListType<L>::force_result_type>
|
Chris@102
|
609 r = NIL
|
Chris@102
|
610 ) const {
|
Chris@102
|
611 if( n <= 0 || null(l)() )
|
Chris@102
|
612 return NIL;
|
Chris@102
|
613 else {
|
Chris@102
|
614 return cons( head(l)(), r( Take(), n-1, tail(l)() )() )();
|
Chris@102
|
615 }
|
Chris@102
|
616 }
|
Chris@102
|
617 };
|
Chris@102
|
618
|
Chris@102
|
619 struct Drop {
|
Chris@102
|
620 template <typename Sig> struct result;
|
Chris@102
|
621
|
Chris@102
|
622 template <typename This, typename Dummy, typename L>
|
Chris@102
|
623 struct result<This(Dummy,L)>
|
Chris@102
|
624 {
|
Chris@102
|
625 typedef typename result_of::ListType<L>::delay_result_type type;
|
Chris@102
|
626 };
|
Chris@102
|
627
|
Chris@102
|
628 template <class L>
|
Chris@102
|
629 typename result<Drop(size_t,L)>::type
|
Chris@102
|
630 operator()( size_t n, const L& ll ) const {
|
Chris@102
|
631 typename L::delay_result_type l = delay(ll);
|
Chris@102
|
632 while( n!=0 && !null(l)() ) {
|
Chris@102
|
633 --n;
|
Chris@102
|
634 l = tail(l)();
|
Chris@102
|
635 }
|
Chris@102
|
636 return l;
|
Chris@102
|
637 }
|
Chris@102
|
638 };
|
Chris@102
|
639
|
Chris@102
|
640 template <class T>
|
Chris@102
|
641 struct EFH
|
Chris@102
|
642 {
|
Chris@102
|
643 mutable T x;
|
Chris@102
|
644 EFH( const T& xx) : x(xx) {}
|
Chris@102
|
645 template <typename Sig> struct result;
|
Chris@102
|
646
|
Chris@102
|
647 template <typename This, class TT>
|
Chris@102
|
648 struct result<This(TT)>
|
Chris@102
|
649 {
|
Chris@102
|
650 typedef typename boost::phoenix::UseList::template
|
Chris@102
|
651 List<TT>::type LType;
|
Chris@102
|
652 typedef typename boost::phoenix::result_of::
|
Chris@102
|
653 ListType<LType>::delay_result_type type;
|
Chris@102
|
654 };
|
Chris@102
|
655 typename result<EFH(T)>::type operator()() const {
|
Chris@102
|
656 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
657 typedef typename result_of::ListType<LType>::
|
Chris@102
|
658 delay_result_type result_type;
|
Chris@102
|
659 typedef boost::function0<result_type> fun1_R_TTT;
|
Chris@102
|
660 //std::cout << "EFH (" << x << ")" << std::endl;
|
Chris@102
|
661 ++x;
|
Chris@102
|
662 fun1_R_TTT efh_R_TTT = EFH<T>(x);
|
Chris@102
|
663 typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
|
Chris@102
|
664 EFH_R_T efh_R_T(efh_R_TTT);
|
Chris@102
|
665 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
666 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
667 throw lazy_exception("Running away in EFH!!");
|
Chris@102
|
668 #endif
|
Chris@102
|
669 return cons( x-1, efh_R_T() );
|
Chris@102
|
670 }
|
Chris@102
|
671 };
|
Chris@102
|
672
|
Chris@102
|
673 struct Enum_from {
|
Chris@102
|
674 template <typename Sig> struct result;
|
Chris@102
|
675
|
Chris@102
|
676 template <typename This, typename T>
|
Chris@102
|
677 struct result<This(T)>
|
Chris@102
|
678 {
|
Chris@102
|
679 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
680 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
681 typedef typename UseList::template List<TTT>::type LType;
|
Chris@102
|
682 typedef typename result_of::ListType<LType>::
|
Chris@102
|
683 delay_result_type type;
|
Chris@102
|
684 };
|
Chris@102
|
685
|
Chris@102
|
686 template <class T>
|
Chris@102
|
687 typename result<Enum_from(T)>::type operator()
|
Chris@102
|
688 (const T & x) const
|
Chris@102
|
689 {
|
Chris@102
|
690 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
691 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
692 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
693 typedef typename result_of::ListType<LType>::
|
Chris@102
|
694 delay_result_type result_type;
|
Chris@102
|
695 typedef boost::function0<result_type> fun1_R_TTT;
|
Chris@102
|
696 fun1_R_TTT efh_R_TTT = EFH<TTT>(x);
|
Chris@102
|
697 typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
|
Chris@102
|
698 EFH_R_T efh_R_T(efh_R_TTT);
|
Chris@102
|
699 //std::cout << "enum_from (" << x << ")" << std::endl;
|
Chris@102
|
700 return efh_R_T();
|
Chris@102
|
701 }
|
Chris@102
|
702 };
|
Chris@102
|
703
|
Chris@102
|
704 template <class T>
|
Chris@102
|
705 struct EFTH
|
Chris@102
|
706 {
|
Chris@102
|
707 mutable T x;
|
Chris@102
|
708 T y;
|
Chris@102
|
709 EFTH( const T& xx, const T& yy) : x(xx), y(yy) {}
|
Chris@102
|
710 template <typename Sig> struct result;
|
Chris@102
|
711
|
Chris@102
|
712 template <typename This, class TT>
|
Chris@102
|
713 struct result<This(TT)>
|
Chris@102
|
714 {
|
Chris@102
|
715 typedef typename boost::phoenix::UseList::template
|
Chris@102
|
716 List<TT>::type LType;
|
Chris@102
|
717 typedef typename boost::phoenix::result_of::
|
Chris@102
|
718 ListType<LType>::delay_result_type type;
|
Chris@102
|
719 };
|
Chris@102
|
720 typename result<EFTH(T)>::type operator()() const {
|
Chris@102
|
721 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
722 typedef typename result_of::ListType<LType>::
|
Chris@102
|
723 delay_result_type result_type;
|
Chris@102
|
724 typedef boost::function0<result_type> fun1_R_TTT;
|
Chris@102
|
725 //std::cout << "EFTH (" << x << ")" << std::endl;
|
Chris@102
|
726 if (x > y ) return NIL;
|
Chris@102
|
727 ++x;
|
Chris@102
|
728 fun1_R_TTT efth_R_TTT = EFTH<T>(x,y);
|
Chris@102
|
729 typedef boost::phoenix::function<fun1_R_TTT> EFTH_R_T;
|
Chris@102
|
730 EFTH_R_T efth_R_T(efth_R_TTT);
|
Chris@102
|
731 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
732 if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
|
Chris@102
|
733 throw lazy_exception("Running away in EFTH!!");
|
Chris@102
|
734 #endif
|
Chris@102
|
735 return cons( x-1, efth_R_T() );
|
Chris@102
|
736 }
|
Chris@102
|
737 };
|
Chris@102
|
738
|
Chris@102
|
739 struct Enum_from_to {
|
Chris@102
|
740 template <typename Sig> struct result;
|
Chris@102
|
741
|
Chris@102
|
742 template <typename This, typename T>
|
Chris@102
|
743 struct result<This(T,T)>
|
Chris@102
|
744 {
|
Chris@102
|
745 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
746 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
747 typedef typename UseList::template List<TTT>::type LType;
|
Chris@102
|
748 typedef typename result_of::ListType<LType>::
|
Chris@102
|
749 delay_result_type type;
|
Chris@102
|
750 };
|
Chris@102
|
751
|
Chris@102
|
752 template <class T>
|
Chris@102
|
753 typename result<Enum_from(T,T)>::type operator()
|
Chris@102
|
754 (const T & x, const T & y) const
|
Chris@102
|
755 {
|
Chris@102
|
756 typedef typename boost::remove_reference<T>::type TT;
|
Chris@102
|
757 typedef typename boost::remove_const<TT>::type TTT;
|
Chris@102
|
758 typedef typename UseList::template List<T>::type LType;
|
Chris@102
|
759 typedef typename result_of::ListType<LType>::
|
Chris@102
|
760 delay_result_type result_type;
|
Chris@102
|
761 typedef boost::function0<result_type> fun1_R_TTT;
|
Chris@102
|
762 fun1_R_TTT efth_R_TTT = EFTH<TTT>(x,y);
|
Chris@102
|
763 typedef boost::phoenix::function<fun1_R_TTT> EFTH_R_T;
|
Chris@102
|
764 EFTH_R_T efth_R_T(efth_R_TTT);
|
Chris@102
|
765 //std::cout << "enum_from (" << x << ")" << std::endl;
|
Chris@102
|
766 return efth_R_T();
|
Chris@102
|
767 }
|
Chris@102
|
768 };
|
Chris@102
|
769
|
Chris@102
|
770 }
|
Chris@102
|
771
|
Chris@102
|
772
|
Chris@102
|
773 //BOOST_PHOENIX_ADAPT_CALLABLE(apply, impl::apply, 3)
|
Chris@102
|
774 // Functors to be used in reuser will have to be defined
|
Chris@102
|
775 // using boost::phoenix::function directly
|
Chris@102
|
776 // in order to be able to be used as arguments.
|
Chris@102
|
777 typedef boost::phoenix::function<impl::Repeat> Repeat;
|
Chris@102
|
778 typedef boost::phoenix::function<impl::Take> Take;
|
Chris@102
|
779 typedef boost::phoenix::function<impl::Drop> Drop;
|
Chris@102
|
780 typedef boost::phoenix::function<impl::Enum_from> Enum_from;
|
Chris@102
|
781 typedef boost::phoenix::function<impl::Enum_from_to> Enum_from_to;
|
Chris@102
|
782 Repeat repeat;
|
Chris@102
|
783 Take take;
|
Chris@102
|
784 Drop drop;
|
Chris@102
|
785 Enum_from enum_from;
|
Chris@102
|
786 Enum_from_to enum_from_to;
|
Chris@102
|
787
|
Chris@102
|
788 namespace fcpp {
|
Chris@102
|
789
|
Chris@102
|
790
|
Chris@102
|
791 }
|
Chris@102
|
792
|
Chris@102
|
793 }
|
Chris@102
|
794
|
Chris@102
|
795 }
|
Chris@102
|
796
|
Chris@102
|
797
|
Chris@102
|
798 #endif
|