From c8187bdf881f30036ae891d91420a38342a90781 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 2 Jun 2025 19:07:05 +0200 Subject: [PATCH] clean-up: complement and modernise basic type-lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - provide complete conversion paths old-style ⟷ new-style - switch the basic tests to the new variadic sequences - modernise the code; replace typedefs by `using` - change some struct-style ''meta-functions'' into constexpr or compile-time constants --- src/lib/meta/function-closure.hpp | 10 +- src/lib/meta/tuple-record-init.hpp | 2 +- src/lib/meta/typelist-util.hpp | 77 ++++------ src/lib/meta/typeseq-util.hpp | 28 +++- src/lib/meta/util.hpp | 4 + src/lib/meta/variadic-helper.hpp | 4 +- src/lib/variant.hpp | 4 +- src/steam/mobject/output-designation.hpp | 2 +- tests/12metaprogramming.tests | 11 +- tests/library/meta/typelist-test.cpp | 30 ++-- tests/library/meta/typelist-util-test.cpp | 40 ++--- wiki/thinkPad.ichthyo.mm | 179 ++++++++++++++++++++++ 12 files changed, 293 insertions(+), 98 deletions(-) diff --git a/src/lib/meta/function-closure.hpp b/src/lib/meta/function-closure.hpp index cb0362714..9b4959938 100644 --- a/src/lib/meta/function-closure.hpp +++ b/src/lib/meta/function-closure.hpp @@ -496,7 +496,7 @@ namespace func{ using BoundFunc = function; - enum { ARG_CNT = count::value }; + enum { ARG_CNT = count() }; /** storing a ref to the parameter tuple */ @@ -577,8 +577,8 @@ namespace func{ using ValList = typename VAL::List; using ValTypes = typename TyOLD::Seq; - enum { ARG_CNT = count::value - , VAL_CNT = count ::value + enum { ARG_CNT = count() + , VAL_CNT = count() , ROFFSET = (VAL_CNT < ARG_CNT)? ARG_CNT-VAL_CNT : 0 }; @@ -681,7 +681,7 @@ namespace func{ using ArgsList = typename Args::List; using ValList = typename TyOLD::List; - enum { ARG_CNT = count::value }; + enum { ARG_CNT = count() }; using RemainingFront = typename Splice::Front; using RemainingBack = typename Splice::Back; @@ -910,7 +910,7 @@ namespace func{ typename _PapE::FunType::Functor bindLast (SIG& f, TERM&& arg) { - enum { LAST_POS = -1 + count::Args::List>::value }; + enum { LAST_POS = -1 + count::Args>() }; return BindToArgument::reduced (f, std::forward (arg)); } diff --git a/src/lib/meta/tuple-record-init.hpp b/src/lib/meta/tuple-record-init.hpp index b4985203b..09ad9ddd9 100644 --- a/src/lib/meta/tuple-record-init.hpp +++ b/src/lib/meta/tuple-record-init.hpp @@ -193,7 +193,7 @@ namespace meta { struct ElementExtractor> { template - using TargetType = typename Pick, i>::Type; + using TargetType = typename Pick, i>::Type; template diff --git a/src/lib/meta/typelist-util.hpp b/src/lib/meta/typelist-util.hpp index 854c26502..2cd13a9ea 100644 --- a/src/lib/meta/typelist-util.hpp +++ b/src/lib/meta/typelist-util.hpp @@ -13,7 +13,7 @@ /** @file typelist-util.hpp - ** Metaprogramming: simple helpers for working with lists-of-types. + ** Metaprogramming: simple helpers for working with lists-of-types. ** This header provides some very basic "meta functions" for extracting ** pieces of information from a list-of-types. In Lumiera, we use template ** metaprogramming and especially such lists-of-types, whenever we build @@ -22,7 +22,7 @@ ** ** The "meta functions" defined here are templates; to access the "result" of ** such a meta function, we instantiate the template and then access one of the - ** embedded constant definitions (usually the enum constant named \c value) + ** embedded constant definitions (usually the compile-time constant named `value`) ** ** @see generator.hpp ** @see TypelistUtil_test @@ -39,6 +39,9 @@ #include "lib/meta/typelist.hpp" +#include "lib/meta/util.hpp" + +#include namespace lib { namespace meta { @@ -46,20 +49,20 @@ namespace meta { /** * Metafunction counting the number of Types in the collection - * @return an embedded constant \c value holding the result + * @return an std::integral_constant type, which can be used + * as constexpr value. + * @note typeseq-util.hpp defines a specialisation for type-seq */ - template + template struct count; template<> struct count - { - enum{ value = 0 }; - }; + : SizConst<0> + { }; template struct count> - { - enum{ value = 1 + count::value }; - }; + : SizConst<1 + count()> + { }; /** @@ -69,16 +72,12 @@ namespace meta { struct maxSize; template<> struct maxSize - { - static constexpr int value = 0; - }; + : SizConst<0> + { }; template struct maxSize> - { - static constexpr size_t thisval = sizeof(TY); - static constexpr size_t nextval = maxSize::value; - static constexpr size_t value = nextval > thisval? nextval:thisval; - }; + : SizConst::value)> + { }; /** @@ -88,16 +87,12 @@ namespace meta { struct maxAlign; template<> struct maxAlign - { - static constexpr int value = 0; - }; + : SizConst<0> + { }; template struct maxAlign> - { - static constexpr size_t thisval = alignof(TY); - static constexpr size_t nextval = maxAlign::value; - static constexpr size_t value = nextval > thisval? nextval:thisval; - }; + : SizConst::value)> + { }; /** @@ -105,30 +100,20 @@ namespace meta { * in a given typelist. Only exact match is detected. */ template - struct IsInList - { - enum{ value = false }; - }; + struct isInList + : std::false_type + { }; template - struct IsInList> - { - enum{ value = true }; - }; + struct isInList> + : std::true_type + { }; template - struct IsInList> - { - enum{ value = IsInList::value }; - }; + struct isInList> + : std::bool_constant::value> + { }; - /** convenience shortcut: query function */ - template - constexpr bool - isInList() - { - return IsInList::value; - } /** @@ -146,7 +131,7 @@ namespace meta { template struct ConstAll> { - using List = Node::List>; + using List = Node, typename ConstAll::List>; }; diff --git a/src/lib/meta/typeseq-util.hpp b/src/lib/meta/typeseq-util.hpp index c258795cf..a8a6af59f 100644 --- a/src/lib/meta/typeseq-util.hpp +++ b/src/lib/meta/typeseq-util.hpp @@ -79,6 +79,23 @@ namespace meta { return 1 + indexOfType(); } + /** series of definitions to level across variadics, + * type-sequences and type-lists + * @see typelist-util.hpp + */ + template + struct count + : SizConst + { }; + template + struct count> + : SizConst + { }; + template + struct count> + : SizConst + { }; + /** * Helper: prepend a type to an existing type sequence, @@ -128,6 +145,7 @@ namespace meta { + //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- to be obsoleted /** * Additional specialisation of the basic type sequence type, * allowing to re-create a (flat) type sequence from a typelist. @@ -157,6 +175,12 @@ namespace meta { using List = typename TyOLD::List; }; + + + /** + * Additional specialisation of the basic type sequence type, + * allowing to re-create a (flat) type sequence from a typelist. + */ template struct TySeq< Node > { @@ -171,9 +195,9 @@ namespace meta { using List = Nil; using Seq = TySeq<>; }; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- to be obsoleted - - /** * temporary workaround: strip trailing Nil entries from a * type sequence, to make it compatible with new-style variadic diff --git a/src/lib/meta/util.hpp b/src/lib/meta/util.hpp index 24849ce6a..863d5341e 100644 --- a/src/lib/meta/util.hpp +++ b/src/lib/meta/util.hpp @@ -52,6 +52,10 @@ namespace lib { namespace meta { + template + using SizConst = std::integral_constant; + + /* === conditional definition selector === */ template diff --git a/src/lib/meta/variadic-helper.hpp b/src/lib/meta/variadic-helper.hpp index dd2bf709d..235905aa9 100644 --- a/src/lib/meta/variadic-helper.hpp +++ b/src/lib/meta/variadic-helper.hpp @@ -306,11 +306,11 @@ namespace meta { return size_t(std::tuple_size::value); else if constexpr (lib::meta::is_Typelist::value) - return lib::meta::count::value; + return lib::meta::count(); else { // Fallback: rebind template arguments into a type sequence using Seq = typename RebindVariadic::Type; - return size_t(count::value); + return size_t(count()); } }; diff --git a/src/lib/variant.hpp b/src/lib/variant.hpp index 869d561ba..308f27956 100644 --- a/src/lib/variant.hpp +++ b/src/lib/variant.hpp @@ -216,8 +216,8 @@ namespace lib { { public: - enum { SIZ = meta::maxSize::value - , ALIGN = meta::maxAlign::value + enum { SIZ = meta::maxSize() + , ALIGN = meta::maxAlign() }; template diff --git a/src/steam/mobject/output-designation.hpp b/src/steam/mobject/output-designation.hpp index 81e6a2a76..93953fa62 100644 --- a/src/steam/mobject/output-designation.hpp +++ b/src/steam/mobject/output-designation.hpp @@ -113,7 +113,7 @@ namespace mobject { { VTABLE = sizeof(size_t) , SPEC_SIZ = VTABLE + mp::maxSize< - mp::TyOLD< PID, lumiera_uid, uint>::List>::value + mp::TyOLD< PID, lumiera_uid, uint>::List>() }; typedef lib::OpaqueHolder SpecBuff; diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index 0c4c914ff..b10ad1768 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -335,19 +335,18 @@ return: 0 END -TEST "TypeList_test" TypeList_test < > out: ctor DoIt > out: ctor DoIt > @@ -368,7 +367,7 @@ return: 0 END -TEST "typelist manipulation" TypeListManip_test <-<2>-<3>- out-lit: List2 :-<5>-<6>-<7>- out-lit: Added2 :-<3>-<4>-<5>- diff --git a/tests/library/meta/typelist-test.cpp b/tests/library/meta/typelist-test.cpp index b9b790876..905a176e9 100644 --- a/tests/library/meta/typelist-test.cpp +++ b/tests/library/meta/typelist-test.cpp @@ -21,8 +21,8 @@ #include -using std::string; using std::cout; +using std::endl; namespace lib { @@ -34,19 +34,21 @@ namespace test { { Block() { cout << "- "< - , Block<2> - , Block<3> - , Block<5> - , Block<8> - , Block<13> - >::List TheList; + using SequenceOfTypes = TySeq< Block<21> + , Block<13> + , Block<8> + , Block<5> + , Block<3> + , Block<2> + , Block<1> + >; + using ListOfTypes = typename SequenceOfTypes::List; template @@ -60,7 +62,8 @@ namespace test { { } ; - typedef Chain AssembledClass; + using AssembledClass = Chain; + /*********************************************************************//** * @test try out Loki-style typelist metaprogramming. @@ -73,10 +76,9 @@ namespace test { void run (Arg) { - AssembledClass wow_me_haz_numbers; + AssembledClass me_haz_numbers; - cout << "\n..Size of = " - << sizeof(wow_me_haz_numbers) <<"\n"; + CHECK (1 == sizeof(me_haz_numbers)); } }; diff --git a/tests/library/meta/typelist-util-test.cpp b/tests/library/meta/typelist-util-test.cpp index 7d434a600..46bfcfd8c 100644 --- a/tests/library/meta/typelist-util-test.cpp +++ b/tests/library/meta/typelist-util-test.cpp @@ -27,13 +27,13 @@ namespace test { - typedef TyOLD< int - , uint - , int64_t - , uint64_t - >::List TheList; + using TheList = TySeq< int + , uint + , int64_t + , uint64_t + >::List; - typedef TyOLD< >::List EmptyList; + using EmptyList = TySeq< >::List; @@ -50,23 +50,25 @@ namespace test { class TypeListUtil_test : public Test { void - run (Arg) + run (Arg) { - CHECK (4 == count::value); - CHECK (0 == count::value); + CHECK (4 == count() ); + CHECK (0 == count()); - CHECK (sizeof(int64_t) == maxSize::value); - CHECK (0 == maxSize::value); + CHECK (sizeof(int64_t) == maxSize() ); + CHECK (0 == maxSize() ); + CHECK (alignof(int64_t) == maxAlign() ); + CHECK (0 == maxAlign()); - CHECK ( bool(IsInList::value)); - CHECK ( bool(IsInList::value)); - CHECK ( bool(IsInList::value)); - CHECK ( bool(IsInList::value)); + CHECK ( bool(isInList())); + CHECK ( bool(isInList())); + CHECK ( bool(isInList())); + CHECK ( bool(isInList())); - CHECK (!bool(IsInList::value)); - CHECK (!bool(IsInList::value)); - CHECK (!bool(IsInList::value)); // Note: not-a-typelist yields false too - } + CHECK (!bool(isInList())); + CHECK (!bool(isInList())); + CHECK (!bool(isInList())); // Note: not-a-typelist yields false too + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index dcb5cf1e7..46b348820 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -164231,6 +164231,185 @@ Since then others have made contributions, see the log for the history. + + + + + + + + + + + + + + + +

+ in typeseq-util (etwas versteckt zwischen den Spezialisierungen von Prepend, was wiederum Vorraussetzung ist, so einen Rückweg konstruieren zu können) +

+ + +
+
+ + + +
+ + + + + + +

+ d.h arbeitet ausschließlich auf Typlisten und bezieht sich nirgends auf Typ-Sequenzen +

+ + +
+
+ + + + + + + + + + + + +

+ es stellt nämllich nur auf einen nested  X::List ab +

+ + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + +

+ ...aber nur wenn's einfach geht; eigentlich ist das außerhalb vom Scope und könnte auch später mal gemacht werden (ist nur ein Implementierungsdetail), sofern die bestehende Impl mit den neuen Typlisten arbeitet +

+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +