rendered paste body/** * Tuples and cons pairs are both pretty common template metaprogramming hacks. * This set of classes attempts to implement a healthy balance between the two. * Tuples generally are implemented with a fixed length; cons pairs have a lot * of overhead and require a ton of typing. * * As with all template metaprograms, it may take a while to compile. */#ifndef QXTUPLE_H#ifndef QXNULL_DEFINED#define QXNULL_DEFINEDstruct QxNull { operator int() const { return 0; } enum { isNull = true }; template<typename T> inline bool operator==(const T& p) { return false; } inline bool operator==(const QxNull& p) { return true; }} NW;#endifnamespace QxType {struct NoExtend { typedef QxNull head; enum { length = 0, extends = false };};template <typename T1 = QxNull, typename T2 = QxNull, typename T3 = QxNull, typename T4 = QxNull, typename T5 = QxNull, typename T6 = QxNull, typename T7 = QxNull, typename T8 = QxNull, typename T9 = QxNull, typename EXTEND = QxType::NoExtend>struct QxTypeList;template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename EXTEND>struct QxTypeList { typedef T1 head; typedef QxTypeList<T2, T3, T4, T5, T6, T7, T8, T9, NoExtend, EXTEND> tail; typedef EXTEND extend; enum { length = tail::length + 1, extends = EXTEND::extends };};template<typename EXTEND>struct QxTypeList<NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, EXTEND> { typedef typename EXTEND::head head; typedef typename EXTEND::tail tail; typedef EXTEND extend; enum { length = EXTEND::length, extends = EXTEND::extends };};template<>struct QxTypeList<NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, NoExtend, QxType::NoExtend> { typedef QxNull extend; enum { length = 0, extends = false };};template<typename TYPELIST, int INDEX, int STEP=0, bool END=(INDEX==STEP), bool ERROR=(TYPELIST::length==0)>struct get { typedef typename get<typename TYPELIST::tail, INDEX, STEP+1>::type type;};template<typename TYPELIST, int INDEX, int STEP>struct get<TYPELIST, INDEX, STEP, false, true> {}; // does not define typetemplate<typename TYPELIST, int INDEX, int STEP, bool ERROR>struct get<TYPELIST, INDEX, STEP, true, ERROR> { typedef typename TYPELIST::head type;};template<typename TYPELIST, bool LONG=false> class QxTuple;template<typename TYPELIST, int INDEX, bool LONG, bool EXT=(INDEX>8)> struct QxTupleValue;template<typename TYPELIST, int INDEX> struct QxTupleValue<TYPELIST, INDEX, true, true> { static typename get<TYPELIST, INDEX>::type value(QxTuple<TYPELIST,true>* t) { return QxTupleValue<typename TYPELIST::extend, INDEX-9, TYPELIST::extend::extends>::value(&t->extend); } static void setValue(QxTuple<TYPELIST,true>* t, typename get<TYPELIST, INDEX>::type val) { QxTupleValue<typename TYPELIST::extend, INDEX-9, TYPELIST::extend::extends>::setValue(&t->extend, val); }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 0, LONG, false> { static typename get<TYPELIST, 0>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t1; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 0>::type val) { t->t1 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 1, LONG, false> { static typename get<TYPELIST, 1>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t2; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 1>::type val) { t->t2 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 2, LONG, false> { static typename get<TYPELIST, 2>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t3; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 2>::type val) { t->t3 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 3, LONG, false> { static typename get<TYPELIST, 3>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t4; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 3>::type val) { t->t4 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 4, LONG, false> { static typename get<TYPELIST, 4>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t5; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 4>::type val) { t->t5 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 5, LONG, false> { static typename get<TYPELIST, 5>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t6; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 5>::type val) { t->t6 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 6, LONG, false> { static typename get<TYPELIST, 6>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t7; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 6>::type val) { t->t7 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 7, LONG, false> { static typename get<TYPELIST, 7>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t8; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 7>::type val) { t->t8 = val; }};template<typename TYPELIST, bool LONG> struct QxTupleValue<TYPELIST, 8, LONG, false> { static typename get<TYPELIST, 8>::type value(QxTuple<TYPELIST,LONG>* t) { return t->t9; } static void setValue(QxTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 8>::type val) { t->t9 = val; }};template<typename TYPELIST>class QxTuple<TYPELIST,false> {public: template<int INDEX> typename get<TYPELIST, INDEX>::type value() { return QxTupleValue<TYPELIST, INDEX, false>::value(this); } template<int INDEX> void setValue(typename get<TYPELIST, INDEX>::type val) { QxTupleValue<TYPELIST, INDEX, false>::setValue(this, val); } // if only we could get away with making these protected typename get<TYPELIST, 0>::type t1; typename get<TYPELIST, 1>::type t2; typename get<TYPELIST, 2>::type t3; typename get<TYPELIST, 3>::type t4; typename get<TYPELIST, 4>::type t5; typename get<TYPELIST, 5>::type t6; typename get<TYPELIST, 6>::type t7; typename get<TYPELIST, 7>::type t8; typename get<TYPELIST, 8>::type t9;};template<typename TYPELIST>class QxTuple<TYPELIST,true> {public: template<int INDEX> typename get<TYPELIST, INDEX>::type value() { return QxTupleValue<TYPELIST, INDEX, true>::value(this); } template<int INDEX> void setValue(typename get<TYPELIST, INDEX>::type val) { QxTupleValue<TYPELIST, INDEX, true>::setValue(this, val); }// if only we could get away with making these protected typename get<TYPELIST, 0>::type t1; typename get<TYPELIST, 1>::type t2; typename get<TYPELIST, 2>::type t3; typename get<TYPELIST, 3>::type t4; typename get<TYPELIST, 4>::type t5; typename get<TYPELIST, 5>::type t6; typename get<TYPELIST, 6>::type t7; typename get<TYPELIST, 7>::type t8; typename get<TYPELIST, 8>::type t9; QxTuple<typename TYPELIST::extend> extend;};}#ifndef QX_NO_USINGusing QxType::QxTypeList;using QxType::QxTuple;#endif#ifndef QX_NO_MACROS#define Qx1Tuple(a) QxTuple<QxTypeList<a > >#define QxPair(a, b) QxTuple<QxTypeList<a, b > >#define QxTriple(a, b, c) QxTuple<QxTypeList<a, b, c > >#define Qx4Tuple(a, b, c, d) QxTuple<QxTypeList<a, b, c, d > >#define Qx5Tuple(a, b, c, d, e) QxTuple<QxTypeList<a, b, c, d, e > >#define Qx6Tuple(a, b, c, d, e, f) QxTuple<QxTypeList<a, b, c, d, e, f > >#define Qx7Tuple(a, b, c, d, e, f, g) QxTuple<QxTypeList<a, b, c, d, e, f, g > >#define Qx8Tuple(a, b, c, d, e, f, g, h) QxTuple<QxTypeList<a, b, c, d, e, f, g, h > >#define Qx9Tuple(a, b, c, d, e, f, g, h, i) QxTuple<QxTypeList<a, b, c, d, e, f, g, h, i > >#define QxLongTuple(a, b, c, d, e, f, g, h, i, j) QxTuple<QxTypeList<a, b, c, d, e, f, g, h, i, j >, true >#endif#endif