45 using err::LUMIERA_ERROR_LIFECYCLE;
46 using std::make_unique;
89 auto fun = [&](uint challenge){
return beacon+challenge; };
91 using Sig = size_t(uint);
92 CHECK (isFunMember<Sig> (&fun));
97 CHECK (beacon+c == fun(c));
100 using FunType = decltype(fun);
101 FunType& funRef = fun;
102 CHECK (beacon+c == funRef(c));
106 RawAddr location{
nullptr};
107 auto delegate = [&](RawAddr adr) -> FunType&
112 using Delegate = decltype(delegate);
113 auto delP = make_unique<Delegate> (delegate);
117 CHECK (beacon+c == (*delP)(
this)(c));
118 CHECK (location ==
this);
122 CHECK (
sizeof(trojanLambda) ==
sizeof(
size_t));
128 CHECK (beacon+c == trojanLambda(c));
129 CHECK (location == &trojanLambda);
132 auto trojanClone = trojanLambda;
135 CHECK (beacon+c == trojanClone(c));
136 CHECK (location == &trojanClone);
137 CHECK (beacon+c == trojanLambda(c));
138 CHECK (location == &trojanLambda);
162 const char* payload =
"please look elsewhere";
163 auto lambda = [payload]{
return RawAddr(&payload); };
165 RawAddr location = lambda();
166 CHECK (location == &lambda);
168 std::function funWrap{lambda};
170 CHECK (not isSameObject (funWrap, lambda));
172 location = funWrap();
173 CHECK (util::isCloseBy (location, funWrap));
180 CHECK (util::isCloseBy (funWrap, lambda));
196 int unrelated{rand()};
203 virtual RawAddr peek()
205 return &nested.anchor;
210 const ptrdiff_t offNested = []{
212 return captureRawAddrOffset(&probe, &probe.anchor);
216 const ptrdiff_t offBase = captureRawAddrOffset(&here, &here.nested);
219 CHECK (offNested > 0);
222 auto farAway = make_unique<Demo> (here);
225 RawAddr startPoint = farAway->peek();
226 Nested* farNested = relocate<Nested>(startPoint, -offNested);
227 CHECK (here.nested.unrelated == farNested->unrelated);
229 Demo* farSelf = relocate<Demo> (farNested, -offBase);
230 CHECK (here.nested.anchor == farSelf->nested.anchor);
231 CHECK (isSameObject (*farSelf, *farAway));
241 using Fun = std::function<float(int)>;
246 auto delegate = [&report](RawAddr insideFun) -> Fun&
248 auto realFun = [&report](
int num)
265 int feed{1+rand()%100};
266 float res = theFun (feed);
269 CHECK (feed == report + 42);
270 CHECK (res = feed -42 +23.55f);
279 CHECK (feed == report);
280 CHECK (res = feed + 23.55f);
290 using Fun = std::function<float(int)>;
295 Lazy funny{funny, [&](Lazy*
self)
297 Fun& thisFun =
static_cast<Fun&
> (*self);
299 thisFun = [&invoked](
int num)
310 int feed = 1 + rand()%99;
311 CHECK (feed*0.555f == funny(feed));
312 CHECK (1 == invoked);
322 using Fun = std::function<int(int)>;
327 template<
typename FUN>
329 buildInit (FUN&& fun2install)
331 return [theFun = forward<FUN> (fun2install)]
337 self->fun = [
self, prevFun=
self->fun, nextFun=theFun]
340 return nextFun (prevFun (i));
344 self->fun = [
self, newFun=theFun]
347 return newFun (i + self->seed);
357 installInitialiser(fun, buildInit([](
int){
return 0; }));
360 template<
typename FUN,
typename =disable_if_self<LazyDemo, FUN>>
365 installInitialiser(fun, buildInit (forward<FUN> (someFun)));
368 template<
typename FUN>
370 attach (FUN&& someFun)
372 installInitialiser(fun, buildInit (forward<FUN> (someFun)));
396 CHECK (not dd.isInit());
400 CHECK (0 == dd.fun(22));
411 CHECK (not dd.isInit());
412 CHECK (dd.seed == 0);
415 CHECK (23 == dd.fun(22));
418 CHECK (26 == dd.fun(22));
428 CHECK (dd.seed == 3);
429 CHECK (12 == dd.fun(21));
430 CHECK (13 == dd.fun(22));
431 CHECK (13 == dd.fun(23));
433 CHECK (14 == dd.fun(23));
434 CHECK (14 == dd.fun(24));
435 CHECK (15 == dd.fun(25));
439 dd =
LazyDemo{[](
int i){
return i+1; }}
440 .attach([](
int i){
return i/2; });
442 CHECK (not dd.isInit());
443 CHECK (dd.seed == 3);
446 CHECK (12 == dd.fun(21));
447 CHECK (13 == dd.fun(22));
448 CHECK (13 == dd.fun(23));
450 CHECK (14 == dd.fun(23));
451 CHECK (14 == dd.fun(24));
452 CHECK (15 == dd.fun(25));
455 dd =
LazyDemo{[](
int i){
return i+1; }};
459 d2.attach ([](
int i){
return i/2; });
461 d2.attach ([](
int i){
return i-1; });
473 CHECK (not dd.isInit() and dd.seed == 3);
474 CHECK (not d1.isInit() and d1.seed == 5);
475 CHECK (not d2.isInit() and d2.seed == 3);
476 CHECK (not d3.isInit() and d3.seed == 0);
478 CHECK (12 == dd.fun(23));
479 CHECK (13 == d1.fun(23));
480 CHECK (13 == d2.fun(23));
481 CHECK (24 == d3.fun(23));
void verify_TargetRelocation()
elaborate setup used for integration test
»Trojan Function« builder.
void verify_trojanLambda()
Mix-in for lazy/delayed initialisation of an embedded functor.
static auto generateTrap(DEL *delegate)
Invocation: build a Lambda to activate the »Trap« and then to forward the invocation to the actual fu...
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
constexpr auto isFunMember(FUN)
Helper to pick up a member field for verification.
Implementation namespace for support and library code.
Building block to allow delayed initialisation of infrastructure tied to a functor.
void verify_complexUsageWithCopy()
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void verify_inlineStorage()
A collection of frequently used helper functions to support unit testing.
const ptrdiff_t FUNCTOR_PAYLOAD_OFFSET
void verify_lazyInitialisation()
void verify_triggerMechanism()
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.