diff --git a/research/try.cpp b/research/try.cpp index 5660841eb..a60df815c 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -78,11 +78,11 @@ namespace meta{ using Sig = Ret(ARGS...); }; - template + template class can_Invoke { template() (std::declval()...))> + typename SEL = decltype(&FF::operator())> struct Probe { }; @@ -96,28 +96,62 @@ namespace meta{ }; - template - struct ProbeFunctionArgument - { - static_assert(not sizeof(FUN), "Tilt"); - }; - - template - struct ProbeFunctionArgument, enable_if> > - : ProbeFunctionInvocation + template + struct _FunT + : std::false_type { }; - template - struct ProbeFunctionArgument, disable_if> > - : ProbeFunctionArgument + template + struct _FunT> > + : _FunT + { }; + + /** Specialisation for a bare function signature */ + template + struct _FunT + : std::true_type { - + using Ret = RET; + using Args = Types; + using Sig = RET(ARGS...); }; + /** Specialisation for using a function pointer */ + template + struct _FunT + : _FunT + { }; + + /** Specialisation when using a function reference */ + template + struct _FunT + : _FunT + { }; + + /** Specialisation for passing a rvalue reference */ + template + struct _FunT + : _FunT + { }; + + /** Specialisation to deal with member pointer to function */ + template + struct _FunT + : _FunT + { }; + + /** Specialisation to handle member pointer to const function; + * indirectly this specialisation also handles lambdas, + * as redirected by the main template (via `decltype`) */ + template + struct _FunT + : _FunT + { }; + }} using lib::meta::Types; -using lib::meta::can_Invoke; -using lib::meta::ProbeFunctionArgument; +using lib::meta::_FunT; +using lib::meta::enable_if; #define SHOW_TYPE(_TY_) \ @@ -126,6 +160,26 @@ using lib::meta::ProbeFunctionArgument; cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ < +struct FunTrait + { + using XXX = decltype(std::declval() (0)); + + static string doIt() { return "Uh OH:" + lib::meta::typeStr(); } + }; + +template +struct FunTrait> > + { + static string doIt() { return "Yeah FUN:" + lib::meta::typeStr::Sig>(); } + }; int main (int, char**) @@ -136,13 +190,18 @@ main (int, char**) SHOW_TYPE (decltype(lamb1)); SHOW_TYPE (decltype(lamb2)); - SHOW_EXPR ((can_Invoke::value)); - SHOW_EXPR ((can_Invoke::value )); + SHOW_EXPR ((_FunT::value)); + SHOW_EXPR ((_FunT::value)); + SHOW_EXPR ((_FunT::value)); + SHOW_EXPR ((_FunT::value)); - using InferredSIG = typename ProbeFunctionArgument::List>::Sig; - //NOTE does not work with the generic lamb2, because instantiating lab2(string) would be a *compile* error, not a substitution failure + auto funky = function (lamb2); + SHOW_EXPR ((_FunT::value)); - SHOW_TYPE (InferredSIG); + cout << FunTrait::doIt() <::doIt() <::doIt() <::doIt() < - - + +