Investigation: dissect argument packs

start investigation on generic techniques to dissect an variadic argument pack
This commit is contained in:
Fischlurch 2017-09-26 19:23:03 +02:00
parent 372512006f
commit e5dc7ba2bc
5 changed files with 70 additions and 168 deletions

View file

@ -32,15 +32,19 @@
// 1/16 - generic to-string conversion for ostream
// 1/16 - build tuple from runtime-typed variant container
// 3/17 - generic function signature traits, including support for Lambdas
// 9/17 - manipulate variadic templates to treat varargs in several chunks
/** @file try.cpp
** Metaprogramming: unified treatment of functors, function references and lambdas.
** Rework our existing function signature trait to also support lambdas, which forces us
** to investigate and in the end to change the handling of function member pointers.
** Metaprogramming: manipulations on variadic template argument packs.
** Investigation how to transform a parameter pack such as to forward a fixed chunk
** to one sub-ctor and delegate the rest to a tail recursive call.
**
** This investigation is a partial step towards #994 and became necessary to support
** Command definition by Lambda
** This investigation was spurred by an attempt to create an inline storage layout
** with possible heap-based extension. Being able to build such an object layout
** would enable several possibly interesting optimisations when most usage scenarios
** of a class will only use a small element count, while some usages still require
** an essentially unlimited open number of elements.
**
*/
@ -56,169 +60,21 @@ typedef unsigned int uint;
using lib::meta::_Fun;
using std::function;
using std::placeholders::_1;
using std::bind;
using std::string;
using std::tuple;
using std::move;
int
funny (uint i)
{
return -i+1;
}
struct Funky
{
int ii = 2;
int
fun (uint i2)
{
return ii + funny(i2);
}
int
operator() (uint i2)
{
return 2*ii - fun(i2);
}
static int
notfunny (uint i)
{
return 2*funny (i);
}
};
#define SHOW_TYPE(_TY_) \
cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() <<endl;
#define EVAL_PREDICATE(_PRED_) \
cout << STRINGIFY(_PRED_) << "\t : " << _PRED_ <<endl;
template<typename F>
void
showType (F)
{
using Sig = typename _Fun<F>::Sig;
SHOW_TYPE (F);
SHOW_TYPE (Sig);
}
template<typename F>
void
showRef (F&)
{
using Sig = typename _Fun<F>::Sig;
SHOW_TYPE (F);
SHOW_TYPE (Sig);
}
template<typename F>
void
showCRef (F&)
{
using Sig = typename _Fun<F>::Sig;
SHOW_TYPE (F);
SHOW_TYPE (Sig);
}
template<typename F>
void
showRRef (F&&)
{
using Sig = typename _Fun<F>::Sig;
SHOW_TYPE (F);
SHOW_TYPE (Sig);
}
using Fun = function<int(uint)>;
using Fuk = function<int(Funky&, uint)>;
int
main (int, char**)
{
Fun f1{funny};
Fun f2{&funny};
Fun f3{Funky::notfunny};
Fun f4{&Funky::notfunny};
auto memfunP = &Funky::fun;
Fuk f5{memfunP};
Funky funk;
Fun f6{bind (f5, funk, _1)};
auto lambda = [&](uint ii) { return funk.fun(ii); };
Fun f7{lambda};
showType (funny);
showType (&funny);
showType (Funky::notfunny);
showType (memfunP);
showType (lambda);
showType (f7);
cout << "\n\n-------\n";
showRef (funny);
showRef (lambda);
showRef (f7);
showCRef (funny);
showCRef (lambda);
showCRef (f7);
showRRef (move(lambda));
showRRef (move(f7));
showType (move(&funny));
showType (move(lambda));
showType (move(f7));
Fun& funRef = f1;
Funky& funkyRef = funk;
Fun const& funCRef = f1;
Funky const& funkyCRef = funk;
showType (funRef);
showType (funkyRef);
showType (funCRef);
showType (funkyCRef);
cout << "\n\n-------\n";
SHOW_TYPE (decltype(&Funky::operator()));
SHOW_TYPE (decltype(lambda));
SHOW_TYPE (_Fun<int(uint)>::Sig);
SHOW_TYPE (_Fun<Fun&>::Sig);
SHOW_TYPE (_Fun<Fun&&>::Sig);
SHOW_TYPE (_Fun<Fun const&>::Sig);
SHOW_TYPE (_Fun<Funky&>::Sig);
SHOW_TYPE (_Fun<Funky&&>::Sig);
SHOW_TYPE (_Fun<Funky const&>::Sig);
using Siggy = _Fun<Fun>::Sig;
SHOW_TYPE (_Fun<Siggy&>::Sig);
SHOW_TYPE (_Fun<Siggy&&>::Sig);
SHOW_TYPE (_Fun<Siggy const&>::Sig);
cout << "\n.gulp.\n";

View file

@ -249,27 +249,25 @@ namespace meta {
/**
* Extensible Adapter to construct a distinct tuple
* from some arbitrary source type. This includes the
* possibility to re-map elements or element positions.
* Extensible Adapter to construct a distinct tuple from some arbitrary source type.
* This includes the possibility to re-map elements or element positions.
* @tparam TYPES sequence of types to use for the tuple
* @tparam _ElmMapper_ a _template_ to extract each
* constructor argument from the source value.
* On invocation, we'll pick up the source type from the
* actual ctor argument, and then invoke this helper template
* iteratively for each component of the tuple, with arguments
* On invocation, we'll pick up the source type from the actual ctor argument,
* and then invoke this helper template iteratively for each component of the
* tuple, passing as template arguments
* - the source type, as picked up from the constructor
* - the target tuple type, i.e. `Tuple<TYPES>`
* - the actual index position of the tuple element
* to be initialised through this concrete instantiation.
* @remarks this design has several extension points. Pretty much
* any conceivable initialisation logic can be embodied in the
* `_ElmMapper_` template. The sole requirement is that the
* concrete instance is _assignable_ by the source type and
* _convertible_ to the individual member type of the target
* tuple it is invoked for. Moreover, it is possible to build
* a generic _element extractor_, which will be specialised
* on base of the source type accepted. See \ref ExtractArg
* @remarks this design has several extension points. Pretty much any conceivable
* initialisation logic can be embodied in the `_ElmMapper_` template. The sole
* requirement is that the concrete instance is _assignable_ by the source type
* and _convertible_ to the individual member type of the target tuple it is
* invoked for. Moreover, it is possible to build a generic _element extractor_,
* which will be specialised on base of the source type accepted.
* @see ExtractArg
*/
template< typename TYPES
, template<class,class, size_t> class _ElmMapper_

View file

@ -34,9 +34,9 @@
** @see typeseq-manip-test.cpp
** @see typelist.hpp
** @see typelist-util.hpp
** @see tuple-helper.hpp
** @see function.hpp
** @see generator.hpp
** @see tuple.hpp
**
*/

View file

@ -63,6 +63,9 @@ namespace lib {
using lib::Literal;
// class GlobalCtx;
namespace { // Implementation helper: variadic init
}//(End)Implementation helper
@ -82,11 +85,13 @@ namespace lib {
template<typename...ARGS>
explicit
PathArray (ARGS&& ...args)
: elms_{}
{
UNIMPLEMENTED ("initialise path array components");
}
PathArray (PathArray const& o)
: elms_(o.elms_)
{
UNIMPLEMENTED ("copy construct path array components");
}

View file

@ -3831,6 +3831,49 @@
<node CREATED="1506263953722" ID="ID_1293486815" MODIFIED="1506263959604" TEXT="Basis-Abstraktion"/>
<node CREATED="1506263960121" ID="ID_381874562" MODIFIED="1506263965699" TEXT="PathArray">
<icon BUILTIN="pencil"/>
<node CREATED="1506301404246" ID="ID_458341734" MODIFIED="1506301409177" TEXT="Impl-Layout">
<node CREATED="1506301410525" ID="ID_176098837" MODIFIED="1506301414840" TEXT="Rekursiv"/>
<node CREATED="1506301415548" ID="ID_212757263" MODIFIED="1506301419912" TEXT="chunk-wise"/>
</node>
<node CREATED="1506301421612" ID="ID_572376877" MODIFIED="1506301426568" TEXT="Meta-Problem">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1506301428698" ID="ID_1290675306" MODIFIED="1506301433910" TEXT="Parameter-Pack zerlegen">
<node CREATED="1506301435826" ID="ID_1852582857" MODIFIED="1506301447508" TEXT="ersten Teil in ein std::array"/>
<node CREATED="1506301448288" ID="ID_1083459556" MODIFIED="1506301457058" TEXT="zweiten Teil rekursiv..."/>
</node>
<node CREATED="1506301468830" ID="ID_291609200" MODIFIED="1506301471937" TEXT="L&#xf6;sungen">
<node CREATED="1506301476836" ID="ID_1339982909" MODIFIED="1506302323712" TEXT="Stackoverflow">
<icon BUILTIN="idea"/>
<node CREATED="1506301629128" ID="ID_1265747852" LINK="https://stackoverflow.com/questions/14261183/how-to-make-generic-computations-over-heterogeneous-argument-packs-of-a-variadic" MODIFIED="1506301640408" TEXT="Param-Pack-Library"/>
<node CREATED="1506301658388" ID="ID_284261237" LINK="https://stackoverflow.com/users/1932150/andy-prowl" MODIFIED="1506301669997" TEXT="von Andy Prowl"/>
<node CREATED="1506302060966" ID="ID_37516099" LINK="https://stackoverflow.com/questions/16821654/splitting-argpack-in-half/16980937#16980937" MODIFIED="1506302137771" TEXT="einfache L&#xf6;sung: split Pack in half"/>
<node CREATED="1506302079276" ID="ID_539701222" LINK="https://stackoverflow.com/users/2361316/joe" MODIFIED="1506302087043" TEXT="von User Joe"/>
<node CREATED="1506303631812" ID="ID_1461128808" LINK="https://stackoverflow.com/questions/5484930/split-variadic-template-arguments/20814644#20814644" MODIFIED="1506303806992" TEXT="direkt initializer_list verwenden"/>
<node CREATED="1506303644395" ID="ID_1907242246" LINK="https://stackoverflow.com/users/2684539/jarod42" MODIFIED="1506303675990" TEXT="von user Jarod42 12/2013"/>
</node>
<node CREATED="1506301674594" ID="ID_573792630" MODIFIED="1506301767802" TEXT="Boost.fusion verwenden">
<icon BUILTIN="button_cancel"/>
<node CREATED="1506301681345" ID="ID_1364627462" MODIFIED="1506301687084" TEXT="Param-Pack in Tupel"/>
<node CREATED="1506301687720" ID="ID_1178221359" MODIFIED="1506301696419" TEXT="Tupel mit Boost.fustion manipulieren"/>
<node CREATED="1506301696911" ID="ID_1626810109" MODIFIED="1506301705897" TEXT="Compiler optimiert Tupel weg">
<node CREATED="1506301725107" ID="ID_1409951481" MODIFIED="1506301731668" TEXT="Tupel von Referenzen"/>
<node CREATED="1506301713285" ID="ID_703461640" MODIFIED="1506301719136" TEXT="GCC und Clang"/>
<node CREATED="1506301719660" ID="ID_1581101665" MODIFIED="1506301722999" TEXT="in Release-Builds"/>
</node>
</node>
<node CREATED="1506301773341" ID="ID_515001314" MODIFIED="1506301831038" TEXT="Entscheidung">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
<node CREATED="1506301780644" ID="ID_143930610" MODIFIED="1506301822914" TEXT="Boost.fustion abgelehnt">
<icon BUILTIN="yes"/>
<node CREATED="1506301789546" ID="ID_322419894" MODIFIED="1506301792558" TEXT="verwendet MPL"/>
<node CREATED="1506301793130" ID="ID_1764621800" MODIFIED="1506301797158" TEXT="verwendet Boost.tuple"/>
<node CREATED="1506301797721" ID="ID_1580459971" MODIFIED="1506301801941" TEXT="generell undurchsichtig"/>
<node CREATED="1506301802865" ID="ID_1127036077" MODIFIED="1506301816915" TEXT="erfordert hohes Abstraktionsniveau"/>
</node>
<node CREATED="1506301834493" ID="ID_52512330" MODIFIED="1506301846055" TEXT="selber schreiben anhand Beispiel"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1506181727069" ID="ID_467120404" MODIFIED="1506181737140" TEXT="lokale Pr&#xe4;dikate">