lazy_prelude.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  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. Distributed under the Boost Software License, Version 1.0. (See accompanying
  119. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  120. ==============================================================================*/
  121. #ifndef BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE
  122. #define BOOST_PHOENIX_FUNCTION_LAZY_PRELUDE
  123. #include <exception>
  124. #include <vector>
  125. #include <boost/phoenix/core.hpp>
  126. #include <boost/phoenix/function.hpp>
  127. #include <boost/phoenix/scope.hpp>
  128. #include <boost/phoenix/operator.hpp>
  129. #include <boost/phoenix/function/lazy_operator.hpp>
  130. #include <boost/phoenix/function/lazy_reuse.hpp>
  131. #include <boost/phoenix/function/lazy_list.hpp>
  132. ////////////////////////////////////////////////////////////////////////////
  133. // To come here, the Haskell Prelude things which need list<T>.
  134. // Things which do not need list<T> are in lazy_operator.hpp.
  135. ////////////////////////////////////////////////////////////////////////////
  136. namespace boost {
  137. namespace phoenix {
  138. // These are in fcpp namespace as they introduce an FC++ style.
  139. namespace fcpp {
  140. template <typename T>
  141. struct Predicate {
  142. typedef typename boost::function1<bool,T> fun1_bool_T;
  143. typedef typename boost::phoenix::function<fun1_bool_T> bool_F_T;
  144. typedef bool_F_T type;
  145. };
  146. template <typename R>
  147. struct Function0 {
  148. typedef typename boost::function0<R> fun0_R;
  149. typedef typename boost::phoenix::function<fun0_R> R_F;
  150. typedef R_F type;
  151. };
  152. template <typename R,typename A0>
  153. struct Function1 {
  154. typedef typename boost::function1<R,A0> fun1_R_A0;
  155. typedef typename boost::phoenix::function<fun1_R_A0> R_F_A0;
  156. typedef R_F_A0 type;
  157. };
  158. template <typename R, typename A0, typename A1>
  159. struct Function2 {
  160. typedef typename boost::function2<R,A0,A1> fun2_R_A0_A1;
  161. typedef typename boost::phoenix::function<fun2_R_A0_A1> R_F_A0_A1;
  162. typedef R_F_A0_A1 type;
  163. };
  164. }
  165. namespace impl {
  166. using fcpp::INV;
  167. using fcpp::VAR;
  168. using fcpp::reuser1;
  169. using fcpp::reuser2;
  170. using fcpp::reuser3;
  171. using boost::phoenix::arg_names::arg1;
  172. struct Pow {
  173. template <typename Sig>
  174. struct result;
  175. template <typename This, typename N, typename A0>
  176. struct result<This(N,A0)>
  177. : boost::remove_reference<A0>
  178. {};
  179. template <typename N, typename A0>
  180. A0 operator()(N n, const A0 & a0,
  181. reuser2<INV,VAR,INV,Pow,N,A0> r = NIL ) const {
  182. if ( n <= 0 )
  183. return A0(1);
  184. else if ( n==1 )
  185. return a0;
  186. else {
  187. A0 a1 = r( Pow(), n-1, a0)();
  188. return a0*a1;
  189. }
  190. }
  191. };
  192. struct Apply {
  193. template <typename Sig>
  194. struct result;
  195. template <typename This, typename N, typename F,typename A0>
  196. struct result<This(N,F,A0)>
  197. : boost::remove_reference<A0>
  198. {};
  199. template <typename N, typename F, typename A0>
  200. A0 operator()(N n, const F &f, const A0 & a0,
  201. reuser3<INV,VAR,INV,INV,Apply,N,F,A0> r = NIL ) const {
  202. if ( n <= 0 )
  203. return a0;
  204. else if ( n==1 )
  205. return f(arg1)(a0);
  206. else {
  207. A0 a1 = r( Apply(), n-1, f, a0)();
  208. return f(a1)();
  209. }
  210. }
  211. };
  212. struct Odd {
  213. template <typename Sig>
  214. struct result;
  215. template <typename This, typename T>
  216. struct result<This(T)>
  217. {
  218. typedef bool type;
  219. };
  220. template <class T>
  221. typename result<Odd(T)>::type operator()( const T& x ) const {
  222. return x%2==1;
  223. }
  224. };
  225. struct Even {
  226. template <typename Sig>
  227. struct result;
  228. template <typename This, typename T>
  229. struct result<This(T)>
  230. {
  231. typedef bool type;
  232. };
  233. template <class T>
  234. typename result<Even(T)>::type operator()( const T& x ) const {
  235. return x%2==0;
  236. }
  237. };
  238. }
  239. typedef boost::phoenix::function<impl::Pow> Pow;
  240. typedef boost::phoenix::function<impl::Apply> Apply;
  241. typedef boost::phoenix::function<impl::Odd> Odd;
  242. typedef boost::phoenix::function<impl::Even> Even;
  243. Pow pow;
  244. Apply apply;
  245. Odd odd;
  246. Even even;
  247. namespace impl {
  248. using fcpp::INV;
  249. using fcpp::VAR;
  250. using fcpp::reuser1;
  251. using fcpp::reuser2;
  252. using fcpp::reuser3;
  253. using boost::phoenix::arg_names::arg1;
  254. // I cannot yet do currying to pass e.g. greater(9,arg1)
  255. // as a function. This can be done using Predicate<T>::type.
  256. struct Until {
  257. template <typename Sig> struct result;
  258. template <typename This, typename Pred, typename Unary, typename T>
  259. struct result<This(Pred,Unary,T)>
  260. : boost::remove_reference<T> {};
  261. template <class Pred, class Unary, class T>
  262. T operator()( const Pred& p,const Unary& op,const T &start) const
  263. {
  264. T tmp = start;
  265. while( !p(tmp)() ) {
  266. tmp = apply(1,op,tmp)();
  267. }
  268. return tmp;
  269. }
  270. };
  271. struct Until2 {
  272. template <typename Sig> struct result;
  273. template <typename This, typename Binary, typename Unary,
  274. typename T, typename X>
  275. struct result<This(Binary,Unary,T,X)>
  276. : boost::remove_reference<T> {};
  277. template <class Binary, class Unary, class T, class X>
  278. typename result<Until2(Binary,Unary,T,X)>::type
  279. operator()( const Binary& p, const Unary& op, const T & start,
  280. const X & check ) const
  281. {
  282. T tmp1 = start;
  283. T tmp2;
  284. while( !p(tmp1,check)() ) {
  285. tmp2 = apply(1,op,tmp1)();
  286. tmp1 = tmp2;
  287. }
  288. return tmp1;
  289. }
  290. };
  291. struct Last {
  292. template <typename Sig> struct result;
  293. template <typename This, typename L>
  294. struct result<This(L)>
  295. {
  296. typedef typename result_of::ListType<L>::value_type type;
  297. };
  298. template <class L>
  299. typename result<Last(L)>::type
  300. operator()( const L& ll ) const {
  301. size_t x = 0;
  302. typename result_of::ListType<L>::delay_result_type l = delay(ll);
  303. while( !null( tail(l)() )() ) {
  304. l = tail(l)();
  305. ++x;
  306. #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
  307. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  308. break;
  309. #endif
  310. }
  311. #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
  312. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  313. throw lazy_exception("Your list is too long!!");
  314. #endif
  315. return head(l)();
  316. }
  317. };
  318. struct Init {
  319. template <typename Sig> struct result;
  320. template <typename This, typename L>
  321. struct result<This(L)>
  322. {
  323. typedef typename result_of::ListType<L>::force_result_type type;
  324. };
  325. template <class L>
  326. typename result<Init(L)>::type
  327. operator()( const L& l,
  328. reuser1<INV,VAR,Init,
  329. typename result_of::ListType<L>::delay_result_type>
  330. r = NIL ) const {
  331. if( null( tail( l )() )() )
  332. return NIL;
  333. else
  334. return cons( head(l)(), r( Init(), tail(l)() )() )();
  335. }
  336. };
  337. struct Length {
  338. template <typename Sig> struct result;
  339. template <typename This, typename L>
  340. struct result<This(L)>
  341. {
  342. typedef size_t type;
  343. };
  344. template <class L>
  345. size_t operator()( const L& ll ) const {
  346. typename L::delay_result_type l = delay(ll);
  347. size_t x = 0;
  348. while( !null(l)() ) {
  349. l = tail(l);
  350. ++x;
  351. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  352. break;
  353. }
  354. #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
  355. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  356. throw lazy_exception("Your list is too long!!");
  357. #endif
  358. return x;
  359. }
  360. };
  361. // at is Haskell's operator (!!)
  362. // This is zero indexed. at(l,0)() returns the first element.
  363. struct At {
  364. template <typename Sig> struct result;
  365. template <typename This, typename L, typename N>
  366. struct result<This(L,N)>
  367. {
  368. typedef typename result_of::ListType<L>::value_type type;
  369. };
  370. template <class L>
  371. typename result<At(L,size_t)>::type
  372. operator()( L l, size_t n ) const {
  373. while( n!=0 ) {
  374. l = tail(l);
  375. --n;
  376. }
  377. return head(l)();
  378. }
  379. };
  380. template <class P,class L>
  381. struct FilterH
  382. {
  383. P p;
  384. L l;
  385. FilterH( const P& pp, const L& ll) : p(pp), l(ll) {}
  386. template <typename Sig> struct result;
  387. template <typename This, class PP, class LL>
  388. struct result<This(PP,LL)>
  389. {
  390. typedef typename boost::phoenix::result_of::
  391. ListType<LL>::delay_result_type type;
  392. };
  393. typename result<FilterH(P,L)>::type operator()() const {
  394. typedef typename result_of::ListType<L>::
  395. delay_result_type result_type;
  396. typedef boost::function0<result_type> Fun2_R_P_L;
  397. typedef boost::phoenix::function<Fun2_R_P_L> FilterH_R_P_L;
  398. if (null(l)() )
  399. return NIL;
  400. Fun2_R_P_L fun2_R_P_L = FilterH<P,L>(p,tail(l));
  401. FilterH_R_P_L filterh_R_P_L(fun2_R_P_L);
  402. if( p(head(l))() )
  403. return cons( head(l)(), filterh_R_P_L() );
  404. else
  405. return filterh_R_P_L();
  406. }
  407. };
  408. struct Filter {
  409. template <typename Sig> struct result;
  410. template <typename This, typename P, typename L>
  411. struct result<This(P,L)>
  412. {
  413. typedef typename result_of::ListType<L>::delay_result_type
  414. type;
  415. };
  416. template <class P, class L>
  417. typename result<Filter(P,L)>::type
  418. operator()( const P& p, const L& ll) const
  419. {
  420. typename result_of::ListType<L>::delay_result_type
  421. l = delay(ll);
  422. typedef typename result_of::ListType<L>::
  423. delay_result_type result_type;
  424. typedef boost::function0<result_type> Fun2_R_P_L;
  425. typedef boost::phoenix::function<Fun2_R_P_L> FilterH_R_P_L;
  426. Fun2_R_P_L fun2_R_P_L = FilterH<P,L>(p,l);
  427. FilterH_R_P_L filterh_R_P_L(fun2_R_P_L);
  428. return filterh_R_P_L();
  429. }
  430. };
  431. template <class F,class T>
  432. struct IterateH
  433. {
  434. F f;
  435. T t;
  436. IterateH( const F& ff, const T& tt) : f(ff), t(tt) {}
  437. template <typename Sig> struct result;
  438. template <typename This,class F2,class T2>
  439. struct result<This(F2,T2)>
  440. {
  441. typedef typename boost::remove_reference<T2>::type TT;
  442. typedef typename boost::remove_const<TT>::type TTT;
  443. typedef typename UseList::template List<TTT>::type LType;
  444. typedef typename result_of::ListType<LType>::
  445. delay_result_type type;
  446. };
  447. typename result<IterateH(F,T)>::type operator()() const {
  448. typedef typename UseList::template List<T>::type LType;
  449. typedef typename result_of::ListType<LType>::
  450. delay_result_type result_type;
  451. typedef boost::function0<result_type> Fun2_R_F_T;
  452. typedef boost::phoenix::function<Fun2_R_F_T> IterateH_R_F_T;
  453. Fun2_R_F_T fun2_R_F_T = IterateH<F,T>(f,f(t)());
  454. IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T);
  455. return cons( t, iterateh_R_F_T() );
  456. }
  457. };
  458. struct Iterate {
  459. // Note: this does always return an odd_list; iterate() takes no ListLike
  460. // parameter, and it requires that its result be lazy.
  461. template <typename Sig> struct result;
  462. template <typename This, typename F, typename T>
  463. struct result<This(F,T)>
  464. {
  465. typedef typename boost::remove_reference<T>::type TT;
  466. typedef typename boost::remove_const<TT>::type TTT;
  467. typedef typename UseList::template List<TTT>::type LType;
  468. typedef typename result_of::ListType<LType>::
  469. delay_result_type type;
  470. };
  471. template <class F, class T>
  472. typename result<Iterate(F,T)>::type operator()
  473. (const F& f, const T& t) const {
  474. typedef typename UseList::template List<T>::type LType;
  475. typedef typename result_of::ListType<LType>::
  476. delay_result_type result_type;
  477. typedef boost::function0<result_type> Fun2_R_F_T;
  478. typedef boost::phoenix::function<Fun2_R_F_T> IterateH_R_F_T;
  479. Fun2_R_F_T fun2_R_F_T = IterateH<F,T>(f,f(t)());
  480. IterateH_R_F_T iterateh_R_F_T(fun2_R_F_T);
  481. return iterateh_R_F_T();
  482. }
  483. };
  484. }
  485. typedef boost::phoenix::function<impl::Until> Until;
  486. typedef boost::phoenix::function<impl::Until2> Until2;
  487. typedef boost::phoenix::function<impl::Last> Last;
  488. typedef boost::phoenix::function<impl::Init> Init;
  489. typedef boost::phoenix::function<impl::Length> Length;
  490. typedef boost::phoenix::function<impl::At> At;
  491. typedef boost::phoenix::function<impl::Filter> Filter;
  492. typedef boost::phoenix::function<impl::Iterate> Iterate;
  493. Until until;
  494. Until2 until2;
  495. Last last;
  496. Init all_but_last; // renamed from init which is not available.
  497. Length length;
  498. At at_; //Renamed from at.
  499. Filter filter;
  500. Iterate iterate;
  501. namespace impl {
  502. struct Repeat {
  503. // See note for iterate()
  504. template <typename Sig> struct result;
  505. template <typename This, typename T>
  506. struct result<This(T)>
  507. {
  508. typedef typename boost::remove_reference<T>::type TT;
  509. typedef typename boost::remove_const<TT>::type TTT;
  510. typedef typename UseList::template List<TTT>::type LType;
  511. typedef typename result_of::ListType<LType>::
  512. delay_result_type type;
  513. };
  514. template <class T>
  515. typename result<Repeat(T)>::type operator()( const T& x) const
  516. {
  517. return iterate(id,x);
  518. }
  519. };
  520. struct Take {
  521. template <typename Sig> struct result;
  522. template <typename This, typename N, typename L>
  523. struct result<This(N,L)>
  524. {
  525. typedef typename result_of::ListType<L>::force_result_type type;
  526. };
  527. template <class N,class L>
  528. typename result<Take(N,L)>::type
  529. operator()( N n, const L& l,
  530. reuser2<INV,VAR,VAR,Take,N,
  531. typename result_of::ListType<L>::force_result_type>
  532. r = NIL
  533. ) const {
  534. if( n <= 0 || null(l)() )
  535. return NIL;
  536. else {
  537. return cons( head(l)(), r( Take(), n-1, tail(l)() )() )();
  538. }
  539. }
  540. };
  541. struct Drop {
  542. template <typename Sig> struct result;
  543. template <typename This, typename Dummy, typename L>
  544. struct result<This(Dummy,L)>
  545. {
  546. typedef typename result_of::ListType<L>::delay_result_type type;
  547. };
  548. template <class L>
  549. typename result<Drop(size_t,L)>::type
  550. operator()( size_t n, const L& ll ) const {
  551. typename L::delay_result_type l = delay(ll);
  552. while( n!=0 && !null(l)() ) {
  553. --n;
  554. l = tail(l)();
  555. }
  556. return l;
  557. }
  558. };
  559. template <class T>
  560. struct EFH
  561. {
  562. mutable T x;
  563. EFH( const T& xx) : x(xx) {}
  564. template <typename Sig> struct result;
  565. template <typename This, class TT>
  566. struct result<This(TT)>
  567. {
  568. typedef typename boost::phoenix::UseList::template
  569. List<TT>::type LType;
  570. typedef typename boost::phoenix::result_of::
  571. ListType<LType>::delay_result_type type;
  572. };
  573. typename result<EFH(T)>::type operator()() const {
  574. typedef typename UseList::template List<T>::type LType;
  575. typedef typename result_of::ListType<LType>::
  576. delay_result_type result_type;
  577. typedef boost::function0<result_type> fun1_R_TTT;
  578. //std::cout << "EFH (" << x << ")" << std::endl;
  579. ++x;
  580. fun1_R_TTT efh_R_TTT = EFH<T>(x);
  581. typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
  582. EFH_R_T efh_R_T(efh_R_TTT);
  583. #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
  584. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  585. throw lazy_exception("Running away in EFH!!");
  586. #endif
  587. return cons( x-1, efh_R_T() );
  588. }
  589. };
  590. struct Enum_from {
  591. template <typename Sig> struct result;
  592. template <typename This, typename T>
  593. struct result<This(T)>
  594. {
  595. typedef typename boost::remove_reference<T>::type TT;
  596. typedef typename boost::remove_const<TT>::type TTT;
  597. typedef typename UseList::template List<TTT>::type LType;
  598. typedef typename result_of::ListType<LType>::
  599. delay_result_type type;
  600. };
  601. template <class T>
  602. typename result<Enum_from(T)>::type operator()
  603. (const T & x) const
  604. {
  605. typedef typename boost::remove_reference<T>::type TT;
  606. typedef typename boost::remove_const<TT>::type TTT;
  607. typedef typename UseList::template List<T>::type LType;
  608. typedef typename result_of::ListType<LType>::
  609. delay_result_type result_type;
  610. typedef boost::function0<result_type> fun1_R_TTT;
  611. fun1_R_TTT efh_R_TTT = EFH<TTT>(x);
  612. typedef boost::phoenix::function<fun1_R_TTT> EFH_R_T;
  613. EFH_R_T efh_R_T(efh_R_TTT);
  614. //std::cout << "enum_from (" << x << ")" << std::endl;
  615. return efh_R_T();
  616. }
  617. };
  618. template <class T>
  619. struct EFTH
  620. {
  621. mutable T x;
  622. T y;
  623. EFTH( const T& xx, const T& yy) : x(xx), y(yy) {}
  624. template <typename Sig> struct result;
  625. template <typename This, class TT>
  626. struct result<This(TT)>
  627. {
  628. typedef typename boost::phoenix::UseList::template
  629. List<TT>::type LType;
  630. typedef typename boost::phoenix::result_of::
  631. ListType<LType>::delay_result_type type;
  632. };
  633. typename result<EFTH(T)>::type operator()() const {
  634. typedef typename UseList::template List<T>::type LType;
  635. typedef typename result_of::ListType<LType>::
  636. delay_result_type result_type;
  637. typedef boost::function0<result_type> fun1_R_TTT;
  638. //std::cout << "EFTH (" << x << ")" << std::endl;
  639. if (x > y ) return NIL;
  640. ++x;
  641. fun1_R_TTT efth_R_TTT = EFTH<T>(x,y);
  642. typedef boost::phoenix::function<fun1_R_TTT> EFTH_R_T;
  643. EFTH_R_T efth_R_T(efth_R_TTT);
  644. #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
  645. if (x > BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH)
  646. throw lazy_exception("Running away in EFTH!!");
  647. #endif
  648. return cons( x-1, efth_R_T() );
  649. }
  650. };
  651. struct Enum_from_to {
  652. template <typename Sig> struct result;
  653. template <typename This, typename T>
  654. struct result<This(T,T)>
  655. {
  656. typedef typename boost::remove_reference<T>::type TT;
  657. typedef typename boost::remove_const<TT>::type TTT;
  658. typedef typename UseList::template List<TTT>::type LType;
  659. typedef typename result_of::ListType<LType>::
  660. delay_result_type type;
  661. };
  662. template <class T>
  663. typename result<Enum_from(T,T)>::type operator()
  664. (const T & x, const T & y) const
  665. {
  666. typedef typename boost::remove_reference<T>::type TT;
  667. typedef typename boost::remove_const<TT>::type TTT;
  668. typedef typename UseList::template List<T>::type LType;
  669. typedef typename result_of::ListType<LType>::
  670. delay_result_type result_type;
  671. typedef boost::function0<result_type> fun1_R_TTT;
  672. fun1_R_TTT efth_R_TTT = EFTH<TTT>(x,y);
  673. typedef boost::phoenix::function<fun1_R_TTT> EFTH_R_T;
  674. EFTH_R_T efth_R_T(efth_R_TTT);
  675. //std::cout << "enum_from (" << x << ")" << std::endl;
  676. return efth_R_T();
  677. }
  678. };
  679. }
  680. //BOOST_PHOENIX_ADAPT_CALLABLE(apply, impl::apply, 3)
  681. // Functors to be used in reuser will have to be defined
  682. // using boost::phoenix::function directly
  683. // in order to be able to be used as arguments.
  684. typedef boost::phoenix::function<impl::Repeat> Repeat;
  685. typedef boost::phoenix::function<impl::Take> Take;
  686. typedef boost::phoenix::function<impl::Drop> Drop;
  687. typedef boost::phoenix::function<impl::Enum_from> Enum_from;
  688. typedef boost::phoenix::function<impl::Enum_from_to> Enum_from_to;
  689. Repeat repeat;
  690. Take take;
  691. Drop drop;
  692. Enum_from enum_from;
  693. Enum_from_to enum_from_to;
  694. namespace fcpp {
  695. }
  696. }
  697. }
  698. #endif