diff --git a/src/lib/par/domain.hpp b/src/lib/par/domain.hpp index 2f668eece..bbfb1a846 100644 --- a/src/lib/par/domain.hpp +++ b/src/lib/par/domain.hpp @@ -129,7 +129,7 @@ namespace par { virtual ~Domain(); ///< this is an interface virtual void applyLimit (ValBuff&) =0; - virtual void assignInto (ValBuff& target, Domain& targetDomain, ValBuff const& source) =0; + virtual void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) =0; protected: }; @@ -168,7 +168,7 @@ _Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"") { public: void applyLimit (ValBuff&) override; - void assignInto (ValBuff& target, Domain& targetDomain, ValBuff const& source) override; + void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) override; }; @@ -300,7 +300,7 @@ _Pragma("GCC diagnostic pop") template inline void - BaseDomain::assignInto (ValBuff& target, Domain& targetDomain, ValBuff const& source) + BaseDomain::transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) { TypeHandler& typeHandler{targetDomain}; typeHandler.conform (target, asValue (source)); diff --git a/tests/lib/par/parameter-domain-test.cpp b/tests/lib/par/parameter-domain-test.cpp index 3aa35b4fd..08aa18916 100644 --- a/tests/lib/par/parameter-domain-test.cpp +++ b/tests/lib/par/parameter-domain-test.cpp @@ -73,6 +73,8 @@ namespace test{ basics(); verify_valueLimits(); verify_valueAccess(); + verify_valueSetting(); + verify_opaqueAssign(); } @@ -173,31 +175,99 @@ namespace test{ verify_valueAccess() { BaseDomain domInt; - Domain& d1{domInt}; + Domain& dom{domInt}; - int val1 = 1 + rani (1000); - ValBuff& src1 = asValBuff (val1); + int val = 1 + rani (1000); + ValBuff& src = asValBuff (val); uint target1{0}; CHECK (not target1); - TypeHandler& du1{d1}; - du1.extractAs (target1, src1); - CHECK (target1 == uint(val1)); + TypeHandler& hu{dom}; + hu.extractAs (target1, src); + CHECK (target1 == uint(val)); float target2{0}; - TypeHandler& df1{d1}; - df1.extractAs (target2, src1); - CHECK (target2 == float(val1)); + TypeHandler& hf{dom}; + hf.extractAs (target2, src); + CHECK (target2 == float(val)); // value clamped to target domain... - val1 = _MIN; + val = _MIN; uint64_t target3{55}; - TypeHandler& du64{d1}; - du64.extractAs (target3, src1); + TypeHandler& hu64{dom}; + hu64.extractAs (target3, src); CHECK (target3 == _MIN); } + + + /** @test base function to assign a directly given data value + * into an opaque buffer with known (yet different) type. + */ + void + verify_valueSetting() + { + BaseDomain domInt; + Domain& dom{domInt}; + + int val_in_buff = 0; + ValBuff& target = asValBuff (val_in_buff); + + uint src1 = 1 + rani (1000); + TypeHandler& hu{dom}; + hu.conform (target, src1); + CHECK (val_in_buff == int(src1)); + + double src2 = ranRange (1,100); + CHECK (1 <= src2 and src2 < 100); + TypeHandler& hd{dom}; + hd.conform (target, src2); + CHECK (val_in_buff == int(floor (src2))); + + // value clamped to target domain... + auto mini = _MIN; + TypeHandler& h64{dom}; + h64.conform (target, mini); + CHECK (val_in_buff == _MIN); + } + + + /** @test value transfer between opaque buffers with double-dispatch. + * - use several typed values, yet access these only marked as `ValBuff` + * - the call must be passed through _two virtual functions_, in order + * to re-gain the fully typed context; this is the »visitor pattern« + * @remark the API might seem bewildering; this is due to passing both source + * and target as reference to _some value buffer_, since this API describes + * only a data type disposition, while the actual data storage is defined + * as derived parameter data type. + */ + void + verify_opaqueAssign() + { + double double_val = ranRange (2,100); + int64_t i64_val{0}; + bool boo{false}; + + BaseDomain ddom; + BaseDomain idom; + BaseDomain bdom; + + Domain& d1{ddom}; + Domain& d3{bdom}; + + CHECK (i64_val == 0); + d1.transferTo (asValBuff(double_val), idom, asValBuff(i64_val)); + CHECK (i64_val == int64_t(floor (double_val))); + + CHECK (not boo); + d1.transferTo (asValBuff(double_val), bdom, asValBuff(boo)); + CHECK (boo); + + CHECK (double_val != 1.0); + d3.transferTo (asValBuff(boo), ddom, asValBuff(double_val)); + CHECK (double_val == 1.0); + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9d2da9a93..523f851d8 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -83021,7 +83021,8 @@ - + + @@ -83080,7 +83081,8 @@ - + + @@ -83123,19 +83125,17 @@ - + - + - - - +

aber signed vs. unsigned- Werte lassen sich @@ -83464,7 +83464,8 @@ - + + @@ -83482,9 +83483,7 @@ - - - +

kann nun auch generisch implementieren: conform (Buffer, TY&&) @@ -83492,7 +83491,7 @@ - + @@ -83502,9 +83501,9 @@ - - - + + + @@ -83515,9 +83514,7 @@ - - - +

...sonst funktioniert diese doppelte Indirektion gar nicht; die erste aufgerufene Funktion ist ja ein visit(opaqueTarget) — und erst in der Implementierung  derselben kenne ich den konkreten »Quell«-Typ. Hier aber ist die Sache nochmal komplexer, da ich die Idee hatte, den Visitor "reflexiv" zu machen, womit ich meine, daß der Mechanismus in beide Richtungen anwendbar ist; keine Ahnung ob das überhaupt geht... @@ -83532,9 +83529,7 @@ - - - +

...deshalb bin ich ja ins Prototyping eingestiegen... @@ -83559,7 +83554,7 @@ - + @@ -83573,9 +83568,7 @@ - - - +

@@ -83600,12 +83593,11 @@ - + + - - - +

virtual void supply(ValBuff  const& src, ValBuff&  target, Domain& targetDomain) @@ -83617,9 +83609,7 @@ - - - +

kann nun auf dieser Basis die umgekehrte Richtung auch implementieren @@ -83629,21 +83619,20 @@ - + - - - +

Zwischenfazit: ja man kann

- + + - + @@ -83670,7 +83659,9 @@ - + + + @@ -83680,12 +83671,31 @@ - + + + + + +

+ ...was auf den ersten Blick verwirrend erscheint; +

+

+ aber es muß so sein, wegen der double-dispatch-Struktur: die eigentliche Operation erfolgt erst im zweiten Schritt, und das muß logischerweise eine »conform«-Operation sein — mithin passiert der erste Schritt auf der Quelle (die »accept«-Operation des Visitors) +

+ +
+ +
+ + + +
+