clean-up: define variadic type-sequences independently
To bootstrap this tricky refactoring, initially a bridge definition was used, with a variadic argument pack, but delegating to the old non-variadic type sequence and from there further into LISP style list processing of types and meta definitions, as pioneered by the Loki libarary. Luimiera uses this technique since a long time to perform the complex tasks sometimes required for code generation and generic function and type adaptation. with this changeset, a direct variadics based entrance into type list processing is provided, so that the old definition is now completely separate and can be removed eventually.
This commit is contained in:
parent
412abbace2
commit
429a7e2339
7 changed files with 115 additions and 60 deletions
|
|
@ -162,14 +162,14 @@ namespace meta {
|
|||
template<class H, typename TAIL>
|
||||
struct BuildTupleType<Node<H, TAIL>>
|
||||
{
|
||||
using Seq = typename TyOLD< Node<H,TAIL>>::Seq;
|
||||
using Seq = typename TySeq<Node<H,TAIL>>::Seq;
|
||||
using Type = typename BuildTupleType<Seq>::Type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BuildTupleType<Nil>
|
||||
{
|
||||
using Type = typename BuildTupleType<TyOLD<>>::Type;
|
||||
using Type = std::tuple<>;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,22 +31,32 @@ This code is heavily inspired by
|
|||
|
||||
/** @file typelist.hpp
|
||||
** A template metaprogramming technique for manipulating collections of types.
|
||||
** Effectively this is a tailored and simplified version of what can be found in the Loki library.
|
||||
** We use it in other generic library-style code to generate repetitive code.
|
||||
** - **Type Sequences** are used to transport a variadic sequence of types
|
||||
** - **Type Lists** (»Loki style«) can be created from a type sequence and
|
||||
** represent the same information by _nodes_ with _head_ and _tail_.
|
||||
** The latter brings LISP style recursive manipulation techniques into the
|
||||
** realm of type metaprogramming; this approach was pioneered with the
|
||||
** **Loki Library** by Alexandrescu (2001) and makes complex processing
|
||||
** much easier to write and to understand following. Effectively the set
|
||||
** of definitions used here is a tailored version of what could be found
|
||||
** in the Loki library, and was in the following years integrated with
|
||||
** processing of variadics, function manipulation and std::tuple.
|
||||
** This framework is typically used to generate repetitive code,
|
||||
** based on a collection of types, with type-specific adaptations.
|
||||
** @remark If you tend to find the use of template metaprogramming detrimental
|
||||
** (or functional programming and generally any kind of abstraction)
|
||||
** please kindly ignore the technical details and just consider the
|
||||
** benefit of simplification for the client code.
|
||||
**
|
||||
** Interface for using this facility is the template `Types<TS...>`.
|
||||
** Interface for using this facility is the template `Types<TS...>` (the type sequence).
|
||||
** To start typelist processing, other templates typically pick up the Types<...>::List type.
|
||||
** This allows for LISP-style list processing, with a pattern match on either `Node<TY,TYPES>`
|
||||
** or the type `Nil` to terminate recursion. In C++ template metaprogramming, "pattern match"
|
||||
** is done by partial template specialisations (the compiler will pick up and thus
|
||||
** match the template parameters). A typedef acts like a declaration in normal
|
||||
** programming. Because such a "declaration" can't be changed after the fact,
|
||||
** effectively this is a flavour of functional programming. Just the
|
||||
** "execution environment" is the compiler, during compilation.
|
||||
** match the template parameters). A type definition acts like a variable declaration
|
||||
** in regular programming. Because such a "declaration" can't be changed after the fact,
|
||||
** effectively this is a flavour of functional programming; the _execution environment_
|
||||
** is the compiler, and evaluation is set off by some template instantiation.
|
||||
**
|
||||
** @warning the metaprogramming part of Lumiera to deal with type sequences is in a
|
||||
** state of transition, since C++11 now offers direct language support for
|
||||
|
|
@ -59,10 +69,12 @@ This code is heavily inspired by
|
|||
** since the latter can only be rebound through pattern matching.
|
||||
** @todo transition lib::meta::Types to variadic parameters /////////////////////////////////TICKET #987
|
||||
**
|
||||
** @see lib::visitor::Applicable usage example
|
||||
** @see control::CommandSignature more elaborate usage example (dissecting a functor signature)
|
||||
** @see TypeList_test
|
||||
** @see TypeListManip_test
|
||||
** @see TypeSecManip_test
|
||||
** @see function.hpp
|
||||
** @see tuple-helper.hpp
|
||||
** @see variadic-helper.hpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -75,24 +87,28 @@ This code is heavily inspired by
|
|||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
|
||||
struct Nil
|
||||
{
|
||||
using List = Nil;
|
||||
};
|
||||
|
||||
template<class H, class T>
|
||||
struct Node
|
||||
{
|
||||
using List = Node;
|
||||
using Head = H;
|
||||
using Tail = T;
|
||||
};
|
||||
|
||||
using NilNode = Node<Nil,Nil>;
|
||||
|
||||
|
||||
|
||||
|
||||
/** »Empty« mark */
|
||||
struct Nil
|
||||
{
|
||||
using List = Nil;
|
||||
};
|
||||
|
||||
/** Type list with head and tail;
|
||||
* T ≡ Nil marks list end. */
|
||||
template<class H, class T>
|
||||
struct Node
|
||||
{
|
||||
using List = Node;
|
||||
using Head = H;
|
||||
using Tail = T;
|
||||
};
|
||||
|
||||
using NilNode = Node<Nil,Nil>;
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 : this is the old non-variadic definition from lib Loki -- it will be obsoleted with the transition
|
||||
template
|
||||
< class T01=Nil
|
||||
, class T02=Nil
|
||||
|
|
@ -135,7 +151,7 @@ namespace meta {
|
|||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- to be obsoleted
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- transition to variadic type-sequences
|
||||
/**
|
||||
* temporary workaround:
|
||||
* alternative definition of "type sequence",
|
||||
|
|
@ -147,13 +163,26 @@ namespace meta {
|
|||
* entries do not play well with other variadic defs.
|
||||
* @deprecated when we switch our primary type sequence type
|
||||
* to variadic parameters, this type will be obsoleted. ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic
|
||||
* @todo 6/25 the transition is now mostly settled
|
||||
* and will be completed by just _renaming_ this
|
||||
* definition back into `Types<...>`
|
||||
*/
|
||||
template<typename...TYPES>
|
||||
struct TySeq
|
||||
struct TySeq;
|
||||
|
||||
template<typename T, typename...TS>
|
||||
struct TySeq<T,TS...>
|
||||
{
|
||||
using Seq = TySeq;
|
||||
using List = typename TyOLD<TYPES...>::List;
|
||||
using List = Node<T, typename TySeq<TS...>::List>;
|
||||
using Seq = TySeq;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND(End) -- to be obsoleted
|
||||
|
||||
template<>
|
||||
struct TySeq<>
|
||||
{
|
||||
using List = Nil;
|
||||
using Seq = TySeq<>;
|
||||
};
|
||||
|
||||
}} // namespace lib::meta
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ namespace meta {
|
|||
struct Prepend<T, TySeq<TYPES...>>
|
||||
{
|
||||
using Seq = TySeq<T, TYPES...>;
|
||||
using List = typename TyOLD<T, TYPES...>::List;
|
||||
using List = typename TySeq<T, TYPES...>::List;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -195,6 +195,10 @@ namespace meta {
|
|||
using List = Nil;
|
||||
using Seq = TySeq<>;
|
||||
};
|
||||
template<>
|
||||
struct TySeq<NilNode>
|
||||
: TySeq<Nil>
|
||||
{ };
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- to be obsoleted
|
||||
|
|
@ -338,19 +342,18 @@ namespace meta {
|
|||
template<class TYPES, uint i=1>
|
||||
class Shifted
|
||||
{
|
||||
typedef typename Split<TYPES>::Tail Tail;
|
||||
using Tail = typename Split<TYPES>::Tail;
|
||||
public:
|
||||
typedef typename Shifted<Tail,i-1>::Type Type;
|
||||
typedef typename Split<Type>::Head Head;
|
||||
using Type = typename Shifted<Tail,i-1>::Type;
|
||||
using Head = typename Split<Type>::Head;
|
||||
};
|
||||
|
||||
template<class TYPES>
|
||||
struct Shifted<TYPES,0>
|
||||
{
|
||||
typedef TYPES Type;
|
||||
typedef typename Split<Type>::Head Head;
|
||||
using Type = TYPES;
|
||||
using Head = typename Split<Type>::Head; ///< @warning may be Nil in case of an empty list
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////////TICKET #987 : reimplement for variadic type-sequences
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ namespace meta {
|
|||
struct Printer<Nil, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string show() { return _Fmt("-<%u>%s") % "·" % BASE::show(); }
|
||||
static string show() { return _Fmt("-<%s>%s") % "·" % BASE::show(); }
|
||||
};
|
||||
|
||||
template<class BASE, int I>
|
||||
|
|
@ -133,19 +133,19 @@ namespace meta {
|
|||
struct Printer<int, BASE> ///< display the presence of a plain int in the typelist
|
||||
: BASE
|
||||
{
|
||||
static string show() { return _Fmt("-<%u>%s") % 'i' % BASE::show(); }
|
||||
static string show() { return _Fmt("-<%s>%s") % 'i' % BASE::show(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** call the debug-print for a typelist
|
||||
* utilising the Printer template */
|
||||
template<class L>
|
||||
template<class LIST>
|
||||
string
|
||||
printSublist ()
|
||||
{
|
||||
typedef InstantiateChained<L, Printer, NullP> SubList;
|
||||
return SubList::show();
|
||||
using PrinterChain = InstantiateChained<LIST, Printer, NullP>;
|
||||
return PrinterChain::show();
|
||||
}
|
||||
|
||||
/** Specialisation for debug-printing of a nested sublist */
|
||||
|
|
@ -184,8 +184,8 @@ namespace meta {
|
|||
string >
|
||||
showType ()
|
||||
{
|
||||
typedef InstantiateChained<typename TYPES::List, Printer, NullP> DumpPrinter;
|
||||
return DumpPrinter::show();
|
||||
using TypeList = typename TYPES::List;
|
||||
return printSublist<TypeList>();
|
||||
}
|
||||
|
||||
// Note: we define overloads of this function for other types, especially Tuples
|
||||
|
|
|
|||
|
|
@ -172,8 +172,8 @@ namespace test {
|
|||
using NilSplit = PickLast<Nil>::Type;
|
||||
using NilList = PickLast<Nil>::List;
|
||||
|
||||
EXPECT (TySeq<NilSplit>, "-");
|
||||
EXPECT (NilList , "-");
|
||||
EXPECT (NilSplit, "-");
|
||||
EXPECT (NilList , "-");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,8 @@ namespace test {
|
|||
using Head_3 = TySeq<Shifted<Seq,3>::Head>; EXPECT (Head_3, "-<1>-");
|
||||
using Head_4 = TySeq<Shifted<Seq,4>::Head>; EXPECT (Head_4, "-<2>-");
|
||||
using Head_5 = TySeq<Shifted<Seq,5>::Head>; EXPECT (Head_5, "-<3>-");
|
||||
using Head_6 = TySeq<Shifted<Seq,6>::Head>; EXPECT (Head_6, "-");
|
||||
using Head_6 = TySeq<Shifted<Seq,6>::Head>; EXPECT (Head_6, "-" );
|
||||
using Head_7 = TySeq<Shifted<Seq,7>::Head>; EXPECT (Head_7, "-" );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -155,7 +156,10 @@ namespace test {
|
|||
using Head = Split<Seq>::Head;
|
||||
using End = Split<Seq>::End;
|
||||
|
||||
using HeadEnd = TySeq<Head,End>; EXPECT (HeadEnd, "-<1>-<9>-");
|
||||
using Ends = TySeq<Head,End>; EXPECT (Ends , "-<1>-<9>-");
|
||||
|
||||
using NoList = Split<TySeq<>>::List; EXPECT (NoList, "-");
|
||||
using NoHead = Split<TySeq<>>::Head; EXPECT (NoHead, "-");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -164238,6 +164238,21 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1748828247849" ID="ID_476644412" MODIFIED="1748869713383" TEXT="Verbindung mit Typelisten">
|
||||
<node COLOR="#338800" CREATED="1749001830758" ID="ID_91346918" MODIFIED="1749007560980" TEXT="eigenständige Konstruktion von Type-Listen hinzufügen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
bisher wurde das durch Delegieren an die alte Loki-Implementierung bewerkstelligt; das nun direkt auf der Basis von Variadics zu machen, wäre der zentrale Schritt, der das neue Ökosystem der variadischen Typlisten autonom macht (so daß man am Ende die alte nicht-variadische Definition entfernen kann)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#8ec9a3" DESTINATION="ID_1097523075" ENDARROW="Default" ENDINCLINATION="1324;0;" ID="Arrow_ID_370033957" STARTARROW="None" STARTINCLINATION="481;24;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1748828313009" ID="ID_1470463237" MODIFIED="1748869832016" TEXT="Rückweg Typelist ⟶ Typsequenz">
|
||||
<arrowlink DESTINATION="ID_281104576" ENDARROW="Default" ENDINCLINATION="589;-82;" ID="Arrow_ID_351374746" STARTARROW="None" STARTINCLINATION="458;41;"/>
|
||||
<node CREATED="1748828416378" ID="ID_1994646495" MODIFIED="1748869656471" TEXT="es gibt eine Spezialisierung von TyOLD">
|
||||
|
|
@ -164274,12 +164289,12 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748828920169" ID="ID_511778446" MODIFIED="1748869770714" TEXT="generator.hpp arbeitet ebenfalls nur auf Typlisten">
|
||||
<node COLOR="#435e98" CREATED="1748828920169" ID="ID_511778446" MODIFIED="1749003965023" 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;"/>
|
||||
<node CREATED="1748828953483" ID="ID_1328523415" MODIFIED="1748828958980" TEXT="das kommt mir nun zugute"/>
|
||||
<node CREATED="1748828933676" ID="ID_1716238563" MODIFIED="1748828952655" TEXT="man könnte dann convenience-Front-End definieren"/>
|
||||
</node>
|
||||
<node CREATED="1748828754106" ID="ID_138237629" MODIFIED="1748869733060" TEXT="typelist-diagnostic ebenso">
|
||||
<node COLOR="#435e98" CREATED="1748828754106" ID="ID_138237629" MODIFIED="1749003967494" TEXT="typelist-diagnostic ebenso">
|
||||
<node CREATED="1748828767089" ID="ID_1047311703" MODIFIED="1748828818895" TEXT="meta::is_Typelist ist geschickt definiert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -164309,17 +164324,19 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748829095135" ID="ID_1295682918" MODIFIED="1748829098145" TEXT="Funktionen">
|
||||
<node CREATED="1748829099022" ID="ID_766756688" MODIFIED="1748829101916" TEXT="Signatur-Utils">
|
||||
<node COLOR="#435e98" CREATED="1748829095135" ID="ID_1295682918" MODIFIED="1749007403090" TEXT="Funktionen">
|
||||
<node COLOR="#435e98" CREATED="1748829099022" ID="ID_766756688" MODIFIED="1749007398648" TEXT="Signatur-Utils">
|
||||
<node CREATED="1748829959670" ID="ID_1188075291" MODIFIED="1748829968228" TEXT="sind bereits mit beiden kompatibel"/>
|
||||
</node>
|
||||
<node CREATED="1748829102455" ID="ID_1254282139" MODIFIED="1748829106392" TEXT="Closure">
|
||||
<node CREATED="1748829838133" ID="ID_1933174501" MODIFIED="1748829845923" TEXT="hat nur wenige Verwendungen">
|
||||
<node COLOR="#338800" CREATED="1748829102455" ID="ID_1254282139" MODIFIED="1749007395415" TEXT="Closure">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1748829838133" ID="ID_1933174501" MODIFIED="1748995159628" TEXT="wenige wichtige Verwendungen">
|
||||
<node CREATED="1748829860803" ID="ID_517247632" MODIFIED="1748829863739" TEXT="Commands"/>
|
||||
<node CREATED="1748829872320" ID="ID_568804131" MODIFIED="1748829875428" TEXT="Random-Draw"/>
|
||||
<node CREATED="1748829881837" ID="ID_1354679657" MODIFIED="1748829885400" TEXT="tuple-closure"/>
|
||||
<node CREATED="1748829890844" ID="ID_1803577911" MODIFIED="1748829894782" TEXT="view-spec-dsl"/>
|
||||
</node>
|
||||
<node CREATED="1749007506535" ID="ID_240022720" MODIFIED="1749007506535" TEXT="muß auf einen Schlag geschwenkt werden (Komplexität)"/
|
||||
<node CREATED="1748829733384" ID="ID_83679265" MODIFIED="1748829744922" TEXT="sollte sich bereits ohne weiteres schwenken lassen"/>
|
||||
<node CREATED="1748829745682" ID="ID_61352432" MODIFIED="1748829759664" TEXT="erzeugt nur Tuple, oder macht Split / Prepend"/>
|
||||
<node CREATED="1748829779637" ID="ID_1158113558" MODIFIED="1748829835939" TEXT="man könnte dann im Nachgang die Apply-Definition eliminieren">
|
||||
|
|
@ -164394,7 +164411,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<node CREATED="1748829468217" MODIFIED="1748829468217" TEXT="SessionServiceAccess_test"/>
|
||||
<node CREATED="1748829480048" MODIFIED="1748829480048" TEXT="FunctionClosure_test"/>
|
||||
<node CREATED="1748829502213" MODIFIED="1748829502213" TEXT="FunctionComposition_test"/>
|
||||
<node CREATED="1748829512571" MODIFIED="1748829512571" TEXT="GeneratorCombinations_test"/>
|
||||
<node COLOR="#435e98" CREATED="1748829512571" ID="ID_1542151497" MODIFIED="1749007468620" TEXT="GeneratorCombinations_test"/>
|
||||
<node COLOR="#435e98" CREATED="1748829523737" ID="ID_803058969" MODIFIED="1748883754992" TEXT="TypeListGenerator_test">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_803058969" ENDARROW="Default" ENDINCLINATION="852;0;" ID="Arrow_ID_1971292758" SOURCE="ID_511778446" STARTARROW="None" STARTINCLINATION="302;17;"/>
|
||||
</node>
|
||||
|
|
@ -164415,7 +164432,9 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<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;"/>
|
||||
</node>
|
||||
<node CREATED="1748829567920" ID="ID_1097523075" MODIFIED="1748959903101" TEXT="TypeList_test"/>
|
||||
<node COLOR="#435e98" CREATED="1748829567920" ID="ID_1097523075" MODIFIED="1749007565198" TEXT="TypeList_test">
|
||||
<linktarget COLOR="#8ec9a3" DESTINATION="ID_1097523075" ENDARROW="Default" ENDINCLINATION="1324;0;" ID="Arrow_ID_370033957" SOURCE="ID_91346918" STARTARROW="None" STARTINCLINATION="481;24;"/>
|
||||
</node>
|
||||
<node CREATED="1748829607017" MODIFIED="1748829607017" TEXT="Variant_test"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue