test the combination generator
This commit is contained in:
parent
86f805f803
commit
06cc4c93fd
2 changed files with 121 additions and 15 deletions
|
|
@ -46,9 +46,7 @@ namespace lumiera {
|
|||
struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
|
||||
|
||||
|
||||
template< class TYPES
|
||||
, template<class> class _P_
|
||||
>
|
||||
template< class TYPES , template<class> class _P_>
|
||||
struct Filter;
|
||||
|
||||
template<template<class> class _P_>
|
||||
|
|
@ -57,7 +55,7 @@ namespace lumiera {
|
|||
template< class TY, class TYPES
|
||||
, template<class> class _P_
|
||||
>
|
||||
struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode<_P_<TY>::value
|
||||
struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
|
||||
, TY
|
||||
, typename Filter<TYPES,_P_>::List
|
||||
>::Next
|
||||
|
|
@ -92,7 +90,7 @@ namespace lumiera {
|
|||
|
||||
|
||||
template<class T, class TY>
|
||||
struct PrefixAll { typedef typename Append<T,TY>::List List; };
|
||||
struct PrefixAll { typedef Node< typename Append<T,TY>::List, NullType> List; };
|
||||
|
||||
template<class T>
|
||||
struct PrefixAll<T, NullType> { typedef NullType List; };
|
||||
|
|
@ -108,7 +106,10 @@ namespace lumiera {
|
|||
|
||||
|
||||
template<class TY1,class TY2>
|
||||
struct Distribute { typedef typename Append<TY1,TY2>::List List; };
|
||||
struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
|
||||
|
||||
template<class T,class TS>
|
||||
struct Distribute<Node<T,TS>,NullType> { typedef Node<T,TS> List; };
|
||||
|
||||
template< class TY, class TYPES
|
||||
, class TAIL
|
||||
|
|
@ -148,7 +149,6 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
using std::max;
|
||||
|
||||
|
||||
template<char bit> struct Flag { typedef Flag ID; };
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace lumiera {
|
|||
boost::format fmt ("<%i>");
|
||||
|
||||
/** constant-wrapper type for debugging purposes,
|
||||
* usable for generating lists of distinghishable types
|
||||
* usable for generating lists of distinguishable types
|
||||
*/
|
||||
template<int I>
|
||||
struct Num
|
||||
|
|
@ -77,16 +77,44 @@ namespace lumiera {
|
|||
template<class NUM=NullType, class BASE=NullType>
|
||||
struct Printer;
|
||||
|
||||
template<class X>
|
||||
struct Printer<NullType, X>
|
||||
{
|
||||
static string print () { return "-"; }
|
||||
};
|
||||
|
||||
template<class BASE, int I>
|
||||
struct Printer<Num<I>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print () { return string("-") + Num<I>::str() + BASE::print(); }
|
||||
};
|
||||
template<class X>
|
||||
struct Printer<NullType, X>
|
||||
|
||||
|
||||
typedef Printer<NullType> NullP;
|
||||
|
||||
/** call the debug-print for a typelist
|
||||
* utilizing the Printer template */
|
||||
template<class L>
|
||||
string
|
||||
printSublist ()
|
||||
{
|
||||
typedef InstantiateChained<L, Printer, NullP> SubList;
|
||||
return SubList::print();
|
||||
}
|
||||
|
||||
/** Spezialisation for debug-printing of a nested sublist */
|
||||
template<class TY, class TYPES, class BASE>
|
||||
struct Printer<Node<TY,TYPES>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print () { return "-"; }
|
||||
static string print ()
|
||||
{
|
||||
//typedef InstantiateChained<Node<TY,TYPES>, Printer, NullP> SubList;
|
||||
typedef Node<TY,TYPES> List;
|
||||
return string("\n\t+--") + printSublist<List>()+"+"
|
||||
+ BASE::print();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -99,10 +127,16 @@ namespace lumiera {
|
|||
, Num<6>
|
||||
, Num<7>
|
||||
>::List List2;
|
||||
|
||||
|
||||
template<class X> struct CountDown { typedef NullType List; };
|
||||
template<> struct CountDown<Num<0> > { typedef Node<Num<0>, NullType> List; };
|
||||
template<int I> struct CountDown<Num<I> > { typedef Node<Num<I>, typename CountDown<Num<I-1> >::List> List; };
|
||||
|
||||
|
||||
|
||||
#define DIAGNOSE(LIST) \
|
||||
typedef InstantiateChained<LIST::List, Printer, Printer<NullType> > Contents_##LIST;
|
||||
typedef InstantiateChained<LIST::List, Printer, NullP> Contents_##LIST;
|
||||
|
||||
#define DISPLAY(NAME) \
|
||||
DIAGNOSE(NAME); cout << STRINGIFY(NAME) << "\t" << Contents_##NAME::print() << "\n";
|
||||
|
|
@ -116,9 +150,13 @@ namespace lumiera {
|
|||
|
||||
/*************************************************************************
|
||||
* @test check utilities for manipulating lists-of-types.
|
||||
* <ul><li>build an list of constant-wrapper-types and
|
||||
* print them for debugging purpose.</li>
|
||||
* </ul>
|
||||
* - build an list of constant-wrapper-types and
|
||||
* print them for debugging purpose.
|
||||
* - append lists, single elements and NullType
|
||||
* in various combinations
|
||||
* - filtering out some types from a typelist by
|
||||
* using a "predicate template" (metafuction)
|
||||
* - building combinations and permutations
|
||||
*/
|
||||
class TypeListManipl_test : public Test
|
||||
{
|
||||
|
|
@ -126,6 +164,10 @@ namespace lumiera {
|
|||
{
|
||||
check_diagnostics ();
|
||||
check_append ();
|
||||
check_filter ();
|
||||
check_prefix ();
|
||||
check_distribute();
|
||||
check_combine();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -174,6 +216,70 @@ namespace lumiera {
|
|||
DISPLAY (Append9);
|
||||
}
|
||||
|
||||
|
||||
template<class X> struct IsEven { enum {value = false }; };
|
||||
template<int I> struct IsEven<Num<I> > { enum {value = (0 == I % 2) }; };
|
||||
|
||||
void check_filter ()
|
||||
{
|
||||
typedef Filter<Append<List1,List2>::List, IsEven > FilterEven;
|
||||
DISPLAY (FilterEven);
|
||||
}
|
||||
|
||||
|
||||
void check_prefix ()
|
||||
{
|
||||
typedef PrefixAll<Num<11>,Num<22> > Prefix1;
|
||||
DISPLAY (Prefix1);
|
||||
|
||||
typedef PrefixAll<Num<101>,List1> Prefix2;
|
||||
DISPLAY (Prefix2);
|
||||
|
||||
typedef PrefixAll<NullType,List1> Prefix3;
|
||||
DISPLAY (Prefix3);
|
||||
|
||||
typedef Types<List1::List,Num<0>,List2::List>::List List_of_Lists;
|
||||
typedef PrefixAll<Num<111>,List_of_Lists> Prefix4;
|
||||
DISPLAY (Prefix4);
|
||||
|
||||
typedef PrefixAll<List1,List2> Prefix5;
|
||||
DISPLAY (Prefix5);
|
||||
|
||||
typedef PrefixAll<List1,List_of_Lists> Prefix6;
|
||||
DISPLAY (Prefix6);
|
||||
}
|
||||
|
||||
|
||||
void check_distribute()
|
||||
{
|
||||
typedef Distribute<Num<11>, List1> Dist1;
|
||||
DISPLAY (Dist1);
|
||||
|
||||
typedef Types<Num<11>,Num<22>,Num<33> >::List Prefixes;
|
||||
typedef Distribute<Prefixes, Num<0> > Dist2;
|
||||
DISPLAY (Dist2);
|
||||
|
||||
typedef Distribute<Prefixes, List1> Dist3;
|
||||
DISPLAY (Dist3);
|
||||
|
||||
typedef Distribute<Prefixes, Types<List1::List,List2::List>::List> Dist4;
|
||||
DISPLAY (Dist4);
|
||||
}
|
||||
|
||||
|
||||
void check_combine()
|
||||
{
|
||||
typedef CountDown<Num<11> > Down;
|
||||
DISPLAY (Down);
|
||||
|
||||
typedef Combine<List1::List, CountDown> Combi;
|
||||
DISPLAY (Combi);
|
||||
|
||||
typedef CombineFlags<List1::List> OnOff;
|
||||
DISPLAY (OnOff);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue