Scheduler: solve difficulties with member function signature
The approach to provide the ExecutionCtx seems to work out well; after some investigation I found a solution how to code a generic signature-check for "any kind of function-like member"... (the trick is to pass a pointer or member-pointer, which happens to be syntactically the same and can be handled with our existing function signature helper after some minor tweaks)
This commit is contained in:
parent
0d2d8c3413
commit
d67c62b02f
5 changed files with 286 additions and 115 deletions
173
research/try.cpp
173
research/try.cpp
|
|
@ -46,17 +46,15 @@
|
|||
// 03/20 - investigate type deduction bug with PtrDerefIter
|
||||
// 01/21 - look for ways to detect the presence of an (possibly inherited) getID() function
|
||||
// 08/22 - techniques to supply additional feature selectors to a constructor call
|
||||
// 10/23 - search for ways to detect signatures of member functions and functors uniformly
|
||||
|
||||
|
||||
/** @file try.cpp
|
||||
* Investigate techniques to supply additional descriptive ctor arguments in a type safe way.
|
||||
* The idea is to provide friend functors, which might tweak or reset internal settings;
|
||||
* these functors are packaged into free standing friend functions with intuitive naming,
|
||||
* which, on call-site, look like algebraic expressions/data-types.
|
||||
*
|
||||
* If desired, this mechanism can be mixed-in and integrated into a constructor call,
|
||||
* thus optionally allowing for arbitrary extra qualifiers, even with extra arguments.
|
||||
* @see builder-qualifier-support.hpp (wrapped as support lib)
|
||||
* Investigate how to detect the signature of a _function-like member,_ irrespective
|
||||
* if referring to a static function, a member function or a functor member. Turns out this
|
||||
* can be achieved in a syntactically uniform way by passing either a pointer or member pointer.
|
||||
* @see vault::gear::_verify_usable_as_ExecutionContext
|
||||
* @see lib::meta::isFunMember
|
||||
*/
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
|
@ -67,100 +65,101 @@ typedef unsigned int uint;
|
|||
#include "lib/test/diagnostic-output.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include "lib/meta/function.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
template<class TAR>
|
||||
class PropertyQualifierSupport
|
||||
struct Stat
|
||||
{
|
||||
protected:
|
||||
using Manipulator = std::function<void(TAR&)>;
|
||||
|
||||
struct Qualifier
|
||||
: Manipulator
|
||||
{
|
||||
using Manipulator::Manipulator;
|
||||
};
|
||||
static long fun (double, char*) {return 42; }
|
||||
};
|
||||
|
||||
template<class... QUALS>
|
||||
friend void qualify(TAR& target, Qualifier& qualifier, QUALS& ...qs)
|
||||
struct Funi
|
||||
{
|
||||
std::function<long(double, char*)> fun;
|
||||
short gun;
|
||||
};
|
||||
|
||||
struct Dyna
|
||||
{
|
||||
long fun (double, char*) const {return 42; }
|
||||
};
|
||||
|
||||
|
||||
using lib::meta::_Fun;
|
||||
|
||||
|
||||
/** @deprecated this is effectively the same than using decltype */
|
||||
template<typename P>
|
||||
struct Probe
|
||||
: _Fun<P>
|
||||
{
|
||||
qualifier(target);
|
||||
qualify(target, qs...);
|
||||
}
|
||||
|
||||
friend void qualify(TAR&){ }
|
||||
Probe(P&&){}
|
||||
};
|
||||
|
||||
public:
|
||||
// default construct and copyable
|
||||
};
|
||||
template<typename FUN, typename SIG, bool =_Fun<FUN>()>
|
||||
struct has_SIGx
|
||||
: std::is_same<SIG, typename _Fun<FUN>::Sig>
|
||||
{
|
||||
// has_SIGx() = default;
|
||||
// has_SIGx(FUN, _Fun<SIG>){ }
|
||||
};
|
||||
|
||||
|
||||
class Feat
|
||||
: PropertyQualifierSupport<Feat>
|
||||
template<typename FUN, typename X>
|
||||
struct has_SIGx<FUN,X,false>
|
||||
: std::false_type
|
||||
{
|
||||
// has_SIGx() = default;
|
||||
// has_SIGx(FUN, _Fun<X>){ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename SIG, typename FUN>
|
||||
constexpr inline auto
|
||||
isFunMember (FUN)
|
||||
{
|
||||
|
||||
friend Qualifier bla();
|
||||
friend Qualifier blubb(string);
|
||||
|
||||
public:
|
||||
Feat() = default;
|
||||
|
||||
template<class... QS>
|
||||
Feat(Qualifier qual, QS... qs)
|
||||
: Feat{}
|
||||
{
|
||||
qualify(*this, qual, qs...);
|
||||
}
|
||||
|
||||
operator string () const
|
||||
{
|
||||
return "Feat{"+prop_+"}";
|
||||
}
|
||||
|
||||
private:
|
||||
string prop_{"∅"};
|
||||
};
|
||||
|
||||
|
||||
Feat::Qualifier
|
||||
bla()
|
||||
{
|
||||
return Feat::Qualifier{[](Feat& feat)
|
||||
{
|
||||
feat.prop_ = "bla";
|
||||
}};
|
||||
}
|
||||
|
||||
Feat::Qualifier
|
||||
blubb(string murks)
|
||||
{
|
||||
return Feat::Qualifier{[=](Feat& feat)
|
||||
{
|
||||
feat.prop_ += ".blubb("+murks+")";
|
||||
}};
|
||||
}
|
||||
|
||||
return has_SIGx<FUN,SIG>{};
|
||||
}
|
||||
|
||||
#define ARSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
|
||||
static_assert (isFunMember<_SIG_>(_EXPR_), \
|
||||
"Member " STRINGIFY(_EXPR_) " unsuitable, expect function signature: " STRINGIFY(_SIG_));
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
{
|
||||
Feat f0;
|
||||
SHOW_EXPR(f0);
|
||||
using F1 = decltype(Stat::fun);
|
||||
using F2 = decltype(Funi::fun);
|
||||
using F3 = decltype(&Dyna::fun);
|
||||
|
||||
Feat f1(bla());
|
||||
SHOW_EXPR(f1);
|
||||
SHOW_TYPE(F1)
|
||||
SHOW_TYPE(F2)
|
||||
SHOW_TYPE(F3)
|
||||
|
||||
Feat f2(blubb("Ψ"));
|
||||
SHOW_EXPR(f2);
|
||||
using F1a = decltype(&Stat::fun);
|
||||
using F2a = decltype(&Funi::fun);
|
||||
using F2b = decltype(&Funi::gun);
|
||||
SHOW_TYPE(F1a)
|
||||
SHOW_TYPE(F2a)
|
||||
SHOW_TYPE(F2b)
|
||||
|
||||
Feat f3(bla(),blubb("↯"));
|
||||
SHOW_EXPR(f3);
|
||||
SHOW_TYPE(_Fun<F1>::Sig)
|
||||
SHOW_TYPE(_Fun<F2>::Sig)
|
||||
SHOW_TYPE(_Fun<F3>::Sig)
|
||||
|
||||
SHOW_TYPE(_Fun<F1a>::Sig)
|
||||
SHOW_TYPE(_Fun<F2a>::Sig)
|
||||
|
||||
Feat f4(blubb("💡"), bla()); // Note: evaluated from left to right, bla() overwrites prop
|
||||
SHOW_EXPR(f4);
|
||||
SHOW_EXPR(_Fun<F2a>::value)
|
||||
SHOW_EXPR(_Fun<F2b>::value)
|
||||
cout << "\n--------\n";
|
||||
|
||||
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Stat::fun)))
|
||||
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Funi::fun)))
|
||||
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Funi::gun)))
|
||||
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Dyna::fun)))
|
||||
|
||||
ARSERT_MEMBER_FUNCTOR (&Stat::fun, long(double,char*));
|
||||
ARSERT_MEMBER_FUNCTOR (&Dyna::fun, long(double,char*));
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@
|
|||
* Defines a metafunction (template), allowing to detect
|
||||
* the presence of a member function with the specific
|
||||
* signature, as defined by the parameters.
|
||||
* @note this check is not sensible to overloads,
|
||||
* @note this check is not sensitive to overloads,
|
||||
* due to the explicitly given argument types
|
||||
*/
|
||||
#define META_DETECT_FUNCTION(_RET_TYPE_,_FUN_NAME_,_ARGS_) \
|
||||
|
|
|
|||
|
|
@ -175,6 +175,12 @@ namespace meta{
|
|||
: _Fun<RET(ARGS...)>
|
||||
{ };
|
||||
|
||||
/** allow also to probe _plain member fields,_ which may hold a functor */
|
||||
template<class C, typename FUN>
|
||||
struct _Fun<FUN (C::*)>
|
||||
: _Fun<FUN>
|
||||
{ };
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -187,11 +193,17 @@ namespace meta{
|
|||
* or std::function instance, or λ instance or language function
|
||||
* reference or function pointer
|
||||
*/
|
||||
template<typename FUN, typename SIG>
|
||||
template<typename FUN, typename SIG, bool =_Fun<FUN>()>
|
||||
struct has_Sig
|
||||
: std::is_same<SIG, typename _Fun<FUN>::Sig>
|
||||
{ };
|
||||
|
||||
/** catch-all to prevent compilation failure for anything not function-like. */
|
||||
template<typename FUN, typename X>
|
||||
struct has_Sig<FUN,X, false>
|
||||
: std::false_type
|
||||
{ };
|
||||
|
||||
/**
|
||||
* Macro for a compile-time check to verify the given
|
||||
* generic functors or lambdas expose some expected signature.
|
||||
|
|
@ -203,6 +215,33 @@ namespace meta{
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to pick up a member field for verification
|
||||
* @tparam SIG signature of the _function like_ entity expected
|
||||
* @tparam FUN address- or member-pointer, e.g. `&Class::member`
|
||||
* @return suitably parametrised \ref has_Sig instance (which is bool convertible)
|
||||
* @remark intended for use with generic types, when expecting a _somehow invokable_
|
||||
* member, irrespective if a static function, member function or functor object
|
||||
*/
|
||||
template<typename SIG, typename FUN>
|
||||
constexpr inline auto
|
||||
isFunMember (FUN)
|
||||
{
|
||||
return has_Sig<FUN,SIG>{};
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro for a compile-time check to verify some member is present
|
||||
* and comprises something invokable with a specific signature.
|
||||
* @remark typically used with _generic types_ or bindings
|
||||
*/
|
||||
#define ASSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
|
||||
static_assert (lib::meta::isFunMember<_SIG_>(_EXPR_), \
|
||||
"Member " STRINGIFY(_EXPR_) " unsuitable, expect function signature: " STRINGIFY(_SIG_));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Placeholder marker for a special argument position to be supplied later */
|
||||
|
|
|
|||
|
|
@ -182,21 +182,13 @@ namespace gear {
|
|||
constexpr void
|
||||
_verify_usable_as_ExecutionContext ()
|
||||
{
|
||||
#define ASSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
|
||||
static_assert (lib::meta::has_Sig<decltype(_EXPR_), _SIG_>(), \
|
||||
"Execution-Context: " STRINGIFY(_EXPR_) " expect function with signature: " STRINGIFY(_SIG_));
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::post, Proc(Time, Activity&, EXE&));
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::work, void(Time, size_t));
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::done, void(Time, size_t));
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::tick, Proc(Time));
|
||||
|
||||
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::post, Proc(Time, Activity&, EXE&));
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::work, void(Time, size_t));
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::done, void(Time, size_t));
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::tick, Proc(Time));
|
||||
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::getWaitDelay, Offset());
|
||||
ASSERT_MEMBER_FUNCTOR (EXE::getSchedTime, Time());
|
||||
|
||||
|
||||
#undef ASSERT_MEMBER_FUNCTOR
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::getWaitDelay, Offset());
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::getSchedTime, Time());
|
||||
}
|
||||
|
||||
}//(End)namespace activity
|
||||
|
|
@ -604,7 +596,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::activate (Time now, EXE& executionCtx)
|
||||
{
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case INVOKE:
|
||||
|
|
@ -651,7 +643,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::dispatch (Time now, EXE& executionCtx)
|
||||
{
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case NOTIFY:
|
||||
|
|
@ -681,7 +673,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::notify (Time now, EXE& executionCtx)
|
||||
{
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case GATE:
|
||||
|
|
|
|||
|
|
@ -57321,6 +57321,121 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1697906135803" ID="ID_47415467" MODIFIED="1697927623614" TEXT="Function utils">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1697906141042" FOLDED="true" ID="ID_334205441" MODIFIED="1697927708161" TEXT="lib::meta::_Fun">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1697906147625" ID="ID_940224255" MODIFIED="1697906184451">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
damit kann man von jedem <i>»Invocable« </i>eine Signatur abgreifen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#690f14" CREATED="1697906227094" ID="ID_1918952021" LINK="https://issues.lumiera.org/ticket/994" MODIFIED="1697906274433" TEXT="inzwischen auch für λ verwendbar (siehe #994)">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1697906296845" ID="ID_1333452635" MODIFIED="1697906312015" TEXT="potentielle Gefahr: generische λ">
|
||||
<node CREATED="1697906315163" ID="ID_1259843032" MODIFIED="1697906324382" TEXT="diese sind Templates"/>
|
||||
<node CREATED="1697906360413" ID="ID_1391705943" MODIFIED="1697906588857" TEXT="man muß sie instantiieren — mit vorgegebenen Argument-Typ(en)">
|
||||
<linktarget COLOR="#ee5278" DESTINATION="ID_1391705943" ENDARROW="Default" ENDINCLINATION="161;7;" ID="Arrow_ID_1833361444" SOURCE="ID_648143154" STARTARROW="None" STARTINCLINATION="-42;-40;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697906435810" FOLDED="true" ID="ID_717292125" MODIFIED="1697927695084" TEXT="beliebige funktions-artige Member analysieren">
|
||||
<linktarget COLOR="#6e85a1" DESTINATION="ID_717292125" ENDARROW="Default" ENDINCLINATION="-1818;113;" ID="Arrow_ID_979493428" SOURCE="ID_118455784" STARTARROW="None" STARTINCLINATION="-869;-95;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1697905686767" ID="ID_1640341474" MODIFIED="1697927541329" TEXT="lib::meta::_Fun für einfache Member-Pointer ergänzen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1697905716970" ID="ID_1853665060" MODIFIED="1697905729917" TEXT="unterstützt bisher nur Function-Member-Pointer"/>
|
||||
<node CREATED="1697905731145" ID="ID_1467529623" MODIFIED="1697906017054" TEXT="die Erweiterung erscheint mir relativ ungefährlich">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn man verwendet diese Metafunktion ja stets explizit mit einem gegebenen Typ, und im Falle eines Ausdrucks muß man noch einen decltype() darum wickeln. Mögliche Probleme:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
der Ausdruck in decltype() ist syntaktisch gar nicht valide (z.B. Scope::member  bei einer Member-Funktion)
|
||||
</li>
|
||||
<li>
|
||||
der sich ergebende Typ ist keine Funktion, und deshalb sind die nested-typedefs (Sig, Args...) nicht vorhanden ⟹ compile Fehler bzw. SFINAE
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1697906024514" ID="ID_1643639913" MODIFIED="1697906047450" TEXT="mögliche Gefahr: generische λ"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1697906053470" ID="ID_648143154" MODIFIED="1697906588857" TEXT="wenn man diese per negativ-Check zu erkennen versucht">
|
||||
<arrowlink COLOR="#ee5278" DESTINATION="ID_1391705943" ENDARROW="Default" ENDINCLINATION="161;7;" ID="Arrow_ID_1833361444" STARTARROW="None" STARTINCLINATION="-42;-40;"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node CREATED="1697906594973" ID="ID_1834320957" MODIFIED="1697906613333" TEXT="lib::IterExplorer macht das">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1697906663564" ID="ID_1606991462" MODIFIED="1697906676958" TEXT="aber an einer Stelle, an der man einen Funktor übergibt"/>
|
||||
<node CREATED="1697906678426" ID="ID_1127757601" MODIFIED="1697906784367" TEXT="ein blanken Member-Pointer macht an dieser Stelle überhaupt keinen Sinn">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Beispiel: explore(elements).transform(....irgendwas....)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697906733939" ID="ID_798052808" MODIFIED="1697906747346" TEXT="möglicherweise ist die Fehlermeldung dann aber verwirrend">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1697905742823" ID="ID_1985279591" MODIFIED="1697905792612" TEXT="es gibt ja immer noch den bool-check (⟼ ist eine Funktion)"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697906799162" ID="ID_1510624814" MODIFIED="1697927539161" TEXT="Hilfsmittel für einfache Signatur-Checks">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1697925677041" ID="ID_1103856898" MODIFIED="1697925691803" TEXT="has_Sig wäre eigentlich bereits hinreichend">
|
||||
<node CREATED="1697925743952" ID="ID_949441284" MODIFIED="1697925765736" TEXT="man könnte einen Konstruktor verwenden und template argument deduction"/>
|
||||
<node CREATED="1697925766453" ID="ID_503135543" MODIFIED="1697925790856" TEXT="weiteres Problem: wenn das übergebene Objekt überhaupt keine Funktion ist...."/>
|
||||
</node>
|
||||
<node CREATED="1697925692678" ID="ID_1669099345" MODIFIED="1697925712517" TEXT="aber die Reihenfolge der Template-Argumente ist genau falsch herum"/>
|
||||
<node CREATED="1697925713308" ID="ID_770980099" MODIFIED="1697925732217" TEXT="dann besser eine free-Function">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1697925795562" ID="ID_340665610" MODIFIED="1697925947597" TEXT="und catch-all-Specialisation">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
has_Sig sollte keine Compile-Fehler auslösen, wenn der gegebene Typ überhaupt nicht Funktions-artig ist (⟹ denn dann ist die Aussage trivialer Weise wiederlegt; was gar keine Signatur hat, kann auch nicht eine bestimmte Signatur haben). Realisieren kann man das über den bool-Check, den ich vor einiger Zeit bereits in lib::meta::_Fun eingebaut habe (im Zusammenhang mit IterExplorer)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697925949821" ID="ID_1361817287" MODIFIED="1697926000759" TEXT="dann auch gleich noch ein spezielles ASSERT-Macro bereitstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Warum Macro? damit man per STRINGIFY() einen lesbareren Hinweis in die Static-Assertion bekommt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1573230375839" ID="ID_270568302" MODIFIED="1573230382276" TEXT="policies">
|
||||
|
|
@ -80285,7 +80400,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1690490297125" ID="ID_1766901032" MODIFIED="1690490313350" TEXT="Vorgriff auf Concepts: Signaturen statisch prüfen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1697849524591" ID="ID_747589769" MODIFIED="1697849564995" TEXT="statische Prüfung schwierig">
|
||||
<node COLOR="#435e98" CREATED="1697849524591" FOLDED="true" ID="ID_747589769" MODIFIED="1697927669544" TEXT="statische Prüfung schwierig">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1697849570913" ID="ID_155562107" MODIFIED="1697849610947" TEXT="ging gut solange ich stets Functor-Objekte verwendet hatte">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -80297,9 +80412,39 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...also solange ich nur mit Unit-Tests gearbeitet habe
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697901649263" ID="ID_1005179743" MODIFIED="1697902145753" TEXT="der Zugriff auf den Typ hängt von der Art des Members ab">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
von einer statischen Funktion kan man direkt den Typ aufgreifen, qualifiziert durch den Scope: <font face="Monospaced" color="#1509b8">decltype( Scope::fun )</font>
|
||||
</li>
|
||||
<li>
|
||||
von einem regulären Member-Function kann man den Typ nach einem Pseudo-Zugriff erfassen: <font face="Monospaced" color="#1509b8">decltype( std::declval<Scope>().fun )</font>
|
||||
</li>
|
||||
<li>
|
||||
bei einem Functor-Member geht das nicht, aber man kann hier entweder statisch qualifzieren (wie 1.Fall), oder einen Pointer nehmen: <font face="Monospaced" color="#1509b8">decltype( &Scope::fun )</font>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1697902156764" ID="ID_1064629278" MODIFIED="1697902191903" TEXT="die Syntax Address-of-scope-qualfied-Member wäre für alle drei Fälle valide">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1697902217469" ID="ID_1785157426" MODIFIED="1697902255305" TEXT="...liefert aber in jedem Fall einen anders zu behandelnden Typ-Ausdruck">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697905677360" ID="ID_118455784" MODIFIED="1697927641347" TEXT="Hilfsmittel ausbauen...">
|
||||
<arrowlink COLOR="#6e85a1" DESTINATION="ID_717292125" ENDARROW="Default" ENDINCLINATION="-1818;113;" ID="Arrow_ID_979493428" STARTARROW="None" STARTINCLINATION="-869;-95;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1690068793535" ID="ID_1906823317" MODIFIED="1697844595733" TEXT="ist tatsächlich implementiert durch den Scheduler selber">
|
||||
|
|
@ -80320,8 +80465,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
der Scheduler-Service <i>überhaupt</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -80331,8 +80475,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...nämlich die Fähigkeit, einen Activity-chain zu einem geplanten Zeitpunkt oder auf Signal hin auszuführen — und diese Fähigkeit muß selbstverständlich der Sprache selber zu Gebote stehen, damit sie komplexe Aktionsmuster flexibel ausdrücken kann
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1692286145852" ID="ID_596906210" MODIFIED="1692370174170" TEXT="Fake-Setup für Tests (ActivityDetector)">
|
||||
|
|
@ -81876,8 +82019,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
es genügte, an diesen Stellen die Ausführung der abstrahierten Aktionen zu loggen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697844649091" ID="ID_939726274" MODIFIED="1697844696080" TEXT="als Abstraktion wurde (bewußt) ein Template-Parameter gewählt"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697844697092" ID="ID_766922475" MODIFIED="1697845768002" TEXT="kokretes Funktions-Binding">
|
||||
|
|
@ -81896,8 +82038,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
⟹ <i>der Scheduler selber</i> kann diese Rolle <b>generisch</b> übernehmen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697845608675" ID="ID_610860781" MODIFIED="1697845760326" TEXT="noch sauberer: ein Sub-Interface-Mapping">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
|
|||
Loading…
Reference in a new issue