tuple test pass

This commit is contained in:
Fischlurch 2009-06-22 06:05:32 +02:00
parent db9ef808a5
commit 61f8c1814d
3 changed files with 207 additions and 54 deletions

View file

@ -22,13 +22,13 @@
/** @file tuple.hpp
** Metaprogramming with tuples-of-types and a very simple Tuple datatype.
** Metaprogramming with tuples-of-types and a simple Tuple (record) datatype.
** The metaprogramming part of this header complements typelist.hpp and allows
** to re-build a new tuple-of-types from an existing typelist. Such a finite
** tuple of types can at times be more handy than a typelist, especially when
** capturing specific types to use as template parameter.
** sequence or tuple of types can at times be more handy than a typelist,
** especially when capturing specific types to use as template parameter.
**
** Additionally, this header augments the Tuple template into a very simple Tuple
** Additionally, this header augments the Tuple template into a simple Tuple
** (run time) datatype. This isn't meant as competing with std::tr1::tuple, which is
** much more capable, but also has the downside of pulling in a lot of other headers.
** But when all we need is to define a generic typed record of N data elements and
@ -55,8 +55,8 @@
namespace lumiera {
namespace typelist{
/**
* Helper: prepend a type to an existing type sequence,
@ -99,6 +99,8 @@ namespace typelist{
, T06,T07,T08,T09,T10
, T11,T12,T13,T14,T15
, T16,T17,T18,T19,T20 > Tuple;
typedef typename Tuple::List List;
};
@ -171,13 +173,23 @@ namespace typelist{
typedef TYPES Type;
typedef typename Split<Type>::Head Head;
};
/**
* simple generic Tuple datatype.
* Usable both for metaprogramming and as a generic record.
* The types within this tuple can either be specified
* as Type sequence or as typelist
* as Type sequence or as typelist. Default and canonical
* is the type-sequence based tuple form \c Tuple<Types<T1,T2,...>>
* The secondary from of specifying a tuple is based on a typelist
* (and this form is used actually to implement the storage, while
* the plain-flat (type sequence based) form acts as interface.
*
* Irrespective of the flavour actually used, you can always
* - get the canonical TupleType (sequence based)
* - get the types of head and tail, and a list version of the types
* - access the head element and the tail tuple
* - access the Nth element and a shifted-b-N sub (tail) tuple
*/
template<class TYPES>
struct Tuple;
@ -248,6 +260,7 @@ namespace typelist{
typedef Tuple<typename ShiftedTypes_::List> Type;
};
template<uint i>
typename ShiftedTuple<i>::Type&
getShifted ()
@ -375,6 +388,8 @@ namespace typelist{
/* ====== Helpers for working with Tuples ========= */
namespace tuple { // some convenience access functions
template<uint n, class TUP>
@ -494,9 +509,10 @@ namespace typelist{
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > (a1,a2,a3,a4,a5,a6,a7,a8,a9);
}
}
} // (END) access / tuple building helper functions (namespace tuple)
/** Trait template for detecting a type tuple */
template<typename TUP>
class is_Tuple
@ -504,7 +520,7 @@ namespace typelist{
template<class X> struct Check { typedef No_t It; };
template<class TY> struct Check<Tuple<TY> > { typedef Yes_t It; };
public:
public:
static const bool value = (sizeof(Yes_t)==sizeof(typename Check<TUP>::It));
};
@ -513,7 +529,7 @@ namespace typelist{
template<typename TUP>
class is_TupleListType
{
template<class X>
template<class X>
struct Check
{
enum{ result = sizeof(No_t)};
@ -546,7 +562,7 @@ namespace typelist{
template<typename TUP>
class is_NullTuple
{
template<class X>
template<class X>
struct Check
{
enum{ result = sizeof(No_t)};
@ -555,9 +571,9 @@ namespace typelist{
template<class TY>
struct Check<Tuple<TY> >
{
Yes_t check(Types<>*);
Yes_t check(NullType*);
No_t check(...);
Yes_t static check(Types<>*);
Yes_t static check(NullType*);
No_t static check(...);
enum{ result = sizeof(check( (TY*)0)) };
};
@ -565,7 +581,7 @@ namespace typelist{
public:
static const bool value = (sizeof(Yes_t)== Check<TUP>::result);
};
/**
* Decorating a tuple type with auxiliary data access operations.
@ -576,13 +592,13 @@ namespace typelist{
* type of the individual elements within the Tuple. To achieve this, for each
* type within the Tuple, the BASE type is decorated with an instance of the
* template passed in as template template parameter _X_. Each of these
* decorating instances is provided with a member pointer to access "his"
* decorating instances is provided with a index allowing to access "his"
* specific element within the underlying tuple.
*
* The decorating template _X_ need to take its own base class as template
* parameter. Typically, operations on _X_ will be defined in a recursive fashion,
* calling down into this templated base class. To support this, an instantiation
* of _X_ with the 0 member ptr is generated for detecting recursion end
* of _X_ with the empty type sequence is generated for detecting recursion end
* (built as innermost decorator, i.e. immediate subclass of BASE)
*/
template
@ -645,7 +661,7 @@ namespace typelist{
};
}} // namespace lumiera::typelist

View file

@ -562,7 +562,114 @@ return: 0
END
PLANNED "TypeTuple_test" TypeTuple_test <<END
TEST "TypeTuple_test" TypeTuple_test <<END
out: L1 :-<1>-<3>-<5>-
out: L2 :-<2>-<4>-
out: L3 :-<7>-
out: Tup1 :TYPES-<>-<1>-<3>-<5>-
out: Tup1\(\) :...Tuple\(\(1\),\(3\),\(5\)\)
out: tup1x :...Tuple\(\{11\},\(3\),\(5\)\)
out: Type1 :-<1>-<3>-<5>-
out: T_L1 :TYPES-\[\]-<1>-<3>-<5>-
out: T1 :TYPES-<>-<1>-<3>-<5>-
out: tup1 :...Tuple\(\{8\},\(3\),\(5\)\)
out: tup2 :...Tuple\(\{9\},\(3\),\(5\)\)
out: Prepend :TYPES-\[\]-<i>-<1>-<3>-<5>-
out: prepend :...Tuple\(22,\{9\},\(3\),\(5\)\)
out: :$
out: : ---Sub-Tuple-Types----
out: T_L2 :TYPES-\[\]-<2>-<4>-<1>-<3>-<5>-
out: Head :-<2>-
out: Tail :-<4>-<1>-<3>-<5>-
out: T2 :TYPES-<>-<2>-<4>-<1>-<3>-<5>-
out: Head2 :-<2>-
out: Tail2 :-<4>-<1>-<3>-<5>-
out: T2::Type :-<2>-<4>-<1>-<3>-<5>-
out: T2::TailType :-<4>-<1>-<3>-<5>-
out: T2::TupleType :TYPES-<>-<2>-<4>-<1>-<3>-<5>-
out: T2::ThisType :TYPES-<>-<2>-<4>-<1>-<3>-<5>-
out: T2::Tail :TYPES-<>-<4>-<1>-<3>-<5>-
out: T2::ArgList :-<2>-<4>-<1>-<3>-<5>-
out: T_L2::Type :-<2>-<4>-<1>-<3>-<5>-
out: T_L2::TailType :-<4>-<1>-<3>-<5>-
out: T_L2::TupleType :TYPES-<>-<2>-<4>-<1>-<3>-<5>-
out: T_L2::ThisType :TYPES-\[\]-<2>-<4>-<1>-<3>-<5>-
out: T_L2::Tail :TYPES-\[\]-<4>-<1>-<3>-<5>-
out: T_L2::ArgList :-<2>-<4>-<1>-<3>-<5>-
out: NulT::Type :-
out: NulT::TailType :-
out: NulT::TupleType :TYPES-<>-
out: NulT::ThisType :TYPES-<>-
out: NulT::Tail :TYPES-<>-
out: NulT::ArgList :-
out: NulL::Type :-
out: NulL::TailType :-
out: NulL::TupleType :TYPES-<>-
out: NulL::ThisType :TYPES-\[\]-
out: NulL::Tail :TYPES-\[\]-
out: NulL::ArgList :-
out: :$
out: : ---Shifted-Tuple---
out: Ty_0 :-<2>-<4>-<7>-
out: Ty_1 :-<4>-<7>-
out: Ty_2 :-<7>-
out: Ty_3 :-
out: Ty_4 :-
out: T_0 :TYPES-\[\]-<2>-<4>-<7>-
out: T_1 :TYPES-\[\]-<4>-<7>-
out: T_2 :TYPES-\[\]-<7>-
out: T_3 :TYPES-\[\]-
out: T_4 :TYPES-\[\]-
out: tu3 :...Tuple\(\(2\),\(4\),\(7\)\)
out: tu3_0 :...Tuple\(\(2\),\(4\),\(7\)\)
out: tu3_1 :...Tuple\(\(4\),\(7\)\)
out: tu3_2 :...Tuple\(\(7\)\)
out: tu3_3 :...Tuple\(\)
out: tu3_4 :...Tuple\(\)
out: :$
out: : ---creating-Tuples---
out: tup1 :...Tuple\(\(1\),\(3\),\(5\)\)
out: tup11 :...Tuple\(\{11\},\(3\),\(5\)\)
out: tup12 :...Tuple\(\(1\),\{33\},\(5\)\)
out: tup13 :...Tuple\(\{11\},\{33\},\(5\)\)
out: Tup2 :TYPES-<>-<i>-<i>-<11>-
out: tup2 :...Tuple\(41,42,\{43\}\)
out: Tup22 :TYPES-<>-<i>-<11>-
out: tup22 :...Tuple\(42,\{43\}\)
out: Tup222 :TYPES-<>-<11>-
out: tup222 :...Tuple\(\{43\}\)
out: T0T :TYPES-<>-
out: T0L :TYPES-\[\]-
out: nullT :...Tuple\(\)
out: nullL :...Tuple\(\)
out: nulTcpy :...Tuple\(\)
out: nulTref :...Tuple\(\)
out: :$
out: : ---copy-operations---
out: tup1 :...Tuple\(\{11\},\{33\},\(5\)\)
out: tup11 :...Tuple\(\{11\},\{33\},\{44\}\)
out: tup1 :...Tuple\(\{11\},\{33\},\{44\}\)
out: tupL :...Tuple\(\{11\},\{33\},\{44\}\)
out: tup1L :...Tuple\(\{11\},\{33\},\{44\}\)
out: :$
out: : ---value-access---
out: TupX :TYPES-\[\]-<2>-<4>-<2>-<4>-
out: tupX :...Tuple\(\(2\),\(4\),\(2\),\(4\)\)
out: tu2 :...Tuple\(\(2\),\(4\)\)
out: tu2 :...Tuple\(\{5\},\{5\}\)
out: tupX :...Tuple\(\(2\),\(4\),\{5\},\{5\}\)
out: T4 :TYPES-<>-<2>-<4>-
out: t4 :...Tuple\(\{5\},\{5\}\)
out: TupX::Type :-<2>-<4>-<2>-<4>-
out: TupX::TailType :-<4>-<2>-<4>-
out: TupX::ThisType :TYPES-\[\]-<2>-<4>-<2>-<4>-
out: TupX::TupleType :TYPES-<>-<2>-<4>-<2>-<4>-
out: TupT::Type :-<2>-<4>-<2>-<4>-
out: TupT::TailType :-<4>-<2>-<4>-
out: TupT::ThisType :TYPES-<>-<2>-<4>-<2>-<4>-
out: TupT::TupleType :TYPES-<>-<2>-<4>-<2>-<4>-
out: tupXcopy :...Tuple\(\(2\),\(4\),\{5\},\{5\}\)
out: tupXcast :...Tuple\(\(2\),\(4\),\{5\},\{5\}\)
return: 0
END

View file

@ -22,8 +22,8 @@
/** @file type-tuple-test.cpp
** Interconnection of typelists, type tuples and simple record
** data types build on top of them.
** Interplay of typelists, type tuples and simple record
** data types build on top of them.
**
** @see lumiera::typelist::Tuple
** @see tuple.hpp
@ -34,18 +34,13 @@
#include "lib/test/run.hpp"
#include "lib/meta/typelist.hpp" ////////////TODO really?
#include "lib/meta/tuple.hpp"
#include "meta/typelist-diagnostics.hpp"
#include "meta/tuple-diagnostics.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/format.hpp>
#include <iostream>
using ::test::Test;
using std::string;
using std::cout;
using std::endl;
@ -81,9 +76,10 @@ namespace test {
* - build a tuple type from an existing typelist
* - create sub tuple types and types with shifted parameters
* Additionally, check the behaviour when creating tuple instances
* at runtime. Effectively, these are simple record types, which are
* synthesised by recursion over the related typelist.
* - create tuples from a list of values
* at runtime. Effectively, these are simple record types, which
* are synthesised by recursion over the related typelist.
* - diagnostics through TupleAccessor retrieving stored values
* - creating tuples by direct function call, providing values
* - copy and copy construct
* - access the "head" and access values by numeric index
* - create a tuple with shifted values
@ -130,7 +126,7 @@ namespace test {
void
check_tuple_from_Typelist()
{
typedef Types1::List L1; // starting from an existing Typelist...
typedef Types1::List L1; // starting from an existing Typelist...
typedef Tuple<L1> T_L1; // ListType based tuple type
typedef Tuple<L1>::TupleType T1; // corresponding plain tuple type
@ -150,6 +146,40 @@ namespace test {
Prepend prepend (22, tup2); // but note: the ListType based tuple has an "(head,tail)" style ctor
DUMPVAL (prepend); // ... and in construction, tup2 has been copied and coerced to ListType style
typedef Tuple<Types<> > NulT; // plain-flat empty Tuple
typedef Tuple<NullType> NulL; // list-style empty Tuple
ASSERT ( is_Tuple<T1>::value);
ASSERT ( is_TuplePlain<T1>::value);
ASSERT (! is_TupleListType<T1>::value);
ASSERT (! is_NullTuple<T1>::value);
ASSERT ( is_Tuple<T_L1>::value);
ASSERT (! is_TuplePlain<T_L1>::value);
ASSERT ( is_TupleListType<T_L1>::value);
ASSERT (! is_NullTuple<T_L1>::value);
ASSERT ( is_Tuple<NulT>::value);
ASSERT ( is_TuplePlain<NulT>::value);
ASSERT (! is_TupleListType<NulT>::value);
ASSERT ( is_NullTuple<NulT>::value);
ASSERT ( is_Tuple<NulL>::value);
ASSERT (! is_TuplePlain<NulL>::value);
ASSERT ( is_TupleListType<NulL>::value);
ASSERT ( is_NullTuple<NulL>::value);
ASSERT (! is_Tuple<Type1>::value);
ASSERT (! is_TuplePlain<Type1>::value);
ASSERT (!is_TupleListType<Type1>::value);
ASSERT (! is_NullTuple<Type1>::value);
ASSERT (! is_Tuple<Types1::List>::value);
ASSERT (! is_TuplePlain<Types1::List>::value);
ASSERT (!is_TupleListType<Types1::List>::value);
ASSERT (! is_NullTuple<Types1::List>::value);
}
@ -160,36 +190,36 @@ namespace test {
typedef Append<Types2::List, Types1::List>::List L2;
typedef Tuple<L2> T_L2;
typedef Tuple<L2> T_L2; // list-style Tuple
typedef Types<T_L2::HeadType> Head;
typedef T_L2::TailType Tail;
DISPLAY (T_L2);
DISPLAY (Head);
DISPLAY (Tail);
typedef T_L2::TupleType T2;
typedef T_L2::TupleType T2; // plain-flat Tuple
typedef Types<T2::HeadType> Head2;
typedef T2::TailType Tail2;
DISPLAY (T2);
DISPLAY (Head2);
DISPLAY (Tail2);
typedef Tuple<Types<> > NulT;
typedef Tuple<NullType> NulL;
typedef Tuple<Types<> > NulT; // plain-flat empty Tuple
typedef Tuple<NullType> NulL; // list-style empty Tuple
DISPLAY (T2::Type);
DISPLAY (T2::TailType);
DISPLAY (T2::TupleType);
DISPLAY (T2::Type); // irrespective of the flavour,
DISPLAY (T2::TailType); // a basic set of typedefs is
DISPLAY (T2::TupleType); // always available
DISPLAY (T2::ThisType);
DISPLAY (T2::Tail);
DISPLAY (T2::ArgList);
DISPLAY (T_L2::Type);
DISPLAY (T_L2::TailType);
DISPLAY (T_L2::TupleType);
DISPLAY (T_L2::ThisType);
DISPLAY (T_L2::Tail);
DISPLAY (T_L2::ArgList);
DISPLAY (T_L2::Type); // the element types as type sequence
DISPLAY (T_L2::TailType); // the element types of the "tail" tuple
DISPLAY (T_L2::TupleType); // corresponding plain-flat tuple type
DISPLAY (T_L2::ThisType); // "type_of(this)"
DISPLAY (T_L2::Tail); // tail tuple
DISPLAY (T_L2::ArgList); // typelist comprised of the element types
DISPLAY (NulT::Type);
DISPLAY (NulT::TailType);
@ -243,8 +273,8 @@ namespace test {
{
cout << "\t:\n\t: ---creating-Tuples---\n";
Tuple<Types1> tup1 ;
Tuple<Types1> tup11 (Num<1>(11) );
Tuple<Types1> tup1 ;
Tuple<Types1> tup11 (Num<1>(11) );
Tuple<Types1> tup12 (Num<1>(), Num<3>(33) );
Tuple<Types1> tup13 (Num<1>(11), Num<3>(33), Num<5>() );
DUMPVAL (tup1);
@ -253,7 +283,7 @@ namespace test {
DUMPVAL (tup13);
typedef Tuple<Types<int,int,Num<11> > > Tup2;
Tup2 tup2 = tuple::make(41,42, Num<11>(43));
Tup2 tup2 = tuple::make(41,42, Num<11>(43)); // build tuple from given values
DISPLAY (Tup2);
DUMPVAL (tup2);
@ -298,7 +328,7 @@ namespace test {
DUMPVAL (tup1);
Tuple<Types1::List> tupL = tup11.getShifted<0>();
Tuple<Types1> tup1L (tupL);
Tuple<Types1> tup1L (tupL); // create plain tuple from list-style tuple
DUMPVAL (tupL);
DUMPVAL (tup1L);
}
@ -320,8 +350,8 @@ namespace test {
tuple::element<1>(tu2).o_ = 5;
tu2.getHead() = Num<2> (tu2.getAt<1>().o_);
DUMPVAL (tu2);
tupX.getShifted<2>() = tu2;
DUMPVAL (tupX);
@ -344,10 +374,10 @@ namespace test {
TupT tupXcopy (tupX);
DUMPVAL (tupXcopy);
TupT& tupXcast (tupX.tupleCast());
TupT& tupXcast (tupX.tupleCast()); // (down)cast list-style to plain tuple
DUMPVAL (tupXcast);
}
};