1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtCore module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
23 ****************************************************************************/
27 #include <qxttypelist.h>
32 template<typename TYPELIST, int INDEX, int STEP=0, bool END=(INDEX==STEP), bool ERROR=(TYPELIST::length==0)>
35 typedef typename get<typename TYPELIST::tail, INDEX, STEP+1>::type type;
38 template<typename TYPELIST, int INDEX, int STEP>
39 struct get<TYPELIST, INDEX, STEP, false, true>
40 {}; // does not define type
42 template<typename TYPELIST, int INDEX, int STEP, bool ERROR>
43 struct get<TYPELIST, INDEX, STEP, true, ERROR>
45 typedef typename TYPELIST::head type;
48 template<typename TYPELIST, bool LONG=false> class QxtTuple;
49 template<typename TYPELIST, int INDEX, bool LONG, bool EXT=(INDEX>8)> struct QxtTupleValue;
51 template<typename TYPELIST, int INDEX> struct QxtTupleValue<TYPELIST, INDEX, true, true>
53 static typename get<TYPELIST, INDEX>::type value(QxtTuple<TYPELIST,true>* t)
55 return QxtTupleValue<typename TYPELIST::extend, INDEX-9, TYPELIST::extend::extends>::value(&t->extend);
58 static void setValue(QxtTuple<TYPELIST,true>* t, typename get<TYPELIST, INDEX>::type val)
60 QxtTupleValue<typename TYPELIST::extend, INDEX-9, TYPELIST::extend::extends>::setValue(&t->extend, val);
64 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 0, LONG, false>
66 static typename get<TYPELIST, 0>::type value(QxtTuple<TYPELIST,LONG>* t)
70 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 0>::type val)
76 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 1, LONG, false>
78 static typename get<TYPELIST, 1>::type value(QxtTuple<TYPELIST,LONG>* t)
82 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 1>::type val)
88 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 2, LONG, false>
90 static typename get<TYPELIST, 2>::type value(QxtTuple<TYPELIST,LONG>* t)
94 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 2>::type val)
100 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 3, LONG, false>
102 static typename get<TYPELIST, 3>::type value(QxtTuple<TYPELIST,LONG>* t)
106 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 3>::type val)
112 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 4, LONG, false>
114 static typename get<TYPELIST, 4>::type value(QxtTuple<TYPELIST,LONG>* t)
118 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 4>::type val)
124 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 5, LONG, false>
126 static typename get<TYPELIST, 5>::type value(QxtTuple<TYPELIST,LONG>* t)
130 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 5>::type val)
136 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 6, LONG, false>
138 static typename get<TYPELIST, 6>::type value(QxtTuple<TYPELIST,LONG>* t)
142 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 6>::type val)
148 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 7, LONG, false>
150 static typename get<TYPELIST, 7>::type value(QxtTuple<TYPELIST,LONG>* t)
154 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 7>::type val)
160 template<typename TYPELIST, bool LONG> struct QxtTupleValue<TYPELIST, 8, LONG, false>
162 static typename get<TYPELIST, 8>::type value(QxtTuple<TYPELIST,LONG>* t)
166 static void setValue(QxtTuple<TYPELIST,LONG>* t, typename get<TYPELIST, 8>::type val)
172 //-----------------------------------------------------------------------------------------------
174 template<typename TYPELIST>
176 \class QxtTuple QxtTuple
180 \brief Arbitrary-length templated list
182 Tuples and cons pairs are both pretty common template metaprogramming hacks. This set of classes
183 attempts to implement a healthy balance between the two. Tuples generally are implemented with a
184 fixed length; cons pairs have a lot of overhead and require a ton of typing. As with all template
185 metaprograms, it may take a while to compile.
187 It is recommended to use the convenience macros to create tuples, but you can construct the
188 QxtTypeList template yourself if you desire; this may be preferable if you want to write generic
189 functions that use tuples.
193 #include <QxtTuple.h>
197 int main(int argc, char** argv) {
198 Qxt7Tuple(bool, char, short, int, long long, float, double) tuple;
200 tuple.setValue<0>(true);
201 tuple.setValue<1>('a');
202 tuple.setValue<2>(32767);
203 tuple.setValue<3>(1234567);
204 tuple.setValue<4>(987654321);
205 tuple.setValue<5>(1.414);
206 tuple.setValue<6>(3.14159265);
208 cout << 0 << "=" << tuple.value<0>() << endl;
209 cout << 1 << "=" << tuple.value<1>() << endl;
210 cout << 2 << "=" << tuple.value<2>() << endl;
211 cout << 3 << "=" << tuple.value<3>() << endl;
212 cout << 4 << "=" << tuple.value<4>() << endl;
213 cout << 5 << "=" << tuple.value<5>() << endl;
214 cout << 6 << "=" << tuple.value<6>() << endl;
219 class QxtTuple<TYPELIST,false>
222 template<int INDEX> typename get<TYPELIST, INDEX>::type value()
224 return QxtTupleValue<TYPELIST, INDEX, false>::value(this);
226 template<int INDEX> void setValue(typename get<TYPELIST, INDEX>::type val)
228 QxtTupleValue<TYPELIST, INDEX, false>::setValue(this, val);
230 bool operator<(const QxtTuple<TYPELIST,false>& other)
232 if (t1 < other.t1) return true;
233 if (t2 < other.t2) return true;
234 if (t3 < other.t3) return true;
235 if (t4 < other.t4) return true;
236 if (t5 < other.t5) return true;
237 if (t6 < other.t6) return true;
238 if (t7 < other.t7) return true;
239 if (t8 < other.t8) return true;
240 if (t9 < other.t9) return true;
243 bool operator==(const QxtTuple<TYPELIST,false>& other)
245 if (t1 != other.t1) return false;
246 if (t2 != other.t2) return false;
247 if (t3 != other.t3) return false;
248 if (t4 != other.t4) return false;
249 if (t5 != other.t5) return false;
250 if (t6 != other.t6) return false;
251 if (t7 != other.t7) return false;
252 if (t8 != other.t8) return false;
253 if (t9 != other.t9) return false;
256 bool operator>=(const QxtTuple<TYPELIST,false>& other)
258 return !(*this < other);
260 bool operator<=(const QxtTuple<TYPELIST,false>& other)
262 if (t1 <= other.t1) return true;
263 if (t2 <= other.t2) return true;
264 if (t3 <= other.t3) return true;
265 if (t4 <= other.t4) return true;
266 if (t5 <= other.t5) return true;
267 if (t6 <= other.t6) return true;
268 if (t7 <= other.t7) return true;
269 if (t8 <= other.t8) return true;
270 if (t9 <= other.t9) return true;
273 bool operator>(const QxtTuple<TYPELIST,false>& other)
275 return !(*this <= other);
277 bool operator!=(const QxtTuple<TYPELIST,false>& other)
279 return !(*this == other);
283 // if only we could get away with making these protected
284 typename get<TYPELIST, 0>::type t1;
285 typename get<TYPELIST, 1>::type t2;
286 typename get<TYPELIST, 2>::type t3;
287 typename get<TYPELIST, 3>::type t4;
288 typename get<TYPELIST, 4>::type t5;
289 typename get<TYPELIST, 5>::type t6;
290 typename get<TYPELIST, 6>::type t7;
291 typename get<TYPELIST, 7>::type t8;
292 typename get<TYPELIST, 8>::type t9;
295 //-----------------------------------------------------------------------------------------------
297 template<typename TYPELIST>
298 class QxtTuple<TYPELIST,true>
301 template<int INDEX> typename get<TYPELIST, INDEX>::type value()
303 return QxtTupleValue<TYPELIST, INDEX, true>::value(this);
305 template<int INDEX> void setValue(typename get<TYPELIST, INDEX>::type val)
307 QxtTupleValue<TYPELIST, INDEX, true>::setValue(this, val);
309 bool operator<(const QxtTuple<TYPELIST,true>& other)
311 if (t1 < other.t1) return true;
312 if (t2 < other.t2) return true;
313 if (t3 < other.t3) return true;
314 if (t4 < other.t4) return true;
315 if (t5 < other.t5) return true;
316 if (t6 < other.t6) return true;
317 if (t7 < other.t7) return true;
318 if (t8 < other.t8) return true;
319 if (t9 < other.t9) return true;
320 if (extend < other.extend) return true;
323 bool operator==(const QxtTuple<TYPELIST,true>& other)
325 if (t1 != other.t1) return false;
326 if (t2 != other.t2) return false;
327 if (t3 != other.t3) return false;
328 if (t4 != other.t4) return false;
329 if (t5 != other.t5) return false;
330 if (t6 != other.t6) return false;
331 if (t7 != other.t7) return false;
332 if (t8 != other.t8) return false;
333 if (t9 != other.t9) return false;
334 if (extend != other.extend) return false;
337 bool operator>=(const QxtTuple<TYPELIST,true>& other)
339 return !(*this < other);
341 bool operator<=(const QxtTuple<TYPELIST,true>& other)
343 if (t1 <= other.t1) return true;
344 if (t2 <= other.t2) return true;
345 if (t3 <= other.t3) return true;
346 if (t4 <= other.t4) return true;
347 if (t5 <= other.t5) return true;
348 if (t6 <= other.t6) return true;
349 if (t7 <= other.t7) return true;
350 if (t8 <= other.t8) return true;
351 if (t9 <= other.t9) return true;
352 if (extend <= other.extend) return true;
355 bool operator>(const QxtTuple<TYPELIST,true>& other)
357 return !(*this <= other);
359 bool operator!=(const QxtTuple<TYPELIST,true>& other)
361 return !(*this == other);
364 // if only we could get away with making these protected
365 typename get<TYPELIST, 0>::type t1;
366 typename get<TYPELIST, 1>::type t2;
367 typename get<TYPELIST, 2>::type t3;
368 typename get<TYPELIST, 3>::type t4;
369 typename get<TYPELIST, 4>::type t5;
370 typename get<TYPELIST, 5>::type t6;
371 typename get<TYPELIST, 6>::type t7;
372 typename get<TYPELIST, 7>::type t8;
373 typename get<TYPELIST, 8>::type t9;
374 QxtTuple<typename TYPELIST::extend> extend;
380 using QxtType::QxtTuple;
383 #ifndef QXT_NO_MACROS
384 /*! \relates QxtTuple
385 * Declares a one-column tuple.
387 #define Qxt1Tuple(a) QxtTuple<QxtTypeList<a > >
389 /*! \relates QxtTuple
390 * Declares a two-column tuple, similar to QPair.
392 #define Qxt2Tuple(a, b) QxtTuple<QxtTypeList<a, b > >
394 /*! \relates QxtTuple
395 * Declares a three-column tuple, similar to QxtTriple.
397 #define Qxt3Tuple(a, b, c) QxtTuple<QxtTypeList<a, b, c > >
399 /*! \relates QxtTuple
400 * Declares a four-column tuple.
402 #define Qxt4Tuple(a, b, c, d) QxtTuple<QxtTypeList<a, b, c, d > >
404 /*! \relates QxtTuple
405 * Declares a five-column tuple.
407 #define Qxt5Tuple(a, b, c, d, e) QxtTuple<QxtTypeList<a, b, c, d, e > >
409 /*! \relates QxtTuple
410 * Declares a six-column tuple.
412 #define Qxt6Tuple(a, b, c, d, e, f) QxtTuple<QxtTypeList<a, b, c, d, e, f > >
414 /*! \relates QxtTuple
415 * Declares a seven-column tuple.
417 #define Qxt7Tuple(a, b, c, d, e, f, g) QxtTuple<QxtTypeList<a, b, c, d, e, f, g > >
419 /*! \relates QxtTuple
420 * Declares an eight-column tuple.
422 #define Qxt8Tuple(a, b, c, d, e, f, g, h) QxtTuple<QxtTypeList<a, b, c, d, e, f, g, h > >
424 /*! \relates QxtTuple
425 * Declares a nine-column tuple.
427 #define Qxt9Tuple(a, b, c, d, e, f, g, h, i) QxtTuple<QxtTypeList<a, b, c, d, e, f, g, h, i > >
429 /*! \relates QxtTuple
430 * Declares an extended tuple with ten or more columns. Pay special attention to the syntax of the tenth parameter, which
431 * must be a QxtTypeList, not a storage type.
433 QxtLongTuple(int, int, int, int, int, int, int, int, int, Qxt1TypeList(int)) tuple; // correct way to implement a 10-tuple
434 QxtLongTuple(int, int, int, int, int, int, int, int, int, int) tuple; // this will produce a (very long) compile-time error
437 #define QxtLongTuple(a, b, c, d, e, f, g, h, i, extend) QxtTuple<QxtTypeList<a, b, c, d, e, f, g, h, i, extend >, true >