use the attributeID to activate the right closure

...under the assumption that the number of attributes is small,
using just a chained sequence of inlined if-statements
"would be acceptable"
This commit is contained in:
Fischlurch 2015-05-02 01:39:58 +02:00
parent 6de24bc7f0
commit 2ce85a1449
3 changed files with 24 additions and 23 deletions

View file

@ -77,7 +77,6 @@ namespace diff{
template<class PAR> template<class PAR>
class Builder; class Builder;
////////TODO only preliminary....
typedef Literal ID; typedef Literal ID;
using Attribute = DataCap; using Attribute = DataCap;
} }
@ -124,11 +123,7 @@ namespace diff{
UNIMPLEMENTED("expose a recursive TreeMutator to transform the denoted child"); UNIMPLEMENTED("expose a recursive TreeMutator to transform the denoted child");
} }
virtual void virtual void setAttribute (ID, Attribute&) { /* do nothing by default */ }
setAttribute (ID id, Attribute& newValue)
{
std::cout << "Empty Base Impl: apply a value change to the named attribute"<<std::endl; ////////////////TODO empty implementation should be NOP
}
/** /**
* start building a custom adapted tree mutator, * start building a custom adapted tree mutator,
@ -144,19 +139,22 @@ namespace diff{
struct ChangeOperation struct ChangeOperation
: PAR : PAR
{ {
ID attribID_;
function<void(string)> change_; function<void(string)> change_;
virtual void virtual void
setAttribute (ID id, Attribute& newValue) setAttribute (ID id, Attribute& newValue)
{ {
// Decorator-style chained invocation of inherited implementation if (id == attribID_)
PAR::setAttribute(id, newValue); change_(newValue.get<string>());
change_(newValue.get<string>()); else // delegate to other closures (Decorator-style)
PAR::setAttribute(id, newValue);
} }
ChangeOperation(function<void(string)> clo, PAR const& chain) ChangeOperation(ID id, function<void(string)> clo, PAR const& chain)
: PAR(chain) : PAR(chain)
, attribID_(id)
, change_(clo) , change_(clo)
{ } { }
}; };
@ -177,7 +175,7 @@ namespace diff{
Builder<Change> Builder<Change>
change (Literal attributeID, function<void(string)> closure) change (Literal attributeID, function<void(string)> closure)
{ {
return Change (closure, *this); return Change (attributeID, closure, *this);
} }
}; };

View file

@ -222,7 +222,10 @@ return: 0
END END
PLANNED "GenericTreeMutator_test" GenericTreeMutator_test <<END TEST "Generic recursive mutation with closure binding" GenericTreeMutator_test <<END
out: concrete TreeMutator .+Builder<.+ChangeOperation<.+TreeMutator
out-lit: "data" closure received something that would be acceptable
out-lit: localData changed to: that would be acceptable
return: 0 return: 0
END END

View file

@ -92,24 +92,24 @@ namespace test{
string localData; string localData;
auto mutator = auto mutator =
TreeMutator::build() TreeMutator::build()
.change("something", [&](string val) .change("data", [&](string val)
{ {
cout << "Oink-Oink"<<endl; cout << "\"data\" closure received something "<<val<<endl;
localData = "Oink-Oink";
})
.change("something", [&](string val)
{
cout << "Change closure invoked with val="<<val<<endl;
localData = val; localData = val;
}); });
cout << "concrete TreeMutator type="<< demangleCxx (showType (mutator)) <<endl; cout << "concrete TreeMutator size=" << sizeof(mutator)
<< " type="<< demangleCxx (showType (mutator))
<< endl;
CHECK (isnil (localData)); CHECK (isnil (localData));
Attribute testAttribute(string ("boing")); Attribute testAttribute(string ("that would be acceptable"));
mutator.setAttribute ("zoing", testAttribute); mutator.setAttribute ("lore", testAttribute);
CHECK ( isnil (localData)); // nothing happens, nothing changed
mutator.setAttribute ("data", testAttribute);
CHECK (!isnil (localData)); CHECK (!isnil (localData));
cout << "localData changed to:"<<localData<<endl; cout << "localData changed to: "<<localData<<endl;
CHECK (localData == "that would be acceptable");
} }