Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // lazy prelude.hpp Chris@102: // Chris@102: // Build lazy operations for Phoenix equivalents for FC++ Chris@102: // Chris@102: // These are equivalents of the Boost FC++ functoids in prelude.hpp Chris@102: // Chris@102: // Usage: All of these are functors which need various numbers of arguments. Chris@102: // Those can be supplied as real arguments or as Phoenix arguments. Chris@102: // Execution will happen when all the arguments are supplied. Chris@102: // e.g. Chris@102: // take(2,list)() or take(2,arg1)(list) Chris@102: // Chris@102: // Implemented so far: Chris@102: // Chris@102: // id (moved back to operators.hpp) Chris@102: // Chris@102: // A lot of what comes here uses the list type, so that will be needed first. Chris@102: // Chris@102: // Now that list is available I can start to build things here. Chris@102: // Chris@102: // Chris@102: // until(pred,f,start) - if pred(start) is true, return start Chris@102: // apply value = f(start) Chris@102: // apply value = f(value) Chris@102: // until pred(value) is true Chris@102: // return value Chris@102: // Chris@102: // The predicate argument pred must be a lazy function taking one argument Chris@102: // and returning bool. Chris@102: // This can be a lazy function with an argument already. Chris@102: // This has to be declared before the call to until. Chris@102: // The type can be declated using Predicate as in this example: Chris@102: // Chris@102: // Predicate::type f(greater(arg1,10)); Chris@102: // std::cout << until(f, inc, 1)() << std::endl; Chris@102: // Chris@102: // until2(pred,f,start,value2) - if pred(start,value2) is true, return start Chris@102: // apply value1 = f(start) Chris@102: // apply value1 = f(value1) Chris@102: // until pred(value1,value2) is true Chris@102: // return value1 Chris@102: // Chris@102: // NOTE: until2 has been defined because this code does not support Chris@102: // FC++ currying, so that a partial function cannot be passed Chris@102: // as an argument. This provides a way of passing a second parameter. Chris@102: // There is now the option to use Predicate as shown above. Chris@102: // Chris@102: // odd(n) true if n is odd Chris@102: // even(n) true if n is even Chris@102: // Chris@102: // last(list) Chris@102: // all_but_last(list) Chris@102: // at(list,n) Chris@102: // length(list) Chris@102: // filter(pred,list) Chris@102: // iterate(function,value) Chris@102: // repeat(value) Chris@102: // take(n,list) Chris@102: // drop(n,list) Chris@102: // enum_from(x) Chris@102: // enum_from_to(x,y) Chris@102: // Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // Interdependence: Chris@102: // The old Boost FC++ has a set of headers which interelate and call each Chris@102: // other in a complicated way. I am going to document the interdependence Chris@102: // of the files here. I will then make sure that they are called correctly Chris@102: // starting from this file. John Fletcher. February 2015. Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // BoostFC++ header sequence: Chris@102: // Chris@102: // prelude.hpp -> list.hpp (optinally monad.hpp at end) Chris@102: // list.hpp -> reuse.hpp Chris@102: // reuse.hpp -> function.hpp Chris@102: // function.hpp -> ref_count.hpp operator.hpp Chris@102: // ref_count.hpp -> config.hpp boost headers and RefCountType definition Chris@102: // operator.hpp -> lambda.hpp Chris@102: // lambda.hpp -> full.hpp (use of lambda internals is optional) Chris@102: // full.hpp -> smart.hpp curry.hpp pre_lambda.hpp (optionally full4.hpp) Chris@102: // smart.hpp -> signature.hpp Chris@102: // curry.hpp -> signature.hpp Chris@102: // signature.hpp -> config.hpp Chris@102: // Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // Proposed order in lazy_prelude.hpp Chris@102: // on the basis that files need what they call. Chris@102: // Chris@102: // lazy_config.hpp (If needed)* probably not needed. Chris@102: // lazy_signature.hpp (If needed)* Chris@102: // lazy_smart.hpp (If needed)* Chris@102: // lazy_curry.hpp (If needed)* Chris@102: // lazy_full.hpp (If needed)* Chris@102: // lazy_operator.hpp (absorb definition of RefCountType) Chris@102: // lazy_function.hpp (may not now be needed) Chris@102: // lazy_reuse.hpp (implemented without use of FC++ functions) Chris@102: // lazy_list.hpp Chris@102: // Chris@102: // * file does not yet exist. Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // This is implemented such that no other lazy_ file calls other lazy_ files. Chris@102: // They do call their own external files, which may well be duplicates. Chris@102: // That can be sorted out later. Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // Notes: full and curry operations should be covered by Phoenix. Chris@102: // The lambda operations are quite different from Phoenix lambda Chris@102: // and will be omitted. Chris@102: // The implementation monad can be postponed. Chris@102: // Some of function and reuse are needed for the list type. Chris@102: // I will review later whether they are part of the external interface. Chris@102: // Chris@102: // John Fletcher February 2015. Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: /*============================================================================= Chris@102: Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis Chris@102: Copyright (c) 2001-2007 Joel de Guzman Chris@102: Copyright (c) 2015 John Fletcher Chris@102: Chris@102: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: ==============================================================================*/ Chris@102: Chris@102: Chris@102: #ifndef BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE Chris@102: #define BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: // To come here, the Haskell Prelude things which need list. Chris@102: // Things which do not need list are in lazy_operator.hpp. Chris@102: //////////////////////////////////////////////////////////////////////////// Chris@102: Chris@102: namespace boost { Chris@102: Chris@102: namespace phoenix { Chris@102: Chris@102: // These are in fcpp namespace as they introduce an FC++ style. Chris@102: namespace fcpp { Chris@102: Chris@102: template Chris@102: struct Predicate { Chris@102: typedef typename boost::function1 fun1_bool_T; Chris@102: typedef typename boost::phoenix::function bool_F_T; Chris@102: typedef bool_F_T type; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct Function0 { Chris@102: typedef typename boost::function0 fun0_R; Chris@102: typedef typename boost::phoenix::function R_F; Chris@102: typedef R_F type; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct Function1 { Chris@102: typedef typename boost::function1 fun1_R_A0; Chris@102: typedef typename boost::phoenix::function R_F_A0; Chris@102: typedef R_F_A0 type; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct Function2 { Chris@102: typedef typename boost::function2 fun2_R_A0_A1; Chris@102: typedef typename boost::phoenix::function R_F_A0_A1; Chris@102: typedef R_F_A0_A1 type; Chris@102: }; Chris@102: Chris@102: } Chris@102: Chris@102: namespace impl { Chris@102: using fcpp::INV; Chris@102: using fcpp::VAR; Chris@102: using fcpp::reuser1; Chris@102: using fcpp::reuser2; Chris@102: using fcpp::reuser3; Chris@102: using boost::phoenix::arg_names::arg1; Chris@102: Chris@102: struct Pow { Chris@102: Chris@102: template Chris@102: struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: : boost::remove_reference Chris@102: {}; Chris@102: Chris@102: template Chris@102: A0 operator()(N n, const A0 & a0, Chris@102: reuser2 r = NIL ) const { Chris@102: if ( n <= 0 ) Chris@102: return A0(1); Chris@102: else if ( n==1 ) Chris@102: return a0; Chris@102: else { Chris@102: A0 a1 = r( Pow(), n-1, a0)(); Chris@102: return a0*a1; Chris@102: } Chris@102: } Chris@102: Chris@102: }; Chris@102: Chris@102: struct Apply { Chris@102: Chris@102: template Chris@102: struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: : boost::remove_reference Chris@102: {}; Chris@102: Chris@102: template Chris@102: A0 operator()(N n, const F &f, const A0 & a0, Chris@102: reuser3 r = NIL ) const { Chris@102: if ( n <= 0 ) Chris@102: return a0; Chris@102: else if ( n==1 ) Chris@102: return f(arg1)(a0); Chris@102: else { Chris@102: A0 a1 = r( Apply(), n-1, f, a0)(); Chris@102: return f(a1)(); Chris@102: } Chris@102: } Chris@102: Chris@102: }; Chris@102: Chris@102: struct Odd { Chris@102: template Chris@102: struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef bool type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator()( const T& x ) const { Chris@102: return x%2==1; Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Even { Chris@102: template Chris@102: struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef bool type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator()( const T& x ) const { Chris@102: return x%2==0; Chris@102: } Chris@102: }; Chris@102: Chris@102: } Chris@102: typedef boost::phoenix::function Pow; Chris@102: typedef boost::phoenix::function Apply; Chris@102: typedef boost::phoenix::function Odd; Chris@102: typedef boost::phoenix::function Even; Chris@102: Pow pow; Chris@102: Apply apply; Chris@102: Odd odd; Chris@102: Even even; Chris@102: Chris@102: namespace impl { Chris@102: using fcpp::INV; Chris@102: using fcpp::VAR; Chris@102: using fcpp::reuser1; Chris@102: using fcpp::reuser2; Chris@102: using fcpp::reuser3; Chris@102: using boost::phoenix::arg_names::arg1; Chris@102: Chris@102: // I cannot yet do currying to pass e.g. greater(9,arg1) Chris@102: // as a function. This can be done using Predicate::type. Chris@102: struct Until { Chris@102: Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: : boost::remove_reference {}; Chris@102: Chris@102: template Chris@102: T operator()( const Pred& p,const Unary& op,const T &start) const Chris@102: { Chris@102: T tmp = start; Chris@102: while( !p(tmp)() ) { Chris@102: tmp = apply(1,op,tmp)(); Chris@102: } Chris@102: return tmp; Chris@102: } Chris@102: Chris@102: }; Chris@102: Chris@102: struct Until2 { Chris@102: Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: : boost::remove_reference {}; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( const Binary& p, const Unary& op, const T & start, Chris@102: const X & check ) const Chris@102: { Chris@102: T tmp1 = start; Chris@102: T tmp2; Chris@102: while( !p(tmp1,check)() ) { Chris@102: tmp2 = apply(1,op,tmp1)(); Chris@102: tmp1 = tmp2; Chris@102: Chris@102: } Chris@102: return tmp1; Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Last { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::value_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( const L& ll ) const { Chris@102: size_t x = 0; Chris@102: typename result_of::ListType::delay_result_type l = delay(ll); Chris@102: while( !null( tail(l)() )() ) { Chris@102: l = tail(l)(); Chris@102: ++x; Chris@102: #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: break; Chris@102: #endif Chris@102: } Chris@102: #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: throw lazy_exception("Your list is too long!!"); Chris@102: #endif Chris@102: return head(l)(); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Init { Chris@102: Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::force_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( const L& l, Chris@102: reuser1::delay_result_type> Chris@102: r = NIL ) const { Chris@102: if( null( tail( l )() )() ) Chris@102: return NIL; Chris@102: else Chris@102: return cons( head(l)(), r( Init(), tail(l)() )() )(); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Length { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef size_t type; Chris@102: }; Chris@102: Chris@102: template Chris@102: size_t operator()( const L& ll ) const { Chris@102: typename L::delay_result_type l = delay(ll); Chris@102: size_t x = 0; Chris@102: while( !null(l)() ) { Chris@102: l = tail(l); Chris@102: ++x; Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: break; Chris@102: } Chris@102: #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: throw lazy_exception("Your list is too long!!"); Chris@102: #endif Chris@102: return x; Chris@102: } Chris@102: }; Chris@102: Chris@102: // at is Haskell's operator (!!) Chris@102: // This is zero indexed. at(l,0)() returns the first element. Chris@102: struct At { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::value_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( L l, size_t n ) const { Chris@102: while( n!=0 ) { Chris@102: l = tail(l); Chris@102: --n; Chris@102: } Chris@102: return head(l)(); Chris@102: } Chris@102: }; Chris@102: Chris@102: template Chris@102: struct FilterH Chris@102: { Chris@102: P p; Chris@102: L l; Chris@102: FilterH( const P& pp, const L& ll) : p(pp), l(ll) {} Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::phoenix::result_of:: Chris@102: ListType::delay_result_type type; Chris@102: }; Chris@102: typename result::type operator()() const { Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 Fun2_R_P_L; Chris@102: typedef boost::phoenix::function FilterH_R_P_L; Chris@102: if (null(l)() ) Chris@102: return NIL; Chris@102: Fun2_R_P_L fun2_R_P_L = FilterH(p,tail(l)); Chris@102: FilterH_R_P_L filterh_R_P_L(fun2_R_P_L); Chris@102: if( p(head(l))() ) Chris@102: return cons( head(l)(), filterh_R_P_L() ); Chris@102: else Chris@102: return filterh_R_P_L(); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Filter { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::delay_result_type Chris@102: type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( const P& p, const L& ll) const Chris@102: { Chris@102: typename result_of::ListType::delay_result_type Chris@102: l = delay(ll); Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 Fun2_R_P_L; Chris@102: typedef boost::phoenix::function FilterH_R_P_L; Chris@102: Fun2_R_P_L fun2_R_P_L = FilterH(p,l); Chris@102: FilterH_R_P_L filterh_R_P_L(fun2_R_P_L); Chris@102: return filterh_R_P_L(); Chris@102: } Chris@102: }; Chris@102: Chris@102: template Chris@102: struct IterateH Chris@102: { Chris@102: F f; Chris@102: T t; Chris@102: IterateH( const F& ff, const T& tt) : f(ff), t(tt) {} Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type type; Chris@102: }; Chris@102: Chris@102: typename result::type operator()() const { Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 Fun2_R_F_T; Chris@102: typedef boost::phoenix::function IterateH_R_F_T; Chris@102: Fun2_R_F_T fun2_R_F_T = IterateH(f,f(t)()); Chris@102: IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T); Chris@102: return cons( t, iterateh_R_F_T() ); Chris@102: } Chris@102: }; Chris@102: Chris@102: Chris@102: struct Iterate { Chris@102: // Note: this does always return an odd_list; iterate() takes no ListLike Chris@102: // parameter, and it requires that its result be lazy. Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator() Chris@102: (const F& f, const T& t) const { Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 Fun2_R_F_T; Chris@102: typedef boost::phoenix::function IterateH_R_F_T; Chris@102: Fun2_R_F_T fun2_R_F_T = IterateH(f,f(t)()); Chris@102: IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T); Chris@102: return iterateh_R_F_T(); Chris@102: } Chris@102: }; Chris@102: Chris@102: } Chris@102: Chris@102: typedef boost::phoenix::function Until; Chris@102: typedef boost::phoenix::function Until2; Chris@102: typedef boost::phoenix::function Last; Chris@102: typedef boost::phoenix::function Init; Chris@102: typedef boost::phoenix::function Length; Chris@102: typedef boost::phoenix::function At; Chris@102: typedef boost::phoenix::function Filter; Chris@102: typedef boost::phoenix::function Iterate; Chris@102: Until until; Chris@102: Until2 until2; Chris@102: Last last; Chris@102: Init all_but_last; // renamed from init which is not available. Chris@102: Length length; Chris@102: At at_; //Renamed from at. Chris@102: Filter filter; Chris@102: Iterate iterate; Chris@102: Chris@102: namespace impl { Chris@102: Chris@102: struct Repeat { Chris@102: // See note for iterate() Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator()( const T& x) const Chris@102: { Chris@102: return iterate(id,x); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Take { Chris@102: Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::force_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( N n, const L& l, Chris@102: reuser2::force_result_type> Chris@102: r = NIL Chris@102: ) const { Chris@102: if( n <= 0 || null(l)() ) Chris@102: return NIL; Chris@102: else { Chris@102: return cons( head(l)(), r( Take(), n-1, tail(l)() )() )(); Chris@102: } Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Drop { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename result_of::ListType::delay_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type Chris@102: operator()( size_t n, const L& ll ) const { Chris@102: typename L::delay_result_type l = delay(ll); Chris@102: while( n!=0 && !null(l)() ) { Chris@102: --n; Chris@102: l = tail(l)(); Chris@102: } Chris@102: return l; Chris@102: } Chris@102: }; Chris@102: Chris@102: template Chris@102: struct EFH Chris@102: { Chris@102: mutable T x; Chris@102: EFH( const T& xx) : x(xx) {} Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::phoenix::UseList::template Chris@102: List::type LType; Chris@102: typedef typename boost::phoenix::result_of:: Chris@102: ListType::delay_result_type type; Chris@102: }; Chris@102: typename result::type operator()() const { Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 fun1_R_TTT; Chris@102: //std::cout << "EFH (" << x << ")" << std::endl; Chris@102: ++x; Chris@102: fun1_R_TTT efh_R_TTT = EFH(x); Chris@102: typedef boost::phoenix::function EFH_R_T; Chris@102: EFH_R_T efh_R_T(efh_R_TTT); Chris@102: #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: throw lazy_exception("Running away in EFH!!"); Chris@102: #endif Chris@102: return cons( x-1, efh_R_T() ); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Enum_from { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator() Chris@102: (const T & x) const Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 fun1_R_TTT; Chris@102: fun1_R_TTT efh_R_TTT = EFH(x); Chris@102: typedef boost::phoenix::function EFH_R_T; Chris@102: EFH_R_T efh_R_T(efh_R_TTT); Chris@102: //std::cout << "enum_from (" << x << ")" << std::endl; Chris@102: return efh_R_T(); Chris@102: } Chris@102: }; Chris@102: Chris@102: template Chris@102: struct EFTH Chris@102: { Chris@102: mutable T x; Chris@102: T y; Chris@102: EFTH( const T& xx, const T& yy) : x(xx), y(yy) {} Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::phoenix::UseList::template Chris@102: List::type LType; Chris@102: typedef typename boost::phoenix::result_of:: Chris@102: ListType::delay_result_type type; Chris@102: }; Chris@102: typename result::type operator()() const { Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 fun1_R_TTT; Chris@102: //std::cout << "EFTH (" << x << ")" << std::endl; Chris@102: if (x > y ) return NIL; Chris@102: ++x; Chris@102: fun1_R_TTT efth_R_TTT = EFTH(x,y); Chris@102: typedef boost::phoenix::function EFTH_R_T; Chris@102: EFTH_R_T efth_R_T(efth_R_TTT); Chris@102: #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS Chris@102: if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH) Chris@102: throw lazy_exception("Running away in EFTH!!"); Chris@102: #endif Chris@102: return cons( x-1, efth_R_T() ); Chris@102: } Chris@102: }; Chris@102: Chris@102: struct Enum_from_to { Chris@102: template struct result; Chris@102: Chris@102: template Chris@102: struct result Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type type; Chris@102: }; Chris@102: Chris@102: template Chris@102: typename result::type operator() Chris@102: (const T & x, const T & y) const Chris@102: { Chris@102: typedef typename boost::remove_reference::type TT; Chris@102: typedef typename boost::remove_const::type TTT; Chris@102: typedef typename UseList::template List::type LType; Chris@102: typedef typename result_of::ListType:: Chris@102: delay_result_type result_type; Chris@102: typedef boost::function0 fun1_R_TTT; Chris@102: fun1_R_TTT efth_R_TTT = EFTH(x,y); Chris@102: typedef boost::phoenix::function EFTH_R_T; Chris@102: EFTH_R_T efth_R_T(efth_R_TTT); Chris@102: //std::cout << "enum_from (" << x << ")" << std::endl; Chris@102: return efth_R_T(); Chris@102: } Chris@102: }; Chris@102: Chris@102: } Chris@102: Chris@102: Chris@102: //BOOST_PHOENIX_ADAPT_CALLABLE(apply, impl::apply, 3) Chris@102: // Functors to be used in reuser will have to be defined Chris@102: // using boost::phoenix::function directly Chris@102: // in order to be able to be used as arguments. Chris@102: typedef boost::phoenix::function Repeat; Chris@102: typedef boost::phoenix::function Take; Chris@102: typedef boost::phoenix::function Drop; Chris@102: typedef boost::phoenix::function Enum_from; Chris@102: typedef boost::phoenix::function Enum_from_to; Chris@102: Repeat repeat; Chris@102: Take take; Chris@102: Drop drop; Chris@102: Enum_from enum_from; Chris@102: Enum_from_to enum_from_to; Chris@102: Chris@102: namespace fcpp { Chris@102: Chris@102: Chris@102: } Chris@102: Chris@102: } Chris@102: Chris@102: } Chris@102: Chris@102: Chris@102: #endif