generalise to arbitrary acceptable attribute values

...not yet able to pick up the closure argument type automagically
however, right now we can only hypothesise this might be possible
This commit is contained in:
Fischlurch 2015-05-02 02:02:48 +02:00
parent 2ce85a1449
commit f45884975b
3 changed files with 17 additions and 11 deletions

View file

@ -135,24 +135,26 @@ namespace diff{
namespace { namespace {
template<class PAR> template<class PAR, typename VAL>
struct ChangeOperation struct ChangeOperation
: PAR : PAR
{ {
using Closure = function<void(VAL)>;
ID attribID_; ID attribID_;
function<void(string)> change_; Closure change_;
virtual void virtual void
setAttribute (ID id, Attribute& newValue) setAttribute (ID id, Attribute& newValue)
{ {
if (id == attribID_) if (id == attribID_)
change_(newValue.get<string>()); change_(newValue.get<VAL>());
else // delegate to other closures (Decorator-style) else // delegate to other closures (Decorator-style)
PAR::setAttribute(id, newValue); PAR::setAttribute(id, newValue);
} }
ChangeOperation(ID id, function<void(string)> clo, PAR const& chain) ChangeOperation(ID id, Closure clo, PAR const& chain)
: PAR(chain) : PAR(chain)
, attribID_(id) , attribID_(id)
, change_(clo) , change_(clo)
@ -163,19 +165,23 @@ namespace diff{
struct Builder struct Builder
: PAR : PAR
{ {
using Change = ChangeOperation<PAR>;
Builder(PAR par) Builder(PAR par)
: PAR(par) : PAR(par)
{ } { }
template<typename VAL>
using Change = ChangeOperation<PAR,VAL>;
template<typename VAL>
using Closure = typename Change<VAL>::Closure;
/* ==== binding API ==== */ /* ==== binding API ==== */
Builder<Change> template<typename VAL>
change (Literal attributeID, function<void(string)> closure) Builder<Change<VAL>>
change (Literal attributeID, Closure<VAL> closure)
{ {
return Change (attributeID, closure, *this); return Change<VAL> (attributeID, closure, *this);
} }
}; };

View file

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

View file

@ -92,7 +92,7 @@ namespace test{
string localData; string localData;
auto mutator = auto mutator =
TreeMutator::build() TreeMutator::build()
.change("data", [&](string val) .change<string>("data", [&](string val)
{ {
cout << "\"data\" closure received something "<<val<<endl; cout << "\"data\" closure received something "<<val<<endl;
localData = val; localData = val;