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:
parent
6de24bc7f0
commit
2ce85a1449
3 changed files with 24 additions and 23 deletions
|
|
@ -77,7 +77,6 @@ namespace diff{
|
|||
template<class PAR>
|
||||
class Builder;
|
||||
|
||||
////////TODO only preliminary....
|
||||
typedef Literal ID;
|
||||
using Attribute = DataCap;
|
||||
}
|
||||
|
|
@ -124,11 +123,7 @@ namespace diff{
|
|||
UNIMPLEMENTED("expose a recursive TreeMutator to transform the denoted child");
|
||||
}
|
||||
|
||||
virtual void
|
||||
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
|
||||
}
|
||||
virtual void setAttribute (ID, Attribute&) { /* do nothing by default */ }
|
||||
|
||||
/**
|
||||
* start building a custom adapted tree mutator,
|
||||
|
|
@ -144,19 +139,22 @@ namespace diff{
|
|||
struct ChangeOperation
|
||||
: PAR
|
||||
{
|
||||
ID attribID_;
|
||||
function<void(string)> change_;
|
||||
|
||||
virtual void
|
||||
setAttribute (ID id, Attribute& newValue)
|
||||
{
|
||||
// Decorator-style chained invocation of inherited implementation
|
||||
PAR::setAttribute(id, newValue);
|
||||
if (id == attribID_)
|
||||
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)
|
||||
, attribID_(id)
|
||||
, change_(clo)
|
||||
{ }
|
||||
};
|
||||
|
|
@ -177,7 +175,7 @@ namespace diff{
|
|||
Builder<Change>
|
||||
change (Literal attributeID, function<void(string)> closure)
|
||||
{
|
||||
return Change (closure, *this);
|
||||
return Change (attributeID, closure, *this);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,10 @@ return: 0
|
|||
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
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -92,24 +92,24 @@ namespace test{
|
|||
string localData;
|
||||
auto mutator =
|
||||
TreeMutator::build()
|
||||
.change("something", [&](string val)
|
||||
.change("data", [&](string val)
|
||||
{
|
||||
cout << "Oink-Oink"<<endl;
|
||||
localData = "Oink-Oink";
|
||||
})
|
||||
.change("something", [&](string val)
|
||||
{
|
||||
cout << "Change closure invoked with val="<<val<<endl;
|
||||
cout << "\"data\" closure received something "<<val<<endl;
|
||||
localData = val;
|
||||
});
|
||||
|
||||
cout << "concrete TreeMutator type="<< demangleCxx (showType (mutator)) <<endl;
|
||||
cout << "concrete TreeMutator size=" << sizeof(mutator)
|
||||
<< " type="<< demangleCxx (showType (mutator))
|
||||
<< endl;
|
||||
|
||||
CHECK (isnil (localData));
|
||||
Attribute testAttribute(string ("boing"));
|
||||
mutator.setAttribute ("zoing", testAttribute);
|
||||
Attribute testAttribute(string ("that would be acceptable"));
|
||||
mutator.setAttribute ("lore", testAttribute);
|
||||
CHECK ( isnil (localData)); // nothing happens, nothing changed
|
||||
mutator.setAttribute ("data", testAttribute);
|
||||
CHECK (!isnil (localData));
|
||||
cout << "localData changed to:"<<localData<<endl;
|
||||
cout << "localData changed to: "<<localData<<endl;
|
||||
CHECK (localData == "that would be acceptable");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue