00001 #ifndef TAG_TUPLE_H
00002 #define TAG_TUPLE_H
00003
00004 namespace tag
00005 {
00007
00008
00009
00010
00011 template<class C, class D> class T_list;
00012
00013 #ifndef DOXYGEN_IGNORE_INTERNAL
00014 namespace Internal
00015 {
00016 struct null{};
00017
00018 static null nv;
00019
00020
00021
00022 template<class C, class D, int i> struct index_l
00023 {
00024 typedef typename index_l<typename D::val_type, typename D::next_type, i-1>::val_type val_type;
00025
00026 static const val_type& value(const T_list<C,D>& l)
00027 {
00028 return index_l<typename D::val_type, typename D::next_type, i-1>::value(l.next);
00029 }
00030 };
00031
00032 template<class C, class D> struct index_l<C,D,0>
00033 {
00034 typedef C val_type;
00035 static const val_type& value(const T_list<C,D>& l)
00036 {
00037 return l.val;
00038 }
00039 };
00040
00041
00042 template<class C, class D> struct length
00043 {
00044 enum
00045 {
00046 len = length<typename D::val_type, typename D::next_type>::len + 1
00047 };
00048 };
00049
00050 template<> struct length<null, null>
00051 {
00052 enum
00053 {
00054 len = 0
00055 };
00056 };
00057
00058
00059 template<class C, class D, int i> struct T_index_forward
00060 {
00061 enum
00062 {
00063 len = length<C,D>::len
00064 };
00065
00066 typedef typename index_l<C,D,len-i-1>::val_type val_type;
00067
00068 static const val_type& value(const T_list<C,D>& l)
00069 {
00070 return index_l<C, D, len-i-1>::value(l);
00071 }
00072 };
00073 }
00074 #endif
00075
00076
00210 template<class C, class D> struct T_list
00211 {
00213 const C& val;
00215 typedef C val_type;
00216
00218 const D& next;
00220 typedef D next_type;
00221
00222
00226 T_list(const C& c, const D& d)
00227 :val(c),next(d){}
00228
00242 template<class X> T_list<X, T_list<C, D> > operator,(const X& c) const
00243 {
00244 return T_list<X, T_list<C, D> >(c, *this);
00245 }
00246
00249 template<int i> const typename Internal::T_index_forward<C,D,i>::val_type& index() const
00250 {
00251 return Internal::T_index_forward<C,D,i>::value(*this);
00252 }
00253
00256 template<int i> class index_type
00257 {
00258 typedef typename Internal::T_index_forward<C,D,i>::val_type type;
00259 };
00260
00261 enum
00262 {
00264 elements = (Internal::length<C,D>::len)
00265 };
00266
00267 };
00268
00269
00276 template<class C, class D> struct V_list
00277 {
00278 #ifndef DOXYGEN_IGNORE_INTERNAL
00279 C val;
00280 typedef C val_type;
00281
00282 D next;
00283 typedef D next_type;
00284
00285
00286 V_list(const C& c, const D& d)
00287 :val(c),next(d){}
00288
00289 template<class X> V_list<X, V_list<C, D> > operator,(const X& c)
00290 {
00291 return V_list<X, V_list<C, D> >(c, *this);
00292 }
00293 #endif
00294 };
00295
00296
00297 #ifndef DOXYGEN_IGNORE_INTERNAL
00298
00299
00300
00301 namespace Internal
00302 {
00303 template<class X, class Y> struct r2v
00304 {
00305 typedef V_list<X, typename r2v<typename Y::val_type, typename Y::next_type>::v> v;
00306 };
00307
00308 template<> struct r2v<Internal::null, Internal::null>
00309 {
00310 typedef V_list<null, null> v;
00311 };
00312 }
00313 #endif
00314
00315 #ifndef DOXYGEN_IGNORE_INTERNAL
00316 template<class C, class D> struct R_list
00317 {
00318 private:
00319 typedef typename Internal::r2v<C,D>::v equivalent_V_list;
00320 R_list(const R_list& );
00321 void operator=(const R_list&);
00322
00323
00324 public:
00325 C& val;
00326 typedef C val_type;
00327
00328 D& next;
00329 typedef D next_type;
00330
00331 R_list(C& c, D& d)
00332 :val(c),next(d){}
00333
00334 template<class X> R_list<X, R_list<C, D> > operator,(X& c)
00335 {
00336 return R_list<X, R_list<C, D> >(c, *this);
00337 }
00338
00339
00340 template<class X, class Y> friend class R_list;
00341 void operator=(const equivalent_V_list& vlist)
00342 {
00343 val = vlist.val;
00344 next = vlist.next;
00345 }
00346 };
00347 #endif
00348
00349 #ifndef DOXYGEN_IGNORE_INTERNAL
00350 typedef R_list<Internal::null,Internal::null> R_ListEnd;
00351 typedef V_list<Internal::null,Internal::null> V_ListEnd;
00352
00353
00354 static R_ListEnd R_TupleHead(Internal::nv, Internal::nv);
00355 static V_ListEnd V_TupleHead(Internal::nv, Internal::nv);
00356 template<class A, class B, class C=Internal::null, class D=Internal::null, class E=Internal::null, class F=Internal::null, class G=Internal::null, class H=Internal::null, class I=Internal::null, class J=Internal::null> struct V_tuple
00357 {
00358 typedef V_list<J,V_list<I, V_list<H, V_list<G, V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > > > > > > type;
00359 };
00360
00361 template<class A, class B, class C, class D, class E, class F, class G, class H, class I> struct V_tuple<A,B,C,D,E,F,G,H,I,Internal::null>
00362 {
00363 typedef V_list<I, V_list<H, V_list<G, V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > > > > > type;
00364 };
00365
00366 template<class A, class B, class C, class D, class E, class F, class G, class H> struct V_tuple<A,B,C,D,E,F,G,H,Internal::null,Internal::null>
00367 {
00368 typedef V_list<H, V_list<G, V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > > > > type;
00369 };
00370
00371 template<class A, class B, class C, class D, class E, class F, class G> struct V_tuple<A,B,C,D,E,F,G,Internal::null,Internal::null,Internal::null>
00372 {
00373 typedef V_list<G, V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > > > type;
00374 };
00375
00376 template<class A, class B, class C, class D, class E, class F> struct V_tuple<A,B,C,D,E,F,Internal::null,Internal::null,Internal::null,Internal::null>
00377 {
00378 typedef V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > > type;
00379 };
00380
00381 template<class A, class B, class C, class D, class E> struct V_tuple<A,B,C,D,E,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null>
00382 {
00383 typedef V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > > type;
00384 };
00385
00386 template<class A, class B, class C, class D> struct V_tuple<A,B,C,D,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null>
00387 {
00388 typedef V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > > type;
00389 };
00390
00391 template<class A, class B, class C> struct V_tuple<A,B,C,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null>
00392 {
00393 typedef V_list<C, V_list<B, V_list<A, V_ListEnd> > > type;
00394 };
00395
00396 template<class A, class B> struct V_tuple<A,B,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null>
00397 {
00398 typedef V_list<B, V_list<A, V_ListEnd> > type;
00399 };
00400 #else
00405 template<class A, class B, class C, ...> struct V_tuple
00406 {
00408 typedef V_list<..., V_list<C, V_list<B, V_list<A, V_ListEnd> > > > type;
00409 };
00410 #endif
00411
00412
00413
00414
00415
00418 typedef T_list<Internal::null,Internal::null> T_ListEnd;
00421 static const T_ListEnd TupleHead=T_ListEnd(Internal::null(), Internal::null());
00422 }
00423
00426 #define make_tuple(...) ((tag::TupleHead, ## __VA_ARGS__))
00427
00428
00431 #define make_vtuple(...) ((tag::V_TupleHead, ## __VA_ARGS__))
00432
00435 #define make_rtuple(...) ((tag::R_TupleHead, ## __VA_ARGS__))
00436
00437
00438 #endif
00439
00440