Library: extract type rebinding helper

...turns out this is entirely generic and not tied to the context
within ActivityDetector, where it was first introduced to build a
mock functor to log all invocations.

Basically this meta-function generates a new instantiation of the
template X, using the variadic argument pack from template U<ARGS...>
This commit is contained in:
Fischlurch 2023-08-01 14:52:20 +02:00
parent db1adb63a7
commit 49f2e34e4c
8 changed files with 48 additions and 28 deletions

View file

@ -129,13 +129,13 @@ namespace meta {
/** temporary workaround: match and rebind the type sequence from a tuple */ /** temporary workaround: match and rebind the type sequence from a tuple */
template<typename...TYPES> template<typename...TYPES>
struct RebindTySeq struct RebindTupleTypes
{ {
using Seq = typename Types<TYPES...>::Seq; using Seq = typename Types<TYPES...>::Seq;
using List = typename Seq::List; using List = typename Seq::List;
}; };
template<typename...TYPES> template<typename...TYPES>
struct RebindTySeq<std::tuple<TYPES...>> struct RebindTupleTypes<std::tuple<TYPES...>>
{ {
using Seq = typename Types<TYPES...>::Seq; using Seq = typename Types<TYPES...>::Seq;
using List = typename Seq::List; using List = typename Seq::List;

View file

@ -60,6 +60,7 @@
namespace lib { namespace lib {
namespace meta { namespace meta {
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND -- to be obsoleted
/** /**
* temporary workaround: * temporary workaround:
* alternative definition of "type sequence", * alternative definition of "type sequence",
@ -117,6 +118,7 @@ namespace meta {
{ {
using Seq = TySeq<>; // NOTE: this causes the result to be a TySeq using Seq = TySeq<>; // NOTE: this causes the result to be a TySeq
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #987 temporary WORKAROUND(End) -- to be obsoleted
@ -144,6 +146,10 @@ namespace meta {
/* ==== Build Variadic Sequences ==== **/
/** Hold a sequence of index numbers as template parameters */ /** Hold a sequence of index numbers as template parameters */
template<size_t...idx> template<size_t...idx>
struct IndexSeq struct IndexSeq
@ -230,7 +236,7 @@ namespace meta {
template<typename...TYPES> template<typename...TYPES>
struct BuildIdxIter<Types<TYPES...>> struct BuildIdxIter<Types<TYPES...>>
{ {
/////TODO as long as Types is not variadic (#987), we need to strip NullType here (instead of just using sizeof...(TYPES) ///////////////////////TICKET #987 : since Types<T...> is not variadic, need to strip NullType here (instead of just using sizeof...(TYPES)
enum {SIZ = lib::meta::count<typename Types<TYPES...>::List>::value }; enum {SIZ = lib::meta::count<typename Types<TYPES...>::List>::value };
using Builder = BuildIndexSeq<SIZ>; using Builder = BuildIndexSeq<SIZ>;
@ -254,6 +260,34 @@ namespace meta {
/* ==== Rebinding Variadic Arguments ==== **/
/**
* Metaprogramming helper to transfer variadic arguments.
* - builds a new type instantiation from the Template \a X
* - possibly picks up the variadic argument pack from a given
* source template `U<ARGS....>`
* @tparam X a variadic template
*/
template<template<typename...> class X, typename...ARGS>
struct RebindVariadic
{
using Type = X<ARGS...>;
};
template<template<typename...> class X
,template<typename...> class U
,typename...ARGS>
struct RebindVariadic<X, U<ARGS...>>
{
using Type = X<ARGS...>;
};
/* ==== Manipulation of variadic arguments ==== **/ /* ==== Manipulation of variadic arguments ==== **/

View file

@ -80,7 +80,7 @@ namespace control {
using ArgumentBuff = InPlaceBuffer<ArgHolder>; using ArgumentBuff = InPlaceBuffer<ArgHolder>;
using ArgTuple = typename ArgHolder::ArgTuple; using ArgTuple = typename ArgHolder::ArgTuple;
using Args = typename lib::meta::RebindTySeq<ArgTuple>::Seq; // std::tuple<ARGS...> to Types<ARGS...> using Args = typename lib::meta::RebindTupleTypes<ArgTuple>::Seq; // std::tuple<ARGS...> to Types<ARGS...>
/* ====== in-place argument storage ====== */ /* ====== in-place argument storage ====== */

View file

@ -86,7 +86,7 @@ namespace control {
using MementoBuff = InPlaceBuffer<MemHolder>; using MementoBuff = InPlaceBuffer<MemHolder>;
using ArgTuple = typename ArgHolder::ArgTuple; using ArgTuple = typename ArgHolder::ArgTuple;
using Args = typename lib::meta::RebindTySeq<ArgTuple>::Seq; // std::tuple<ARGS...> to Types<ARGS...> using Args = typename lib::meta::RebindTupleTypes<ArgTuple>::Seq; // std::tuple<ARGS...> to Types<ARGS...>
/* ====== in-place storage buffers ====== */ /* ====== in-place storage buffers ====== */

View file

@ -80,7 +80,7 @@ namespace test {
string > string >
showType () showType ()
{ {
using TypeList = typename RebindTySeq<TUP>::List; using TypeList = typename RebindTupleTypes<TUP>::List;
using DumpPrinter = InstantiateChained<TypeList, Printer, NullP>; using DumpPrinter = InstantiateChained<TypeList, Printer, NullP>;
return "TUPLE" return "TUPLE"

View file

@ -117,10 +117,10 @@ namespace test {
void void
check_tuple_from_Typelist() check_tuple_from_Typelist()
{ {
typedef Types1::List L1; // starting from an existing Typelist... using L1 = Types1::List; // ... start from existing Typelist...
typedef Tuple<L1> T_L1; // derive a tuple type from this typelist using T_L1 = Tuple<L1>; // derive a tuple type from this typelist
typedef RebindTySeq<T_L1>::Seq Seq1; using Seq1 = RebindTupleTypes<T_L1>::Seq;
// extract the underlying type sequence // extract the underlying type sequence
DISPLAY (T_L1); DISPLAY (T_L1);
DISPLAY (Seq1); DISPLAY (Seq1);

View file

@ -85,6 +85,7 @@ namespace test {
// using lib::time::TimeValue; // using lib::time::TimeValue;
// using lib::time::Time; // using lib::time::Time;
// using lib::HashVal; // using lib::HashVal;
using lib::meta::RebindVariadic;
using util::isnil; using util::isnil;
// using util::isSameObject; // using util::isSameObject;
// using fixture::Segmentation; // using fixture::Segmentation;
@ -92,22 +93,6 @@ namespace test {
// using vault::gear::Job; // using vault::gear::Job;
// using vault::gear::JobClosure; // using vault::gear::JobClosure;
namespace {
template<template<typename...> class X, typename...ARGS>
struct _RebindTypeSeq
{
using Type = X<ARGS...>;
};
template<template<typename...> class X
,template<typename...> class U
,typename...ARGS>
struct _RebindTypeSeq<X, U<ARGS...>>
{
using Type = X<ARGS...>;
};
}
/** /**
@ -191,7 +176,7 @@ namespace test {
using Args = typename lib::meta::_Fun<SIG>::Args; using Args = typename lib::meta::_Fun<SIG>::Args;
using ArgsX = typename lib::meta::StripNullType<Args>::Seq; ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic using ArgsX = typename lib::meta::StripNullType<Args>::Seq; ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic
using SigTypes = typename lib::meta::Prepend<Ret, ArgsX>::Seq; using SigTypes = typename lib::meta::Prepend<Ret, ArgsX>::Seq;
using Functor = typename _RebindTypeSeq<DiagnosticFun, SigTypes>::Type; using Functor = typename RebindVariadic<DiagnosticFun, SigTypes>::Type;
return Functor{id, eventLog_}; return Functor{id, eventLog_};
} }

View file

@ -81678,8 +81678,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/> <icon BUILTIN="yes"/>
</node> </node>
<node CREATED="1690832776060" ID="ID_135731051" MODIFIED="1690832801676" TEXT="X&lt;ARGS...&gt; &#x27fc; U&lt;ARGS...&gt;"/> <node CREATED="1690832776060" ID="ID_135731051" MODIFIED="1690832801676" TEXT="X&lt;ARGS...&gt; &#x27fc; U&lt;ARGS...&gt;"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690832821366" ID="ID_958989562" MODIFIED="1690832834253" TEXT="als generisches Util extrahieren"> <node COLOR="#338800" CREATED="1690832821366" ID="ID_958989562" MODIFIED="1690894004134" TEXT="als generisches Util extrahieren">
<icon BUILTIN="flag-yellow"/> <icon BUILTIN="button_ok"/>
</node>
</node> </node>
</node> </node>
</node> </node>