annotate DEPENDENCIES/generic/include/boost/phoenix/function/lazy_prelude.hpp @ 125:34e428693f5d vext

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