Listing 2
#include <boost/tuple/tuple.hpp> // Template to append a type to a cons, thus creating a new cons. template< class CONS, class TYPE > struct AppendCons { typedef boost::tuples::cons< typename CONS::head_type, typename AppendCons< typename CONS::tail_type, TYPE >::type > type; }; // Partially specialize for the end of the list. template< class TYPE > struct AppendCons< boost::tuples::null_type, TYPE > { typedef boost::tuples::cons< TYPE, boost::tuples::null_type > type; }; // A type that collects values. Like Boost tuple, this type is a cons. // However, unlike Boost tuple, it is left-associative. That's // because the dot operator is left-associative. template< class HEAD, class TAIL > struct GenTuple { // The GenTuple defining the first part of the set. HEAD head; // Use of TAIL reference makes it possible for the compiler to optimize. // However, it also means that the object lifetime must be shorter than // the values it manages. Fortunately, this class // is only intended to be used as a temporary. const TAIL &tail; // Generate the type of Boost cons, which is the workhorse behind tuple. typedef typename AppendCons< typename HEAD::cons, TAIL >::type cons; // Count the items in the tuple. enum { DEPTH = HEAD::DEPTH+1 }; GenTuple( const HEAD &h, const TAIL &t ) : head( h ), tail( t ) {} // Return new object that also implements add, which lets you chain calls. template< class NEXT > GenTuple< GenTuple< HEAD, TAIL >, NEXT > add( const NEXT &next ) const { return GenTuple< GenTuple< HEAD, TAIL >, NEXT > ( *this, next ); } // Construct, initialize, and return a Boost tuple. cons tuple() const { cons value; prepareTuple( value ); return value; } // Recursively fill in the tuple. template< class TUPLE > void prepareTuple( TUPLE &t ) const { head.prepareTuple( t ); ::boost::tuples::get<DEPTH>(t) = tail; } // Discourage declaration of non-temporaries. GenTuple(); }; // Start with a type that generates an empty tuple. struct GenTupleStart { enum { DEPTH = -1 }; typedef boost::tuples::null_type cons; template< class TUPLE > void prepareTuple( TUPLE &t ) const { } }; // Start the process with a function. template< class FIRST > GenTuple< GenTupleStart, FIRST > genTuple( const FIRST &first ) { return GenTuple< GenTupleStart, FIRST > ( GenTupleStart(), first ); }