From e5dc7ba2bcb82e74d9b9978f3126097744a3d7cf Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 26 Sep 2017 19:23:03 +0200 Subject: [PATCH] Investigation: dissect argument packs start investigation on generic techniques to dissect an variadic argument pack --- research/try.cpp | 162 ++-------------------------------- src/lib/meta/tuple-helper.hpp | 26 +++--- src/lib/meta/typeseq-util.hpp | 2 +- src/lib/path-array.hpp | 5 ++ wiki/thinkPad.ichthyo.mm | 43 +++++++++ 5 files changed, 70 insertions(+), 168 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 5be3b928d..9a2a8a207 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -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_>() < -void -showType (F) - { - using Sig = typename _Fun::Sig; - - SHOW_TYPE (F); - SHOW_TYPE (Sig); - } - -template -void -showRef (F&) - { - using Sig = typename _Fun::Sig; - - SHOW_TYPE (F); - SHOW_TYPE (Sig); - } - -template -void -showCRef (F&) - { - using Sig = typename _Fun::Sig; - - SHOW_TYPE (F); - SHOW_TYPE (Sig); - } - -template -void -showRRef (F&&) - { - using Sig = typename _Fun::Sig; - - SHOW_TYPE (F); - SHOW_TYPE (Sig); - } - - -using Fun = function; -using Fuk = function; 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::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - - using Siggy = _Fun::Sig; - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); - SHOW_TYPE (_Fun::Sig); cout << "\n.gulp.\n"; diff --git a/src/lib/meta/tuple-helper.hpp b/src/lib/meta/tuple-helper.hpp index 66337c970..ea940a02e 100644 --- a/src/lib/meta/tuple-helper.hpp +++ b/src/lib/meta/tuple-helper.hpp @@ -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` * - 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 _ElmMapper_ diff --git a/src/lib/meta/typeseq-util.hpp b/src/lib/meta/typeseq-util.hpp index 88f4d9ba1..cab1eb686 100644 --- a/src/lib/meta/typeseq-util.hpp +++ b/src/lib/meta/typeseq-util.hpp @@ -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 ** */ diff --git a/src/lib/path-array.hpp b/src/lib/path-array.hpp index 54b74c273..738666925 100644 --- a/src/lib/path-array.hpp +++ b/src/lib/path-array.hpp @@ -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 explicit PathArray (ARGS&& ...args) + : elms_{} { UNIMPLEMENTED ("initialise path array components"); } PathArray (PathArray const& o) + : elms_(o.elms_) { UNIMPLEMENTED ("copy construct path array components"); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 985b78e09..7ddc91a11 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -3831,6 +3831,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +