Research: possiblity to detect a generic Lambda?

This commit is contained in:
Fischlurch 2017-11-23 17:49:43 +01:00
parent 18553f22b2
commit 01937f9736
3 changed files with 77 additions and 52 deletions

View file

@ -34,31 +34,21 @@
// 3/17 - generic function signature traits, including support for Lambdas
// 9/17 - manipulate variadic templates to treat varargs in several chunks
// 11/17 - metaprogramming to detect the presence of extension points
// 11/17 - detect generic lambda
/** @file try.cpp
** Metaprogramming: how to detect that a type in question exposes a free function extension point.
** Since such an extension point is typically injected alongside with the type exposing the extension
** point and intended to be picked up by ADL, all we have to check is if it is valid to invoke the
** extension point function with an instance of the target type.
**
** There are two difficulties to overcome, though
** - a function might return void. And while we may indeed pick up `void` from `decltype(expr)`,
** there is not much we can do with a void type. The remedy is just to use this type as template
** parameter on another template instantiation, which fails if this type can not legally be formed.
** - we do not know how to get a value of the type to probe, in order to feed it into the extension
** point function. Fortunately, the `std::declval<TYPE>()` function was included into the C++ language
** for this very purpose.
** Metaprogramming: is it possible to distinguish a generic lambda from something not a function at all?
*/
typedef unsigned int uint;
#include "lib/format-cout.hpp"
#include "lib/format-util.hpp"
#include "lib/meta/duck-detector.hpp"
#include "lib/meta/function.hpp"
#include "lib/test/test-helper.hpp"
#include <functional>
//#include <functional>
#include <utility>
#include <string>
@ -108,49 +98,15 @@ class Fishy
friend void fun1 (Fishy&);
};
#define META_DETECT_EXTENSION_POINT(_FUN_) \
template<typename TY> \
class HasExtensionPoint_##_FUN_ \
{ \
template<typename X, \
typename SEL = decltype( _FUN_(std::declval<X>()))>\
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
META_DETECT_EXTENSION_POINT (fun)
META_DETECT_EXTENSION_POINT (fun1)
int
main (int, char**)
{
fun1 (23);
fun1 ();
auto lamb1 = [](int i) { return double(i) / (i*i); };
auto lamb2 = [](auto i) { return double(i) / (i*i); };
SHOW_EXPR ( HasExtensionPoint_fun<long>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<long>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<long&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<long&&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<char>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<char&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<char&&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<string>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<void>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<Cheesy>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<Fishy>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<Fishy&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<Fishy&&>::value );
SHOW_EXPR ( HasExtensionPoint_fun1<Fishy const&>::value );
SHOW_TYPE (decltype(lamb1));
SHOW_TYPE (decltype(lamb2));
cout << "\n.gulp.\n";

View file

@ -311,6 +311,13 @@ namespace test{
treeExplore(CountDown{5})
.expand([](CountDown const& core){ return CountDown{ yield(core) - 1}; })
);
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1117
verify_treeExpandingIterator(
treeExplore(CountDown{5})
.expand([](auto & it){ return CountDown{ *it - 1}; })
);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1117
}

View file

@ -5188,6 +5188,68 @@
<node CREATED="1511402855174" ID="ID_386377958" MODIFIED="1511402861001" TEXT="beides k&#xf6;nnen unterschiedliche Typen sein"/>
<node CREATED="1511402861613" ID="ID_1536434222" MODIFIED="1511402872072" TEXT="solange der expandFunktor beide akzeptiert...."/>
</node>
<node CREATED="1511455454190" ID="ID_1384978479" MODIFIED="1511455481991" TEXT="Problem: kein generischer Expand-Functor">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1511455484027" ID="ID_548359395" MODIFIED="1511455605340" TEXT="unmittelbare Folge davon, da&#xdf; wir den Typ des Expand-Funktors analysieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
_fun&lt;FUN&gt;::Sig scheitert
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="info"/>
</node>
<node CREATED="1511455502648" ID="ID_1704619802" MODIFIED="1511455566686">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
das ist aber <i>unpraktisch</i>....
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="smily_bad"/>
</node>
<node CREATED="1511455513119" ID="ID_128446946" MODIFIED="1511455554663" TEXT="denn grade Iterator-Typen kennt der Benutzer typischerweise nicht">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
....also ist es gradezu nat&#252;rlich,
</p>
<p>
einen Expand-Funktor als generisches Lambda zu schreiben!
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1511455607914" HGAP="56" ID="ID_1866082603" MODIFIED="1511455626668" TEXT="Untersuchung" VSHIFT="39">
<icon BUILTIN="pencil"/>
<node CREATED="1511455644829" ID="ID_1545300823" MODIFIED="1511455655796" TEXT="ist generisches Labmda detektierbar?">
<icon BUILTIN="help"/>
</node>
<node CREATED="1511455664043" ID="ID_1966980711" MODIFIED="1511455676078" TEXT="kann man Fallback-Mechanismus bauen?">
<icon BUILTIN="help"/>
<node CREATED="1511455698398" ID="ID_91244603" MODIFIED="1511455735493" TEXT="wenn generisch...">
<icon BUILTIN="idea"/>
<node CREATED="1511455705149" ID="ID_1094783485" MODIFIED="1511455710889" TEXT="dann versuche"/>
<node CREATED="1511455711525" ID="ID_1584168712" MODIFIED="1511455721127" TEXT="(a) mit dem Value-Type ins Argument"/>
<node CREATED="1511455721907" ID="ID_312038081" MODIFIED="1511455730558" TEXT="(b) mit dem Iterator-Typ ins Argument"/>
</node>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1510969031379" ID="ID_358406634" MODIFIED="1511227807158" TEXT="verify_transformOperation();">