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