toon-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Toon-members] tag/tag tuple.h


From: Edward Rosten
Subject: [Toon-members] tag/tag tuple.h
Date: Fri, 14 Jul 2006 22:02:35 +0000

CVSROOT:        /cvsroot/toon
Module name:    tag
Changes by:     Edward Rosten <edrosten>        06/07/14 22:02:35

Modified files:
        tag            : tuple.h 

Log message:
        Added more tuple functionality. Value and non-const reference lists also
        exist. These do not have most of the functionality of T_list, they are
        designed for multiple return vaules from functions. See the docs.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/tag/tag/tuple.h?cvsroot=toon&r1=1.3&r2=1.4

Patches:
Index: tuple.h
===================================================================
RCS file: /cvsroot/toon/tag/tag/tuple.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- tuple.h     11 Jul 2006 18:00:43 -0000      1.3
+++ tuple.h     14 Jul 2006 22:02:35 -0000      1.4
@@ -15,6 +15,8 @@
        {
                struct null{};
                
+               static null nv;
+
                //Index the list, retrieving the value and the type
                //with a good optimizer, this should be constant time at 
run-time.
                template<class C, class D, int i> struct index_l
@@ -72,25 +74,96 @@
        #endif
 
 
-       /// @defgroup tuple Tuple types of arbitrary length
-       /// This group containg classes for dealing with tuples (or typelists)
-       /// of arbitrary length. These are used for making variadic functions.
+       /** @defgroup tuple Tuple types of arbitrary length
+           This group containg classes for dealing with tuples (or typelists)
+               of arbitrary length. 
+               
+               There are two types:
+               - tag::T_list: Typelist with <code>const&</code> mebers.
+                       - Fully functional type list which supports static 
indexing of both values and types.
+                       - Used for typesafe variadic functions such as @ref 
Printf
+                       - See tag::T_list for a usage example.
+
+               - tag::V_list: Typelist with value members.
+                       - Used for returning tuples from functions, since 
references can not be used.
+                       - tag::V_tuple is a convinience class for generating 
the types.
+                       - Supports basic functionality, but not indexing.
+
+               V_list is designed primarily to allow multiple
+               return values from functions (see also tag::rpair) and can be 
uses as follows:
+               @code
+                       V_tuple<int, float, char>::type func()
+                       {
+                               int i;
+                               float f;
+                               char c;
+
+                               //Function body goes here
+                               return make_vtuple(i, f, c);
+                       }
+
+                   void foo()
+                       {
+                               int a;
+                               float b;
+                               char c;
 
-       /** Tuple/ typelist class.
+                               //Call func() and collect all return values
+                               make_rtuple(a,b,c) = func();
+                               
+                               //a,b,c are now set.
+                       }
+               @endcode
+
+
+       */
+
+       /** Tuple/ typelist class. Passed by const reference.
        @ingroup tuple
        
         A typelist containing an int, float and char* represented by the class:
        @code
-       T_list<int, T_list<float, T_list< char*, @ref T_ListEnd> > >
+       T_list<int, T_list<float, T_list< char*, T_ListEnd> > >
        @endcode
 
+       Typelists can be conviniently be built through use of the <code>,</code>
+       operator. The following code will have the type given above:
+       @code
+       (TupleHead, "hello", 2.2f, 1)
+       @endcode
+       or more convieniently with a macro:
+       @code
+       make_tuple("hello", 2.2f, 1)
+       @endcode
+       Note that the order is reversed between how the type is written and
+       how a list is written using <code>operator,()</code>. The lists can be 
+       statically indexed, and the indexing matches the order written using 
+       <code>,</code>. That is index 0 will refer to <code>(char*) 
"hello"</code>.
+       Indexing can be performed by value:
+       @code
+       char* ptr = some_tuple.index<0>();
+       @endcode
+       and by type:
+       @code
+       some_tuples_type::index_type<0>::type a_value = some_tuple.index<0>();
+       @endcode
+       The length of the list is a static member, so the last element can be 
eccessed
+       by:
+       @code
+               some_tuple.index<some_tuples_type::elements-1>()
+       @endcode
+
+
+
+
+
        The following code gives a simple example of the usage. The code simply
        prints out a list of values.
        @code
        #include <tag/tuple.h>
        #include <iostream>
 
-       using namespace EdUtil;
+       using namespace tag;
        using namespace std;
 
        template<class C, int i, int max> struct dump_list
@@ -193,6 +266,153 @@
                
        };
 
+
+       ///This is a Tuple/typelist class where members are stored by value.
+       ///It is designed primarily allowing multiple return values from 
+       ///functions. See address@hidden tuple'', @ref make_vtuple and @ref 
make_rtuple. You probably
+       ///do not waht to use this class directly, since it is rather 
cumbersome. See
+       ///tag::V_list.
+       ///@ingroup tuple
+       template<class C, class D> struct V_list
+       {
+               #ifndef DOXYGEN_IGNORE_INTERNAL
+               C val;
+               typedef C val_type;
+
+               D next;
+               typedef D next_type;
+               
+               
+               V_list(const C& c, const D& d)
+               :val(c),next(d){}
+
+               template<class X> V_list<X, V_list<C, D> > operator,(X& c) 
+               {
+                        return V_list<X, V_list<C, D> >(c, *this);
+               }
+               #endif
+       };
+
+
+       #ifndef DOXYGEN_IGNORE_INTERNAL
+       //This class converts a typelist in to an equivalent V_list
+       //This allows R_list to figure out the T_list it should allow
+       //assignment from.
+       namespace Internal
+       {
+               template<class X, class Y> struct r2v
+               {
+                       typedef V_list<X, typename r2v<typename Y::val_type, 
typename Y::next_type>::v> v;
+               };
+
+               template<> struct r2v<Internal::null, Internal::null>
+               {
+                       typedef V_list<null, null> v;
+               };
+       }
+       #endif
+
+       #ifndef DOXYGEN_IGNORE_INTERNAL
+       template<class C, class D> struct R_list
+       {
+               private:
+                       typedef typename Internal::r2v<C,D>::v 
equivalent_V_list;
+                       R_list(const R_list& );
+                       void operator=(const R_list&);
+
+
+               public:
+                       C& val;
+                       typedef C val_type;
+
+                       D& next;
+                       typedef D next_type;
+                       
+                       R_list(C& c, D& d)
+                       :val(c),next(d){}
+
+                       template<class X> R_list<X, R_list<C, D> > operator,(X& 
c) 
+                       {
+                                return R_list<X, R_list<C, D> >(c, *this);
+                       }
+
+                               
+                       template<class X, class Y> friend class R_list;
+                       void operator=(const equivalent_V_list& vlist)
+                       {
+                               val = vlist.val;
+                               next = vlist.next;
+                       }
+       };
+       #endif
+       
+       #ifndef DOXYGEN_IGNORE_INTERNAL
+       typedef R_list<Internal::null,Internal::null> R_ListEnd;
+       typedef V_list<Internal::null,Internal::null> V_ListEnd;
+
+
+       static  R_ListEnd R_TupleHead(Internal::nv, Internal::nv);
+       static  V_ListEnd V_TupleHead(Internal::nv, Internal::nv);
+       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
+       {
+               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;
+       };
+
+       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>
+       {
+               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;
+       };
+
+       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>
+       {
+               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;
+       };
+
+       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>
+       {
+               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;
+       };
+
+       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>
+       {
+               typedef V_list<F, V_list<E, V_list<D, V_list<C, V_list<B, 
V_list<A, V_ListEnd> > > > > > type;
+       };
+
+       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>
+       {
+               typedef V_list<E, V_list<D, V_list<C, V_list<B, V_list<A, 
V_ListEnd> > > > > type;
+       };
+
+       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>
+       {
+               typedef V_list<D, V_list<C, V_list<B, V_list<A, V_ListEnd> > > 
> type;
+       };
+
+       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>
+       {
+               typedef V_list<C, V_list<B, V_list<A, V_ListEnd> > > type;
+       };
+
+       template<class A, class B> struct 
V_tuple<A,B,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null,Internal::null>
+       {
+               typedef V_list<B, V_list<A, V_ListEnd> > type;
+       };
+       #else
+       ///A convinience type for generating tag::V_list  types. Note that 
+       ///the arguments are written in the order which matches use of 
<code>operator,()</code>.
+       ///This can be used to generate V_list types with up to 10 elements.
+       ///@ingroup tuple
+       template<class A, class B, class C, ...> struct V_tuple
+       {
+               ///The V_list type with elements A, B, C, ...
+               typedef V_list<..., V_list<C, V_list<B, V_list<A, V_ListEnd> > 
> > type;
+       };
+       #endif
+
+
+
+
+
        ///Guard type to mark the end of the list       
        ///@ingroup tuple
        typedef T_list<Internal::null,Internal::null> T_ListEnd;
@@ -205,6 +425,16 @@
 ///@ingroup tuple
 #define make_tuple(...) ((tag::TupleHead, ## __VA_ARGS__))
 
+
+///This macro is used to return multiple values from a function.
+///@ingroup tuple
+#define make_vtuple(...) ((tag::V_TupleHead, ## __VA_ARGS__))
+
+///This macro is used to collect multiple return values from a function.
+///@ingroup tuple
+#define make_rtuple(...) ((tag::R_TupleHead, ## __VA_ARGS__))
+
+
 #endif
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]