Back to home page

EIC code displayed by LXR

 
 

    


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 // lazy_list.hpp
0003 //
0004 // Build lazy operations for Phoenix equivalents for FC++
0005 //
0006 // These are equivalents of the Boost FC++ functoids in list.hpp
0007 //
0008 // Implemented so far:
0009 //
0010 // head tail null
0011 //
0012 // strict_list<T> and associated iterator.
0013 //
0014 // list<T> and odd_list<T>
0015 //
0016 // cons cat
0017 //
0018 // Comparisons between list and odd_list types and separately for strict_list.
0019 //
0020 // NOTES: There is a fix at the moment as I have not yet sorted out
0021 //        how to get back the return type of a functor returning a list type.
0022 //        For the moment I have fixed this as odd_list<T> at two locations,
0023 //        one in list<T> and one in Cons. I am going to leave it like this
0024 //        for now as reading the code, odd_list<T> seems to be correct.
0025 //
0026 //        I am also not happy at the details needed to detect types in Cons.
0027 //
0028 // I think the structure of this file is now complete.
0029 // John Fletcher  February 2015.
0030 //
0031 ////////////////////////////////////////////////////////////////////////////
0032 /*=============================================================================
0033     Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
0034     Copyright (c) 2001-2007 Joel de Guzman
0035     Copyright (c) 2015 John Fletcher
0036 
0037     Distributed under the Boost Software License, Version 1.0. (See accompanying
0038     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0039 ==============================================================================*/
0040 
0041 ///////////////////////////////////////////////////////////////////////
0042 // This is from Boost FC++ list.hpp reimplemented without Fun0 or Full0
0043 ///////////////////////////////////////////////////////////////////////
0044 
0045 /*
0046 concept ListLike: Given a list representation type L
0047 
0048 L<T> inherits ListLike and has
0049    // typedefs just show typical values
0050    typedef T value_type
0051    typedef L<T> force_result_type
0052    typedef L<T> delay_result_type
0053    typedef L<T> tail_result_type
0054    template <class UU> struct cons_rebind {
0055       typedef L<UU> type;        // force type
0056       typedef L<UU> delay_type;  // delay type
0057    };
0058 
0059    L()
0060    L( a_unique_type_for_nil )
0061    template <class F> L(F)       // F :: ()->L
0062 
0063    constructor: force_result_type( T, L<T> )
0064    template <class F>
0065    constructor: force_result_type( T, F )  // F :: ()->L
0066 
0067    template <class It>
0068    L( It, It )
0069 
0070    // FIX THIS instead of operator bool(), does Boost have something better?
0071    operator bool() const
0072    force_result_type force() const
0073    delay_result_type delay() const
0074    T head() const
0075    tail_result_type tail() const
0076 
0077    static const bool is_lazy;   // true if can represent infinite lists
0078 
0079    typedef const_iterator;
0080    typedef const_iterator iterator;  // ListLikes are immutable
0081    iterator begin() const
0082    iterator end() const
0083 */
0084 
0085 //////////////////////////////////////////////////////////////////////
0086 // End of section from Boost FC++ list.hpp
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 //#include "lazy_reuse.hpp"
0098 
0099 namespace boost {
0100 
0101   namespace phoenix {
0102 
0103 //////////////////////////////////////////////////////////////////////
0104 // These are the list types being declared.
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    // in ref_count.hpp in BoostFC++ now in lazy_operator.hpp
0113    //typedef unsigned int RefCountType;
0114 
0115 //////////////////////////////////////////////////////////////////////
0116 // a_unique_type_for_nil moved to lazy_operator.hpp.
0117 //////////////////////////////////////////////////////////////////////
0118 
0119 
0120 //////////////////////////////////////////////////////////////////////
0121 // Distinguish lazy lists (list and odd_list) from strict_list.
0122 //////////////////////////////////////////////////////////////////////
0123 
0124     namespace lazy {
0125       // Copied from Boost FC++ list.hpp
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 // Provide remove reference for types defined for list types.
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         //typedef a_unique_type_for_nil value_type;
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 // ListLike is a property inherited by any list type to enable it to
0172 // work with the functions being implemented in this file.
0173 // It provides the check for the structure described above.
0174 //////////////////////////////////////////////////////////////////////
0175 
0176    namespace listlike {
0177 
0178        struct ListLike {};   // This lets us use is_base_and_derived() to see
0179        // (at compile-time) what classes are user-defined lists.
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& /*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& /* n */) {
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 // Implement lazy functions for list types. cat and cons come later.
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         //bool
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     //BOOST_PHOENIX_ADAPT_CALLABLE(head, impl::head, 1)
0353     //BOOST_PHOENIX_ADAPT_CALLABLE(tail, impl::tail, 1)
0354     //BOOST_PHOENIX_ADAPT_CALLABLE(null, impl::null, 1)
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 // These definitions used for strict_list are imported from BoostFC++
0368 // unchanged.
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 {  // needed for operator->
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      // I cannot do this yet.
0480      //functoid_traits<F>::template ensure_accepts<0>::args();
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       // How ironic.  We need to reverse the iterator range in order to
0511       // non-recursively build this!
0512       std::vector<T> tmp(a,b);
0513       rep = help( tmp.rbegin(), tmp.rend() );
0514    }
0515 
0516    // Since the strict_cons destructor can't call the strict_list
0517    // destructor, the "simple" iterative destructor is correct and
0518    // efficient.  Hurray.
0519    ~strict_list() { while(rep && (rep->refC == 1)) rep = rep->tail; }
0520 
0521    // The following helps makes strict_list almost an STL "container"
0522    typedef impl::strict_list_iterator<T> const_iterator;
0523    typedef const_iterator iterator;         // strict_list is immutable
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     // All of these null head and tail are now non lazy using e.g. null(a)().
0530     // They need an extra () e.g. null(a)().
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 // Class list<T> is the primary interface to the user for lazy lists.
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 /*: public c_fun_type<It,It,odd_list<T> >*/ {
0581         // This will need a return type.
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         // never NIL, unless an empty odd_list
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>  // works on both ()->odd_list and ()->list
0642         // At the moment this is fixed for odd_list<T>.
0643         // I need to do more work to get the general result.
0644         list( const F& f )
0645           : rep( ListHelp<T,F,odd_list<T> >()(f) ) { }
0646         //: rep( ListHelp<T,F,typename F::result_type>()(f) ) { }
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         // Note: force returns a reference;
0652         // implicit conversion now returns a copy.
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         // The following helps makes list almost an STL "container"
0659         typedef list_iterator<T> const_iterator;
0660         typedef const_iterator iterator;         // list is immutable
0661         iterator begin() const { return list_iterator<T>( *this ); }
0662         iterator end() const   { return list_iterator<T>(); }
0663 
0664         // end of list<T>
0665       };
0666 
0667 //////////////////////////////////////////////////////////////////////
0668 // Class odd_list<T> is not normally accessed by the user.
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;   // If XNIL, then this odd_list is NIL
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         // The following helps makes odd_list almost an STL "container"
0783         typedef list_iterator<T> const_iterator;
0784         typedef const_iterator iterator;         // odd_list is immutable
0785         iterator begin() const { return list_iterator<T>( this->delay() ); }
0786         iterator end() const   { return list_iterator<T>(); }
0787 
0788         // end of odd_list<T>
0789       };
0790 
0791 //////////////////////////////////////////////////////////////////////
0792 // struct cvt
0793 //////////////////////////////////////////////////////////////////////
0794 
0795       // This converts ()->list<T> to ()->odd_list<T>.
0796       // In other words, here is the 'extra work' done when using the
0797       // unoptimized interface.
0798       template <class U,class F>
0799       struct cvt /*: public c_fun_type<odd_list<U> >*/ {
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 // Cache<T> and associated functions.
0812 //////////////////////////////////////////////////////////////////////
0813 
0814 // I malloc a RefCountType to hold the refCount and init it to 1 to ensure the
0815 // refCount will never get to 0, so the destructor-of-global-object
0816 // order at the end of the program is a non-issue.  In other words, the
0817 // memory allocated here is only reclaimed by the operating system.
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     // This makes a boost phoenix function type with return type
0844     // odd_list<T>
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         // Overload for the case where it is a boost phoenix function already.
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        // This is the boost::function type
0881        typedef typename fun0_type_helper<T>::fun_type fun_odd_list_T;
0882        // This is the boost::phoenix::function type;
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        // val.second.rep can be XBAD, XNIL, or a valid ptr
0887        //  - XBAD: val is invalid (fxn is valid)
0888        //  - XNIL: this is the empty list
0889        //  - anything else: val.first() is head, val.second is tail()
0890 
0891        // This functoid should never be called; it represents a
0892        // self-referent Cache, which should be impossible under the current
0893        // implementation.  Nonetheless, we need a 'dummy' function object to
0894        // represent invalid 'fxn's (val.second.rep!=XBAD), and this
0895        // implementation seems to be among the most reasonable.
0896        struct blackhole_helper /*: c_fun_type< odd_list<T> >*/ {
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        // Don't get rid of these XFOO() functions; they impose no overhead,
0908        // and provide a useful place to add debugging code for tracking down
0909        // before-main()-order-of-initialization problems.
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        // this list is nil
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        // the pair is invalid; use fxn
0922           static boost::intrusive_ptr<Cache<T> > xbad( xnil_helper_bad<T>() );
0923           return xbad;
0924        }
0925 
0926        static fun0_odd_list_T /*<odd_list<T> >*/ the_blackhole;
0927        static fun0_odd_list_T& blackhole() {
0928          static fun0_odd_list_T the_blackhole;
0929          //( make_fun0_odd_list<T>()( blackhole_helper() ) );
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        // f must be a boost phoenix function object?
0957        template <class F>
0958        Cache( const F& f )    // ()->odd_list
0959          : refC(0), fxn(make_fun0_odd_list<T>()(f)), val( OddListDummyY() ) {}
0960 
0961        // This is for ()->list<T> to ()->odd_list<T>
0962        struct CvtFxn {};
0963        template <class F>
0964        Cache( CvtFxn, const F& f )    // ()->list
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 // Rest of list's stuff
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 {  // needed for operator->
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     } // namespace impl
1045 
1046   using impl::list;
1047   using impl::odd_list;
1048   using impl::list_iterator;
1049 
1050 //////////////////////////////////////////////////////////////////////
1051 // op== and op<, overloaded for all combos of list, odd_list, and NIL
1052 //////////////////////////////////////////////////////////////////////
1053 // All of these null head and tail are now non lazy using e.g. null(a)().
1054 // They need an extra () e.g. null(a)().
1055 
1056 // FIX THIS comparison operators can be implemented simpler with enable_if
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 // Implement cat and cons after the list types are defined.
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         // It's a function returning a list
1218         // This is the one I have not fixed yet....
1219         // typedef typename F::result_type L;
1220         // typedef typename result_of::template ListType<F>::result_type L;
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           // This removes any references from L for correct return type
1253           // identification.
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       // cons (t,l) - cons a value to the front of a list.
1261       // Note: The first arg,  t, must be a value.
1262       //       The second arg, l, can be a list or NIL
1263       //       or a function that returns a list.
1264       /////////////////////////////////////////////////////////////////////
1265       struct Cons
1266       {
1267         /* template <class T, class L> struct sig : public fun_type<
1268         typename ConsHelp1<T,L,
1269       boost::is_base_and_derived<ListLike,L>::value>::type> {};
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         //typedef L type;
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         //typedef L type;
1331       };
1332 
1333       template <class LL, class MM>
1334       struct CatHelp0<LL,MM,false> {
1335           // This removes any references from L for correct return type
1336           // identification.
1337         typedef typename result_of::template ListType<LL>::LType type;
1338         //    typedef typename ConsHelp1<T,LType,
1339         //   boost::is_base_and_derived<ListLike,LType>::value>::type type;
1340       };
1341 
1342       /////////////////////////////////////////////////////////////////////
1343       // cat (l,m) - concatenate lists.
1344       // Note: The first arg,  l, must be a list or NIL.
1345       //       The second arg, m, can be a list or NIL
1346       //       or a function that returns a list.
1347       /////////////////////////////////////////////////////////////////////
1348       struct Cat
1349       {
1350          template <class L, class M, bool b, class R>
1351          struct Helper /*: public c_fun_type<L,M,R>*/ {
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> /*: public c_fun_type<L,M,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       /*: public c_fun_type<L,
1394         a_unique_type_for_nil,odd_list<typename L::value_type> > */
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         /*template <class L, class M> struct sig : public fun_type<
1404         typename RT<cons_type,typename L::value_type,M>::result_type>
1405       {}; */
1406    // Need to work out the return type here.
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         // typedef typename result_of::ListType<L>::tail_result_type type;
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& /* n */ ) 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 // Handy functions for making list literals
1449 //////////////////////////////////////////////////////////////////////
1450 // Yes, these aren't functoids, they're just template functions.  I'm
1451 // lazy and created these mostly to make it easily to make little lists
1452 // in the sample code snippets that appear in papers.
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