Warning, file /include/boost/phoenix/function/lazy_list.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_LIST
0090 #define BOOST_PHOENIX_FUNCTION_LAZY_LIST
0091
0092 #include <boost/phoenix/core.hpp>
0093 #include <boost/phoenix/function.hpp>
0094 #include <boost/intrusive_ptr.hpp>
0095 #include <boost/function.hpp>
0096 #include <boost/type_traits/type_with_alignment.hpp>
0097
0098
0099 namespace boost {
0100
0101 namespace phoenix {
0102
0103
0104
0105
0106
0107 template <class T> class strict_list;
0108 namespace impl {
0109 template <class T> class list;
0110 template <class T> class odd_list;
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 namespace lazy {
0125
0126 template <class L, bool is_lazy> struct ensure_lazy_helper {};
0127 template <class L> struct ensure_lazy_helper<L,true> {
0128 static void requires_lazy_list_to_prevent_infinite_recursion() {}
0129 };
0130 template <class L>
0131 void ensure_lazy() {
0132 ensure_lazy_helper<L,L::is_lazy>::
0133 requires_lazy_list_to_prevent_infinite_recursion();
0134 }
0135
0136 }
0137
0138
0139
0140
0141
0142 namespace result_of {
0143
0144 template < typename L >
0145 class ListType
0146 {
0147 public:
0148 typedef typename boost::remove_reference<L>::type LType;
0149 typedef typename LType::value_type value_type;
0150 typedef typename LType::tail_result_type tail_result_type;
0151 typedef typename LType::force_result_type force_result_type;
0152 typedef typename LType::delay_result_type delay_result_type;
0153 };
0154
0155 template <>
0156 class ListType<a_unique_type_for_nil>
0157 {
0158 public:
0159 typedef a_unique_type_for_nil LType;
0160
0161 };
0162
0163 template <typename F, typename T>
0164 struct ResultType {
0165 typedef typename impl::odd_list<T> type;
0166 };
0167
0168 }
0169
0170
0171
0172
0173
0174
0175
0176 namespace listlike {
0177
0178 struct ListLike {};
0179
0180
0181
0182 template <class L, bool is_lazy> struct ensure_lazy_helper {};
0183 template <class L> struct ensure_lazy_helper<L,true> {
0184 static void requires_lazy_list_to_prevent_infinite_recursion() {}
0185 };
0186 template <class L>
0187 void ensure_lazy() {
0188 ensure_lazy_helper<L,L::is_lazy>::
0189 requires_lazy_list_to_prevent_infinite_recursion();
0190 }
0191
0192 template <class L, bool b>
0193 struct EnsureListLikeHelp {
0194 static void trying_to_call_a_list_function_on_a_non_list() {}
0195 };
0196 template <class L> struct EnsureListLikeHelp<L,false> { };
0197 template <class L>
0198 void EnsureListLike() {
0199 typedef typename result_of::ListType<L>::LType LType;
0200 EnsureListLikeHelp<L,boost::is_base_and_derived<ListLike,LType>::value>::
0201 trying_to_call_a_list_function_on_a_non_list();
0202 }
0203
0204 template <class L>
0205 bool is_a_unique_type_for_nil(const L& ) {
0206 return false;
0207 }
0208
0209 template <>
0210 bool is_a_unique_type_for_nil<a_unique_type_for_nil>
0211 (const a_unique_type_for_nil& ) {
0212 return true;
0213 }
0214
0215 template <class L>
0216 struct detect_nil {
0217 static const bool is_nil = false;
0218 };
0219
0220 template <>
0221 struct detect_nil<a_unique_type_for_nil> {
0222 static const bool is_nil = true;
0223 };
0224
0225 template <>
0226 struct detect_nil<a_unique_type_for_nil&> {
0227 static const bool is_nil = true;
0228 };
0229
0230 template <>
0231 struct detect_nil<const a_unique_type_for_nil&> {
0232 static const bool is_nil = true;
0233 };
0234
0235 }
0236
0237
0238
0239
0240
0241 #ifndef BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH
0242 #define BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH 1000
0243 #endif
0244
0245 namespace impl {
0246
0247 struct Head
0248 {
0249 template <typename Sig>
0250 struct result;
0251
0252 template <typename This, typename L>
0253 struct result<This(L)>
0254 {
0255 typedef typename result_of::ListType<L>::value_type type;
0256 };
0257
0258 template <typename L>
0259 typename result<Head(L)>::type
0260 operator()(const L & l) const
0261 {
0262 listlike::EnsureListLike<L>();
0263 return l.head();
0264 }
0265
0266 };
0267
0268 struct Tail
0269 {
0270 template <typename Sig>
0271 struct result;
0272
0273 template <typename This, typename L>
0274 struct result<This(L)>
0275 {
0276 typedef typename result_of::ListType<L>::tail_result_type type;
0277 };
0278
0279 template <typename L>
0280 typename result<Tail(L)>::type
0281 operator()(const L & l) const
0282 {
0283 listlike::EnsureListLike<L>();
0284 return l.tail();
0285 }
0286
0287 };
0288
0289 struct Null
0290 {
0291 template <typename Sig>
0292 struct result;
0293
0294 template <typename This, typename L>
0295 struct result<This(L)>
0296 {
0297 typedef bool type;
0298 };
0299
0300 template <typename L>
0301 typename result<Null(L)>::type
0302
0303 operator()(const L& l) const
0304 {
0305 listlike::EnsureListLike<L>();
0306 return !l;
0307 }
0308
0309 };
0310
0311 struct Delay {
0312 template <typename Sig>
0313 struct result;
0314
0315 template <typename This, typename L>
0316 struct result<This(L)>
0317 {
0318 typedef typename result_of::ListType<L>::delay_result_type type;
0319 };
0320
0321 template <typename L>
0322 typename result<Delay(L)>::type
0323 operator()(const L & l) const
0324 {
0325 listlike::EnsureListLike<L>();
0326 return l.delay();
0327 }
0328
0329 };
0330
0331 struct Force {
0332 template <typename Sig>
0333 struct result;
0334
0335 template <typename This, typename L>
0336 struct result<This(L)>
0337 {
0338 typedef typename result_of::ListType<L>::force_result_type type;
0339 };
0340
0341 template <typename L>
0342 typename result<Force(L)>::type
0343 operator()(const L & l) const
0344 {
0345 listlike::EnsureListLike<L>();
0346 return l.force();
0347 }
0348
0349 };
0350
0351 }
0352
0353
0354
0355 typedef boost::phoenix::function<impl::Head> Head;
0356 typedef boost::phoenix::function<impl::Tail> Tail;
0357 typedef boost::phoenix::function<impl::Null> Null;
0358 typedef boost::phoenix::function<impl::Delay> Delay;
0359 typedef boost::phoenix::function<impl::Force> Force;
0360 Head head;
0361 Tail tail;
0362 Null null;
0363 Delay delay;
0364 Force force;
0365
0366
0367
0368
0369
0370
0371 namespace impl {
0372 template <class T>
0373 struct strict_cons : public boost::noncopyable {
0374 mutable RefCountType refC;
0375 T head;
0376 typedef boost::intrusive_ptr<strict_cons> tail_type;
0377 tail_type tail;
0378 strict_cons( const T& h, const tail_type& t ) : refC(0), head(h), tail(t) {}
0379
0380 };
0381 template <class T>
0382 void intrusive_ptr_add_ref( const strict_cons<T>* p ) {
0383 ++ (p->refC);
0384 }
0385 template <class T>
0386 void intrusive_ptr_release( const strict_cons<T>* p ) {
0387 if( !--(p->refC) ) delete p;
0388 }
0389
0390 template <class T>
0391 class strict_list_iterator {
0392 typedef boost::intrusive_ptr<strict_cons<T> > rep_type;
0393 rep_type l;
0394 bool is_nil;
0395 void advance() {
0396 l = l->tail;
0397 if( !l )
0398 is_nil = true;
0399 }
0400 class Proxy {
0401 const T x;
0402 friend class strict_list_iterator;
0403 Proxy( const T& xx ) : x(xx) {}
0404 public:
0405 const T* operator->() const { return &x; }
0406 };
0407 public:
0408 typedef std::input_iterator_tag iterator_category;
0409 typedef T value_type;
0410 typedef ptrdiff_t difference_type;
0411 typedef T* pointer;
0412 typedef T& reference;
0413
0414 strict_list_iterator() : l(), is_nil(true) {}
0415 explicit strict_list_iterator( const rep_type& ll ) : l(ll), is_nil(!ll) {}
0416
0417 const T operator*() const { return l->head; }
0418 const Proxy operator->() const { return Proxy(l->head); }
0419 strict_list_iterator<T>& operator++() {
0420 advance();
0421 return *this;
0422 }
0423 const strict_list_iterator<T> operator++(int) {
0424 strict_list_iterator<T> i( *this );
0425 advance();
0426 return i;
0427 }
0428 bool operator==( const strict_list_iterator<T>& i ) const {
0429 return is_nil && i.is_nil;
0430 }
0431 bool operator!=( const strict_list_iterator<T>& i ) const {
0432 return ! this->operator==(i);
0433 }
0434 };
0435 }
0436
0437
0438
0439
0440 template <class T>
0441 class strict_list : public listlike::ListLike
0442 {
0443 typedef boost::intrusive_ptr<impl::strict_cons<T> > rep_type;
0444 rep_type rep;
0445 struct Make {};
0446
0447 template <class Iter>
0448 static rep_type help( Iter a, const Iter& b ) {
0449 rep_type r;
0450 while( a != b ) {
0451 T x( *a );
0452 r = rep_type( new impl::strict_cons<T>( x, r ) );
0453 ++a;
0454 }
0455 return r;
0456 }
0457
0458 public:
0459 static const bool is_lazy = false;
0460
0461 typedef T value_type;
0462 typedef strict_list force_result_type;
0463 typedef strict_list delay_result_type;
0464 typedef strict_list tail_result_type;
0465 template <class UU> struct cons_rebind {
0466 typedef strict_list<UU> type;
0467 typedef strict_list<UU> delay_type;
0468 };
0469
0470
0471 strict_list( Make, const rep_type& r ) : rep(r) {}
0472
0473 strict_list() : rep() {}
0474
0475 strict_list( a_unique_type_for_nil ) : rep() {}
0476
0477 template <class F>
0478 strict_list( const F& f ) : rep( f().rep ) {
0479
0480
0481 }
0482
0483 strict_list( const T& x, const strict_list& y )
0484 : rep( new impl::strict_cons<T>(x,y.rep) ) {}
0485
0486 template <class F>
0487 strict_list( const T& x, const F& f )
0488 : rep( new impl::strict_cons<T>(x,f().rep) ) {}
0489
0490 operator bool() const { return (bool)rep; }
0491 force_result_type force() const { return *this; }
0492 delay_result_type delay() const { return *this; }
0493 T head() const {
0494 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0495 if( !*this )
0496 throw lazy_exception("Tried to take head() of empty strict_list");
0497 #endif
0498 return rep->head;
0499 }
0500 tail_result_type tail() const {
0501 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0502 if( !*this )
0503 throw lazy_exception("Tried to take tail() of empty strict_list");
0504 #endif
0505 return strict_list(Make(),rep->tail);
0506 }
0507
0508 template <class Iter>
0509 strict_list( const Iter& a, const Iter& b ) : rep( rep_type() ) {
0510
0511
0512 std::vector<T> tmp(a,b);
0513 rep = help( tmp.rbegin(), tmp.rend() );
0514 }
0515
0516
0517
0518
0519 ~strict_list() { while(rep && (rep->refC == 1)) rep = rep->tail; }
0520
0521
0522 typedef impl::strict_list_iterator<T> const_iterator;
0523 typedef const_iterator iterator;
0524 iterator begin() const { return impl::strict_list_iterator<T>( rep ); }
0525 iterator end() const { return impl::strict_list_iterator<T>(); }
0526
0527 };
0528
0529
0530
0531 template <class T>
0532 bool operator==( const strict_list<T>& a, a_unique_type_for_nil ) {
0533 return null(a)();
0534 }
0535 template <class T>
0536 bool operator==( a_unique_type_for_nil, const strict_list<T>& a ) {
0537 return null(a)();
0538 }
0539 template <class T>
0540 bool operator==( const strict_list<T>& a, const strict_list<T>& b ) {
0541 if( null(a)() && null(b)() )
0542 return true;
0543 if( null(a)() || null(b)() )
0544 return false;
0545 return (head(a)()==head(b)()) &&
0546 (tail(a)()==tail(b)());
0547 }
0548
0549 template <class T>
0550 bool operator<( const strict_list<T>& a, const strict_list<T>& b ) {
0551 if( null(a)() && !null(b)() ) return true;
0552 if( null(b)() ) return false;
0553 if( head(b)() < head(a)() ) return false;
0554 if( head(a)() < head(b)() ) return true;
0555 return (tail(a)() < tail(b)());
0556 }
0557 template <class T>
0558 bool operator<( const strict_list<T>&, a_unique_type_for_nil ) {
0559 return false;
0560 }
0561 template <class T>
0562 bool operator<( a_unique_type_for_nil, const strict_list<T>& b ) {
0563 return !(null(b)());
0564 }
0565
0566
0567
0568
0569 namespace impl {
0570 using fcpp::INV;
0571 using fcpp::VAR;
0572 using fcpp::reuser2;
0573
0574 struct CacheEmpty {};
0575
0576 template <class T> class Cache;
0577 template <class T> class odd_list;
0578 template <class T> class list_iterator;
0579 template <class It, class T>
0580 struct ListItHelp2 {
0581
0582 typedef odd_list<T> return_type;
0583 odd_list<T> operator()( It begin, const It& end,
0584 reuser2<INV,VAR,INV,ListItHelp2<It,T>,It,It> r = NIL ) const;
0585 };
0586 template <class U,class F> struct cvt;
0587 template <class T, class F, class R> struct ListHelp;
0588 template <class T> Cache<T>* xempty_helper();
0589 template <class T, class F, class L, bool b> struct ConsHelp2;
0590
0591 struct ListRaw {};
0592
0593 template <class T>
0594 class list : public listlike::ListLike
0595 {
0596
0597 boost::intrusive_ptr<Cache<T> > rep;
0598
0599 template <class U> friend class Cache;
0600 template <class U> friend class odd_list;
0601 template <class TT, class F, class L, bool b> friend struct ConsHelp2;
0602 template <class U,class F> friend struct cvt;
0603
0604 list( const boost::intrusive_ptr<Cache<T> >& p ) : rep(p) { }
0605 list( ListRaw, Cache<T>* p ) : rep(p) { }
0606
0607 bool priv_isEmpty() const {
0608 return rep->cache().second.rep == Cache<T>::XNIL();
0609 }
0610 T priv_head() const {
0611 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0612 if( priv_isEmpty() )
0613 throw lazy_exception("Tried to take head() of empty list");
0614 #endif
0615 return rep->cache().first();
0616 }
0617 list<T> priv_tail() const {
0618 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0619 if( priv_isEmpty() )
0620 throw lazy_exception("Tried to take tail() of empty list");
0621 #endif
0622 return rep->cache().second;
0623 }
0624
0625
0626 public:
0627 static const bool is_lazy = true;
0628
0629 typedef T value_type;
0630 typedef list tail_result_type;
0631 typedef odd_list<T> force_result_type;
0632 typedef list delay_result_type;
0633 template <class UU> struct cons_rebind {
0634 typedef odd_list<UU> type;
0635 typedef list<UU> delay_type;
0636 };
0637
0638 list( a_unique_type_for_nil ) : rep( Cache<T>::XEMPTY() ) { }
0639 list() : rep( Cache<T>::XEMPTY() ) { }
0640
0641 template <class F>
0642
0643
0644 list( const F& f )
0645 : rep( ListHelp<T,F,odd_list<T> >()(f) ) { }
0646
0647
0648 operator bool() const { return !priv_isEmpty(); }
0649 const force_result_type& force() const { return rep->cache(); }
0650 const delay_result_type& delay() const { return *this; }
0651
0652
0653 operator odd_list<T>() const { return force(); }
0654
0655 T head() const { return priv_head(); }
0656 tail_result_type tail() const { return priv_tail(); }
0657
0658
0659 typedef list_iterator<T> const_iterator;
0660 typedef const_iterator iterator;
0661 iterator begin() const { return list_iterator<T>( *this ); }
0662 iterator end() const { return list_iterator<T>(); }
0663
0664
0665 };
0666
0667
0668
0669
0670
0671 struct OddListDummyY {};
0672
0673 template <class T>
0674 class odd_list : public listlike::ListLike
0675 {
0676 public:
0677 typedef
0678 typename boost::type_with_alignment<boost::alignment_of<T>::value>::type
0679 xfst_type;
0680 private:
0681 union { xfst_type fst; unsigned char dummy[sizeof(T)]; };
0682
0683 const T& first() const {
0684 return *static_cast<const T*>(static_cast<const void*>(&fst));
0685 }
0686 T& first() {
0687 return *static_cast<T*>(static_cast<void*>(&fst));
0688 }
0689 list<T> second;
0690
0691 template <class U> friend class list;
0692 template <class U> friend class Cache;
0693
0694 odd_list( OddListDummyY )
0695 : second( Cache<T>::XBAD() ) { }
0696
0697 void init( const T& x ) {
0698 new (static_cast<void*>(&fst)) T(x);
0699 }
0700
0701 bool fst_is_valid() const {
0702 if( second.rep != Cache<T>::XNIL() )
0703 if( second.rep != Cache<T>::XBAD() )
0704 return true;
0705 return false;
0706 }
0707
0708 bool priv_isEmpty() const { return second.rep == Cache<T>::XNIL(); }
0709 T priv_head() const {
0710 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0711 if( priv_isEmpty() )
0712 throw lazy_exception("Tried to take head() of empty odd_list");
0713 #endif
0714 return first();
0715 }
0716
0717 list<T> priv_tail() const {
0718 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0719 if( priv_isEmpty() )
0720 throw lazy_exception("Tried to take tail() of empty odd_list");
0721 #endif
0722 return second;
0723 }
0724
0725 public:
0726 static const bool is_lazy = true;
0727
0728 typedef T value_type;
0729 typedef list<T> tail_result_type;
0730 typedef odd_list<T> force_result_type;
0731 typedef list<T> delay_result_type;
0732 template <class UU> struct cons_rebind {
0733 typedef odd_list<UU> type;
0734 typedef list<UU> delay_type;
0735 };
0736
0737 odd_list() : second( Cache<T>::XNIL() ) { }
0738 odd_list( a_unique_type_for_nil ) : second( Cache<T>::XNIL() ) { }
0739 odd_list( const T& x, const list<T>& y ) : second(y) { init(x); }
0740 odd_list( const T& x, a_unique_type_for_nil ) : second(NIL) { init(x); }
0741
0742 odd_list( const odd_list<T>& x ) : second(x.second) {
0743 if( fst_is_valid() ) {
0744 init( x.first() );
0745 }
0746 }
0747
0748 template <class It>
0749 odd_list( It begin, const It& end )
0750 : second( begin==end ? Cache<T>::XNIL() :
0751 ( init(*begin++), list<T>( begin, end ) ) ) {}
0752
0753 odd_list<T>& operator=( const odd_list<T>& x ) {
0754 if( this == &x ) return *this;
0755 if( fst_is_valid() ) {
0756 if( x.fst_is_valid() )
0757 first() = x.first();
0758 else
0759 first().~T();
0760 }
0761 else {
0762 if( x.fst_is_valid() )
0763 init( x.first() );
0764 }
0765 second = x.second;
0766 return *this;
0767 }
0768
0769 ~odd_list() {
0770 if( fst_is_valid() ) {
0771 first().~T();
0772 }
0773 }
0774
0775 operator bool() const { return !priv_isEmpty(); }
0776 const force_result_type& force() const { return *this; }
0777 delay_result_type delay() const { return list<T>(*this); }
0778
0779 T head() const { return priv_head(); }
0780 tail_result_type tail() const { return priv_tail(); }
0781
0782
0783 typedef list_iterator<T> const_iterator;
0784 typedef const_iterator iterator;
0785 iterator begin() const { return list_iterator<T>( this->delay() ); }
0786 iterator end() const { return list_iterator<T>(); }
0787
0788
0789 };
0790
0791
0792
0793
0794
0795
0796
0797
0798 template <class U,class F>
0799 struct cvt {
0800 typedef odd_list<U> return_type;
0801 F f;
0802 cvt( const F& ff ) : f(ff) {}
0803 odd_list<U> operator()() const {
0804 list<U> l = f();
0805 return l.force();
0806 }
0807 };
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818 template <class T>
0819 Cache<T>* xnil_helper() {
0820 void *p = std::malloc( sizeof(RefCountType) );
0821 *((RefCountType*)p) = 1;
0822 return static_cast<Cache<T>*>( p );
0823 }
0824
0825 template <class T>
0826 Cache<T>* xnil_helper_nil() {
0827 Cache<T>* p = xnil_helper<T>();
0828 return p;
0829 }
0830
0831 template <class T>
0832 Cache<T>* xnil_helper_bad() {
0833 Cache<T>* p = xnil_helper<T>();
0834 return p;
0835 }
0836
0837 template <class T>
0838 Cache<T>* xempty_helper() {
0839 Cache<T>* p = new Cache<T>( CacheEmpty() );
0840 return p;
0841 }
0842
0843
0844
0845 template <class T>
0846 struct fun0_type_helper{
0847 typedef boost::function0<odd_list<T> > fun_type;
0848 typedef boost::phoenix::function<fun_type> phx_type;
0849 };
0850
0851
0852 template <class T>
0853 struct make_fun0_odd_list {
0854
0855 typedef typename fun0_type_helper<T>::fun_type fun_type;
0856 typedef typename fun0_type_helper<T>::phx_type phx_type;
0857 typedef phx_type result_type;
0858
0859 template <class F>
0860 result_type operator()(const F& f) const
0861 {
0862 fun_type ff(f);
0863 phx_type g(ff);
0864 return g;
0865 }
0866
0867
0868 template <class F>
0869 typename boost::phoenix::function<F> operator()
0870 (const boost::phoenix::function<F>& f) const
0871 {
0872 return f;
0873 }
0874
0875 };
0876
0877 template <class T>
0878 class Cache : boost::noncopyable {
0879 mutable RefCountType refC;
0880
0881 typedef typename fun0_type_helper<T>::fun_type fun_odd_list_T;
0882
0883 typedef typename fun0_type_helper<T>::phx_type fun0_odd_list_T;
0884 mutable fun0_odd_list_T fxn;
0885 mutable odd_list<T> val;
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896 struct blackhole_helper {
0897 typedef odd_list<T> return_type;
0898 odd_list<T> operator()() const {
0899 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
0900 throw lazy_exception("You have entered a black hole.");
0901 #else
0902 return odd_list<T>();
0903 #endif
0904 }
0905 };
0906
0907
0908
0909
0910 static const boost::intrusive_ptr<Cache<T> >& XEMPTY() {
0911 static boost::intrusive_ptr<Cache<T> > xempty( xempty_helper<T>() );
0912 return xempty;
0913 }
0914 static const boost::intrusive_ptr<Cache<T> >& XNIL() {
0915
0916 static boost::intrusive_ptr<Cache<T> > xnil( xnil_helper_nil<T>() );
0917 return xnil;
0918 }
0919
0920 static const boost::intrusive_ptr<Cache<T> >& XBAD() {
0921
0922 static boost::intrusive_ptr<Cache<T> > xbad( xnil_helper_bad<T>() );
0923 return xbad;
0924 }
0925
0926 static fun0_odd_list_T the_blackhole;
0927 static fun0_odd_list_T& blackhole() {
0928 static fun0_odd_list_T the_blackhole;
0929
0930 return the_blackhole;
0931 }
0932
0933 odd_list<T>& cache() const {
0934 if( val.second.rep == XBAD() ) {
0935 val = fxn()();
0936 fxn = blackhole();
0937 }
0938 return val;
0939 }
0940
0941 template <class U> friend class list;
0942 template <class U> friend class odd_list;
0943 template <class TT, class F, class L, bool b> friend struct ConsHelp2;
0944 template <class U,class F> friend struct cvt;
0945 template <class U, class F, class R> friend struct ListHelp;
0946 template <class U> friend Cache<U>* xempty_helper();
0947
0948 Cache( CacheEmpty ) : refC(0), fxn(blackhole()), val() {}
0949 Cache( const odd_list<T>& x ) : refC(0), fxn(blackhole()), val(x) {}
0950 Cache( const T& x, const list<T>& l ) : refC(0),fxn(blackhole()),val(x,l)
0951 {}
0952
0953 Cache( const fun0_odd_list_T& f )
0954 : refC(0), fxn(f), val( OddListDummyY() ) {}
0955
0956
0957 template <class F>
0958 Cache( const F& f )
0959 : refC(0), fxn(make_fun0_odd_list<T>()(f)), val( OddListDummyY() ) {}
0960
0961
0962 struct CvtFxn {};
0963 template <class F>
0964 Cache( CvtFxn, const F& f )
0965 : refC(0), fxn(make_fun0_odd_list<T>()(cvt<T,F>(f))), val( OddListDummyY() ) {}
0966
0967 template <class X>
0968 friend void intrusive_ptr_add_ref( const Cache<X>* p );
0969 template <class X>
0970 friend void intrusive_ptr_release( const Cache<X>* p );
0971 };
0972
0973 template <class T>
0974 void intrusive_ptr_add_ref( const Cache<T>* p ) {
0975 ++ (p->refC);
0976 }
0977 template <class T>
0978 void intrusive_ptr_release( const Cache<T>* p ) {
0979 if( !--(p->refC) ) delete p;
0980 }
0981
0982
0983
0984
0985
0986 template <class T, class F> struct ListHelp<T,F,list<T> > {
0987 boost::intrusive_ptr<Cache<T> > operator()( const F& f ) const {
0988 return boost::intrusive_ptr<Cache<T> >
0989 (new Cache<T>(typename Cache<T>::CvtFxn(),f));
0990 }
0991 };
0992 template <class T, class F> struct ListHelp<T,F,odd_list<T> > {
0993 boost::intrusive_ptr<Cache<T> > operator()( const F& f ) const {
0994 return boost::intrusive_ptr<Cache<T> >(new Cache<T>(f));
0995 }
0996 };
0997
0998 template <class T>
0999 class list_iterator {
1000 list<T> l;
1001 bool is_nil;
1002 void advance() {
1003 l = l.tail();
1004 if( !l )
1005 is_nil = true;
1006 }
1007 class Proxy {
1008 const T x;
1009 friend class list_iterator;
1010 Proxy( const T& xx ) : x(xx) {}
1011 public:
1012 const T* operator->() const { return &x; }
1013 };
1014 public:
1015 typedef std::input_iterator_tag iterator_category;
1016 typedef T value_type;
1017 typedef ptrdiff_t difference_type;
1018 typedef T* pointer;
1019 typedef T& reference;
1020
1021 list_iterator() : l(), is_nil(true) {}
1022 explicit list_iterator( const list<T>& ll ) : l(ll), is_nil(!ll) {}
1023
1024 const T operator*() const { return l.head(); }
1025 const Proxy operator->() const { return Proxy(l.head()); }
1026 list_iterator<T>& operator++() {
1027 advance();
1028 return *this;
1029 }
1030 const list_iterator<T> operator++(int) {
1031 list_iterator<T> i( *this );
1032 advance();
1033 return i;
1034 }
1035 bool operator==( const list_iterator<T>& i ) const {
1036 return is_nil && i.is_nil;
1037 }
1038 bool operator!=( const list_iterator<T>& i ) const {
1039 return ! this->operator==(i);
1040 }
1041 };
1042
1043
1044 }
1045
1046 using impl::list;
1047 using impl::odd_list;
1048 using impl::list_iterator;
1049
1050
1051
1052
1053
1054
1055
1056
1057 template <class T>
1058 bool operator==( const odd_list<T>& a, a_unique_type_for_nil ) {
1059 return null(a)();
1060 }
1061 template <class T>
1062 bool operator==( const list<T>& a, a_unique_type_for_nil ) {
1063 return null(a)();
1064 }
1065 template <class T>
1066 bool operator==( a_unique_type_for_nil, const odd_list<T>& a ) {
1067 return null(a)();
1068 }
1069 template <class T>
1070 bool operator==( a_unique_type_for_nil, const list<T>& a ) {
1071 return null(a)();
1072 }
1073 template <class T>
1074 bool operator==( const list<T>& a, const list<T>& b ) {
1075 if( null(a)() && null(b)() )
1076 return true;
1077 if( null(a)() || null(b)() )
1078 return false;
1079 return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
1080 }
1081 template <class T>
1082 bool operator==( const odd_list<T>& a, const odd_list<T>& b ) {
1083 if( null(a)() && null(b)() )
1084 return true;
1085 if( null(a)() || null(b)() )
1086 return false;
1087 return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
1088 }
1089 template <class T>
1090 bool operator==( const list<T>& a, const odd_list<T>& b ) {
1091 if( null(a)() && null(b)() )
1092 return true;
1093 if( null(a)() || null(b)() )
1094 return false;
1095 return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
1096 }
1097 template <class T>
1098 bool operator==( const odd_list<T>& a, const list<T>& b ) {
1099 if( null(a)() && null(b)() )
1100 return true;
1101 if( null(a)() || null(b)() )
1102 return false;
1103 return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
1104 }
1105
1106 template <class T>
1107 bool operator<( const list<T>& a, const list<T>& b ) {
1108 if( null(a)() && !null(b)() ) return true;
1109 if( null(b)() ) return false;
1110 if( head(b)() < head(a)() ) return false;
1111 if( head(a)() < head(b)() ) return true;
1112 return (tail(a)() < tail(b)());
1113 }
1114 template <class T>
1115 bool operator<( const odd_list<T>& a, const list<T>& b ) {
1116 if( null(a)() && !null(b)() ) return true;
1117 if( null(b)() ) return false;
1118 if( head(b)() < head(a)() ) return false;
1119 if( head(a)() < head(b)() ) return true;
1120 return (tail(a)() < tail(b)());
1121 }
1122 template <class T>
1123 bool operator<( const list<T>& a, const odd_list<T>& b ) {
1124 if( null(a) && !null(b) ) return true;
1125 if( null(b) ) return false;
1126 if( head(b) < head(a) ) return false;
1127 if( head(a) < head(b) ) return true;
1128 return (tail(a) < tail(b));
1129 }
1130 template <class T>
1131 bool operator<( const odd_list<T>& a, const odd_list<T>& b ) {
1132 if( null(a)() && !null(b)() ) return true;
1133 if( null(b)() ) return false;
1134 if( head(b)() < head(a)() ) return false;
1135 if( head(a)() < head(b)() ) return true;
1136 return (tail(a)() < tail(b)());
1137 }
1138 template <class T>
1139 bool operator<( const odd_list<T>&, a_unique_type_for_nil ) {
1140 return false;
1141 }
1142 template <class T>
1143 bool operator<( const list<T>&, a_unique_type_for_nil ) {
1144 return false;
1145 }
1146 template <class T>
1147 bool operator<( a_unique_type_for_nil, const odd_list<T>& b ) {
1148 return !null(b)();
1149 }
1150 template <class T>
1151 bool operator<( a_unique_type_for_nil, const list<T>& b ) {
1152 return !null(b)();
1153 }
1154
1155
1156
1157
1158 namespace impl {
1159 using listlike::ListLike;
1160
1161 template <class T, class F, class L>
1162 struct ConsHelp2<T,F,L,true>
1163 {
1164 typedef typename boost::remove_reference<T>::type TT;
1165 typedef typename L::force_result_type type;
1166 static type go( const TT& x, const F& f ) {
1167 return type( x, f );
1168 }
1169 };
1170 template <class T, class F>
1171 struct ConsHelp2<T,F,list<T>,true>
1172 {
1173 typedef typename boost::remove_reference<T>::type TT;
1174 typedef list<TT> L;
1175 typedef typename L::force_result_type type;
1176 static type go( const TT& x, const F& f ) {
1177 return odd_list<TT>(x, list<TT>(
1178 boost::intrusive_ptr<Cache<TT> >(new Cache<T>(
1179 typename Cache<TT>::CvtFxn(),f))));
1180 }
1181 };
1182 template <class T, class F>
1183 struct ConsHelp2<T,F,odd_list<T>,true>
1184 {
1185 typedef typename boost::remove_reference<T>::type TT;
1186 typedef odd_list<TT> L;
1187 typedef typename L::force_result_type type;
1188 static type go( const TT& x, const F& f ) {
1189 return odd_list<TT>(x, list<TT>( ListRaw(), new Cache<T>(f) ));
1190 }
1191 };
1192 template <class T, class F>
1193 struct ConsHelp2<T,F,a_unique_type_for_nil,false>
1194 {
1195 typedef typename boost::remove_reference<T>::type TT;
1196 typedef odd_list<TT> type;
1197 static type go( const TT& x, const F& f ) {
1198 return odd_list<TT>(x, list<TT>( ListRaw(), new Cache<T>(f) ));
1199 }
1200 };
1201
1202 template <class T, class L, bool b> struct ConsHelp1 {
1203 typedef typename boost::remove_reference<T>::type TT;
1204 typedef typename L::force_result_type type;
1205 static type go( const TT& x, const L& l ) {
1206 return type(x,l);
1207 }
1208 };
1209 template <class T> struct ConsHelp1<T,a_unique_type_for_nil,false> {
1210 typedef typename boost::remove_reference<T>::type TT;
1211 typedef odd_list<TT> type;
1212 static type go( const TT& x, const a_unique_type_for_nil& n ) {
1213 return type(x,n);
1214 }
1215 };
1216 template <class T, class F> struct ConsHelp1<T,F,false> {
1217
1218
1219
1220
1221 typedef odd_list<T> L;
1222 typedef ConsHelp2<T,F,L,boost::is_base_and_derived<ListLike,L>::value> help;
1223 typedef typename help::type type;
1224 static type go( const T& x, const F& f ) {
1225 return help::go(x,f);
1226 }
1227 };
1228
1229 template <class T, class L, bool b>
1230 struct ConsHelp0;
1231
1232 template <class T>
1233 struct ConsHelp0<T,a_unique_type_for_nil,true> {
1234 typedef typename boost::remove_reference<T>::type TT;
1235 typedef odd_list<T> type;
1236 };
1237
1238 template <class T>
1239 struct ConsHelp0<const T &,const a_unique_type_for_nil &,true> {
1240 typedef typename boost::remove_reference<T>::type TT;
1241 typedef odd_list<TT> type;
1242 };
1243
1244 template <class T>
1245 struct ConsHelp0<T &,a_unique_type_for_nil &,true> {
1246 typedef typename boost::remove_reference<T>::type TT;
1247 typedef odd_list<TT> type;
1248 };
1249
1250 template <class T, class L>
1251 struct ConsHelp0<T,L,false> {
1252
1253
1254 typedef typename boost::remove_reference<L>::type LType;
1255 typedef typename ConsHelp1<T,LType,
1256 boost::is_base_and_derived<ListLike,LType>::value>::type type;
1257 };
1258
1259
1260
1261
1262
1263
1264
1265 struct Cons
1266 {
1267
1268
1269
1270
1271 template <typename Sig> struct result;
1272
1273 template <typename This, typename T, typename L>
1274 struct result<This(T, L)>
1275 {
1276 typedef typename ConsHelp0<T,L,
1277 listlike::detect_nil<L>::is_nil>::type type;
1278 };
1279
1280 template <typename This, typename T>
1281 struct result<This(T,a_unique_type_for_nil)>
1282 {
1283 typedef typename boost::remove_reference<T>::type TT;
1284 typedef odd_list<TT> type;
1285 };
1286
1287 template <typename T, typename L>
1288 typename result<Cons(T,L)>::type
1289 operator()( const T& x, const L& l ) const {
1290 typedef typename result_of::ListType<L>::LType LType;
1291 typedef ConsHelp1<T,LType,
1292 boost::is_base_and_derived<ListLike,LType>::value> help;
1293 return help::go(x,l);
1294 }
1295
1296 template <typename T>
1297 typename result<Cons(T,a_unique_type_for_nil)>::type
1298 operator()( const T& x, const a_unique_type_for_nil &n ) const {
1299 typedef typename result<Cons(T,a_unique_type_for_nil)>::type LL;
1300 typedef ConsHelp1<T,LL,
1301 boost::is_base_and_derived<ListLike,LL>::value> help;
1302 return help::go(x,n);
1303 }
1304
1305 };
1306 }
1307
1308 typedef boost::phoenix::function<impl::Cons> Cons;
1309 Cons cons;
1310
1311 namespace impl {
1312
1313 template <class L, class M, bool b>
1314 struct CatHelp0;
1315
1316 template <class LL>
1317 struct CatHelp0<LL,a_unique_type_for_nil,true> {
1318 typedef typename result_of::template ListType<LL>::LType type;
1319 };
1320
1321 template <class LL>
1322 struct CatHelp0<const LL &,const a_unique_type_for_nil &,true> {
1323 typedef typename result_of::template ListType<LL>::LType type;
1324
1325 };
1326
1327 template <class LL>
1328 struct CatHelp0<LL &,a_unique_type_for_nil &,true> {
1329 typedef typename result_of::template ListType<LL>::LType type;
1330
1331 };
1332
1333 template <class LL, class MM>
1334 struct CatHelp0<LL,MM,false> {
1335
1336
1337 typedef typename result_of::template ListType<LL>::LType type;
1338
1339
1340 };
1341
1342
1343
1344
1345
1346
1347
1348 struct Cat
1349 {
1350 template <class L, class M, bool b, class R>
1351 struct Helper {
1352 template <typename Sig> struct result;
1353
1354 template <typename This>
1355 struct result<This(L,M)>
1356 {
1357 typedef typename result_of::ListType<L>::tail_result_type type;
1358 };
1359
1360 typedef R return_type;
1361 R operator()( const L& l, const M& m,
1362 reuser2<INV,VAR,INV,Helper,
1363 typename result_of::template ListType<L>::tail_result_type,M>
1364 r = NIL ) const {
1365 if( null(l)() )
1366 return m().force();
1367 else
1368 return cons( head(l)(), r( Helper<L,M,b,R>(), tail(l), m )() );
1369 }
1370 };
1371 template <class L, class M, class R>
1372 struct Helper<L,M,true,R> {
1373 template <typename Sig> struct result;
1374
1375 template <typename This>
1376 struct result<This(L,M)>
1377 {
1378 typedef typename result_of::ListType<L>::tail_result_type type;
1379 };
1380 typedef R return_type;
1381 R operator()( const L& l, const M& m,
1382 reuser2<INV,VAR,INV,Helper,
1383 typename result_of::template ListType<L>::tail_result_type,M>
1384 r = NIL ) const {
1385 if( null(l)() )
1386 return m.force();
1387 else
1388 return cons( head(l)(), r(Helper<L,M,true,R>(), tail(l), m )());
1389 }
1390 };
1391 template <class L, class R>
1392 struct Helper<L,a_unique_type_for_nil,false,R>
1393
1394
1395 {
1396 typedef odd_list<typename result_of::template ListType<L>::value_type> type;
1397 odd_list<typename result_of::template ListType<L>::value_type>
1398 operator()( const L& l, const a_unique_type_for_nil& ) const {
1399 return l;
1400 }
1401 };
1402 public:
1403
1404
1405
1406
1407 template <typename Sig> struct result;
1408
1409 template <typename This, typename L, typename M>
1410 struct result<This(L,M)>
1411 {
1412 typedef typename CatHelp0<L,M,
1413 listlike::detect_nil<M>::is_nil>::type type;
1414
1415 };
1416
1417 template <typename This, typename L>
1418 struct result<This(L,a_unique_type_for_nil)>
1419 {
1420 typedef typename result_of::ListType<L>::tail_result_type type;
1421 };
1422 template <class L, class M>
1423 typename result<Cat(L,M)>::type operator()( const L& l, const M& m ) const
1424 {
1425 listlike::EnsureListLike<L>();
1426 return Helper<L,M,
1427 boost::is_base_and_derived<typename listlike::ListLike,M>::value,
1428 typename result<Cat(L,M)>::type>()(l,m);
1429 }
1430
1431 template <class L>
1432 typename result<Cat(L,a_unique_type_for_nil)>::type operator()( const L& l, const a_unique_type_for_nil& ) const
1433 {
1434 listlike::EnsureListLike<L>();
1435 return l;
1436 }
1437
1438 };
1439
1440
1441 }
1442
1443 typedef boost::phoenix::function<impl::Cat> Cat;
1444 Cat cat;
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454 struct UseList {
1455 template <class T> struct List { typedef list<T> type; };
1456 };
1457 struct UseOddList {
1458 template <class T> struct List { typedef odd_list<T> type; };
1459 };
1460 struct UseStrictList {
1461 template <class T> struct List { typedef strict_list<T> type; };
1462 };
1463
1464 template <class Kind = UseList>
1465 struct list_with {
1466 template <class T>
1467 typename Kind::template List<T>::type
1468 operator()( const T& a ) const {
1469 typename Kind::template List<T>::type l;
1470 l = cons( a, l );
1471 return l;
1472 }
1473
1474 template <class T>
1475 typename Kind::template List<T>::type
1476 operator()( const T& a, const T& b ) const {
1477 typename Kind::template List<T>::type l;
1478 l = cons( b, l );
1479 l = cons( a, l );
1480 return l;
1481 }
1482
1483 template <class T>
1484 typename Kind::template List<T>::type
1485 operator()( const T& a, const T& b, const T& c ) const {
1486 typename Kind::template List<T>::type l;
1487 l = cons( c, l );
1488 l = cons( b, l );
1489 l = cons( a, l );
1490 return l;
1491 }
1492
1493 template <class T>
1494 typename Kind::template List<T>::type
1495 operator()( const T& a, const T& b, const T& c, const T& d ) const {
1496 typename Kind::template List<T>::type l;
1497 l = cons( d, l );
1498 l = cons( c, l );
1499 l = cons( b, l );
1500 l = cons( a, l );
1501 return l;
1502 }
1503
1504 template <class T>
1505 typename Kind::template List<T>::type
1506 operator()( const T& a, const T& b, const T& c, const T& d,
1507 const T& e ) const {
1508 typename Kind::template List<T>::type l;
1509 l = cons( e, l );
1510 l = cons( d, l );
1511 l = cons( c, l );
1512 l = cons( b, l );
1513 l = cons( a, l );
1514 return l;
1515 }
1516 };
1517
1518
1519 }
1520
1521 }
1522
1523 #endif