diff --git a/src/lib/lazy-init.hpp b/src/lib/lazy-init.hpp index 4d3107a48..e8d6e296d 100644 --- a/src/lib/lazy-init.hpp +++ b/src/lib/lazy-init.hpp @@ -335,6 +335,13 @@ namespace lib { PendingInit prepareInitialiser (std::function& targetFunctor, INI&& initialiser) { + if (isInit() and targetFunctor) + {// object is already »engaged« — no need to delay init + using ExpectedArg = _FunArg; + initialiser (static_cast (this)); + return PendingInit(); // keep engaged; no pending init + } + // else: prepare delayed init... PendingInit storageHandle{ new HeapStorage{ buildInitialiserDelegate (targetFunctor, forward (initialiser))}}; @@ -344,12 +351,22 @@ namespace lib { } template - DelegateType* + static DelegateType* getPointerToDelegate (HeapStorage& buffer) { return reinterpret_cast*> (&buffer); } + template + static std::function + maybeInvoke (PendingInit const& pendingInit, RawAddr location) + { + if (not pendingInit) // no pending init -> empty TargetFun + return std::function(); + auto* pendingDelegate = getPointerToDelegate(*pendingInit); + return (*pendingDelegate) (location); // invoke to create new TargetFun + } + template DelegateType buildInitialiserDelegate (std::function& targetFunctor, INI&& initialiser) @@ -358,12 +375,15 @@ namespace lib { using ExpectedArg = _FunArg; return DelegateType{ [performInit = forward (initialiser) + ,previousInit = move (pendingInit_) ,targetOffset = captureRawAddrOffset (this, &targetFunctor)] (RawAddr location) -> TargetFun& {// apply known offset backwards to find current location of the host object TargetFun* target = relocate (location, -FUNCTOR_PAYLOAD_OFFSET); LazyInit* self = relocate (target, -targetOffset); REQUIRE (self); + // setup target as it would be with eager init + (*target) = maybeInvoke (previousInit, location); // invoke init, possibly downcast to derived *self performInit (static_cast (self)); self->pendingInit_.reset(); // release storage diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 0fff39895..89c474778 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -97558,7 +97558,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -97579,6 +97579,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + @@ -97628,6 +97639,155 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ darauf kommt es jetzt auch nicht mehr an +

+ + +
+
+ + + + + + +

+ Funktor ist Funktor! +

+

+ Deshalb sind sie ja stateless (und müssen auch so bleiben, also nicht mutable). Für jeweils eine Instanz wird ein Funktor einfach »verbrannt«, indem man ihn aufruft und danach das pendingInit leert. Und zwar auf *self  — der Funktor als Solcher bleibt stateless. Wenn ihn noch jemand anders referenziert, dann schön.... +

+ + +
+
+ + + + + + +

+ Beim Umkonfigurieren wird der pendingInit verschoben +

+ + +
+ + + + + +

+ und zwar aus dem LazyInit-Objekt in den Adapter hinein. Der use-count bleibt dadurch gleich. +

+ + +
+
+
+ + + +