All pastes #205725 Raw Edit

ahigerd

public cpp v1 · immutable
#205725 ·published 2006-10-17 00:36 UTC
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