/** * 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_DEFINED struct QxNull { operator int() const { return 0; } enum { isNull = true }; template inline bool operator==(const T& p) { return false; } inline bool operator==(const QxNull& p) { return true; } } NW; #endif namespace QxType { struct NoExtend { typedef QxNull head; enum { length = 0, extends = false }; }; template struct QxTypeList; template struct QxTypeList { typedef T1 head; typedef QxTypeList tail; typedef EXTEND extend; enum { length = tail::length + 1, extends = EXTEND::extends }; }; template struct QxTypeList { typedef typename EXTEND::head head; typedef typename EXTEND::tail tail; typedef EXTEND extend; enum { length = EXTEND::length, extends = EXTEND::extends }; }; template<> struct QxTypeList { typedef QxNull extend; enum { length = 0, extends = false }; }; template struct get { typedef typename get::type type; }; template struct get {}; // does not define type template struct get { typedef typename TYPELIST::head type; }; template class QxTuple; template8)> struct QxTupleValue; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return QxTupleValue::value(&t->extend); } static void setValue(QxTuple* t, typename get::type val) { QxTupleValue::setValue(&t->extend, val); } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t1; } static void setValue(QxTuple* t, typename get::type val) { t->t1 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t2; } static void setValue(QxTuple* t, typename get::type val) { t->t2 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t3; } static void setValue(QxTuple* t, typename get::type val) { t->t3 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t4; } static void setValue(QxTuple* t, typename get::type val) { t->t4 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t5; } static void setValue(QxTuple* t, typename get::type val) { t->t5 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t6; } static void setValue(QxTuple* t, typename get::type val) { t->t6 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t7; } static void setValue(QxTuple* t, typename get::type val) { t->t7 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t8; } static void setValue(QxTuple* t, typename get::type val) { t->t8 = val; } }; template struct QxTupleValue { static typename get::type value(QxTuple* t) { return t->t9; } static void setValue(QxTuple* t, typename get::type val) { t->t9 = val; } }; template class QxTuple { public: template typename get::type value() { return QxTupleValue::value(this); } template void setValue(typename get::type val) { QxTupleValue::setValue(this, val); } // if only we could get away with making these protected typename get::type t1; typename get::type t2; typename get::type t3; typename get::type t4; typename get::type t5; typename get::type t6; typename get::type t7; typename get::type t8; typename get::type t9; }; template class QxTuple { public: template typename get::type value() { return QxTupleValue::value(this); } template void setValue(typename get::type val) { QxTupleValue::setValue(this, val); } // if only we could get away with making these protected typename get::type t1; typename get::type t2; typename get::type t3; typename get::type t4; typename get::type t5; typename get::type t6; typename get::type t7; typename get::type t8; typename get::type t9; QxTuple extend; }; } #ifndef QX_NO_USING using QxType::QxTypeList; using QxType::QxTuple; #endif #ifndef QX_NO_MACROS #define Qx1Tuple(a) QxTuple > #define QxPair(a, b) QxTuple > #define QxTriple(a, b, c) QxTuple > #define Qx4Tuple(a, b, c, d) QxTuple > #define Qx5Tuple(a, b, c, d, e) QxTuple > #define Qx6Tuple(a, b, c, d, e, f) QxTuple > #define Qx7Tuple(a, b, c, d, e, f, g) QxTuple > #define Qx8Tuple(a, b, c, d, e, f, g, h) QxTuple > #define Qx9Tuple(a, b, c, d, e, f, g, h, i) QxTuple > #define QxLongTuple(a, b, c, d, e, f, g, h, i, j) QxTuple, true > #endif #endif