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:
parent
2ce85a1449
commit
f45884975b
3 changed files with 17 additions and 11 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue