#ifndef BOOST_TUPLE_INCLUDED #define BOOST_TUPLE_INCLUDED namespace boost { namespace detail { // Represents an empty tuple slot (up to 5 supported) struct nulltype {}; // For readable error messages struct tuple_component_idx_out_of_bounds; // To share some code for the const/nonconst versions of the getters template struct ConstIf { typedef T t; }; template struct ConstIf { typedef const T t; }; template struct value_getter; template struct list_elem_base { // Store template parameters typedef TNEXT next_type; typedef T type; static const unsigned nidx = NIDX; }; // Represents an element in the tuple component list template struct list_elem : list_elem_base{ // Real members T me; TNEXT next; // Get the value of a specific tuple element template T& get () { value_getter s; return s(*this); } // Get the value of a specific tuple element template const T& get () const { value_getter s; return s(*this); } // Assign a value to the tuple element template /* requires convertible(T2,T) */ list_elem& operator = (const list_elem& other) { me = (T)other.me; next = other.next; return *this; } // Recursively compare two elements bool operator == (const list_elem& s) const { return (me == s.me && next == s.next); } }; // Represents a non-used tuple element - the very last element processed template struct list_elem : list_elem_base { template struct value_getter { /* just dummy members to produce readable error messages */ tuple_component_idx_out_of_bounds operator () (typename ConstIf::t& me); }; template struct type_getter { /* just dummy members to produce readable error messages */ typedef tuple_component_idx_out_of_bounds type; }; // dummy list_elem& operator = (const list_elem& other) { return *this; } // dummy bool operator == (const list_elem& other) { return true; } }; // Represents the absolute end of the list typedef list_elem list_end; // Helper obtain to query the value of a tuple element // NOTE: Could be a nested class, but afaik it's non-standard and at least // MSVC isn't able to evaluate the partial specialization correctly. template struct value_getter { // calling list_elem typedef list_elem outer_elem; // typedef for the getter for next element typedef value_getter next_value_getter; typename ConstIf::t& operator () (typename ConstIf::t& me) { next_value_getter s; return s(me.next); } }; template struct value_getter { typedef list_elem outer_elem; typename ConstIf::t& operator () (typename ConstIf::t& me) { return me.me; } }; // Helper to obtain the type of a tuple element template struct type_getter { typedef type_getter next_elem_getter; typedef typename next_elem_getter::type type; }; template struct type_getter { typedef T type; }; }; // A very minimal implementation for up to 5 elements template class tuple { friend class tuple; private: typedef detail::list_elem > > > > very_long; very_long m; public: // Get a specific tuple element template typename detail::type_getter::type& get () { return m.get(); } // ... and the const version template typename const detail::type_getter::type& get () const { return m.get(); } // assignment operator tuple& operator= (const tuple& other) { m = other.m; return *this; } // comparison operators bool operator== (const tuple& other) const { return m == other.m; } // ... and the other way round bool operator!= (const tuple& other) const { return !(m == other.m); } // cast to another tuple - all single elements must be convertible template < typename T0, typename T1,typename T2, typename T3, typename T4> operator tuple () { tuple s; s.m = m; return s; } }; // Another way to access an element ... template inline typename tuple::very_long::type_getter::type& get ( tuple& m) { return m.get(); } // ... and the const version template inline const typename tuple::very_long::type_getter::type& get ( const tuple& m) { return m.get(); } // Constructs a tuple with 5 elements template inline tuple make_tuple (const T0& t0, const T1& t1,const T2& t2,const T3& t3,const T4& t4) { tuple t; t.get<0>() = t0; t.get<1>() = t1; t.get<2>() = t2; t.get<3>() = t3; t.get<4>() = t4; return t; } // Constructs a tuple with 4 elements template inline tuple make_tuple (const T0& t0, const T1& t1,const T2& t2,const T3& t3) { tuple t; t.get<0>() = t0; t.get<1>() = t1; t.get<2>() = t2; t.get<3>() = t3; return t; } // Constructs a tuple with 3 elements template inline tuple make_tuple (const T0& t0, const T1& t1,const T2& t2) { tuple t; t.get<0>() = t0; t.get<1>() = t1; t.get<2>() = t2; return t; } // Constructs a tuple with 2 elements (fucking idiot, use std::pair instead!) template inline tuple make_tuple (const T0& t0, const T1& t1) { tuple t; t.get<0>() = t0; t.get<1>() = t1; return t; } // Constructs a tuple with 1 elements (no comment ...) template inline tuple make_tuple (const T0& t0) { tuple t; t.get<0>() = t0; return t; } // Constructs a tuple with 0 elements (ehm? Try http://www.promillerechner.net) inline tuple <> make_tuple () { tuple <> t; return t; } }; #endif