diff --git a/src/lib/meta/tuple.hpp b/src/lib/meta/tuple.hpp index e10d86abe..0f534b8c1 100644 --- a/src/lib/meta/tuple.hpp +++ b/src/lib/meta/tuple.hpp @@ -253,6 +253,7 @@ namespace typelist{ typedef Tuple Tail; enum { SIZE = count::value }; + /** standard ctor: create from values */ Tuple ( T1 a1 =T1() , T2 a2 =T2() , T3 a3 =T3() @@ -266,6 +267,12 @@ namespace typelist{ : Tuple(a1, Tuple(a2,a3,a4,a5,a6,a7,a8,a9)) { } + /** shortcut: allow copy construction from a tuple + * which is rather defined by a list type */ + Tuple (Tuple const& listTuple) + : Tuple (listTuple) + { } + using Tuple::getHead; using Tuple::getTail; @@ -455,6 +462,64 @@ namespace typelist{ public: static const bool value = (sizeof(Yes_t)==sizeof(typename Check::It)); }; + + /** Trait template detecting especially tuples + * built directly on top of a Typelist */ + template + class is_TupleListType + { + template + struct Check + { + enum{ result = sizeof(No_t)}; + }; + + template + struct Check > + { + template + Yes_t static check(Node*); + Yes_t static check(NullType*); + No_t static check(...); + + enum{ result = sizeof(check( (N*)0)) }; + }; + + public: + static const bool value = (sizeof(Yes_t)== Check::result); + }; + + /** Trait template to discern plain tuples and list-type tuples */ + template + struct is_TuplePlain + { + static const bool value = is_Tuple::value + && !is_TupleListType::value; + }; + + /** Trait template detecting an empty tuple type */ + template + class is_NullTuple + { + template + struct Check + { + enum{ result = sizeof(No_t)}; + }; + + template + struct Check > + { + Yes_t check(Types<>*); + Yes_t check(NullType*); + No_t check(...); + + enum{ result = sizeof(check( (TY*)0)) }; + }; + + public: + static const bool value = (sizeof(Yes_t)== Check::result); + }; /** diff --git a/tests/lib/meta/tuple-diagnostics.hpp b/tests/lib/meta/tuple-diagnostics.hpp index 283187044..63c176503 100644 --- a/tests/lib/meta/tuple-diagnostics.hpp +++ b/tests/lib/meta/tuple-diagnostics.hpp @@ -40,6 +40,7 @@ #include "lib/meta/tuple.hpp" #include +#include #include #include @@ -47,6 +48,7 @@ using std::string; using boost::str; using boost::format; using boost::enable_if; +using boost::lexical_cast; using util::unConst; @@ -69,6 +71,12 @@ namespace test { return str ( (o.o_==i? constElm:changedElm) % int(o.o_)); } + string + showTupElement(int i) + { + return lexical_cast(i); + } + template string showTupElement(T x) @@ -135,7 +143,8 @@ namespace test { /* ===== printing Tuple types and contents ===== */ template - string + typename enable_if< is_TuplePlain >, + string >::type showDump (Tuple const& tuple) { typedef BuildTupleAccessor BuildAccessor; @@ -144,8 +153,22 @@ namespace test { return "...Tuple" + Displayer(tuple).dump(); } + template + typename enable_if< is_TupleListType >, + string >::type + showDump (Tuple const& tuple) + { + typedef typename Tuple::Type TypeSeq; + Tuple plainTuple (tuple); + + typedef BuildTupleAccessor BuildAccessor; + typedef typename BuildAccessor::Accessor Displayer; + + return "...Tuple" + Displayer(plainTuple).dump(); + } + template - typename enable_if< is_Tuple, + typename enable_if< is_TuplePlain, string >::type showType () { @@ -154,6 +177,16 @@ namespace test { + DumpPrinter::print(); } + template + typename enable_if< is_TupleListType, + string >::type + showType () + { + typedef InstantiateChained DumpPrinter; + return "TYPES-[]" + + DumpPrinter::print(); + } + // see the macros DISPLAY and DUMPVAL defined in typelist-diagnostics.hpp diff --git a/tests/lib/meta/type-tuple-test.cpp b/tests/lib/meta/type-tuple-test.cpp index c3c97a6fb..44e79aab3 100644 --- a/tests/lib/meta/type-tuple-test.cpp +++ b/tests/lib/meta/type-tuple-test.cpp @@ -77,8 +77,17 @@ namespace test { /************************************************************************* - * @test ////////////////////////////////////////// - * - building combinations and permutations + * @test Cover various aspects of the type tuple. + * Check the metaprogramming behaviour... + * - 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 + * - copy and copy construct + * - access the "head" and access values by numeric index + * - create a tuple with shifted values */ class TypeTuple_test : public Test { @@ -86,8 +95,12 @@ namespace test { run (Arg) { check_diagnostics(); - - UNIMPLEMENTED ("verify type tuples"); + check_tuple_from_Typelist(); + check_sub_tuple_types(); + check_shiftedTuple(); + check_tuple_creation(); + check_tuple_copy(); + check_value_access(); } @@ -113,6 +126,71 @@ namespace test { DUMPVAL (Tup1()); // prints the contents DUMPVAL (tup1x); } + + + void + check_tuple_from_Typelist() + { + typedef Types1::List L1; // starting from an existing Typelist... + + typedef Tuple T_L1; // ListType based tuple type + typedef Tuple::ThisTuple T1; // corresponding plain tuple type + typedef Tuple::Type Type1; // extract the underlying type sequence + + DISPLAY (Type1); + DISPLAY (T_L1); + DISPLAY (T1); + + T_L1 tup1 (Num<1>(8)); // both flavours can be created at runtime + T1 tup2 (Num<1>(9)); // (and we provide an explicit value for the 1st element) + DUMPVAL (tup1); + DUMPVAL (tup2); + + typedef Tuple > Prepend; + DISPLAY (Prepend); // another ListType based tuple created by prepending + + 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 + } + + + void + check_sub_tuple_types() + { + UNIMPLEMENTED ("verify head and tail type"); + } + + + void + check_shiftedTuple() + { + UNIMPLEMENTED ("verify shifted type tuple"); + } + + + void + check_tuple_creation() + { + UNIMPLEMENTED ("verify tuple creation"); + + } + + + void + check_tuple_copy() + { + UNIMPLEMENTED ("verify tuple copying and assignment"); + + } + + + void + check_value_access() + { + UNIMPLEMENTED ("verify tuple value access"); + + } + }; diff --git a/tests/lib/meta/typelist-diagnostics.hpp b/tests/lib/meta/typelist-diagnostics.hpp index e2a806776..a5b77ac71 100644 --- a/tests/lib/meta/typelist-diagnostics.hpp +++ b/tests/lib/meta/typelist-diagnostics.hpp @@ -133,6 +133,13 @@ namespace typelist{ static string print () { return str( fmt % uint(Fl) % BASE::print()); } }; + template + struct Printer ///< display the presence of a plain int in the typelist + : BASE + { + static string print () { return str( fmt % 'i' % BASE::print()); } + }; + /** call the debug-print for a typelist