summaryrefslogtreecommitdiff
path: root/boost/phoenix/function/lazy_list.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/phoenix/function/lazy_list.hpp')
-rw-r--r--boost/phoenix/function/lazy_list.hpp1514
1 files changed, 1514 insertions, 0 deletions
diff --git a/boost/phoenix/function/lazy_list.hpp b/boost/phoenix/function/lazy_list.hpp
new file mode 100644
index 0000000000..996d34f822
--- /dev/null
+++ b/boost/phoenix/function/lazy_list.hpp
@@ -0,0 +1,1514 @@
+////////////////////////////////////////////////////////////////////////////
+// lazy_list.hpp
+//
+// Build lazy operations for Phoenix equivalents for FC++
+//
+// These are equivalents of the Boost FC++ functoids in list.hpp
+//
+// Implemented so far:
+//
+// head tail null
+//
+// strict_list<T> and associated iterator.
+//
+// list<T> and odd_list<T>
+//
+// cons cat
+//
+// Comparisons between list and odd_list types and separately for strict_list.
+//
+// NOTES: There is a fix at the moment as I have not yet sorted out
+// how to get back the return type of a functor returning a list type.
+// For the moment I have fixed this as odd_list<T> at two locations,
+// one in list<T> and one in Cons. I am going to leave it like this
+// for now as reading the code, odd_list<T> seems to be correct.
+//
+// I am also not happy at the details needed to detect types in Cons.
+//
+// I think the structure of this file is now complete.
+// John Fletcher February 2015.
+//
+////////////////////////////////////////////////////////////////////////////
+/*=============================================================================
+ Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
+ Copyright (c) 2001-2007 Joel de Guzman
+ Copyright (c) 2015 John Fletcher
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+///////////////////////////////////////////////////////////////////////
+// This is from Boost FC++ list.hpp reimplemented without Fun0 or Full0
+///////////////////////////////////////////////////////////////////////
+
+/*
+concept ListLike: Given a list representation type L
+
+L<T> inherits ListLike and has
+ // typedefs just show typical values
+ typedef T value_type
+ typedef L<T> force_result_type
+ typedef L<T> delay_result_type
+ typedef L<T> tail_result_type
+ template <class UU> struct cons_rebind {
+ typedef L<UU> type; // force type
+ typedef L<UU> delay_type; // delay type
+ };
+
+ L()
+ L( a_unique_type_for_nil )
+ template <class F> L(F) // F :: ()->L
+
+ constructor: force_result_type( T, L<T> )
+ template <class F>
+ constructor: force_result_type( T, F ) // F :: ()->L
+
+ template <class It>
+ L( It, It )
+
+ // FIX THIS instead of operator bool(), does Boost have something better?
+ operator bool() const
+ force_result_type force() const
+ delay_result_type delay() const
+ T head() const
+ tail_result_type tail() const
+
+ static const bool is_lazy; // true if can represent infinite lists
+
+ typedef const_iterator;
+ typedef const_iterator iterator; // ListLikes are immutable
+ iterator begin() const
+ iterator end() const
+*/
+
+//////////////////////////////////////////////////////////////////////
+// End of section from Boost FC++ list.hpp
+//////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_PHOENIX_FUNCTION_LAZY_LIST
+#define BOOST_PHOENIX_FUNCTION_LAZY_LIST
+
+#include <boost/phoenix/core.hpp>
+#include <boost/phoenix/function.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
+//#include "lazy_reuse.hpp"
+
+namespace boost {
+
+ namespace phoenix {
+
+//////////////////////////////////////////////////////////////////////
+// These are the list types being declared.
+//////////////////////////////////////////////////////////////////////
+
+ template <class T> class strict_list;
+ namespace impl {
+ template <class T> class list;
+ template <class T> class odd_list;
+ }
+ // in ref_count.hpp in BoostFC++ now in lazy_operator.hpp
+ //typedef unsigned int RefCountType;
+
+//////////////////////////////////////////////////////////////////////
+// a_unique_type_for_nil moved to lazy_operator.hpp.
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////
+// Distinguish lazy lists (list and odd_list) from strict_list.
+//////////////////////////////////////////////////////////////////////
+
+ namespace lazy {
+ // Copied from Boost FC++ list.hpp
+ template <class L, bool is_lazy> struct ensure_lazy_helper {};
+ template <class L> struct ensure_lazy_helper<L,true> {
+ static void requires_lazy_list_to_prevent_infinite_recursion() {}
+ };
+ template <class L>
+ void ensure_lazy() {
+ ensure_lazy_helper<L,L::is_lazy>::
+ requires_lazy_list_to_prevent_infinite_recursion();
+ }
+
+ }
+
+//////////////////////////////////////////////////////////////////////
+// Provide remove reference for types defined for list types.
+//////////////////////////////////////////////////////////////////////
+
+ namespace result_of {
+
+ template < typename L >
+ class ListType
+ {
+ public:
+ typedef typename boost::remove_reference<L>::type LType;
+ typedef typename LType::value_type value_type;
+ typedef typename LType::tail_result_type tail_result_type;
+ typedef typename LType::force_result_type force_result_type;
+ typedef typename LType::delay_result_type delay_result_type;
+ };
+
+ template <>
+ class ListType<a_unique_type_for_nil>
+ {
+ public:
+ typedef a_unique_type_for_nil LType;
+ //typedef a_unique_type_for_nil value_type;
+ };
+
+ template <typename F, typename T>
+ struct ResultType {
+ typedef typename impl::odd_list<T> type;
+ };
+
+ }
+
+//////////////////////////////////////////////////////////////////////
+// ListLike is a property inherited by any list type to enable it to
+// work with the functions being implemented in this file.
+// It provides the check for the structure described above.
+//////////////////////////////////////////////////////////////////////
+
+ namespace listlike {
+
+ struct ListLike {}; // This lets us use is_base_and_derived() to see
+ // (at compile-time) what classes are user-defined lists.
+
+
+ template <class L, bool is_lazy> struct ensure_lazy_helper {};
+ template <class L> struct ensure_lazy_helper<L,true> {
+ static void requires_lazy_list_to_prevent_infinite_recursion() {}
+ };
+ template <class L>
+ void ensure_lazy() {
+ ensure_lazy_helper<L,L::is_lazy>::
+ requires_lazy_list_to_prevent_infinite_recursion();
+ }
+
+ template <class L, bool b>
+ struct EnsureListLikeHelp {
+ static void trying_to_call_a_list_function_on_a_non_list() {}
+ };
+ template <class L> struct EnsureListLikeHelp<L,false> { };
+ template <class L>
+ void EnsureListLike() {
+ typedef typename result_of::ListType<L>::LType LType;
+ EnsureListLikeHelp<L,boost::is_base_and_derived<ListLike,LType>::value>::
+ trying_to_call_a_list_function_on_a_non_list();
+ }
+
+ template <class L>
+ bool is_a_unique_type_for_nil(const L& l) {
+ return false;
+ }
+
+ template <>
+ bool is_a_unique_type_for_nil<a_unique_type_for_nil>
+ (const a_unique_type_for_nil& /* n */) {
+ return true;
+ }
+
+ template <class L>
+ struct detect_nil {
+ static const bool is_nil = false;
+ };
+
+ template <>
+ struct detect_nil<a_unique_type_for_nil> {
+ static const bool is_nil = true;
+ };
+
+ template <>
+ struct detect_nil<a_unique_type_for_nil&> {
+ static const bool is_nil = true;
+ };
+
+ template <>
+ struct detect_nil<const a_unique_type_for_nil&> {
+ static const bool is_nil = true;
+ };
+
+ }
+
+//////////////////////////////////////////////////////////////////////
+// Implement lazy functions for list types. cat and cons come later.
+//////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH
+#define BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH 1000
+#endif
+
+ namespace impl {
+
+ struct Head
+ {
+ template <typename Sig>
+ struct result;
+
+ template <typename This, typename L>
+ struct result<This(L)>
+ {
+ typedef typename result_of::ListType<L>::value_type type;
+ };
+
+ template <typename L>
+ typename result<Head(L)>::type
+ operator()(const L & l) const
+ {
+ listlike::EnsureListLike<L>();
+ return l.head();
+ }
+
+ };
+
+ struct Tail
+ {
+ template <typename Sig>
+ struct result;
+
+ template <typename This, typename L>
+ struct result<This(L)>
+ {
+ typedef typename result_of::ListType<L>::tail_result_type type;
+ };
+
+ template <typename L>
+ typename result<Tail(L)>::type
+ operator()(const L & l) const
+ {
+ listlike::EnsureListLike<L>();
+ return l.tail();
+ }
+
+ };
+
+ struct Null
+ {
+ template <typename Sig>
+ struct result;
+
+ template <typename This, typename L>
+ struct result<This(L)>
+ {
+ typedef bool type;
+ };
+
+ template <typename L>
+ typename result<Null(L)>::type
+ //bool
+ operator()(const L& l) const
+ {
+ listlike::EnsureListLike<L>();
+ return !l;
+ }
+
+ };
+
+ struct Delay {
+ template <typename Sig>
+ struct result;
+
+ template <typename This, typename L>
+ struct result<This(L)>
+ {
+ typedef typename result_of::ListType<L>::delay_result_type type;
+ };
+
+ template <typename L>
+ typename result<Delay(L)>::type
+ operator()(const L & l) const
+ {
+ listlike::EnsureListLike<L>();
+ return l.delay();
+ }
+
+ };
+
+ struct Force {
+ template <typename Sig>
+ struct result;
+
+ template <typename This, typename L>
+ struct result<This(L)>
+ {
+ typedef typename result_of::ListType<L>::force_result_type type;
+ };
+
+ template <typename L>
+ typename result<Force(L)>::type
+ operator()(const L & l) const
+ {
+ listlike::EnsureListLike<L>();
+ return l.force();
+ }
+
+ };
+
+ }
+ //BOOST_PHOENIX_ADAPT_CALLABLE(head, impl::head, 1)
+ //BOOST_PHOENIX_ADAPT_CALLABLE(tail, impl::tail, 1)
+ //BOOST_PHOENIX_ADAPT_CALLABLE(null, impl::null, 1)
+ typedef boost::phoenix::function<impl::Head> Head;
+ typedef boost::phoenix::function<impl::Tail> Tail;
+ typedef boost::phoenix::function<impl::Null> Null;
+ typedef boost::phoenix::function<impl::Delay> Delay;
+ typedef boost::phoenix::function<impl::Force> Force;
+ Head head;
+ Tail tail;
+ Null null;
+ Delay delay;
+ Force force;
+
+//////////////////////////////////////////////////////////////////////
+// These definitions used for strict_list are imported from BoostFC++
+// unchanged.
+//////////////////////////////////////////////////////////////////////
+
+namespace impl {
+template <class T>
+struct strict_cons : public boost::noncopyable {
+ mutable RefCountType refC;
+ T head;
+ typedef boost::intrusive_ptr<strict_cons> tail_type;
+ tail_type tail;
+ strict_cons( const T& h, const tail_type& t ) : refC(0), head(h), tail(t) {}
+
+};
+template <class T>
+void intrusive_ptr_add_ref( const strict_cons<T>* p ) {
+ ++ (p->refC);
+}
+template <class T>
+void intrusive_ptr_release( const strict_cons<T>* p ) {
+ if( !--(p->refC) ) delete p;
+}
+
+template <class T>
+class strict_list_iterator
+: public std::iterator<std::input_iterator_tag,T,ptrdiff_t> {
+ typedef boost::intrusive_ptr<strict_cons<T> > rep_type;
+ rep_type l;
+ bool is_nil;
+ void advance() {
+ l = l->tail;
+ if( !l )
+ is_nil = true;
+ }
+ class Proxy { // needed for operator->
+ const T x;
+ friend class strict_list_iterator;
+ Proxy( const T& xx ) : x(xx) {}
+ public:
+ const T* operator->() const { return &x; }
+ };
+public:
+ strict_list_iterator() : l(), is_nil(true) {}
+ explicit strict_list_iterator( const rep_type& ll ) : l(ll), is_nil(!ll) {}
+
+ const T operator*() const { return l->head; }
+ const Proxy operator->() const { return Proxy(l->head); }
+ strict_list_iterator<T>& operator++() {
+ advance();
+ return *this;
+ }
+ const strict_list_iterator<T> operator++(int) {
+ strict_list_iterator<T> i( *this );
+ advance();
+ return i;
+ }
+ bool operator==( const strict_list_iterator<T>& i ) const {
+ return is_nil && i.is_nil;
+ }
+ bool operator!=( const strict_list_iterator<T>& i ) const {
+ return ! this->operator==(i);
+ }
+};
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+ template <class T>
+ class strict_list : public listlike::ListLike
+ {
+ typedef boost::intrusive_ptr<impl::strict_cons<T> > rep_type;
+ rep_type rep;
+ struct Make {};
+
+ template <class Iter>
+ static rep_type help( Iter a, const Iter& b ) {
+ rep_type r;
+ while( a != b ) {
+ T x( *a );
+ r = rep_type( new impl::strict_cons<T>( x, r ) );
+ ++a;
+ }
+ return r;
+ }
+
+ public:
+ static const bool is_lazy = false;
+
+ typedef T value_type;
+ typedef strict_list force_result_type;
+ typedef strict_list delay_result_type;
+ typedef strict_list tail_result_type;
+ template <class UU> struct cons_rebind {
+ typedef strict_list<UU> type;
+ typedef strict_list<UU> delay_type;
+ };
+
+
+ strict_list( Make, const rep_type& r ) : rep(r) {}
+
+ strict_list() : rep() {}
+
+ strict_list( a_unique_type_for_nil ) : rep() {}
+
+ template <class F>
+ strict_list( const F& f ) : rep( f().rep ) {
+ // I cannot do this yet.
+ //functoid_traits<F>::template ensure_accepts<0>::args();
+ }
+
+ strict_list( const T& x, const strict_list& y )
+ : rep( new impl::strict_cons<T>(x,y.rep) ) {}
+
+ template <class F>
+ strict_list( const T& x, const F& f )
+ : rep( new impl::strict_cons<T>(x,f().rep) ) {}
+
+ operator bool() const { return (bool)rep; }
+ force_result_type force() const { return *this; }
+ delay_result_type delay() const { return *this; }
+ T head() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( !*this )
+ throw lazy_exception("Tried to take head() of empty strict_list");
+#endif
+ return rep->head;
+ }
+ tail_result_type tail() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( !*this )
+ throw lazy_exception("Tried to take tail() of empty strict_list");
+#endif
+ return strict_list(Make(),rep->tail);
+ }
+
+ template <class Iter>
+ strict_list( const Iter& a, const Iter& b ) : rep( rep_type() ) {
+ // How ironic. We need to reverse the iterator range in order to
+ // non-recursively build this!
+ std::vector<T> tmp(a,b);
+ rep = help( tmp.rbegin(), tmp.rend() );
+ }
+
+ // Since the strict_cons destructor can't call the strict_list
+ // destructor, the "simple" iterative destructor is correct and
+ // efficient. Hurray.
+ ~strict_list() { while(rep && (rep->refC == 1)) rep = rep->tail; }
+
+ // The following helps makes strict_list almost an STL "container"
+ typedef impl::strict_list_iterator<T> const_iterator;
+ typedef const_iterator iterator; // strict_list is immutable
+ iterator begin() const { return impl::strict_list_iterator<T>( rep ); }
+ iterator end() const { return impl::strict_list_iterator<T>(); }
+
+ };
+
+ // All of these null head and tail are now non lazy using e.g. null(a)().
+ // They need an extra () e.g. null(a)().
+ template <class T>
+ bool operator==( const strict_list<T>& a, a_unique_type_for_nil ) {
+ return null(a)();
+ }
+ template <class T>
+ bool operator==( a_unique_type_for_nil, const strict_list<T>& a ) {
+ return null(a)();
+ }
+ template <class T>
+ bool operator==( const strict_list<T>& a, const strict_list<T>& b ) {
+ if( null(a)() && null(b)() )
+ return true;
+ if( null(a)() || null(b)() )
+ return false;
+ return (head(a)()==head(b)()) &&
+ (tail(a)()==tail(b)());
+ }
+
+ template <class T>
+ bool operator<( const strict_list<T>& a, const strict_list<T>& b ) {
+ if( null(a)() && !null(b)() ) return true;
+ if( null(b)() ) return false;
+ if( head(b)() < head(a)() ) return false;
+ if( head(a)() < head(b)() ) return true;
+ return (tail(a)() < tail(b)());
+ }
+ template <class T>
+ bool operator<( const strict_list<T>&, a_unique_type_for_nil ) {
+ return false;
+ }
+ template <class T>
+ bool operator<( a_unique_type_for_nil, const strict_list<T>& b ) {
+ return !(null(b)());
+ }
+
+//////////////////////////////////////////////////////////////////////
+// Class list<T> is the primary interface to the user for lazy lists.
+//////////////////////////////////////////////////////////////////////{
+ namespace impl {
+ using fcpp::INV;
+ using fcpp::VAR;
+ using fcpp::reuser2;
+
+ struct CacheEmpty {};
+
+ template <class T> class Cache;
+ template <class T> class odd_list;
+ template <class T> class list_iterator;
+ template <class It, class T>
+ struct ListItHelp2 /*: public c_fun_type<It,It,odd_list<T> >*/ {
+ // This will need a return type.
+ typedef odd_list<T> return_type;
+ odd_list<T> operator()( It begin, const It& end,
+ reuser2<INV,VAR,INV,ListItHelp2<It,T>,It,It> r = NIL ) const;
+ };
+ template <class U,class F> struct cvt;
+ template <class T, class F, class R> struct ListHelp;
+ template <class T> Cache<T>* xempty_helper();
+ template <class T, class F, class L, bool b> struct ConsHelp2;
+
+ struct ListRaw {};
+
+ template <class T>
+ class list : public listlike::ListLike
+ {
+ // never NIL, unless an empty odd_list
+ boost::intrusive_ptr<Cache<T> > rep;
+
+ template <class U> friend class Cache;
+ template <class U> friend class odd_list;
+ template <class TT, class F, class L, bool b> friend struct ConsHelp2;
+ template <class U,class F> friend struct cvt;
+
+ list( const boost::intrusive_ptr<Cache<T> >& p ) : rep(p) { }
+ list( ListRaw, Cache<T>* p ) : rep(p) { }
+
+ bool priv_isEmpty() const {
+ return rep->cache().second.rep == Cache<T>::XNIL();
+ }
+ T priv_head() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( priv_isEmpty() )
+ throw lazy_exception("Tried to take head() of empty list");
+#endif
+ return rep->cache().first();
+ }
+ list<T> priv_tail() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( priv_isEmpty() )
+ throw lazy_exception("Tried to take tail() of empty list");
+#endif
+ return rep->cache().second;
+ }
+
+
+ public:
+ static const bool is_lazy = true;
+
+ typedef T value_type;
+ typedef list tail_result_type;
+ typedef odd_list<T> force_result_type;
+ typedef list delay_result_type;
+ template <class UU> struct cons_rebind {
+ typedef odd_list<UU> type;
+ typedef list<UU> delay_type;
+ };
+
+ list( a_unique_type_for_nil ) : rep( Cache<T>::XEMPTY() ) { }
+ list() : rep( Cache<T>::XEMPTY() ) { }
+
+ template <class F> // works on both ()->odd_list and ()->list
+ // At the moment this is fixed for odd_list<T>.
+ // I need to do more work to get the general result.
+ list( const F& f )
+ : rep( ListHelp<T,F,odd_list<T> >()(f) ) { }
+ //: rep( ListHelp<T,F,typename F::result_type>()(f) ) { }
+
+ operator bool() const { return !priv_isEmpty(); }
+ const force_result_type& force() const { return rep->cache(); }
+ const delay_result_type& delay() const { return *this; }
+ // Note: force returns a reference;
+ // implicit conversion now returns a copy.
+ operator odd_list<T>() const { return force(); }
+
+ T head() const { return priv_head(); }
+ tail_result_type tail() const { return priv_tail(); }
+
+ // The following helps makes list almost an STL "container"
+ typedef list_iterator<T> const_iterator;
+ typedef const_iterator iterator; // list is immutable
+ iterator begin() const { return list_iterator<T>( *this ); }
+ iterator end() const { return list_iterator<T>(); }
+
+ // end of list<T>
+ };
+
+//////////////////////////////////////////////////////////////////////
+// Class odd_list<T> is not normally accessed by the user.
+//////////////////////////////////////////////////////////////////////
+
+ struct OddListDummyY {};
+
+ template <class T>
+ class odd_list : public listlike::ListLike
+ {
+ public:
+ typedef
+ typename boost::type_with_alignment<boost::alignment_of<T>::value>::type
+ xfst_type;
+ private:
+ union { xfst_type fst; unsigned char dummy[sizeof(T)]; };
+
+ const T& first() const {
+ return *static_cast<const T*>(static_cast<const void*>(&fst));
+ }
+ T& first() {
+ return *static_cast<T*>(static_cast<void*>(&fst));
+ }
+ list<T> second; // If XNIL, then this odd_list is NIL
+
+ template <class U> friend class list;
+ template <class U> friend class Cache;
+
+ odd_list( OddListDummyY )
+ : second( Cache<T>::XBAD() ) { }
+
+ void init( const T& x ) {
+ new (static_cast<void*>(&fst)) T(x);
+ }
+
+ bool fst_is_valid() const {
+ if( second.rep != Cache<T>::XNIL() )
+ if( second.rep != Cache<T>::XBAD() )
+ return true;
+ return false;
+ }
+
+ bool priv_isEmpty() const { return second.rep == Cache<T>::XNIL(); }
+ T priv_head() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( priv_isEmpty() )
+ throw lazy_exception("Tried to take head() of empty odd_list");
+#endif
+ return first();
+ }
+
+ list<T> priv_tail() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ if( priv_isEmpty() )
+ throw lazy_exception("Tried to take tail() of empty odd_list");
+#endif
+ return second;
+ }
+
+ public:
+ static const bool is_lazy = true;
+
+ typedef T value_type;
+ typedef list<T> tail_result_type;
+ typedef odd_list<T> force_result_type;
+ typedef list<T> delay_result_type;
+ template <class UU> struct cons_rebind {
+ typedef odd_list<UU> type;
+ typedef list<UU> delay_type;
+ };
+
+ odd_list() : second( Cache<T>::XNIL() ) { }
+ odd_list( a_unique_type_for_nil ) : second( Cache<T>::XNIL() ) { }
+ odd_list( const T& x, const list<T>& y ) : second(y) { init(x); }
+ odd_list( const T& x, a_unique_type_for_nil ) : second(NIL) { init(x); }
+
+ odd_list( const odd_list<T>& x ) : second(x.second) {
+ if( fst_is_valid() ) {
+ init( x.first() );
+ }
+ }
+
+ template <class It>
+ odd_list( It begin, const It& end )
+ : second( begin==end ? Cache<T>::XNIL() :
+ ( init(*begin++), list<T>( begin, end ) ) ) {}
+
+ odd_list<T>& operator=( const odd_list<T>& x ) {
+ if( this == &x ) return *this;
+ if( fst_is_valid() ) {
+ if( x.fst_is_valid() )
+ first() = x.first();
+ else
+ first().~T();
+ }
+ else {
+ if( x.fst_is_valid() )
+ init( x.first() );
+ }
+ second = x.second;
+ return *this;
+ }
+
+ ~odd_list() {
+ if( fst_is_valid() ) {
+ first().~T();
+ }
+ }
+
+ operator bool() const { return !priv_isEmpty(); }
+ const force_result_type& force() const { return *this; }
+ delay_result_type delay() const { return list<T>(*this); }
+
+ T head() const { return priv_head(); }
+ tail_result_type tail() const { return priv_tail(); }
+
+ // The following helps makes odd_list almost an STL "container"
+ typedef list_iterator<T> const_iterator;
+ typedef const_iterator iterator; // odd_list is immutable
+ iterator begin() const { return list_iterator<T>( this->delay() ); }
+ iterator end() const { return list_iterator<T>(); }
+
+ // end of odd_list<T>
+ };
+
+//////////////////////////////////////////////////////////////////////
+// struct cvt
+//////////////////////////////////////////////////////////////////////
+
+ // This converts ()->list<T> to ()->odd_list<T>.
+ // In other words, here is the 'extra work' done when using the
+ // unoptimized interface.
+ template <class U,class F>
+ struct cvt /*: public c_fun_type<odd_list<U> >*/ {
+ typedef odd_list<U> return_type;
+ F f;
+ cvt( const F& ff ) : f(ff) {}
+ odd_list<U> operator()() const {
+ list<U> l = f();
+ return l.force();
+ }
+ };
+
+
+//////////////////////////////////////////////////////////////////////
+// Cache<T> and associated functions.
+//////////////////////////////////////////////////////////////////////
+
+// I malloc a RefCountType to hold the refCount and init it to 1 to ensure the
+// refCount will never get to 0, so the destructor-of-global-object
+// order at the end of the program is a non-issue. In other words, the
+// memory allocated here is only reclaimed by the operating system.
+ template <class T>
+ Cache<T>* xnil_helper() {
+ void *p = std::malloc( sizeof(RefCountType) );
+ *((RefCountType*)p) = 1;
+ return static_cast<Cache<T>*>( p );
+ }
+
+ template <class T>
+ Cache<T>* xnil_helper_nil() {
+ Cache<T>* p = xnil_helper<T>();
+ return p;
+ }
+
+ template <class T>
+ Cache<T>* xnil_helper_bad() {
+ Cache<T>* p = xnil_helper<T>();
+ return p;
+ }
+
+ template <class T>
+ Cache<T>* xempty_helper() {
+ Cache<T>* p = new Cache<T>( CacheEmpty() );
+ return p;
+ }
+
+ // This makes a boost phoenix function type with return type
+ // odd_list<T>
+ template <class T>
+ struct fun0_type_helper{
+ typedef boost::function0<odd_list<T> > fun_type;
+ typedef boost::phoenix::function<fun_type> phx_type;
+ };
+
+
+ template <class T>
+ struct make_fun0_odd_list {
+
+ typedef typename fun0_type_helper<T>::fun_type fun_type;
+ typedef typename fun0_type_helper<T>::phx_type phx_type;
+ typedef phx_type result_type;
+
+ template <class F>
+ result_type operator()(const F& f) const
+ {
+ fun_type ff(f);
+ phx_type g(ff);
+ return g;
+ }
+
+ // Overload for the case where it is a boost phoenix function already.
+ template <class F>
+ typename boost::phoenix::function<F> operator()
+ (const boost::phoenix::function<F>& f) const
+ {
+ return f;
+ }
+
+ };
+
+ template <class T>
+ class Cache : boost::noncopyable {
+ mutable RefCountType refC;
+ // This is the boost::function type
+ typedef typename fun0_type_helper<T>::fun_type fun_odd_list_T;
+ // This is the boost::phoenix::function type;
+ typedef typename fun0_type_helper<T>::phx_type fun0_odd_list_T;
+ mutable fun0_odd_list_T fxn;
+ mutable odd_list<T> val;
+ // val.second.rep can be XBAD, XNIL, or a valid ptr
+ // - XBAD: val is invalid (fxn is valid)
+ // - XNIL: this is the empty list
+ // - anything else: val.first() is head, val.second is tail()
+
+ // This functoid should never be called; it represents a
+ // self-referent Cache, which should be impossible under the current
+ // implementation. Nonetheless, we need a 'dummy' function object to
+ // represent invalid 'fxn's (val.second.rep!=XBAD), and this
+ // implementation seems to be among the most reasonable.
+ struct blackhole_helper /*: c_fun_type< odd_list<T> >*/ {
+ typedef odd_list<T> return_type;
+ odd_list<T> operator()() const {
+#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
+ throw lazy_exception("You have entered a black hole.");
+#else
+ return odd_list<T>();
+#endif
+ }
+ };
+
+ // Don't get rid of these XFOO() functions; they impose no overhead,
+ // and provide a useful place to add debugging code for tracking down
+ // before-main()-order-of-initialization problems.
+ static const boost::intrusive_ptr<Cache<T> >& XEMPTY() {
+ static boost::intrusive_ptr<Cache<T> > xempty( xempty_helper<T>() );
+ return xempty;
+ }
+ static const boost::intrusive_ptr<Cache<T> >& XNIL() {
+ // this list is nil
+ static boost::intrusive_ptr<Cache<T> > xnil( xnil_helper_nil<T>() );
+ return xnil;
+ }
+
+ static const boost::intrusive_ptr<Cache<T> >& XBAD() {
+ // the pair is invalid; use fxn
+ static boost::intrusive_ptr<Cache<T> > xbad( xnil_helper_bad<T>() );
+ return xbad;
+ }
+
+ static fun0_odd_list_T /*<odd_list<T> >*/ the_blackhole;
+ static fun0_odd_list_T& blackhole() {
+ static fun0_odd_list_T the_blackhole;
+ //( make_fun0_odd_list<T>()( blackhole_helper() ) );
+ return the_blackhole;
+ }
+
+ odd_list<T>& cache() const {
+ if( val.second.rep == XBAD() ) {
+ val = fxn()();
+ fxn = blackhole();
+ }
+ return val;
+ }
+
+ template <class U> friend class list;
+ template <class U> friend class odd_list;
+ template <class TT, class F, class L, bool b> friend struct ConsHelp2;
+ template <class U,class F> friend struct cvt;
+ template <class U, class F, class R> friend struct ListHelp;
+ template <class U> friend Cache<U>* xempty_helper();
+
+ Cache( CacheEmpty ) : refC(0), fxn(blackhole()), val() {}
+ Cache( const odd_list<T>& x ) : refC(0), fxn(blackhole()), val(x) {}
+ Cache( const T& x, const list<T>& l ) : refC(0),fxn(blackhole()),val(x,l)
+ {}
+
+ Cache( const fun0_odd_list_T& f )
+ : refC(0), fxn(f), val( OddListDummyY() ) {}
+
+ // f must be a boost phoenix function object?
+ template <class F>
+ Cache( const F& f ) // ()->odd_list
+ : refC(0), fxn(make_fun0_odd_list<T>()(f)), val( OddListDummyY() ) {}
+
+ // This is for ()->list<T> to ()->odd_list<T>
+ struct CvtFxn {};
+ template <class F>
+ Cache( CvtFxn, const F& f ) // ()->list
+ : refC(0), fxn(make_fun0_odd_list<T>()(cvt<T,F>(f))), val( OddListDummyY() ) {}
+
+ template <class X>
+ friend void intrusive_ptr_add_ref( const Cache<X>* p );
+ template <class X>
+ friend void intrusive_ptr_release( const Cache<X>* p );
+ };
+
+ template <class T>
+ void intrusive_ptr_add_ref( const Cache<T>* p ) {
+ ++ (p->refC);
+ }
+ template <class T>
+ void intrusive_ptr_release( const Cache<T>* p ) {
+ if( !--(p->refC) ) delete p;
+ }
+
+//////////////////////////////////////////////////////////////////////
+// Rest of list's stuff
+//////////////////////////////////////////////////////////////////////
+
+template <class T, class F> struct ListHelp<T,F,list<T> > {
+ boost::intrusive_ptr<Cache<T> > operator()( const F& f ) const {
+ return boost::intrusive_ptr<Cache<T> >
+ (new Cache<T>(typename Cache<T>::CvtFxn(),f));
+ }
+};
+template <class T, class F> struct ListHelp<T,F,odd_list<T> > {
+ boost::intrusive_ptr<Cache<T> > operator()( const F& f ) const {
+ return boost::intrusive_ptr<Cache<T> >(new Cache<T>(f));
+ }
+};
+
+template <class T>
+class list_iterator
+: public std::iterator<std::input_iterator_tag,T,ptrdiff_t> {
+ list<T> l;
+ bool is_nil;
+ void advance() {
+ l = l.tail();
+ if( !l )
+ is_nil = true;
+ }
+ class Proxy { // needed for operator->
+ const T x;
+ friend class list_iterator;
+ Proxy( const T& xx ) : x(xx) {}
+ public:
+ const T* operator->() const { return &x; }
+ };
+public:
+ list_iterator() : l(), is_nil(true) {}
+ explicit list_iterator( const list<T>& ll ) : l(ll), is_nil(!ll) {}
+
+ const T operator*() const { return l.head(); }
+ const Proxy operator->() const { return Proxy(l.head()); }
+ list_iterator<T>& operator++() {
+ advance();
+ return *this;
+ }
+ const list_iterator<T> operator++(int) {
+ list_iterator<T> i( *this );
+ advance();
+ return i;
+ }
+ bool operator==( const list_iterator<T>& i ) const {
+ return is_nil && i.is_nil;
+ }
+ bool operator!=( const list_iterator<T>& i ) const {
+ return ! this->operator==(i);
+ }
+};
+
+
+ } // namespace impl
+
+ using impl::list;
+ using impl::odd_list;
+ using impl::list_iterator;
+
+//////////////////////////////////////////////////////////////////////
+// op== and op<, overloaded for all combos of list, odd_list, and NIL
+//////////////////////////////////////////////////////////////////////
+// All of these null head and tail are now non lazy using e.g. null(a)().
+// They need an extra () e.g. null(a)().
+
+// FIX THIS comparison operators can be implemented simpler with enable_if
+template <class T>
+bool operator==( const odd_list<T>& a, a_unique_type_for_nil ) {
+ return null(a)();
+}
+template <class T>
+bool operator==( const list<T>& a, a_unique_type_for_nil ) {
+ return null(a)();
+}
+template <class T>
+bool operator==( a_unique_type_for_nil, const odd_list<T>& a ) {
+ return null(a)();
+}
+template <class T>
+bool operator==( a_unique_type_for_nil, const list<T>& a ) {
+ return null(a)();
+}
+template <class T>
+bool operator==( const list<T>& a, const list<T>& b ) {
+ if( null(a)() && null(b)() )
+ return true;
+ if( null(a)() || null(b)() )
+ return false;
+ return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
+}
+template <class T>
+bool operator==( const odd_list<T>& a, const odd_list<T>& b ) {
+ if( null(a)() && null(b)() )
+ return true;
+ if( null(a)() || null(b)() )
+ return false;
+ return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
+}
+template <class T>
+bool operator==( const list<T>& a, const odd_list<T>& b ) {
+ if( null(a)() && null(b)() )
+ return true;
+ if( null(a)() || null(b)() )
+ return false;
+ return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
+}
+template <class T>
+bool operator==( const odd_list<T>& a, const list<T>& b ) {
+ if( null(a)() && null(b)() )
+ return true;
+ if( null(a)() || null(b)() )
+ return false;
+ return (head(a)()==head(b)()) && (tail(a)()==tail(b)());
+}
+
+template <class T>
+bool operator<( const list<T>& a, const list<T>& b ) {
+ if( null(a)() && !null(b)() ) return true;
+ if( null(b)() ) return false;
+ if( head(b)() < head(a)() ) return false;
+ if( head(a)() < head(b)() ) return true;
+ return (tail(a)() < tail(b)());
+}
+template <class T>
+bool operator<( const odd_list<T>& a, const list<T>& b ) {
+ if( null(a)() && !null(b)() ) return true;
+ if( null(b)() ) return false;
+ if( head(b)() < head(a)() ) return false;
+ if( head(a)() < head(b)() ) return true;
+ return (tail(a)() < tail(b)());
+}
+template <class T>
+bool operator<( const list<T>& a, const odd_list<T>& b ) {
+ if( null(a) && !null(b) ) return true;
+ if( null(b) ) return false;
+ if( head(b) < head(a) ) return false;
+ if( head(a) < head(b) ) return true;
+ return (tail(a) < tail(b));
+}
+template <class T>
+bool operator<( const odd_list<T>& a, const odd_list<T>& b ) {
+ if( null(a)() && !null(b)() ) return true;
+ if( null(b)() ) return false;
+ if( head(b)() < head(a)() ) return false;
+ if( head(a)() < head(b)() ) return true;
+ return (tail(a)() < tail(b)());
+}
+template <class T>
+bool operator<( const odd_list<T>&, a_unique_type_for_nil ) {
+ return false;
+}
+template <class T>
+bool operator<( const list<T>&, a_unique_type_for_nil ) {
+ return false;
+}
+template <class T>
+bool operator<( a_unique_type_for_nil, const odd_list<T>& b ) {
+ return !null(b)();
+}
+template <class T>
+bool operator<( a_unique_type_for_nil, const list<T>& b ) {
+ return !null(b)();
+}
+
+//////////////////////////////////////////////////////////////////////
+// Implement cat and cons after the list types are defined.
+//////////////////////////////////////////////////////////////////////
+ namespace impl {
+ using listlike::ListLike;
+
+ template <class T, class F, class L>
+ struct ConsHelp2<T,F,L,true>
+ {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef typename L::force_result_type type;
+ static type go( const TT& x, const F& f ) {
+ return type( x, f );
+ }
+ };
+ template <class T, class F>
+ struct ConsHelp2<T,F,list<T>,true>
+ {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef list<TT> L;
+ typedef typename L::force_result_type type;
+ static type go( const TT& x, const F& f ) {
+ return odd_list<TT>(x, list<TT>(
+ boost::intrusive_ptr<Cache<TT> >(new Cache<T>(
+ typename Cache<TT>::CvtFxn(),f))));
+ }
+ };
+ template <class T, class F>
+ struct ConsHelp2<T,F,odd_list<T>,true>
+ {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> L;
+ typedef typename L::force_result_type type;
+ static type go( const TT& x, const F& f ) {
+ return odd_list<TT>(x, list<TT>( ListRaw(), new Cache<T>(f) ));
+ }
+ };
+ template <class T, class F>
+ struct ConsHelp2<T,F,a_unique_type_for_nil,false>
+ {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> type;
+ static type go( const TT& x, const F& f ) {
+ return odd_list<TT>(x, list<TT>( ListRaw(), new Cache<T>(f) ));
+ }
+ };
+
+ template <class T, class L, bool b> struct ConsHelp1 {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef typename L::force_result_type type;
+ static type go( const TT& x, const L& l ) {
+ return type(x,l);
+ }
+ };
+ template <class T> struct ConsHelp1<T,a_unique_type_for_nil,false> {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> type;
+ static type go( const TT& x, const a_unique_type_for_nil& n ) {
+ return type(x,n);
+ }
+ };
+ template <class T, class F> struct ConsHelp1<T,F,false> {
+ // It's a function returning a list
+ // This is the one I have not fixed yet....
+ // typedef typename F::result_type L;
+ // typedef typename result_of::template ListType<F>::result_type L;
+ typedef odd_list<T> L;
+ typedef ConsHelp2<T,F,L,boost::is_base_and_derived<ListLike,L>::value> help;
+ typedef typename help::type type;
+ static type go( const T& x, const F& f ) {
+ return help::go(x,f);
+ }
+ };
+
+ template <class T, class L, bool b>
+ struct ConsHelp0;
+
+ template <class T>
+ struct ConsHelp0<T,a_unique_type_for_nil,true> {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<T> type;
+ };
+
+ template <class T>
+ struct ConsHelp0<const T &,const a_unique_type_for_nil &,true> {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> type;
+ };
+
+ template <class T>
+ struct ConsHelp0<T &,a_unique_type_for_nil &,true> {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> type;
+ };
+
+ template <class T, class L>
+ struct ConsHelp0<T,L,false> {
+ // This removes any references from L for correct return type
+ // identification.
+ typedef typename boost::remove_reference<L>::type LType;
+ typedef typename ConsHelp1<T,LType,
+ boost::is_base_and_derived<ListLike,LType>::value>::type type;
+ };
+
+ /////////////////////////////////////////////////////////////////////
+ // cons (t,l) - cons a value to the front of a list.
+ // Note: The first arg, t, must be a value.
+ // The second arg, l, can be a list or NIL
+ // or a function that returns a list.
+ /////////////////////////////////////////////////////////////////////
+ struct Cons
+ {
+ /* template <class T, class L> struct sig : public fun_type<
+ typename ConsHelp1<T,L,
+ boost::is_base_and_derived<ListLike,L>::value>::type> {};
+ */
+ template <typename Sig> struct result;
+
+ template <typename This, typename T, typename L>
+ struct result<This(T, L)>
+ {
+ typedef typename ConsHelp0<T,L,
+ listlike::detect_nil<L>::is_nil>::type type;
+ };
+
+ template <typename This, typename T>
+ struct result<This(T,a_unique_type_for_nil)>
+ {
+ typedef typename boost::remove_reference<T>::type TT;
+ typedef odd_list<TT> type;
+ };
+
+ template <typename T, typename L>
+ typename result<Cons(T,L)>::type
+ operator()( const T& x, const L& l ) const {
+ typedef typename result<Cons(T,L)>::type LL;
+ typedef typename result_of::ListType<L>::LType LType;
+ typedef ConsHelp1<T,LType,
+ boost::is_base_and_derived<ListLike,LType>::value> help;
+ return help::go(x,l);
+ }
+
+ template <typename T>
+ typename result<Cons(T,a_unique_type_for_nil)>::type
+ operator()( const T& x, const a_unique_type_for_nil &n ) const {
+ typedef typename result<Cons(T,a_unique_type_for_nil)>::type LL;
+ typedef ConsHelp1<T,LL,
+ boost::is_base_and_derived<ListLike,LL>::value> help;
+ return help::go(x,n);
+ }
+
+ };
+ }
+
+ typedef boost::phoenix::function<impl::Cons> Cons;
+ Cons cons;
+
+ namespace impl {
+
+ template <class L, class M, bool b>
+ struct CatHelp0;
+
+ template <class L>
+ struct CatHelp0<L,a_unique_type_for_nil,true> {
+ typedef typename result_of::template ListType<L>::LType type;
+ };
+
+ template <class L>
+ struct CatHelp0<const L &,const a_unique_type_for_nil &,true> {
+ typedef typename result_of::template ListType<L>::LType type;
+ //typedef L type;
+ };
+
+ template <class L>
+ struct CatHelp0<L &,a_unique_type_for_nil &,true> {
+ typedef typename result_of::template ListType<L>::LType type;
+ //typedef L type;
+ };
+
+ template <class L, class M>
+ struct CatHelp0<L,M,false> {
+ // This removes any references from L for correct return type
+ // identification.
+ typedef typename result_of::template ListType<L>::LType type;
+ // typedef typename ConsHelp1<T,LType,
+ // boost::is_base_and_derived<ListLike,LType>::value>::type type;
+ };
+
+ /////////////////////////////////////////////////////////////////////
+ // cat (l,m) - concatenate lists.
+ // Note: The first arg, l, must be a list or NIL.
+ // The second arg, m, can be a list or NIL
+ // or a function that returns a list.
+ /////////////////////////////////////////////////////////////////////
+ struct Cat
+ {
+ template <class L, class M, bool b, class R>
+ struct Helper /*: public c_fun_type<L,M,R>*/ {
+ template <typename Sig> struct result;
+
+ template <typename This>
+ struct result<This(L,M)>
+ {
+ typedef typename result_of::ListType<L>::tail_result_type type;
+ };
+
+ typedef R return_type;
+ R operator()( const L& l, const M& m,
+ reuser2<INV,VAR,INV,Helper,
+ typename result_of::template ListType<L>::tail_result_type,M>
+ r = NIL ) const {
+ if( null(l)() )
+ return m().force();
+ else
+ return cons( head(l)(), r( Helper<L,M,b,R>(), tail(l), m )() );
+ }
+ };
+ template <class L, class M, class R>
+ struct Helper<L,M,true,R> /*: public c_fun_type<L,M,R>*/ {
+ template <typename Sig> struct result;
+
+ template <typename This>
+ struct result<This(L,M)>
+ {
+ typedef typename result_of::ListType<L>::tail_result_type type;
+ };
+ typedef R return_type;
+ R operator()( const L& l, const M& m,
+ reuser2<INV,VAR,INV,Helper,
+ typename result_of::template ListType<L>::tail_result_type,M>
+ r = NIL ) const {
+ if( null(l)() )
+ return m.force();
+ else
+ return cons( head(l)(), r(Helper<L,M,true,R>(), tail(l), m )());
+ }
+ };
+ template <class L, class R>
+ struct Helper<L,a_unique_type_for_nil,false,R>
+ /*: public c_fun_type<L,
+ a_unique_type_for_nil,odd_list<typename L::value_type> > */
+ {
+ typedef odd_list<typename result_of::template ListType<L>::value_type> type;
+ odd_list<typename result_of::template ListType<L>::value_type>
+ operator()( const L& l, const a_unique_type_for_nil& ) const {
+ return l;
+ }
+ };
+ public:
+ /*template <class L, class M> struct sig : public fun_type<
+ typename RT<cons_type,typename L::value_type,M>::result_type>
+ {}; */
+ // Need to work out the return type here.
+ template <typename Sig> struct result;
+
+ template <typename This, typename L, typename M>
+ struct result<This(L,M)>
+ {
+ typedef typename CatHelp0<L,M,
+ listlike::detect_nil<M>::is_nil>::type type;
+ // typedef typename result_of::ListType<L>::tail_result_type type;
+ };
+
+ template <typename This, typename L>
+ struct result<This(L,a_unique_type_for_nil)>
+ {
+ typedef typename result_of::ListType<L>::tail_result_type type;
+ };
+ template <class L, class M>
+ typename result<Cat(L,M)>::type operator()( const L& l, const M& m ) const
+ {
+ listlike::EnsureListLike<L>();
+ return Helper<L,M,
+ boost::is_base_and_derived<typename listlike::ListLike,M>::value,
+ typename result<Cat(L,M)>::type>()(l,m);
+ }
+
+ template <class L>
+ typename result<Cat(L,a_unique_type_for_nil)>::type operator()( const L& l, const a_unique_type_for_nil& /* n */ ) const
+ {
+ listlike::EnsureListLike<L>();
+ return l;
+ }
+
+ };
+
+
+ }
+
+ typedef boost::phoenix::function<impl::Cat> Cat;
+ Cat cat;
+
+
+//////////////////////////////////////////////////////////////////////
+// Handy functions for making list literals
+//////////////////////////////////////////////////////////////////////
+// Yes, these aren't functoids, they're just template functions. I'm
+// lazy and created these mostly to make it easily to make little lists
+// in the sample code snippets that appear in papers.
+
+struct UseList {
+ template <class T> struct List { typedef list<T> type; };
+};
+struct UseOddList {
+ template <class T> struct List { typedef odd_list<T> type; };
+};
+struct UseStrictList {
+ template <class T> struct List { typedef strict_list<T> type; };
+};
+
+template <class Kind = UseList>
+struct list_with {
+ template <class T>
+ typename Kind::template List<T>::type
+ operator()( const T& a ) const {
+ typename Kind::template List<T>::type l;
+ l = cons( a, l );
+ return l;
+ }
+
+ template <class T>
+ typename Kind::template List<T>::type
+ operator()( const T& a, const T& b ) const {
+ typename Kind::template List<T>::type l;
+ l = cons( b, l );
+ l = cons( a, l );
+ return l;
+ }
+
+ template <class T>
+ typename Kind::template List<T>::type
+ operator()( const T& a, const T& b, const T& c ) const {
+ typename Kind::template List<T>::type l;
+ l = cons( c, l );
+ l = cons( b, l );
+ l = cons( a, l );
+ return l;
+ }
+
+ template <class T>
+ typename Kind::template List<T>::type
+ operator()( const T& a, const T& b, const T& c, const T& d ) const {
+ typename Kind::template List<T>::type l;
+ l = cons( d, l );
+ l = cons( c, l );
+ l = cons( b, l );
+ l = cons( a, l );
+ return l;
+ }
+
+ template <class T>
+ typename Kind::template List<T>::type
+ operator()( const T& a, const T& b, const T& c, const T& d,
+ const T& e ) const {
+ typename Kind::template List<T>::type l;
+ l = cons( e, l );
+ l = cons( d, l );
+ l = cons( c, l );
+ l = cons( b, l );
+ l = cons( a, l );
+ return l;
+ }
+};
+//////////////////////////////////////////////////////////////////////
+
+ }
+
+}
+
+#endif