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