clean-up: validate the typelist manipulations
As expected, these work on the new-style variadic type sequences equally well than on the old ones (tail-filled with `Nil` markers). On that occasion, a complete makeover of the huge test case was carried out, now relying on `ExpectString` instead of printing to STDOUT. This has the benefit of showing the expectation immediately next to the code to be tested, and thus makes it much easier to ''actually see'' how these meta-functions operate on their parameters (which in fact are types in a type list)
This commit is contained in:
parent
c8187bdf88
commit
47b57da646
8 changed files with 439 additions and 444 deletions
|
|
@ -18,19 +18,26 @@
|
||||||
** implementations by combining some basic building blocks. Typically, there
|
** implementations by combining some basic building blocks. Typically, there
|
||||||
** is a number of similar, but not suitably related types involved. We want to
|
** is a number of similar, but not suitably related types involved. We want to
|
||||||
** process those types using a common scheme, without being forced to squeeze
|
** process those types using a common scheme, without being forced to squeeze
|
||||||
** all those types into a artificial inheritance relationship. Now, generating
|
** all those types into a artificial inheritance relationship. Instead, generating
|
||||||
** some kind of common factory or adapter, while mixing in pieces of code tailored
|
** some kind of common factory or adapter, while mixing in pieces of code tailored
|
||||||
** specifically to the individual types, allows still to build a common processing
|
** specifically to the individual types, allows still to build a common processing
|
||||||
** in such situations.
|
** in such situations.
|
||||||
**
|
**
|
||||||
** The facilities in this header provide the basics of simple functional list
|
** The facilities in this header provide the basics of simple functional list
|
||||||
** processing (mostly with tail recursion). Usually, there is one template parameter
|
** processing (mostly with tail recursion). Usually, there is one template parameter
|
||||||
** TYPES, which accepts a \em Type-list. The result of the processing step is then
|
** TYPES, which accepts a _type-list_. The result of the processing step is then
|
||||||
** accessible as an embedded typedef named \c List . Here, all of the 'processing'
|
** accessible as nested type definition named `List`. Here, all of the „processing“
|
||||||
** to calculate this result is performed by the compiler, as a side-effect of
|
** to calculate this result is performed by the compiler, as a side-effect set
|
||||||
** figuring out the resulting concrete type. At run time, in the generated
|
** off by the need to compute a requested concrete result type. At run time,
|
||||||
** code, typically the resulting classes are empty, maybe just
|
** in the generated code, typically the resulting classes are empty, maybe
|
||||||
** exposing a specifically built-up function.
|
** just exposing a function outfitted for a specific purpose.
|
||||||
|
**
|
||||||
|
** @remark historically, these functions were developed for the first draft of
|
||||||
|
** the render engine, which (for other reasons) did not come to fruition.
|
||||||
|
** Over time, some of these functions were used on and off for various
|
||||||
|
** purposes; and since (as of 2025) Loki-style type lists are considered
|
||||||
|
** an integral part of the Lumiera framework, useful meta-functions are
|
||||||
|
** added and documented here, even when not currently in use.
|
||||||
**
|
**
|
||||||
** @see generator.hpp
|
** @see generator.hpp
|
||||||
** @see typelist-manip-test.cpp
|
** @see typelist-manip-test.cpp
|
||||||
|
|
@ -57,17 +64,17 @@ namespace meta {
|
||||||
template<class TYPES, size_t i>
|
template<class TYPES, size_t i>
|
||||||
struct Pick
|
struct Pick
|
||||||
{
|
{
|
||||||
typedef Nil Type;
|
using Type = Nil;
|
||||||
};
|
};
|
||||||
template<class TY, class TYPES>
|
template<class TY, class TYPES>
|
||||||
struct Pick<Node<TY,TYPES>, 0>
|
struct Pick<Node<TY,TYPES>, 0>
|
||||||
{
|
{
|
||||||
typedef TY Type;
|
using Type = TY;
|
||||||
};
|
};
|
||||||
template<class TY, class TYPES, size_t i>
|
template<class TY, class TYPES, size_t i>
|
||||||
struct Pick<Node<TY,TYPES>, i>
|
struct Pick<Node<TY,TYPES>, i>
|
||||||
{
|
{
|
||||||
typedef typename Pick<TYPES, i-1>::Type Type;
|
using Type = typename Pick<TYPES, i-1>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -75,121 +82,124 @@ namespace meta {
|
||||||
|
|
||||||
/** apply a transformation (template) to each type in the list */
|
/** apply a transformation (template) to each type in the list */
|
||||||
template<class TY, template<class> class _TRANS_>
|
template<class TY, template<class> class _TRANS_>
|
||||||
struct Apply { typedef TY List; };
|
struct Apply { using List = TY; };
|
||||||
|
|
||||||
template< class TY, class TYPES
|
template< class TY, class TYPES
|
||||||
, template<class> class _TRANS_
|
, template<class> class _TRANS_
|
||||||
>
|
>
|
||||||
struct Apply<Node<TY,TYPES>, _TRANS_ > { typedef Node< typename _TRANS_<TY>::Type
|
struct Apply<Node<TY,TYPES>, _TRANS_ > { using List = Node< typename _TRANS_<TY>::Type
|
||||||
, typename Apply<TYPES,_TRANS_>::List
|
, typename Apply<TYPES,_TRANS_>::List
|
||||||
> List; };
|
>;};
|
||||||
|
|
||||||
|
|
||||||
/** conditional node: skip an element based on evaluating a predicate */
|
/** conditional node: skip an element based on evaluating a predicate */
|
||||||
template<bool, class T, class TAIL>
|
template<bool, class T, class TAIL>
|
||||||
struct CondNode { typedef TAIL Next; };
|
struct CondNode { using Next = TAIL; };
|
||||||
|
|
||||||
template<class T, class TAIL>
|
template<class T, class TAIL>
|
||||||
struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
|
struct CondNode<true, T, TAIL> { using Next = Node<T,TAIL>; };
|
||||||
|
|
||||||
/** filter away those types which don't fulfil a predicate metafunction */
|
/** filter away those types which don't fulfil a predicate metafunction */
|
||||||
template< class TYPES
|
template< class TYPES
|
||||||
, template<class> class _P_ ///< a template providing a boolean member \c ::value
|
, template<class> class _P_ ///< a template providing a boolean member \c ::value
|
||||||
>
|
>
|
||||||
struct Filter;
|
struct Filter;
|
||||||
|
|
||||||
template<template<class> class _P_>
|
template<template<class> class _P_>
|
||||||
struct Filter<Nil,_P_> { typedef Nil List; };
|
struct Filter<Nil,_P_> { using List = Nil; };
|
||||||
|
|
||||||
template< class TY, class TYPES
|
template< class TY, class TYPES
|
||||||
, template<class> class _P_
|
, template<class> class _P_
|
||||||
>
|
>
|
||||||
struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
|
struct Filter<Node<TY,TYPES>,_P_> { using List = typename CondNode< _P_<TY>::value
|
||||||
, TY
|
, TY
|
||||||
, typename Filter<TYPES,_P_>::List
|
, typename Filter<TYPES,_P_>::List
|
||||||
>::Next
|
>::Next
|
||||||
List; };
|
; };
|
||||||
|
|
||||||
|
|
||||||
/** append lists-of-types */
|
/** append (concatenate) lists-of-types */
|
||||||
template<class TY1, class TY2>
|
template<class TY1, class TY2>
|
||||||
struct Append { typedef Node<TY1, typename Append<TY2,Nil>::List> List; };
|
struct Append { using List = Node<TY1, typename Append<TY2,Nil>::List>; };
|
||||||
|
|
||||||
template< class TY, class TYPES
|
template< class TY, class TYPES
|
||||||
, class TAIL
|
, class TAIL
|
||||||
>
|
>
|
||||||
struct Append<Node<TY,TYPES>, TAIL> { typedef Node<TY, typename Append<TYPES, TAIL>::List> List; };
|
struct Append<Node<TY,TYPES>, TAIL> { using List = Node<TY, typename Append<TYPES, TAIL>::List>; };
|
||||||
|
|
||||||
template<class TY, class TYPES>
|
template<class TY, class TYPES>
|
||||||
struct Append<Nil, Node<TY,TYPES>> { typedef Node<TY,TYPES> List; };
|
struct Append<Nil, Node<TY,TYPES>> { using List = Node<TY,TYPES>; };
|
||||||
|
|
||||||
template<class TY, class TYPES>
|
template<class TY, class TYPES>
|
||||||
struct Append<Node<TY,TYPES>, Nil> { typedef Node<TY,TYPES> List; };
|
struct Append<Node<TY,TYPES>, Nil> { using List = Node<TY,TYPES>; };
|
||||||
|
|
||||||
template<class TY1>
|
template<class TY1>
|
||||||
struct Append<TY1,Nil> { typedef Node<TY1,Nil> List; };
|
struct Append<TY1,Nil> { using List = Node<TY1,Nil>; };
|
||||||
|
|
||||||
template<class TY2>
|
template<class TY2>
|
||||||
struct Append<Nil,TY2> { typedef Node<TY2,Nil> List; };
|
struct Append<Nil,TY2> { using List = Node<TY2,Nil>; };
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Append<Nil,Nil> { typedef Nil List; };
|
struct Append<Nil,Nil> { using List = Nil; };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** access the last list element */
|
/** access the last list element */
|
||||||
template<class TYPES>
|
template<class TYPES>
|
||||||
struct SplitLast;
|
struct PickLast;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct SplitLast<Nil> { typedef Nil Type;
|
struct PickLast<Nil> { using Type = Nil;
|
||||||
typedef Nil List; };
|
using List = Nil; };
|
||||||
template<class TY>
|
template<class TY>
|
||||||
struct SplitLast<Node<TY,Nil>> { typedef TY Type;
|
struct PickLast<Node<TY,Nil>> { using Type = TY;
|
||||||
typedef Nil List; };
|
using List = Nil; };
|
||||||
|
|
||||||
template<class TY, class TYPES>
|
template<class TY, class TYPES>
|
||||||
struct SplitLast<Node<TY,TYPES>> { typedef typename SplitLast<TYPES>::Type Type;
|
struct PickLast<Node<TY,TYPES>> { using Type = typename PickLast<TYPES>::Type;
|
||||||
typedef typename Append< TY,
|
using List = typename Append< TY
|
||||||
typename SplitLast<TYPES>::List
|
, typename PickLast<TYPES>::List
|
||||||
>::List
|
>::List
|
||||||
List; };
|
; };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* splice a typelist like an overlay
|
* splice some typelist like an overlay
|
||||||
* into an base typelist, starting at given index.
|
* into a base typelist, starting at given index.
|
||||||
* @return either the combined (spliced) List, or
|
* @return either the combined (spliced) List, or
|
||||||
* the Front/Back part before or after the Overlay
|
* the Front/Back part before or after the Overlay
|
||||||
* @note using a Nil as OVERLAY allows to extract
|
* @remark can be used to _exchange_ some elements in a list,
|
||||||
|
* without shifting the position of the other ones.
|
||||||
|
* @note using a Nil-type as OVERLAY allows to extract
|
||||||
* an arbitrary Front/Back part of the list
|
* an arbitrary Front/Back part of the list
|
||||||
*/
|
*/
|
||||||
template<class BASE, class OVERLAY, uint i=0>
|
template<class BASE, class OVERLAY, uint i=0>
|
||||||
struct Splice;
|
struct Splice;
|
||||||
|
|
||||||
template<class B, class BS,
|
template<class B, class BS,
|
||||||
class OVERLAY, uint i>
|
class OVERLAY,
|
||||||
struct Splice<Node<B,BS>, OVERLAY, i> { typedef Node<B, typename Splice<BS, OVERLAY, i-1>::List> List;
|
uint i>
|
||||||
typedef Node<B, typename Splice<BS, OVERLAY, i-1>::Front> Front;
|
struct Splice<Node<B,BS>, OVERLAY, i> { using List = Node<B, typename Splice<BS, OVERLAY, i-1>::List>;
|
||||||
typedef typename Splice<BS, OVERLAY, i-1>::Back Back; };
|
using Front = Node<B, typename Splice<BS, OVERLAY, i-1>::Front>;
|
||||||
|
using Back = typename Splice<BS, OVERLAY, i-1>::Back; };
|
||||||
|
|
||||||
template<class B, class BS,
|
template<class B, class BS,
|
||||||
class O, class OS >
|
class O, class OS >
|
||||||
struct Splice<Node<B,BS>,Node<O,OS>,0> { typedef Node<O, typename Splice<BS,OS, 0>::List> List;
|
struct Splice<Node<B,BS>,Node<O,OS>,0> { using List = Node<O, typename Splice<BS,OS, 0>::List>;
|
||||||
typedef Nil Front;
|
using Front = Nil;
|
||||||
typedef typename Splice<BS,OS, 0>::Back Back; };
|
using Back = typename Splice<BS,OS, 0>::Back; };
|
||||||
|
|
||||||
template<class B, class BS>
|
template<class B, class BS>
|
||||||
struct Splice<Node<B,BS>, Nil, 0> { typedef Node<B, BS> List;
|
struct Splice<Node<B,BS>, Nil, 0> { using List = Node<B, BS>;
|
||||||
typedef Nil Front;
|
using Front = Nil;
|
||||||
typedef Node<B, BS> Back; };
|
using Back = Node<B, BS>; };
|
||||||
|
|
||||||
template<class XX, uint i>
|
template<class XX, uint i>
|
||||||
struct Splice<Nil, XX, i> { typedef Nil List;
|
struct Splice<Nil, XX, i> { using List = Nil;
|
||||||
typedef Nil Front;
|
using Front = Nil;
|
||||||
typedef Nil Back; };
|
using Back = Nil; };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -204,49 +214,49 @@ namespace meta {
|
||||||
template<class T, class TYPES>
|
template<class T, class TYPES>
|
||||||
struct Dissect<Node<T,TYPES>>
|
struct Dissect<Node<T,TYPES>>
|
||||||
{
|
{
|
||||||
typedef Node<T,TYPES> List; ///< the complete list
|
using List = Node<T,TYPES>; ///< the complete list
|
||||||
typedef T Head; ///< first element
|
using Head = T; ///< first element
|
||||||
typedef Node<T,Nil> First; ///< a list containing the first element
|
using First = Node<T,Nil>; ///< a list containing the first element
|
||||||
typedef TYPES Tail; ///< remainder of the list starting with the second elm.
|
using Tail = TYPES; ///< remainder of the list starting with the second elm.
|
||||||
typedef typename SplitLast<List>::List Prefix;///< all of the list, up to but excluding the last element
|
using Prefix = typename PickLast<List>::List; ///< all of the list, up to but excluding the last element
|
||||||
typedef typename SplitLast<List>::Type End; ///< the last element
|
using End = typename PickLast<List>::Type; ///< the last element
|
||||||
typedef Node<End,Nil> Last; ///< a list containing the last element
|
using Last = Node<End,Nil>; ///< a list containing the last element
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Dissect<Nil>
|
struct Dissect<Nil>
|
||||||
{
|
{
|
||||||
typedef Nil List;
|
using List = Nil;
|
||||||
typedef Nil Head;
|
using Head = Nil;
|
||||||
typedef Nil First;
|
using First = Nil;
|
||||||
typedef Nil Tail;
|
using Tail = Nil;
|
||||||
typedef Nil Prefix;
|
using Prefix = Nil;
|
||||||
typedef Nil End;
|
using End = Nil;
|
||||||
typedef Nil Last;
|
using Last = Nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prefix each of the elements,
|
* prefix each of the elements,
|
||||||
* yielding a list-of lists-of-types
|
* yielding a list-of lists-of-types
|
||||||
*/
|
*/
|
||||||
template<class T, class TY>
|
template<class T, class TY>
|
||||||
struct PrefixAll { typedef Node< typename Append<T,TY>::List, Nil> List; };
|
struct PrefixAll { using List = Node< typename Append<T,TY>::List, Nil>; };
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct PrefixAll<T, Nil> { typedef Nil List; };
|
struct PrefixAll<T, Nil> { using List = Nil; };
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct PrefixAll<T, NilNode> { typedef Node< typename Append<T, NilNode>::List, Nil> List; };
|
struct PrefixAll<T, NilNode> { using List = Node< typename Append<T, NilNode>::List, Nil>; };
|
||||||
|
|
||||||
template< class T
|
template< class T
|
||||||
, class TY, class TYPES
|
, class TY, class TYPES
|
||||||
>
|
>
|
||||||
struct PrefixAll<T, Node<TY,TYPES>> { typedef Node< typename Append<T,TY>::List
|
struct PrefixAll<T, Node<TY,TYPES>> { using List = Node< typename Append<T,TY>::List
|
||||||
, typename PrefixAll<T,TYPES>::List
|
, typename PrefixAll<T,TYPES>::List
|
||||||
> List; };
|
>;};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -258,61 +268,65 @@ namespace meta {
|
||||||
* sources, i.e. the Cartesian product.
|
* sources, i.e. the Cartesian product.
|
||||||
*/
|
*/
|
||||||
template<class TY1,class TY2>
|
template<class TY1,class TY2>
|
||||||
struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
|
struct Distribute { using List = typename PrefixAll<TY1,TY2>::List; };
|
||||||
|
|
||||||
template<class TY>
|
template<class TY>
|
||||||
struct Distribute<Nil,TY> { typedef Nil List; };
|
struct Distribute<Nil,TY> { using List = Nil; };
|
||||||
|
|
||||||
template< class TY, class TYPES
|
template< class TY, class TYPES
|
||||||
, class TAIL
|
, class TAIL
|
||||||
>
|
>
|
||||||
struct Distribute<Node<TY,TYPES>,TAIL> { typedef typename Append< typename PrefixAll<TY,TAIL>::List
|
struct Distribute<Node<TY,TYPES>,TAIL> { using List = typename Append< typename PrefixAll<TY,TAIL>::List
|
||||||
, typename Distribute<TYPES,TAIL>::List
|
, typename Distribute<TYPES,TAIL>::List
|
||||||
>::List
|
>::List
|
||||||
List; };
|
; };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* build all possible combinations, based on a enumeration of the basic cases.
|
* Build all possible combinations, based on a enumeration of the basic cases.
|
||||||
* For each of the types in the argument list, an "enumeration generator" template is invoked,
|
* For each of the types in the argument list, an "enumeration generator" template is invoked,
|
||||||
* yielding a list of the possible base cases. These base cases are then combined with all the
|
* to produce a list of the possible base cases. These base cases are then combined with all the
|
||||||
* combinations of the rest, yielding all ordered combinations of all cases. Here, "ordered"
|
* combinations of the rest, yielding all ordered combinations of all cases. Here, "ordered"
|
||||||
* means that the base cases of the n-th element will appear in the n-th position of the
|
* means that the base cases of the n-th element will appear in the n-th position of the
|
||||||
* resulting lists,
|
* resulting lists,
|
||||||
*
|
* @tparam X a type or type list to drive the tabulation process
|
||||||
* For the typical example, the "base cases" are {flag(on), flag(off)}, so we get a
|
* @tparam _ENUM_ a case generator meta function, which takes one type from the input(list)
|
||||||
* list-of-lists, featuring all possibilities to combine these distinct toggles.
|
* and generates a type-list of cases, which are then feed to `Distribute`
|
||||||
|
* @remark For the typical example, the "base cases" are {flag(on), flag(off)}, so we get a
|
||||||
|
* list-of-lists, featuring all possibilities to combine these distinct toggles.
|
||||||
*/
|
*/
|
||||||
template< class X
|
template< class X
|
||||||
, template<class> class _ENUM_>
|
, template<class> class _ENUM_>
|
||||||
struct Combine { typedef typename Distribute< typename _ENUM_<X>::List
|
struct Combine { using List = typename Distribute< typename _ENUM_<X>::List
|
||||||
, Node<Nil,Nil>
|
, NilNode
|
||||||
>::List List; };
|
>::List; };
|
||||||
template< template<class> class _ENUM_>
|
template< template<class> class _ENUM_>
|
||||||
struct Combine<Nil, _ENUM_ > { typedef NilNode List; };
|
struct Combine<Nil, _ENUM_ > { using List = NilNode; };
|
||||||
|
|
||||||
template< class TY, class TYPES
|
template< class TY, class TYPES
|
||||||
, template<class> class _ENUM_>
|
, template<class> class _ENUM_>
|
||||||
struct Combine<Node<TY,TYPES>,_ENUM_> { typedef typename Distribute< typename _ENUM_<TY>::List
|
struct Combine<Node<TY,TYPES>,_ENUM_> { using List = typename Distribute< typename _ENUM_<TY>::List
|
||||||
, typename Combine<TYPES,_ENUM_>::List
|
, typename Combine<TYPES,_ENUM_>::List
|
||||||
>::List List; };
|
>::List; };
|
||||||
|
|
||||||
/** enumeration generator for the Combine metafunction,
|
/** enumeration generator for the Combine metafunction,
|
||||||
* yielding an "on" and "off" case
|
* yielding an "on" and "off" case; the latter is
|
||||||
|
* represented by a list with a Nil-Entry
|
||||||
*/
|
*/
|
||||||
template<class F>
|
template<class F>
|
||||||
struct FlagOnOff
|
struct FlagOnOff
|
||||||
{
|
{
|
||||||
typedef Node<F, Node<Nil,Nil>> List;
|
using List = Node<F, NilNode>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** generate all possible on-off combinations of the given flags */
|
/** generate all possible on-off combinations of the given flags.
|
||||||
|
* @remark for the «off» case, the flag entry is not present */
|
||||||
template<class FLAGS>
|
template<class FLAGS>
|
||||||
struct CombineFlags
|
struct CombineFlags
|
||||||
{
|
{
|
||||||
typedef typename Combine<FLAGS, FlagOnOff>::List List;
|
using List = typename Combine<FLAGS, FlagOnOff>::List;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,11 +250,11 @@ namespace meta {
|
||||||
|
|
||||||
// for finding the end we need the help of typelist-util.hpp
|
// for finding the end we need the help of typelist-util.hpp
|
||||||
|
|
||||||
using PrefixList = typename SplitLast<List>::List;
|
using PrefixList = typename PickLast<List>::List;
|
||||||
using TailList = typename Tail::List;
|
using TailList = typename Tail::List;
|
||||||
|
|
||||||
using Prefix = typename TySeq<PrefixList>::Seq;
|
using Prefix = typename TySeq<PrefixList>::Seq;
|
||||||
using End = typename SplitLast<List>::Type;
|
using End = typename PickLast<List>::Type;
|
||||||
using Last = TySeq<End>;
|
using Last = TySeq<End>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -320,11 +320,11 @@ namespace meta {
|
||||||
|
|
||||||
// for finding the end we need the help of typelist-util.hpp
|
// for finding the end we need the help of typelist-util.hpp
|
||||||
|
|
||||||
typedef typename SplitLast<List>::List PrefixList;
|
typedef typename PickLast<List>::List PrefixList;
|
||||||
typedef typename Tail::List TailList;
|
typedef typename Tail::List TailList;
|
||||||
|
|
||||||
typedef typename TyOLD<PrefixList>::Seq Prefix;
|
typedef typename TyOLD<PrefixList>::Seq Prefix;
|
||||||
typedef typename SplitLast<List>::Type End;
|
typedef typename PickLast<List>::Type End;
|
||||||
typedef TyOLD<End> Last;
|
typedef TyOLD<End> Last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace control {
|
||||||
using lib::meta::_Fun;
|
using lib::meta::_Fun;
|
||||||
using lib::meta::TyOLD;
|
using lib::meta::TyOLD;
|
||||||
using lib::meta::Append;
|
using lib::meta::Append;
|
||||||
using lib::meta::SplitLast;
|
using lib::meta::PickLast;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,8 +130,8 @@ namespace control {
|
||||||
{
|
{
|
||||||
using Args = typename ARG::List;
|
using Args = typename ARG::List;
|
||||||
|
|
||||||
using Memento = typename SplitLast<Args>::Type;
|
using Memento = typename PickLast<Args>::Type;
|
||||||
using OperationArglist = typename SplitLast<Args>::List;
|
using OperationArglist = typename PickLast<Args>::List;
|
||||||
using OperationArgs = typename TyOLD<OperationArglist>::Seq;
|
using OperationArgs = typename TyOLD<OperationArglist>::Seq;
|
||||||
|
|
||||||
using OperateSig = typename BuildFunType<void, OperationArgs>::Sig;
|
using OperateSig = typename BuildFunType<void, OperationArgs>::Sig;
|
||||||
|
|
|
||||||
|
|
@ -370,133 +370,6 @@ END
|
||||||
TEST "Typelist manipulation" TypeListManip_test <<END
|
TEST "Typelist manipulation" TypeListManip_test <<END
|
||||||
out-lit: List1 :-<1>-<2>-<3>-
|
out-lit: List1 :-<1>-<2>-<3>-
|
||||||
out-lit: List2 :-<5>-<6>-<7>-
|
out-lit: List2 :-<5>-<6>-<7>-
|
||||||
out-lit: Added2 :-<3>-<4>-<5>-
|
|
||||||
out-lit: FilterEven :-<2>-<6>-
|
|
||||||
out-lit: Append1 :-
|
|
||||||
out-lit: Append2 :-<11>-<22>-
|
|
||||||
out-lit: Append3 :-<111>-
|
|
||||||
out-lit: Append4 :-<222>-
|
|
||||||
out-lit: Append5 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Append6 :-<5>-<6>-<7>-
|
|
||||||
out-lit: Append7 :-<111>-<5>-<6>-<7>-
|
|
||||||
out-lit: Append8 :-<1>-<2>-<3>-<222>-
|
|
||||||
out-lit: Append9 :-<1>-<2>-<3>-<5>-<6>-<7>-
|
|
||||||
out-lit: Overl01 :-
|
|
||||||
out-lit: Overl02 :-
|
|
||||||
out-lit: Overl03 :-
|
|
||||||
out-lit: Overl04 :-<9>-<8>-<3>-
|
|
||||||
out-lit: Overl05 :-<1>-<9>-<8>-
|
|
||||||
out-lit: Overl06 :-<1>-<2>-<9>-
|
|
||||||
out-lit: Overl07 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Overl08 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Overl09 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Overl10 :-<1>-<1>-<2>-
|
|
||||||
out-lit: Overl11 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Overl12 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Overl13 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Front1 :-
|
|
||||||
out-lit: Front2 :-<1>-
|
|
||||||
out-lit: Front3 :-<1>-<2>-<3>-
|
|
||||||
out-lit: Back1 :-<2>-<3>-
|
|
||||||
out-lit: Back2 :-<3>-
|
|
||||||
out-lit: Back3 :-
|
|
||||||
out-lit: Front4 :-<1>-
|
|
||||||
out-lit: Back4 :-<2>-<3>-
|
|
||||||
out-lit: Prefix :-<1>-<2>-
|
|
||||||
out-lit: ElmL :-<3>-
|
|
||||||
out-lit: NPrefix :-
|
|
||||||
out-lit: Types<Elm1> :-<3>-
|
|
||||||
out-lit: NList :-
|
|
||||||
out-lit: Types<Nil> :-
|
|
||||||
out-lit: LL :-<1>-<2>-<3>-<5>-<6>-<7>-
|
|
||||||
out-lit: List :-<1>-<2>-<3>-<5>-<6>-<7>-
|
|
||||||
out-lit: First :-<1>-
|
|
||||||
out-lit: Tail :-<2>-<3>-<5>-<6>-<7>-
|
|
||||||
out-lit: Prefix :-<1>-<2>-<3>-<5>-<6>-
|
|
||||||
out-lit: Last :-<7>-
|
|
||||||
out-lit: HeadEnd :-<1>-<7>-
|
|
||||||
out-lit: Prefix1 :
|
|
||||||
out-lit: +---<11>-<22>-+-
|
|
||||||
out-lit: Prefix2 :
|
|
||||||
out-lit: +---<101>-<1>-+
|
|
||||||
out-lit: +---<101>-<2>-+
|
|
||||||
out-lit: +---<101>-<3>-+-
|
|
||||||
out-lit: Prefix3 :
|
|
||||||
out-lit: +---<1>-+
|
|
||||||
out-lit: +---<2>-+
|
|
||||||
out-lit: +---<3>-+-
|
|
||||||
out-lit: Prefix4 :
|
|
||||||
out-lit: +---<111>-<1>-<2>-<3>-+
|
|
||||||
out-lit: +---<111>-<0>-+
|
|
||||||
out-lit: +---<111>-<5>-<6>-<7>-+-
|
|
||||||
out-lit: Prefix5 :
|
|
||||||
out-lit: +---<1>-<2>-<3>-<5>-+
|
|
||||||
out-lit: +---<1>-<2>-<3>-<6>-+
|
|
||||||
out-lit: +---<1>-<2>-<3>-<7>-+-
|
|
||||||
out-lit: Prefix6 :
|
|
||||||
out-lit: +---<1>-<2>-<3>-<1>-<2>-<3>-+
|
|
||||||
out-lit: +---<1>-<2>-<3>-<0>-+
|
|
||||||
out-lit: +---<1>-<2>-<3>-<5>-<6>-<7>-+-
|
|
||||||
out-lit: Dist1 :
|
|
||||||
out-lit: +---<11>-<1>-+
|
|
||||||
out-lit: +---<11>-<2>-+
|
|
||||||
out-lit: +---<11>-<3>-+-
|
|
||||||
out-lit: Dist2 :
|
|
||||||
out-lit: +---<11>-<0>-+
|
|
||||||
out-lit: +---<22>-<0>-+
|
|
||||||
out-lit: +---<33>-<0>-+-
|
|
||||||
out-lit: Dist3 :
|
|
||||||
out-lit: +---<11>-<1>-+
|
|
||||||
out-lit: +---<11>-<2>-+
|
|
||||||
out-lit: +---<11>-<3>-+
|
|
||||||
out-lit: +---<22>-<1>-+
|
|
||||||
out-lit: +---<22>-<2>-+
|
|
||||||
out-lit: +---<22>-<3>-+
|
|
||||||
out-lit: +---<33>-<1>-+
|
|
||||||
out-lit: +---<33>-<2>-+
|
|
||||||
out-lit: +---<33>-<3>-+-
|
|
||||||
out-lit: Dist4 :
|
|
||||||
out-lit: +---<11>-<1>-<2>-<3>-+
|
|
||||||
out-lit: +---<11>-<5>-<6>-<7>-+
|
|
||||||
out-lit: +---<22>-<1>-<2>-<3>-+
|
|
||||||
out-lit: +---<22>-<5>-<6>-<7>-+
|
|
||||||
out-lit: +---<33>-<1>-<2>-<3>-+
|
|
||||||
out-lit: +---<33>-<5>-<6>-<7>-+-
|
|
||||||
out-lit: Down :-<11>-<10>-<9>-<8>-<7>-<6>-<5>-<4>-<3>-<2>-<1>-<0>-
|
|
||||||
out-lit: Combi :
|
|
||||||
out-lit: +---<1>-<2>-<3>-<·>-+
|
|
||||||
out-lit: +---<1>-<2>-<2>-<·>-+
|
|
||||||
out-lit: +---<1>-<2>-<1>-<·>-+
|
|
||||||
out-lit: +---<1>-<2>-<0>-<·>-+
|
|
||||||
out-lit: +---<1>-<1>-<3>-<·>-+
|
|
||||||
out-lit: +---<1>-<1>-<2>-<·>-+
|
|
||||||
out-lit: +---<1>-<1>-<1>-<·>-+
|
|
||||||
out-lit: +---<1>-<1>-<0>-<·>-+
|
|
||||||
out-lit: +---<1>-<0>-<3>-<·>-+
|
|
||||||
out-lit: +---<1>-<0>-<2>-<·>-+
|
|
||||||
out-lit: +---<1>-<0>-<1>-<·>-+
|
|
||||||
out-lit: +---<1>-<0>-<0>-<·>-+
|
|
||||||
out-lit: +---<0>-<2>-<3>-<·>-+
|
|
||||||
out-lit: +---<0>-<2>-<2>-<·>-+
|
|
||||||
out-lit: +---<0>-<2>-<1>-<·>-+
|
|
||||||
out-lit: +---<0>-<2>-<0>-<·>-+
|
|
||||||
out-lit: +---<0>-<1>-<3>-<·>-+
|
|
||||||
out-lit: +---<0>-<1>-<2>-<·>-+
|
|
||||||
out-lit: +---<0>-<1>-<1>-<·>-+
|
|
||||||
out-lit: +---<0>-<1>-<0>-<·>-+
|
|
||||||
out-lit: +---<0>-<0>-<3>-<·>-+
|
|
||||||
out-lit: +---<0>-<0>-<2>-<·>-+
|
|
||||||
out-lit: +---<0>-<0>-<1>-<·>-+
|
|
||||||
out-lit: +---<0>-<0>-<0>-<·>-+-
|
|
||||||
out-lit: OnOff :
|
|
||||||
out-lit: +---<1>-<2>-<3>-<·>-+
|
|
||||||
out-lit: +---<1>-<2>-<·>-+
|
|
||||||
out-lit: +---<1>-<3>-<·>-+
|
|
||||||
out-lit: +---<1>-<·>-+
|
|
||||||
out-lit: +---<2>-<3>-<·>-+
|
|
||||||
out-lit: +---<2>-<·>-+
|
|
||||||
out-lit: +---<3>-<·>-+
|
|
||||||
out-lit: +---<·>-+-
|
|
||||||
return: 0
|
return: 0
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ namespace test {
|
||||||
using DumpPrinter = InstantiateChained<TypeList, Printer, NullP>;
|
using DumpPrinter = InstantiateChained<TypeList, Printer, NullP>;
|
||||||
|
|
||||||
return "TUPLE"
|
return "TUPLE"
|
||||||
+ DumpPrinter::print();
|
+ DumpPrinter::show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// see the macros DISPLAY and DUMPVAL defined in typelist-diagnostics.hpp
|
// see the macros DISPLAY and DUMPVAL defined in typelist-diagnostics.hpp
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
** a Printer template usable for debugging the structure of a typelist built
|
** a Printer template usable for debugging the structure of a typelist built
|
||||||
** upon some simple debugging-style types. Examples being a Num<int> template,
|
** upon some simple debugging-style types. Examples being a Num<int> template,
|
||||||
** or the Flag type. A Printer type generated from this template provides
|
** or the Flag type. A Printer type generated from this template provides
|
||||||
** a static \c print() function. The string returned from this function
|
** a static `show()` function. The string returned from this function
|
||||||
** visualises the structure of the typelist provided as parameter
|
** visualises the structure of the typelist provided as parameter
|
||||||
** to the Printer template.
|
** to the Printer template.
|
||||||
**
|
**
|
||||||
|
|
@ -30,21 +30,21 @@
|
||||||
#define META_TYPELIST_DIAGNOSTICS_H
|
#define META_TYPELIST_DIAGNOSTICS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "lib/test/test-helper.hpp"
|
||||||
#include "lib/meta/typelist.hpp"
|
#include "lib/meta/typelist.hpp"
|
||||||
#include "lib/meta/generator.hpp"
|
#include "lib/meta/generator.hpp"
|
||||||
#include "lib/format-string.hpp"
|
#include "lib/format-string.hpp"
|
||||||
#include "lib/format-cout.hpp"
|
#include "lib/format-cout.hpp"
|
||||||
#include "lib/meta/util.hpp"
|
#include "lib/meta/util.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace meta {
|
namespace meta {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
|
||||||
/** dummy interface / baseclass for diagnostics */
|
/** dummy interface / baseclass for diagnostics */
|
||||||
struct Numz
|
struct Numz
|
||||||
{
|
{
|
||||||
|
|
@ -80,9 +80,9 @@ namespace meta {
|
||||||
|
|
||||||
|
|
||||||
/** helper for generating test lists */
|
/** helper for generating test lists */
|
||||||
template<class X> struct CountDown { typedef Nil List; };
|
template<class X> struct CountDown { using List = Nil; };
|
||||||
template<> struct CountDown<Num<0>> { typedef Node<Num<0>, Nil> List; };
|
template<> struct CountDown<Num<0>> { using List = Node<Num<0>, Nil>; };
|
||||||
template<int I> struct CountDown<Num<I>> { typedef Node<Num<I>, typename CountDown<Num<I-1>>::List> List; };
|
template<int I> struct CountDown<Num<I>> { using List = Node<Num<I>, typename CountDown<Num<I-1>>::List>; };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ namespace meta {
|
||||||
|
|
||||||
struct NullP
|
struct NullP
|
||||||
{
|
{
|
||||||
static string print () { return "-"; }
|
static string show() { return "-"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** debugging template,
|
/** debugging template,
|
||||||
|
|
@ -105,35 +105,35 @@ namespace meta {
|
||||||
struct Printer
|
struct Printer
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print () { return _Fmt("-<%s>%s") % typeStr<T>() % BASE::print(); }
|
static string show() { return _Fmt("-<%s>%s") % typeStr<T>() % BASE::show(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class BASE>
|
template<class BASE>
|
||||||
struct Printer<Nil, BASE>
|
struct Printer<Nil, BASE>
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print () { return _Fmt("-<%u>%s") % "·" % BASE::print(); }
|
static string show() { return _Fmt("-<%u>%s") % "·" % BASE::show(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class BASE, int I>
|
template<class BASE, int I>
|
||||||
struct Printer<Num<I>, BASE> ///< display the presence of a Num instance in the typelist
|
struct Printer<Num<I>, BASE> ///< display the presence of a Num instance in the typelist
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print () { return _Fmt("-<%u>%s") % uint(Num<I>::VAL) % BASE::print(); }
|
static string show() { return _Fmt("-<%u>%s") % uint(Num<I>::VAL) % BASE::show(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class BASE, uint Fl>
|
template<class BASE, uint Fl>
|
||||||
struct Printer<Flag<Fl>, BASE> ///< display the presence of a Flag in the typelist
|
struct Printer<Flag<Fl>, BASE> ///< display the presence of a Flag in the typelist
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print () { return _Fmt("-<%u>%s") % uint(Fl) % BASE::print(); }
|
static string show() { return _Fmt("-<%u>%s") % uint(Fl) % BASE::show(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class BASE>
|
template<class BASE>
|
||||||
struct Printer<int, BASE> ///< display the presence of a plain int in the typelist
|
struct Printer<int, BASE> ///< display the presence of a plain int in the typelist
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print () { return _Fmt("-<%u>%s") % 'i' % BASE::print(); }
|
static string show() { return _Fmt("-<%u>%s") % 'i' % BASE::show(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -145,7 +145,7 @@ namespace meta {
|
||||||
printSublist ()
|
printSublist ()
|
||||||
{
|
{
|
||||||
typedef InstantiateChained<L, Printer, NullP> SubList;
|
typedef InstantiateChained<L, Printer, NullP> SubList;
|
||||||
return SubList::print();
|
return SubList::show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Specialisation for debug-printing of a nested sublist */
|
/** Specialisation for debug-printing of a nested sublist */
|
||||||
|
|
@ -153,11 +153,11 @@ namespace meta {
|
||||||
struct Printer<Node<TY,TYPES>, BASE>
|
struct Printer<Node<TY,TYPES>, BASE>
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print ()
|
static string show()
|
||||||
{
|
{
|
||||||
typedef Node<TY,TYPES> List;
|
typedef Node<TY,TYPES> List;
|
||||||
return string("\n\t+--") + printSublist<List>()+"+"
|
return string("\n\t+--") + printSublist<List>()+"+"
|
||||||
+ BASE::print();
|
+ BASE::show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -165,11 +165,11 @@ namespace meta {
|
||||||
struct Printer<Config<f1,f2,f3,f4,f5>, BASE>
|
struct Printer<Config<f1,f2,f3,f4,f5>, BASE>
|
||||||
: BASE
|
: BASE
|
||||||
{
|
{
|
||||||
static string print ()
|
static string show()
|
||||||
{
|
{
|
||||||
typedef typename Config<f1,f2,f3,f4,f5>::Flags FlagList;
|
typedef typename Config<f1,f2,f3,f4,f5>::Flags FlagList;
|
||||||
return string("\n\t+-Conf-[") + printSublist<FlagList>()+"]"
|
return string("\n\t+-Conf-[") + printSublist<FlagList>()+"]"
|
||||||
+ BASE::print();
|
+ BASE::show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -185,20 +185,25 @@ namespace meta {
|
||||||
showType ()
|
showType ()
|
||||||
{
|
{
|
||||||
typedef InstantiateChained<typename TYPES::List, Printer, NullP> DumpPrinter;
|
typedef InstantiateChained<typename TYPES::List, Printer, NullP> DumpPrinter;
|
||||||
return DumpPrinter::print();
|
return DumpPrinter::show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: we define overloads of this function for other types, especially Tuples
|
// Note: we define overloads of this function for other types, especially Tuples
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ================= convenience macro notation ================= */
|
||||||
|
|
||||||
#define DISPLAY(_IT_) \
|
#define DISPLAY(_IT_) \
|
||||||
cout << STRINGIFY(_IT_) << "\t:" << showType<_IT_>() << endl;
|
cout << STRINGIFY(_IT_) << "\t:" << showType<_IT_>() << endl;
|
||||||
|
|
||||||
#define DUMPVAL(_IT_) \
|
#define DUMPVAL(_IT_) \
|
||||||
cout << STRINGIFY(_IT_) << "\t:" << util::toString(_IT_) << endl;
|
cout << STRINGIFY(_IT_) << "\t:" << util::toString(_IT_) << endl;
|
||||||
|
|
||||||
|
#define EXPECT(_TY_, RENDERED_STRUCTURE ) \
|
||||||
|
CHECK (showType<_TY_>() == RENDERED_STRUCTURE ## _expect)
|
||||||
|
|
||||||
|
|
||||||
}}} // namespace lib::meta::test
|
}}} // namespace lib::meta::test
|
||||||
|
|
|
||||||
|
|
@ -33,30 +33,24 @@
|
||||||
#include "lib/meta/generator.hpp"
|
#include "lib/meta/generator.hpp"
|
||||||
#include "lib/meta/typelist-manip.hpp"
|
#include "lib/meta/typelist-manip.hpp"
|
||||||
#include "meta/typelist-diagnostics.hpp"
|
#include "meta/typelist-diagnostics.hpp"
|
||||||
|
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using ::test::Test;
|
|
||||||
using std::is_same;
|
using std::is_same;
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace meta {
|
namespace meta {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
|
namespace { // type-lists to test with
|
||||||
namespace { // test data
|
|
||||||
|
|
||||||
|
typedef TySeq< Num<1>
|
||||||
|
|
||||||
typedef TyOLD< Num<1>
|
|
||||||
, Num<2>
|
, Num<2>
|
||||||
, Num<3>
|
, Num<3>
|
||||||
>::List List1;
|
>::List List1;
|
||||||
typedef TyOLD< Num<5>
|
typedef TySeq< Num<5>
|
||||||
, Num<6>
|
, Num<6>
|
||||||
, Num<7>
|
, Num<7>
|
||||||
>::List List2;
|
>::List List2;
|
||||||
|
|
@ -85,28 +79,29 @@ namespace test {
|
||||||
class TypeListManip_test : public Test
|
class TypeListManip_test : public Test
|
||||||
{
|
{
|
||||||
virtual void
|
virtual void
|
||||||
run (Arg)
|
run (Arg)
|
||||||
{
|
{
|
||||||
check_diagnostics ();
|
demonstrate_diagnostics();
|
||||||
check_pick_elm ();
|
verify_pick ();
|
||||||
check_apply ();
|
verify_last ();
|
||||||
check_filter ();
|
verify_append ();
|
||||||
check_append ();
|
verify_splice ();
|
||||||
check_splice ();
|
verify_dissect();
|
||||||
check_s_last ();
|
verify_apply ();
|
||||||
check_dissect();
|
verify_filter ();
|
||||||
check_prefix ();
|
verify_prefix ();
|
||||||
check_distribute();
|
verify_distribute();
|
||||||
check_combine();
|
verify_combine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @test can print the type list structure for diagnostic */
|
||||||
void
|
void
|
||||||
check_diagnostics ()
|
demonstrate_diagnostics ()
|
||||||
{
|
{
|
||||||
// Explanation: the DISPLAY macro results in the following definition....
|
// Explanation: the DISPLAY macro results in the following definition....
|
||||||
typedef InstantiateChained<List1::List, Printer, NullP > Contents_List1;
|
typedef InstantiateChained<List1::List, Printer, NullP > Contents_List1;
|
||||||
cout << "List1" << "\t:" << Contents_List1::print() << endl;
|
cout << "List1" << "\t:" << Contents_List1::show() << endl;
|
||||||
|
|
||||||
// That is: we instantiate the "Printer" template for each of the types in List1,
|
// That is: we instantiate the "Printer" template for each of the types in List1,
|
||||||
// forming an inheritance chain. I.e. the defined Type "Contents_List1" inherits
|
// forming an inheritance chain. I.e. the defined Type "Contents_List1" inherits
|
||||||
|
|
@ -114,171 +109,147 @@ namespace test {
|
||||||
// The print() function is defined to create a string showing each.
|
// The print() function is defined to create a string showing each.
|
||||||
|
|
||||||
DISPLAY (List2);
|
DISPLAY (List2);
|
||||||
|
|
||||||
|
// Furthermore, we use verification against lib::test::ExpectString,
|
||||||
|
// which can be given as literal "some text"_expect, to document and
|
||||||
|
// verify that the rendered type structure is indeed as expected
|
||||||
|
CHECK (showType<List1>() == "-<1>-<2>-<3>-"_expect);
|
||||||
|
|
||||||
|
EXPECT (List2, "-<5>-<6>-<7>-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @test pick a type by index from a type list */
|
||||||
void
|
void
|
||||||
check_pick_elm ()
|
verify_pick ()
|
||||||
{
|
{
|
||||||
Pick<List2,0>::Type e0;
|
using E0 = Pick<List2,0>::Type;
|
||||||
Pick<List2,1>::Type e1;
|
using E1 = Pick<List2,1>::Type;
|
||||||
Pick<List2,2>::Type e2;
|
using E2 = Pick<List2,2>::Type;
|
||||||
|
|
||||||
using E3 = Pick<List2,3>::Type;
|
using E3 = Pick<List2,3>::Type;
|
||||||
using NilE = Pick<Nil, 23>::Type;
|
using NilE = Pick<Nil, 23>::Type;
|
||||||
using Irrelevant = Pick<void*,456>::Type;
|
using Bull = Pick<void*,456>::Type;
|
||||||
|
using Shit = Pick<string,0>::Type;
|
||||||
|
|
||||||
|
CHECK ((is_same<E0, Num<5> >() ));
|
||||||
|
CHECK ((is_same<E1, Num<6> >() ));
|
||||||
|
CHECK ((is_same<E2, Num<7> >() ));
|
||||||
|
|
||||||
|
CHECK ((is_same<E3, Nil >() ));
|
||||||
|
CHECK ((is_same<NilE, Nil >() ));
|
||||||
|
CHECK ((is_same<Bull, Nil >() ));
|
||||||
|
CHECK ((is_same<Shit, Nil >() ));
|
||||||
|
|
||||||
|
// note: in the end, all this meta-processing yields types,
|
||||||
|
// which can be instantiated and used as if defined directly
|
||||||
|
E0 e0;
|
||||||
|
E1 e1;
|
||||||
|
E2 e2;
|
||||||
CHECK (5 == e0);
|
CHECK (5 == e0);
|
||||||
CHECK (6 == e1);
|
CHECK (6 == e1);
|
||||||
CHECK (7 == e2);
|
CHECK (7 == e2);
|
||||||
|
CHECK (7 == e2.o_);
|
||||||
CHECK ((is_same<Nil, E3> ::value));
|
|
||||||
CHECK ((is_same<Nil, NilE> ::value));
|
|
||||||
CHECK ((is_same<Nil, Irrelevant>::value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
check_append ()
|
verify_last()
|
||||||
{
|
{
|
||||||
using Append1 = Append<Nil, Nil>;
|
using Elm = PickLast<List1>::Type;
|
||||||
DISPLAY (Append1);
|
using Prefix = PickLast<List1>::List;
|
||||||
|
|
||||||
using Append2 = Append<Num<11>,Num<22>>;
|
using ElmL = TySeq<Elm>::List;
|
||||||
DISPLAY (Append2);
|
|
||||||
|
|
||||||
using Append3 = Append<Num<111>,Nil>;
|
EXPECT (Prefix, "-<1>-<2>-");
|
||||||
DISPLAY (Append3);
|
EXPECT (ElmL , "-<3>-" );
|
||||||
|
|
||||||
using Append4 = Append<Nil,Num<222>>;
|
using Elm1 = PickLast<ElmL>::Type;
|
||||||
DISPLAY (Append4);
|
using NPrefix = PickLast<ElmL>::List;
|
||||||
|
|
||||||
using Append5 = Append<List1,Nil>;
|
EXPECT (TySeq<Elm1>, "-<3>-");
|
||||||
DISPLAY (Append5);
|
EXPECT (NPrefix , "-");
|
||||||
|
|
||||||
using Append6 = Append<Nil,List2>;
|
using NilSplit = PickLast<Nil>::Type;
|
||||||
DISPLAY (Append6);
|
using NilList = PickLast<Nil>::List;
|
||||||
|
|
||||||
using Append7 = Append<Num<111>,List2>;
|
EXPECT (TySeq<NilSplit>, "-");
|
||||||
DISPLAY (Append7);
|
EXPECT (NilList , "-");
|
||||||
|
|
||||||
using Append8 = Append<List1,Num<222>>;
|
|
||||||
DISPLAY (Append8);
|
|
||||||
|
|
||||||
using Append9 = Append<List1,List2>;
|
|
||||||
DISPLAY (Append9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @test append and concatenate type lists */
|
||||||
void
|
void
|
||||||
check_splice ()
|
verify_append ()
|
||||||
{
|
{
|
||||||
using OLi = TyOLD<Num<9>,Num<8>>::List;
|
using Append1 = Append<Nil , Nil >; EXPECT (Append1, "-" );
|
||||||
|
using Append2 = Append<Num<11> , Num<22> >; EXPECT (Append2, "-<11>-<22>-" );
|
||||||
|
using Append3 = Append<Num<111>, Nil >; EXPECT (Append3, "-<111>-" );
|
||||||
|
using Append4 = Append<Nil , Num<222>>; EXPECT (Append4, "-<222>-" );
|
||||||
|
using Append5 = Append<List1 , Nil >; EXPECT (Append5, "-<1>-<2>-<3>-" );
|
||||||
|
using Append6 = Append<Nil , List2 >; EXPECT (Append6, "-<5>-<6>-<7>-" );
|
||||||
|
using Append7 = Append<Num<111>, List2 >; EXPECT (Append7, "-<111>-<5>-<6>-<7>-" );
|
||||||
|
using Append8 = Append<List1 , Num<222>>; EXPECT (Append8, "-<1>-<2>-<3>-<222>-" );
|
||||||
|
using Append9 = Append<List1 , List2 >; EXPECT (Append9, "-<1>-<2>-<3>-<5>-<6>-<7>-");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @test splice (or rather paste) a list on top of a base list
|
||||||
|
* @remark the intended use case is to manipulate some parameters
|
||||||
|
* in a given function-type argument list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
verify_splice ()
|
||||||
|
{
|
||||||
|
using OLi = TySeq<Num<9>,Num<8>>::List;
|
||||||
// will "paste" the list OLi "on top" of another Typelist...
|
// will "paste" the list OLi "on top" of another Typelist...
|
||||||
|
|
||||||
using Overl01 = Splice<Nil, Nil>;
|
using Overl01 = Splice<Nil, Nil>; EXPECT (Overl01, "-");
|
||||||
DISPLAY (Overl01);
|
using Overl02 = Splice<Nil, OLi>; EXPECT (Overl02, "-");
|
||||||
|
using Overl03 = Splice<Nil, OLi, 5>; EXPECT (Overl03, "-");
|
||||||
|
using Overl04 = Splice<List1, OLi>; EXPECT (Overl04, "-<9>-<8>-<3>-");
|
||||||
|
using Overl05 = Splice<List1, OLi, 1>; EXPECT (Overl05, "-<1>-<9>-<8>-");
|
||||||
|
using Overl06 = Splice<List1, OLi, 2>; EXPECT (Overl06, "-<1>-<2>-<9>-");
|
||||||
|
using Overl07 = Splice<List1, OLi, 3>; EXPECT (Overl07, "-<1>-<2>-<3>-");
|
||||||
|
using Overl08 = Splice<List1, OLi, 5>; EXPECT (Overl08, "-<1>-<2>-<3>-");
|
||||||
|
using Overl09 = Splice<List1, List1>; EXPECT (Overl09, "-<1>-<2>-<3>-");
|
||||||
|
using Overl10 = Splice<List1, List1, 1>; EXPECT (Overl10, "-<1>-<1>-<2>-");
|
||||||
|
using Overl11 = Splice<List1, Nil>; EXPECT (Overl11, "-<1>-<2>-<3>-");
|
||||||
|
using Overl12 = Splice<List1, Nil, 1>; EXPECT (Overl12, "-<1>-<2>-<3>-");
|
||||||
|
using Overl13 = Splice<List1, Nil, 5>; EXPECT (Overl13, "-<1>-<2>-<3>-");
|
||||||
|
|
||||||
using Overl02 = Splice<Nil, OLi>;
|
using OLi2 = TySeq<Num<99>>::List;
|
||||||
DISPLAY (Overl02);
|
// can retrieve the remaining part of the original list, left and right of splice
|
||||||
|
using Front1 = Splice<List1, OLi2, 0>::Front; EXPECT (Front1, "-" );
|
||||||
using Overl03 = Splice<Nil, OLi, 5>;
|
using Front2 = Splice<List1, OLi2, 1>::Front; EXPECT (Front2, "-<1>-" );
|
||||||
DISPLAY (Overl03);
|
using Front3 = Splice<List1, OLi2, 5>::Front; EXPECT (Front3, "-<1>-<2>-<3>-");
|
||||||
|
using Back1 = Splice<List1, OLi2, 0>::Back; EXPECT (Back1 , "-<2>-<3>-" );
|
||||||
using Overl04 = Splice<List1, OLi>;
|
using Back2 = Splice<List1, OLi2, 1>::Back; EXPECT (Back2 , "-<3>-" );
|
||||||
DISPLAY (Overl04);
|
using Back3 = Splice<List1, OLi2, 5>::Back; EXPECT (Back3 , "-" );
|
||||||
|
|
||||||
using Overl05 = Splice<List1, OLi, 1>;
|
|
||||||
DISPLAY (Overl05);
|
|
||||||
|
|
||||||
using Overl06 = Splice<List1, OLi, 2>;
|
|
||||||
DISPLAY (Overl06);
|
|
||||||
|
|
||||||
using Overl07 = Splice<List1, OLi, 3>;
|
|
||||||
DISPLAY (Overl07);
|
|
||||||
|
|
||||||
using Overl08 = Splice<List1, OLi, 5>;
|
|
||||||
DISPLAY (Overl08);
|
|
||||||
|
|
||||||
using Overl09 = Splice<List1, List1>;
|
|
||||||
DISPLAY (Overl09);
|
|
||||||
|
|
||||||
using Overl10 = Splice<List1, List1, 1>;
|
|
||||||
DISPLAY (Overl10);
|
|
||||||
|
|
||||||
using Overl11 = Splice<List1, Nil>;
|
|
||||||
DISPLAY (Overl11);
|
|
||||||
|
|
||||||
using Overl12 = Splice<List1, Nil, 1>;
|
|
||||||
DISPLAY (Overl12);
|
|
||||||
|
|
||||||
using Overl13 = Splice<List1, Nil, 5>;
|
|
||||||
DISPLAY (Overl13);
|
|
||||||
|
|
||||||
|
|
||||||
using OLi2 = TyOLD<Num<99>>::List;
|
|
||||||
using Front1 = Splice<List1, OLi2, 0>::Front;
|
|
||||||
using Front2 = Splice<List1, OLi2, 1>::Front;
|
|
||||||
using Front3 = Splice<List1, OLi2, 5>::Front;
|
|
||||||
DISPLAY (Front1);
|
|
||||||
DISPLAY (Front2);
|
|
||||||
DISPLAY (Front3);
|
|
||||||
using Back1 = Splice<List1, OLi2, 0>::Back;
|
|
||||||
using Back2 = Splice<List1, OLi2, 1>::Back;
|
|
||||||
using Back3 = Splice<List1, OLi2, 5>::Back;
|
|
||||||
DISPLAY (Back1);
|
|
||||||
DISPLAY (Back2);
|
|
||||||
DISPLAY (Back3);
|
|
||||||
|
|
||||||
// Note: with a Null-Overlay, this can be used to extract arbitrary sublists:
|
// Note: with a Null-Overlay, this can be used to extract arbitrary sublists:
|
||||||
using Front4 = Splice<List1, Nil, 1>::Front;
|
using Front4 = Splice<List1, Nil, 1>::Front; EXPECT (Front4, "-<1>-" );
|
||||||
using Back4 = Splice<List1, Nil, 1>::Back;
|
using Back4 = Splice<List1, Nil, 1>::Back; EXPECT (Back4 , "-<2>-<3>-");
|
||||||
DISPLAY (Front4);
|
|
||||||
DISPLAY (Back4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
check_s_last()
|
|
||||||
{
|
|
||||||
using Elm = SplitLast<List1>::Type;
|
|
||||||
using Prefix = SplitLast<List1>::List;
|
|
||||||
|
|
||||||
using ElmL = TyOLD<Elm>::List;
|
|
||||||
|
|
||||||
DISPLAY (Prefix);
|
|
||||||
DISPLAY (ElmL);
|
|
||||||
|
|
||||||
using Elm1 = SplitLast<ElmL>::Type;
|
|
||||||
using NPrefix = SplitLast<ElmL>::List;
|
|
||||||
|
|
||||||
DISPLAY (NPrefix);
|
|
||||||
DISPLAY (TyOLD<Elm1>);
|
|
||||||
|
|
||||||
using NilSplit = SplitLast<Nil>::Type;
|
|
||||||
using NList = SplitLast<Nil>::List;
|
|
||||||
|
|
||||||
DISPLAY (NList);
|
|
||||||
DISPLAY (TyOLD<NilSplit>);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @test dissect and access front and back parts of a list */
|
||||||
void
|
void
|
||||||
check_dissect()
|
verify_dissect()
|
||||||
{
|
{
|
||||||
typedef Append<List1,List2>::List LL;
|
using LL = Append<List1,List2>::List; EXPECT (LL , "-<1>-<2>-<3>-<5>-<6>-<7>-");
|
||||||
DISPLAY (LL);
|
|
||||||
|
|
||||||
using List = Dissect<LL>::List; DISPLAY(List);
|
using List = Dissect<LL>::List; EXPECT (List , "-<1>-<2>-<3>-<5>-<6>-<7>-");
|
||||||
using First = Dissect<LL>::First; DISPLAY(First);
|
using First = Dissect<LL>::First; EXPECT (First , "-<1>-" );
|
||||||
using Tail = Dissect<LL>::Tail; DISPLAY(Tail);
|
using Tail = Dissect<LL>::Tail; EXPECT (Tail , "-<2>-<3>-<5>-<6>-<7>-" );
|
||||||
using Prefix = Dissect<LL>::Prefix; DISPLAY(Prefix);
|
using Prefix = Dissect<LL>::Prefix; EXPECT (Prefix, "-<1>-<2>-<3>-<5>-<6>-" );
|
||||||
using Last = Dissect<LL>::Last; DISPLAY(Last);
|
using Last = Dissect<LL>::Last; EXPECT (Last , "-<7>-" );
|
||||||
|
|
||||||
using Head = Dissect<LL>::Head;
|
using Head = Dissect<LL>::Head;
|
||||||
using End = Dissect<LL>::End;
|
using End = Dissect<LL>::End;
|
||||||
|
|
||||||
using HeadEnd = TyOLD<Head,End>; DISPLAY(HeadEnd);
|
using HeadEnd = TySeq<Head,End>; EXPECT (HeadEnd, "-<1>-<7>-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -287,80 +258,185 @@ namespace test {
|
||||||
template<class X> struct AddConst2 { typedef X Type; };
|
template<class X> struct AddConst2 { typedef X Type; };
|
||||||
template<int I> struct AddConst2<Num<I>> { typedef Num<I+2> Type; };
|
template<int I> struct AddConst2<Num<I>> { typedef Num<I+2> Type; };
|
||||||
|
|
||||||
|
/** @test apply a _meta-function_ to each type in list */
|
||||||
void
|
void
|
||||||
check_apply ()
|
verify_apply()
|
||||||
{
|
{
|
||||||
using Added2 = Apply<List1, AddConst2>;
|
using Added2 = Apply<List1, AddConst2>;
|
||||||
DISPLAY (Added2);
|
EXPECT (List1 , "-<1>-<2>-<3>-");
|
||||||
|
EXPECT (Added2, "-<3>-<4>-<5>-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class X> struct IsEven { enum {value = false }; };
|
template<class X> struct IsEven { enum {value = false }; };
|
||||||
template<int I> struct IsEven<Num<I>> { enum {value = (0 == I % 2) }; };
|
template<int I> struct IsEven<Num<I>> { enum {value = (0 == I % 2) }; };
|
||||||
|
|
||||||
|
/** @test filter a type list based on a meta-predicate */
|
||||||
void
|
void
|
||||||
check_filter ()
|
verify_filter()
|
||||||
{
|
{
|
||||||
using FilterEven = Filter<Append<List1,List2>::List, IsEven >;
|
CHECK (not IsEven<Num<5>>::value);
|
||||||
DISPLAY (FilterEven);
|
CHECK ( IsEven<Num<6>>::value);
|
||||||
|
|
||||||
|
using FilterEven = Filter<Append<List1,List2>::List, IsEven >;
|
||||||
|
EXPECT (FilterEven, "-<2>-<6>-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @test verify generation of nested lists-of-lists
|
||||||
|
* by distributing the elements from the first list
|
||||||
|
* as prefix-concatenation to the elements of the second list
|
||||||
|
* @note the second list can actually be already a list-of-lists,
|
||||||
|
* allowing to set up quite elaborate generation schemes.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
check_prefix ()
|
verify_prefix ()
|
||||||
{
|
{
|
||||||
using Prefix1 = PrefixAll<Num<11>,Num<22>>;
|
using Prefix1 = PrefixAll<Num<11>,Num<22>>;
|
||||||
DISPLAY (Prefix1);
|
// Note this creates a nested two-dimensional structure,
|
||||||
|
// i.e. a type-list, whose elements are again type-lists.
|
||||||
|
// The diagnostic helper prints each sublist in a new line,
|
||||||
|
// and prefixed by a tab:
|
||||||
|
EXPECT (Prefix1, "\n\t" "+---<11>-<22>-+-");
|
||||||
|
|
||||||
using Prefix2 = PrefixAll<Num<101>,List1>;
|
using Prefix2 = PrefixAll<Num<101>,List1>;
|
||||||
DISPLAY (Prefix2);
|
EXPECT (List1 , "-<1>-<2>-<3>-");
|
||||||
|
EXPECT (Prefix2, "\n\t" "+---<101>-<1>-+"
|
||||||
|
"\n\t" "+---<101>-<2>-+"
|
||||||
|
"\n\t" "+---<101>-<3>-+-");
|
||||||
|
|
||||||
using Prefix3 = PrefixAll<Nil,List1>;
|
using Prefix3 = PrefixAll<Nil,List1>;
|
||||||
DISPLAY (Prefix3);
|
EXPECT (Prefix3, "\n\t" "+---<1>-+"
|
||||||
|
"\n\t" "+---<2>-+"
|
||||||
|
"\n\t" "+---<3>-+-");
|
||||||
|
|
||||||
|
// Notably this can also be used to distribute into an already nested structure,
|
||||||
|
// since the implementation is based on Append, which will actually concatenate lists
|
||||||
|
// To demonstrate this, we first create a mixed list, where some elements are nested lists
|
||||||
|
using List_of_Lists = TySeq<List1::List
|
||||||
|
,Num<0> // ◁—————————————— this one is a regular element
|
||||||
|
,List2::List>::List;
|
||||||
|
EXPECT (List_of_Lists,
|
||||||
|
"\n\t" "+---<1>-<2>-<3>-+"
|
||||||
|
"-<0>" // ◁—————————————— here shows the regular element
|
||||||
|
"\n\t" "+---<5>-<6>-<7>-+-");
|
||||||
|
|
||||||
using List_of_Lists = TyOLD<List1::List,Num<0>,List2::List>::List;
|
|
||||||
using Prefix4 = PrefixAll<Num<111>, List_of_Lists>;
|
using Prefix4 = PrefixAll<Num<111>, List_of_Lists>;
|
||||||
DISPLAY (Prefix4);
|
EXPECT (Prefix4, "\n\t" "+---<111>-<1>-<2>-<3>-+" // ◁——————— concatenation »flattens« the lists
|
||||||
|
"\n\t" "+---<111>-<0>-+"
|
||||||
|
"\n\t" "+---<111>-<5>-<6>-<7>-+-");
|
||||||
|
|
||||||
using Prefix5 = PrefixAll<List1,List2>;
|
using Prefix5 = PrefixAll<List1,List2>;
|
||||||
DISPLAY (Prefix5);
|
EXPECT (Prefix5, "\n\t" "+---<1>-<2>-<3>-<5>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<3>-<6>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<3>-<7>-+-");
|
||||||
|
|
||||||
using Prefix6 = PrefixAll<List1,List_of_Lists>;
|
using Prefix6 = PrefixAll<List1,List_of_Lists>;
|
||||||
DISPLAY (Prefix6);
|
EXPECT (Prefix6, "\n\t" "+---<1>-<2>-<3>-<1>-<2>-<3>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<3>-<0>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<3>-<5>-<6>-<7>-+-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @test use the Prefix mechanism to generate a _cartesian product_ */
|
||||||
void
|
void
|
||||||
check_distribute()
|
verify_distribute()
|
||||||
{
|
{
|
||||||
using Dist1 = Distribute<Num<11>, List1>;
|
using Dist1 = Distribute<Num<11>, List1>;
|
||||||
DISPLAY (Dist1);
|
EXPECT (Dist1, "\n\t" "+---<11>-<1>-+"
|
||||||
|
"\n\t" "+---<11>-<2>-+"
|
||||||
|
"\n\t" "+---<11>-<3>-+-");
|
||||||
|
|
||||||
using Prefixes = TyOLD<Num<11>,Num<22>,Num<33>>::List;
|
using Prefixes = TySeq<Num<11>,Num<22>,Num<33>>::List;
|
||||||
using Dist2 = Distribute<Prefixes, Num<0>>;
|
using Dist2 = Distribute<Prefixes, Num<0>>;
|
||||||
DISPLAY (Dist2);
|
EXPECT (Dist2, "\n\t" "+---<11>-<0>-+"
|
||||||
|
"\n\t" "+---<22>-<0>-+"
|
||||||
|
"\n\t" "+---<33>-<0>-+-");
|
||||||
|
|
||||||
using Dist3 = Distribute<Prefixes, List1>;
|
using Dist3 = Distribute<Prefixes, List1>;
|
||||||
DISPLAY (Dist3);
|
EXPECT (Dist3, "\n\t" "+---<11>-<1>-+"
|
||||||
|
"\n\t" "+---<11>-<2>-+"
|
||||||
|
"\n\t" "+---<11>-<3>-+"
|
||||||
|
"\n\t" "+---<22>-<1>-+"
|
||||||
|
"\n\t" "+---<22>-<2>-+"
|
||||||
|
"\n\t" "+---<22>-<3>-+"
|
||||||
|
"\n\t" "+---<33>-<1>-+"
|
||||||
|
"\n\t" "+---<33>-<2>-+"
|
||||||
|
"\n\t" "+---<33>-<3>-+-");
|
||||||
|
|
||||||
using Dist4 = Distribute<Prefixes, TyOLD<List1::List,List2::List>::List>;
|
using LioLi = TySeq<List1::List,List2::List>::List;
|
||||||
DISPLAY (Dist4);
|
EXPECT (LioLi, "\n\t" "+---<1>-<2>-<3>-+"
|
||||||
|
"\n\t" "+---<5>-<6>-<7>-+-");
|
||||||
|
using Dist4 = Distribute<Prefixes, LioLi>;
|
||||||
|
EXPECT (Dist4, "\n\t" "+---<11>-<1>-<2>-<3>-+"
|
||||||
|
"\n\t" "+---<11>-<5>-<6>-<7>-+"
|
||||||
|
"\n\t" "+---<22>-<1>-<2>-<3>-+"
|
||||||
|
"\n\t" "+---<22>-<5>-<6>-<7>-+"
|
||||||
|
"\n\t" "+---<33>-<1>-<2>-<3>-+"
|
||||||
|
"\n\t" "+---<33>-<5>-<6>-<7>-+-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @test demonstrate special setup to enumerate case combinations
|
||||||
|
* @remark can be used to pre-generate template instantiations
|
||||||
|
* at compile time, for a complete configuration space
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
check_combine()
|
verify_combine()
|
||||||
{
|
{ // ▽▽▽ ———————————————defined in typelist-diagnostic.cpp
|
||||||
using Down = CountDown<Num<11>>;
|
using Count = CountDown<Num<11>>;
|
||||||
DISPLAY (Down);
|
EXPECT (Count, "-<11>-<10>-<9>-<8>-<7>-<6>-<5>-<4>-<3>-<2>-<1>-<0>-");
|
||||||
|
|
||||||
|
// Apply on a single type and tabulate
|
||||||
|
using Apply = Combine<Num<5>, CountDown>;
|
||||||
|
EXPECT (Apply, "\n\t" "+---<5>-<·>-+"
|
||||||
|
"\n\t" "+---<4>-<·>-+"
|
||||||
|
"\n\t" "+---<3>-<·>-+"
|
||||||
|
"\n\t" "+---<2>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<·>-+-");
|
||||||
|
|
||||||
|
// Apply recursively to generate all combinations
|
||||||
using Combi = Combine<List1::List, CountDown>;
|
using Combi = Combine<List1::List, CountDown>;
|
||||||
DISPLAY (Combi);
|
EXPECT (Combi, "\n\t" "+---<1>-<2>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<0>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<1>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<1>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<1>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<1>-<0>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<0>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<0>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<0>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<0>-<0>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<2>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<2>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<2>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<2>-<0>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<1>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<1>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<1>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<1>-<0>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<0>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<0>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<0>-<1>-<·>-+"
|
||||||
|
"\n\t" "+---<0>-<0>-<0>-<·>-+-");
|
||||||
|
|
||||||
|
// Special use-case: call combinations of a set of flags
|
||||||
using OnOff = CombineFlags<List1::List>;
|
using OnOff = CombineFlags<List1::List>;
|
||||||
DISPLAY (OnOff);
|
EXPECT (OnOff, "\n\t" "+---<1>-<2>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<2>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<1>-<·>-+"
|
||||||
|
"\n\t" "+---<2>-<3>-<·>-+"
|
||||||
|
"\n\t" "+---<2>-<·>-+"
|
||||||
|
"\n\t" "+---<3>-<·>-+"
|
||||||
|
"\n\t" "+---<·>-+-");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164257,7 +164257,7 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748828579825" ID="ID_873142911" MODIFIED="1748869733060" TEXT="typelist-manip ist völlig eigenständig">
|
<node COLOR="#338800" CREATED="1748828579825" ID="ID_873142911" MODIFIED="1748900607872" TEXT="typelist-manip ist völlig eigenständig">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
|
@ -164269,6 +164269,10 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
</richcontent>
|
</richcontent>
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
|
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1748900614743" ID="ID_516014802" MODIFIED="1748900632652" TEXT="durch Test belegt: funtioniert auch mit den neuen Type-Sequenzen">
|
||||||
|
<font NAME="SansSerif" SIZE="10"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748828920169" ID="ID_511778446" MODIFIED="1748869770714" TEXT="generator.hpp arbeitet ebenfalls nur auf Typlisten">
|
<node CREATED="1748828920169" ID="ID_511778446" MODIFIED="1748869770714" TEXT="generator.hpp arbeitet ebenfalls nur auf Typlisten">
|
||||||
<arrowlink DESTINATION="ID_803058969" ENDARROW="Default" ENDINCLINATION="852;0;" ID="Arrow_ID_1971292758" STARTARROW="None" STARTINCLINATION="302;17;"/>
|
<arrowlink DESTINATION="ID_803058969" ENDARROW="Default" ENDINCLINATION="852;0;" ID="Arrow_ID_1971292758" STARTARROW="None" STARTINCLINATION="302;17;"/>
|
||||||
|
|
@ -164290,6 +164294,16 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
</richcontent>
|
</richcontent>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748828781783" ID="ID_691444823" MODIFIED="1748828794388" TEXT="sollte also für alle Varianten gleichermaßen greifen"/>
|
<node CREATED="1748828781783" ID="ID_691444823" MODIFIED="1748828794388" TEXT="sollte also für alle Varianten gleichermaßen greifen"/>
|
||||||
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748888164617" ID="ID_145174722" MODIFIED="1748888298322" TEXT="sollte Tests ustellen auf Inline-Checks (mit _expect)">
|
||||||
|
<arrowlink DESTINATION="ID_1431343903" ENDARROW="Default" ENDINCLINATION="156;-14;" ID="Arrow_ID_1374886089" STARTARROW="None" STARTINCLINATION="253;316;"/>
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
<node CREATED="1748888193247" ID="ID_979097077" MODIFIED="1748888251981" TEXT="in der bisherigen Form sind sie ordentlich — aber wertlos">
|
||||||
|
<icon BUILTIN="smiley-neutral"/>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1748888215764" ID="ID_1132022634" MODIFIED="1748888243058" TEXT="(und ja ... diese Umstellung ist ein ziemlicher Aufwarnd)">
|
||||||
|
<font NAME="SansSerif" SIZE="11"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748829095135" ID="ID_1295682918" MODIFIED="1748829098145" TEXT="Funktionen">
|
<node CREATED="1748829095135" ID="ID_1295682918" MODIFIED="1748829098145" TEXT="Funktionen">
|
||||||
|
|
@ -164320,16 +164334,19 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748829133428" ID="ID_266502224" MODIFIED="1748829134942" TEXT="Tuple">
|
<node COLOR="#435e98" CREATED="1748829133428" ID="ID_266502224" MODIFIED="1748884086384" TEXT="Tuple">
|
||||||
<node CREATED="1748829135672" ID="ID_1078202790" MODIFIED="1748829142923" TEXT="tuple-record-init">
|
<node COLOR="#435e98" CREATED="1748829135672" ID="ID_1078202790" MODIFIED="1748884086383" TEXT="tuple-record-init">
|
||||||
<node CREATED="1748869115796" ID="ID_508891239" MODIFIED="1748869125930" TEXT="sehr wichtig für GenNode via UI-Bus"/>
|
<node CREATED="1748869115796" ID="ID_508891239" MODIFIED="1748869125930" TEXT="sehr wichtig für GenNode via UI-Bus"/>
|
||||||
<node CREATED="1748869126637" ID="ID_1892597632" MODIFIED="1748869141216" TEXT="verwendet Type-Sequenze lediglich zum Re-binding eines Tuple-Typs"/>
|
<node CREATED="1748869126637" ID="ID_1892597632" MODIFIED="1748869141216" TEXT="verwendet Type-Sequenze lediglich zum Re-binding eines Tuple-Typs"/>
|
||||||
<node COLOR="#338800" CREATED="1748869141825" ID="ID_893825351" MODIFIED="1748869166877" TEXT="kann man einfach auf die neue Variante schwenken">
|
<node COLOR="#338800" CREATED="1748869141825" ID="ID_893825351" MODIFIED="1748869166877" TEXT="kann man einfach auf die neue Variante schwenken">
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
<node COLOR="#338800" CREATED="1748884068125" ID="ID_12615533" MODIFIED="1748884080973" TEXT="ansonsten bereits beidseitig kompatibel">
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748829164245" ID="ID_1618911636" MODIFIED="1748829167991" TEXT="variadic-helper">
|
</node>
|
||||||
|
<node COLOR="#435e98" CREATED="1748829164245" ID="ID_1618911636" MODIFIED="1748884058416" TEXT="variadic-helper">
|
||||||
<node CREATED="1748830128123" ID="ID_450144323" MODIFIED="1748830132130" TEXT="(nur am Rande)"/>
|
<node CREATED="1748830128123" ID="ID_450144323" MODIFIED="1748830132130" TEXT="(nur am Rande)"/>
|
||||||
<node CREATED="1748830132883" ID="ID_1589913777" MODIFIED="1748830138854" TEXT="IndexIter unterstützt beide"/>
|
<node CREATED="1748830132883" ID="ID_1589913777" MODIFIED="1748830138854" TEXT="IndexIter unterstützt beide"/>
|
||||||
<node CREATED="1748830139501" ID="ID_622177889" MODIFIED="1748830160252" TEXT="ElmTypes ist nur für neue (variadisch) definiert"/>
|
<node CREATED="1748830139501" ID="ID_622177889" MODIFIED="1748830160252" TEXT="ElmTypes ist nur für neue (variadisch) definiert"/>
|
||||||
|
|
@ -164344,8 +164361,11 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
<node CREATED="1748829283559" ID="ID_373354659" MODIFIED="1748829291711" TEXT="hängt vermutlich an Variant bzw. Visitor"/>
|
<node CREATED="1748829283559" ID="ID_373354659" MODIFIED="1748829291711" TEXT="hängt vermutlich an Variant bzw. Visitor"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748829316732" ID="ID_733906672" MODIFIED="1748829324434" TEXT="Timecode-formate"/>
|
<node CREATED="1748829316732" ID="ID_733906672" MODIFIED="1748829324434" TEXT="Timecode-formate"/>
|
||||||
<node CREATED="1748829331775" ID="ID_1553022384" MODIFIED="1748829333067" TEXT="Tests">
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748829331775" ID="ID_1553022384" MODIFIED="1748900515205" TEXT="Tests">
|
||||||
<node CREATED="1748829335663" ID="ID_953757498" MODIFIED="1748829343651" TEXT="jeweils bei Bezug mit umstellen"/>
|
<icon BUILTIN="pencil"/>
|
||||||
|
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1748829335663" ID="ID_953757498" MODIFIED="1748900529301" TEXT="jeweils bei Bezug mit umstellen">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
</node>
|
||||||
<node CREATED="1748829344620" ID="ID_1034418764" MODIFIED="1748883769361" TEXT="im Einzelnen">
|
<node CREATED="1748829344620" ID="ID_1034418764" MODIFIED="1748883769361" TEXT="im Einzelnen">
|
||||||
<icon BUILTIN="list"/>
|
<icon BUILTIN="list"/>
|
||||||
<node CREATED="1748829369449" MODIFIED="1748829369449" TEXT="FormatSupport_test"/>
|
<node CREATED="1748829369449" MODIFIED="1748829369449" TEXT="FormatSupport_test"/>
|
||||||
|
|
@ -164367,7 +164387,9 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
<node CREATED="1748829534601" MODIFIED="1748829534601" TEXT="MetaUtils_test"/>
|
<node CREATED="1748829534601" MODIFIED="1748829534601" TEXT="MetaUtils_test"/>
|
||||||
<node CREATED="1748829542074" MODIFIED="1748829542074" TEXT="TupleHelper_test"/>
|
<node CREATED="1748829542074" MODIFIED="1748829542074" TEXT="TupleHelper_test"/>
|
||||||
<node CREATED="1748829551216" MODIFIED="1748829551216" TEXT="TupleRecordInit_test"/>
|
<node CREATED="1748829551216" MODIFIED="1748829551216" TEXT="TupleRecordInit_test"/>
|
||||||
<node CREATED="1748829559066" MODIFIED="1748829559066" TEXT="TypeListManip_test"/>
|
<node COLOR="#435e98" CREATED="1748829559066" ID="ID_1431343903" MODIFIED="1748900495968" TEXT="TypeListManip_test">
|
||||||
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1431343903" ENDARROW="Default" ENDINCLINATION="156;-14;" ID="Arrow_ID_1374886089" SOURCE="ID_145174722" STARTARROW="None" STARTINCLINATION="253;316;"/>
|
||||||
|
</node>
|
||||||
<node CREATED="1748829567920" MODIFIED="1748829567920" TEXT="TypeList_test"/>
|
<node CREATED="1748829567920" MODIFIED="1748829567920" TEXT="TypeList_test"/>
|
||||||
<node COLOR="#435e98" CREATED="1748829576396" ID="ID_281104576" MODIFIED="1748883754992" TEXT="TypeListUtil_test">
|
<node COLOR="#435e98" CREATED="1748829576396" ID="ID_281104576" MODIFIED="1748883754992" TEXT="TypeListUtil_test">
|
||||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_281104576" ENDARROW="Default" ENDINCLINATION="589;-82;" ID="Arrow_ID_351374746" SOURCE="ID_1470463237" STARTARROW="None" STARTINCLINATION="458;41;"/>
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_281104576" ENDARROW="Default" ENDINCLINATION="589;-82;" ID="Arrow_ID_351374746" SOURCE="ID_1470463237" STARTARROW="None" STARTINCLINATION="458;41;"/>
|
||||||
|
|
@ -164395,7 +164417,12 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748871829578" ID="ID_308061484" MODIFIED="1748883860119" TEXT="Meta-Wertfunktionen in constexpr überführen">
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748871829578" ID="ID_308061484" MODIFIED="1748883860119" TEXT="Meta-Wertfunktionen in constexpr überführen">
|
||||||
<icon BUILTIN="pencil"/>
|
<icon BUILTIN="pencil"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1748871856256" ID="ID_304666403" MODIFIED="1748871864810" TEXT="Tests vervollständigen"/>
|
<node CREATED="1748871856256" ID="ID_304666403" MODIFIED="1748900585714" TEXT="Tests ggfs vervollständigen">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748900565184" ID="ID_1203054358" MODIFIED="1748900572521" TEXT="ExpectString verwenden">
|
||||||
|
<icon BUILTIN="pencil"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue