Main Page | Modules | Namespace List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

tuple.h

Go to the documentation of this file.
00001 #ifndef TAG_TUPLE_H
00002 #define TAG_TUPLE_H
00003 
00004 namespace tag
00005 {
00007     //
00008     // Typesafe, varadic arguments are provided by a typelist
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         //Index the list, retrieving the value and the type
00021         //with a good optimizer, this should be constant time at run-time.
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         //Compute the length of a list
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     //This class converts a typelist in to an equivalent V_list
00299     //This allows R_list to figure out the T_list it should allow
00300     //assignment from.
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 

Generated on Wed Aug 8 14:30:35 2007 for TooN Algorithm Library - tag by  doxygen 1.3.9.1