[Top][All Lists]
[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