From ee99c405fdb7f5c25876025091f648a50d4f3eb6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 29 May 2016 03:01:27 +0200 Subject: [PATCH] Reorganise implementation into base class + overlay ...as preparation for implementing the two flavours of binding attributes either via a setter lambda or via creation of a nested mutator. --- .../diff/tree-mutator-attribute-binding.hpp | 139 ++++++++++-------- wiki/thinkPad.ichthyo.mm | 35 ++++- 2 files changed, 113 insertions(+), 61 deletions(-) diff --git a/src/lib/diff/tree-mutator-attribute-binding.hpp b/src/lib/diff/tree-mutator-attribute-binding.hpp index b8f19af48..90ebc96c9 100644 --- a/src/lib/diff/tree-mutator-attribute-binding.hpp +++ b/src/lib/diff/tree-mutator-attribute-binding.hpp @@ -56,18 +56,18 @@ //== anonymous namespace... - template - class ChangeOperation + template + class AttributeBindingBase : public PAR { - using CloArgs = typename _ClosureType::Args; - using ValueType = typename lib::meta::Pick::Type; - using ID = idi::EntryID; - - ID attribID_; - CLO change_; + IDI attribID_; + protected: + AttributeBindingBase (IDI attribID, PAR&& chain) + : PAR(std::forward(chain)) + , attribID_(attribID) + { } /** hard wired "selector predicate" for this binding layer. * We do only handle mutation operations pertaining attributes @@ -83,17 +83,9 @@ and attribID_ == spec.idi; } - public: - ChangeOperation (Symbol attribKey, CLO clo, PAR&& chain) - : PAR(std::forward(chain)) - , attribID_(attribKey) - , change_(clo) - { } - - /* ==== re-Implementation of the operation API ==== */ - + public: /** this binding to an object field can not support any reordering, * inserting or deletion of "Elements", since the structure of an object * is fixed through the underlying class definition. For this reason, @@ -126,35 +118,6 @@ return isApplicable (spec); } - /** while, strictly speaking, one can not "insert" fields into a - * given class definition, this binding can tolerate an `INS` verb - * whenever this means to touch a field which is actually known and - * present in the class definition underlying this binding. In such - * a case, we just assign the given value. This implementation leeway - * is deliberate to support classes with optional / defaultable properties. - */ - virtual bool - injectNew (GenNode const& spec) override - { - if (not isApplicable(spec)) - return PAR::injectNew(spec); - - change_(spec.data.get()); - return true; - } - - /** has no meaning, since object fields have no notion of "order". - * @note it would be desirable to throw, but due to other restrictions - * in the "diff protocol" this operation does not get any arguments. - * Thus we're not able to determine, if this layer is in charge, so - * we need just to pass on the invocation. - */ - virtual void - skipSrc () override - { - PAR::skipSrc(); - } - /** any reordering or deletion of object fields is prohibited * @throw error::Logic when this binding layer becomes responsible for * handling the given diff spec, because a proper diff must be arranged @@ -175,37 +138,93 @@ /** repeatedly accept, until after the designated location */ virtual bool - accept_until (GenNode const& spec) + accept_until (GenNode const& spec) override { UNIMPLEMENTED("only support UNTIL END"); } + }; + + + template + struct AttribType + { + using CloArgs = typename _ClosureType::Args; + using ValueType = typename lib::meta::Pick::Type; + using ID = idi::EntryID; + }; + + + template + class ChangeOperation + : public AttributeBindingBase::ID> + { + using ID = typename AttribType::ID; + using ValueType = typename AttribType::ValueType; - /** invoke the setter lambda, in case this binding layer is in charge */ + CLO change_; + + + public: + ChangeOperation (Symbol attribKey, CLO clo, PAR&& chain) + : AttributeBindingBase(ID{attribKey}, std::forward(chain)) + , change_(clo) + { } + + + /* ==== Implementation of value assignment operation ==== */ + + /** while, strictly speaking, one can not "insert" fields into a + * given class definition, this binding can tolerate an `INS` verb + * whenever this means to touch a field which is actually known and + * present in the class definition underlying this binding. In such + * a case, we just assign the given value. This implementation leeway + * is deliberate to support classes with optional / defaultable properties. + */ virtual bool - assignElm (GenNode const& spec) + injectNew (GenNode const& spec) override { - if (not isApplicable(spec)) - return PAR::assignElm(spec); + if (not this->isApplicable(spec)) + return PAR::injectNew(spec); change_(spec.data.get()); return true; } + /** invoke the setter lambda, in case this binding layer is in charge */ + virtual bool + assignElm (GenNode const& spec) override + { + if (not this->isApplicable(spec)) + return PAR::assignElm(spec); + + change_(spec.data.get()); + return true; + } + }; + + + template + class MutationOperation + : public AttributeBindingBase + { + + MUT mutatorBuilder_; + + + public: + MutationOperation (IDI attribID, MUT clo, PAR&& chain) + : AttributeBindingBase(attribID, std::forward(chain)) + , mutatorBuilder_(clo) + { } + + /** locate the designated target element and build a suitable * sub-mutator for this element into the provided target buffer */ virtual bool - mutateChild (GenNode const& spec, TreeMutator::MutatorBuffer targetBuff) + mutateChild (GenNode const& spec, TreeMutator::MutatorBuffer targetBuff) override { UNIMPLEMENTED("invoke mutator builder"); } - - /** verify all our pending (old) source elements where mentioned. - * @note allows chained "onion-layers" to clean-up and verify.*/ - virtual bool - completeScope() - { - return PAR::completeScope(); - } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ec5aa276d..625bdeb58 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -4050,7 +4050,8 @@ - + + @@ -4058,6 +4059,38 @@ + + + + + + + + + + + + + +

+ in einem Fall kann man sie aus der Closure abgreifen +

+

+ im anderen Fall muß es doch der Client leisten. +

+

+ Keine klare Linie +

+ + +
+ +
+ + + +
+