diff --git a/src/lib/par/domain.hpp b/src/lib/par/domain.hpp index 1371b8ceb..9881ca1bb 100644 --- a/src/lib/par/domain.hpp +++ b/src/lib/par/domain.hpp @@ -92,7 +92,7 @@ namespace par { class TypeHandler { public: - virtual void extractAs (X&, ValBuff const&) =0; + virtual void conformInto (ValBuff&, X const&) =0; }; // using lib::meta::typeseq; @@ -127,6 +127,13 @@ namespace par { virtual ~Domain(); ///< this is an interface virtual void applyLimit (ValBuff&) =0; + virtual void supply(ValBuff const& src, ValBuff& target, Domain& targetDomain) =0; + + template + void extractAs (X& targetVal, ValBuff const& valBuff); + + template + void conform (ValBuff& targetBuff, X&& srcVal); protected: }; @@ -142,7 +149,7 @@ _Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"") - template + template struct DomainSetup { @@ -150,7 +157,7 @@ _Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"") class TypeHandlerImpl : public BAS { - void extractAs (X& targetVal, ValBuff const& valBuff) override; + void conformInto (ValBuff& targetBuff, X const& srcVal) override; }; using TypeHandlerChain = meta::InstantiateChained; @@ -158,12 +165,13 @@ _Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"") - template + template class BaseDomain - : public DomainSetup::TypeHandlerChain + : public DomainSetup::TypeHandlerChain { public: void applyLimit (ValBuff&) override; + void supply (ValBuff const& src, ValBuff& target, Domain& targetDomain) override; }; @@ -244,36 +252,73 @@ _Pragma("GCC diagnostic pop") } - template + + template inline void - BaseDomain::applyLimit (ValBuff& valBuff) + BaseDomain::applyLimit (ValBuff& valBuff) { - X& val{asValue (valBuff)}; - val = preClamp (val); + V& val{asValue (valBuff)}; + val = preClamp (val); } - - template - template + template inline void - DomainSetup::TypeHandlerImpl::extractAs (X& targetVal, ValBuff const& valBuff) + assignConverted (V& targetVal, X const& srcVal) { - if constexpr (std::is_assignable_v) + if constexpr (std::is_assignable_v) { - targetVal = preClamp (asValue (valBuff)); + targetVal = preClamp (srcVal); } else - if constexpr (std::is_constructible_v) + if constexpr (std::is_constructible_v) { - targetVal.~X(); - new(&targetVal) X (preClamp (asValue (valBuff))); + targetVal.~U(); + new(&targetVal) V (preClamp (srcVal)); } else static_assert (!sizeof(X), "this type conversion is not supported"); } + template + template + inline void + DomainSetup::TypeHandlerImpl::conformInto (ValBuff& targetBuff, X const& srcVal) + { + V& targetVal = asValue (targetBuff); + assignConverted (targetVal, srcVal); + } + + + template + inline void + BaseDomain::supply (ValBuff const& srcBuff, ValBuff& targetBuff, Domain& targetDomain) + { + targetDomain.conform (targetBuff, asValue (srcBuff)); + } + + template + inline void + Domain::extractAs (X& targetVal, ValBuff const& valBuff) + { + BaseDomain target; + ValBuff& targetBuff{asValBuff (targetVal)}; + supply (valBuff, targetBuff, target); + } + + template + inline void + Domain::conform (ValBuff& targetBuff, X&& srcVal) + { + using Src = std::decay_t; + TypeHandler& typeHandler{*this}; + typeHandler.conformInto (targetBuff, srcVal); + applyLimit (targetBuff); + } + + + }} // namespace lib::par #endif /*LIB_PAR_DOMAIN_H*/ diff --git a/tests/lib/par/parameter-domain-test.cpp b/tests/lib/par/parameter-domain-test.cpp index 3aa35b4fd..eafec7d4b 100644 --- a/tests/lib/par/parameter-domain-test.cpp +++ b/tests/lib/par/parameter-domain-test.cpp @@ -181,21 +181,24 @@ namespace test{ uint target1{0}; CHECK (not target1); - TypeHandler& du1{d1}; - du1.extractAs (target1, src1); +// TypeHandler& du1{d1}; +// du1.extractAs (target1, src1); + d1.extractAs(target1, src1); CHECK (target1 == uint(val1)); float target2{0}; - TypeHandler& df1{d1}; - df1.extractAs (target2, src1); +// TypeHandler& df1{d1}; +// df1.extractAs (target2, src1); + d1.extractAs(target2, src1); CHECK (target2 == float(val1)); // value clamped to target domain... val1 = _MIN; uint64_t target3{55}; - TypeHandler& du64{d1}; - du64.extractAs (target3, src1); +// TypeHandler& du64{d1}; +// du64.extractAs (target3, src1); + d1.extractAs (target3, src1); CHECK (target3 == _MIN); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 0539d46aa..04792773f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82650,12 +82650,15 @@ - + - + + + - + + @@ -83478,6 +83481,181 @@ + + + + + + +

+ kann nun auch generisch implementieren: conform (Buffer, TY&&) +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...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... +

+ + +
+
+
+ + + + + + + + + + +

+ ...deshalb bin ich ja ins Prototyping eingestiegen... +

+
    +
  • + ich möchte „etwas mit einem PolymorphicValue“ bauen +
  • +
  • + die konkrete Ausgestaltung des opaque-Buffers möchte ich mir offen halten +
  • +
  • + ich brauche einen Typ-Deskriptor, will aber dessen Storage einsparen (bzw. in der VTable verstecken) +
  • +
  • + ich brauche aber BaseDomains als Anker, und diese müssen statisch konstruierbar sein +
  • +
  • + letztlich möchte ich ein generisches front-End, das dann entweder „durchmarschiert“ — oder eben in den Visitor-call einsteigt +
  • +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + +
+
+

+ template<typename X> +

+

+ void extractAs (X&  targetVal, ValBuff const&  valBuff); +

+

+ +

+

+ template<typename X> +

+

+ void conform (ValBuff&  targetBuff, X&&  srcVal); +

+
+
+ + +
+
+
+ + + + + + + +

+ virtual void supply(ValBuff  const& src, ValBuff&  target, Domain& targetDomain) +

+ + +
+ +
+ + + + + + + +

+ kann nun auf dieser Basis die umgekehrte Richtung auch implementieren +

+ + +
+
+
+
+ + + + + + +

+ Zwischenfazit: ja man kann +

+ + +
+ + + + + + +
+