// A very small replacement for boost::tuple // (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net] #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; }; // Predeclare some stuff template struct value_getter; // 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; }; // Base class for all explicit specializations of list_elem 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 typename type_getter::type& get () { value_getter s; return s(*this); } // Get the value of a specific tuple element template const typename type_getter::type& get () const { value_getter s; return s(*this); } // Explicit cast template operator list_elem () const { list_elem ret; ret.me = (T2)me; ret.next = next; return ret; } // Recursively compare two elements (last element returns always true) 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: This can't be a nested class as the compiler won't accept a full or // partial specialization of a nested class of a non-specialized template 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::type>::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; } }; } // A very minimal implementation for up to 5 elements template class tuple { template 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.template get(); } // ... and the const version template const typename detail::type_getter::type& get () const { return m.template get(); } // 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 operator tuple () const { tuple s; s.m = (typename tuple ::very_long)m; return s; } }; // Another way to access an element ... template inline typename tuple::very_long::template type_getter::type& get ( tuple& m) { return m.template get(); } // ... and the const version template inline const typename tuple::very_long::template type_getter::type& get ( const tuple& m) { return m.template 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.template get<0>() = t0; t.template get<1>() = t1; t.template get<2>() = t2; t.template get<3>() = t3; t.template 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.template get<0>() = t0; t.template get<1>() = t1; t.template get<2>() = t2; t.template 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.template get<0>() = t0; t.template get<1>() = t1; t.template get<2>() = t2; return t; } // Constructs a tuple with 2 elements template inline tuple make_tuple (const T0& t0, const T1& t1) { tuple t; t.template get<0>() = t0; t.template get<1>() = t1; return t; } // Constructs a tuple with 1 elements (well ...) template inline tuple make_tuple (const T0& t0) { tuple t; t.template get<0>() = t0; return t; } // Constructs a tuple with 0 elements (well ...) inline tuple <> make_tuple () { tuple <> t; return t; } } #endif // !! BOOST_TUPLE_INCLUDED