From c5bff75bc2abd4eb96493dcf44697b041c4b64c1 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 18 Mar 2017 23:31:10 +0100 Subject: [PATCH] Function-Tools: start investigation regarding Signatures and member pointers It is not clear what would be the 'right' way to handle a member pointer to function within the function-trait _Fun. The existing implementation choose to inject an additional parameter for the enclosing class ("this"), which seems to collide with the intention to use this overload with the "decltype trick" to integrate support for lambdas. As it turns out, this specific code path of the existing _Fun trait was not yet used, fortunately, so we're free to search for the proper design here... --- research/try.cpp | 116 ++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 2d42e76ff..a4b034715 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -31,47 +31,62 @@ // 8/15 - generalising the Variant::Visitor // 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 /** @file try.cpp - ** Metaprogramming: how to unload the contents of a runtime typed variant sequence - ** into ctor arguments of a (compile time typed) tuple. This involves two problems - ** - how to combine iteration, compile-time indexing and run-time access. - ** - how to overcome the runtime-to-compiletime barrier, using a pre-generated - ** double-dispatch (visitor). + ** Metaprogramming: unified treatment of functors, function references and lambdas. ** - ** The concrete problem prompting this research is the necessity to receive - ** a command invocation parameter tuple from a Record + ** This investigation is a partial step towards #994 and became necessary to support + ** Command definition by Lambda ** */ typedef unsigned int uint; -#include "lib/symbol.hpp" -#include "lib/time/timevalue.hpp" -#include "lib/meta/tuple-record-init.hpp" #include "lib/format-cout.hpp" #include "lib/format-util.hpp" +#include "lib/meta/function.hpp" -#include +#include #include -using lib::Literal; -using lib::Variant; -using lib::idi::EntryID; -using lib::diff::Rec; -using lib::diff::MakeRec; -using lib::diff::GenNode; -using lib::meta::Types; -using lib::meta::Tuple; -using lib::meta::buildTuple; -using lib::time::TimeVar; -using lib::time::Time; +using lib::meta::_Fun; +using std::function; +using std::placeholders::_1; +using std::bind; using std::string; using std::tuple; +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); + } + }; @@ -81,55 +96,44 @@ using std::tuple; #define EVAL_PREDICATE(_PRED_) \ cout << STRINGIFY(_PRED_) << "\t : " << _PRED_ < void -verifyConversions() +showType (F) { - using lib::meta::GenNodeAccessor; - using std::is_arithmetic; - using std::is_floating_point; - using lib::meta::is_nonFloat; - using lib::hash::LuidH; + using Sig = typename _Fun::Sig; - - EVAL_PREDICATE(is_arithmetic ::value) - EVAL_PREDICATE(is_arithmetic ::value) - EVAL_PREDICATE(is_floating_point::value) - EVAL_PREDICATE(is_nonFloat ::value) - - EVAL_PREDICATE(GenNodeAccessor ::allow_Conversion ::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion ::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion ::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor ::allow_Conversion ::value) - EVAL_PREDICATE(GenNodeAccessor ::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor::allow_Conversion::value) - EVAL_PREDICATE(GenNodeAccessor ::allow_Conversion::value) - - cout <; +using Fuk = function; int main (int, char**) { - verifyConversions(); + Fun f1{funny}; + Fun f2{&funny}; - using NiceTypes = Types; - using UgglyTypes = Types, string, int, int64_t, double, TimeVar>; + Fun f3{Funky::notfunny}; + Fun f4{&Funky::notfunny}; - Rec args = MakeRec().scope("lalü", 42); - Rec urgs = MakeRec().scope("lalü", "lala", 12, 34, 5.6, Time(7,8,9)); + auto memfunP = &Funky::fun; - cout << args < (args) < (urgs) <