WIP: decision about the builder sequence

after sleeping a night over this, it seems obvios
that we do not want to start the build proces "implicitly",
starting from a Record<GenNode>. Rather, we always want
the user to plant a dedicated Mutator object, which then
can remain noncopyable and is passed by reference through
the whole builder chain. Movin innards of *this object*
are moved away a the end of the chain does not pose much risk.
This commit is contained in:
Fischlurch 2015-07-04 14:55:36 +02:00
parent d92878876a
commit d14c502ea9
3 changed files with 35 additions and 55 deletions

View file

@ -123,6 +123,7 @@ namespace diff{
class GenNode;
using Rec = Record<GenNode>;
using MakeRec = Rec::Mutator;
using DataValues = meta::Types<int
,int64_t
,short
@ -233,6 +234,19 @@ namespace diff{
return util::startsWith (idi.getSym(), "_CHILD_");
}
bool
contains (GenNode const&) const
{
UNIMPLEMENTED("containment check");
}
bool
contains (ID const&) const
{
UNIMPLEMENTED("containment check by ID");
}
friend string
name (GenNode const& node)
{

View file

@ -246,44 +246,6 @@ namespace diff{
/* ==== extension point for fluent builder API ====== */
// to initiate and open builder chain:
Mutator
type (string const& typeID)
{
return Mutator(*this).type(typeID);
}
template<typename...ARGS>
Mutator
attrib (ARGS&& ...args)
{
return Mutator(*this).attrib(std::forward<ARGS>(args)...);
}
template<typename...ARGS>
Mutator
scope (ARGS&& ...args)
{
return Mutator(*this).scope(std::forward<ARGS>(args)...);
}
// to close and finish builder chain (needs specialisation)
VAL&&
genNode()
{
return Mutator(*this).genNode();
}
VAL&&
genNode(string const& symbolicID)
{
return Mutator(*this).genNode(symbolicID);
}
/* ==== Exposing scope and contents for iteration ====== */
using iterator = IterAdapter<typename _Vec::const_iterator, const Record*>;
@ -370,6 +332,10 @@ namespace diff{
Rec record_;
public:
Mutator()
: record_()
{ }
explicit
Mutator (Rec const& startingPoint)
: record_(startingPoint)

View file

@ -149,10 +149,10 @@ namespace test{
void
objectShortcut()
{
auto o0 = Rec().genNode();
auto o1 = Rec().genNode("νόμος");
auto o2 = Rec().type("spam").genNode();
auto o3 = Rec().attrib("Ψ", int64_t(42), "π", 3.14159265358979323846264338328).genNode("νόμος");
auto o0 = MakeRec().genNode();
auto o1 = MakeRec().genNode("νόμος");
auto o2 = MakeRec().type("spam").genNode();
auto o3 = MakeRec().attrib("Ψ", int64_t(42), "π", 3.14159265358979323846264338328).genNode("λόγος");
CHECK (!o0.isNamed());
CHECK (isnil(o0.data.get<Rec>()));
@ -167,22 +167,22 @@ namespace test{
CHECK (isnil(o2.data.get<Rec>()));
CHECK (o3.isNamed());
CHECK ("νόμος" == o3.idi.getSym());
CHECK ("λόγος" == o3.idi.getSym());
CHECK ("NIL" == o3.data.get<Rec>().getType());
CHECK (GenNode("Ψ", int64_t(42)) == o3.data.get<Rec>().get("Ψ"));
CHECK (42L == o3.data.get<Rec>().get("Ψ").data.get<int64_t>);
CHECK (1e-7 > fabs (3.14159265 - o3.data.get<Rec>().get("π").data.get<double>));
CHECK (42L == o3.data.get<Rec>().get("Ψ").data.get<int64_t>());
CHECK (1e-7 > fabs (3.14159265 - o3.data.get<Rec>().get("π").data.get<double>()));
LuidH luid;
//Demonstration: object builder is based on the mutator mechanism for Records...
auto o4 = Rec::Mutator(o2) // ...use GenNode o2 as starting point
.appendChild(GenNode("τ", Time(1,2,3,4))) // a named node with Time value
.scope('*' // a char node
,"" // a string node
,luid // a hash value (LUID)
,TimeSpan(Time::ZERO, FSecs(23,25)) // a time span
,Rec().type("ham").scope("eggs").genNode()) // a spam object
.genNode("baked beans"); // ---> finish into named node
auto o4 = Rec::Mutator(o2.data.get<Rec>()) // ...use GenNode o2 as starting point
.appendChild(GenNode("τ", Time(1,2,3,4))) // a named node with Time value
.scope('*' // a char node
,"" // a string node
,luid // a hash value (LUID)
,TimeSpan(Time::ZERO, FSecs(23,25)) // a time span
,MakeRec().type("ham").scope("eggs").genNode()) // a spam object
.genNode("baked beans"); // ---> finish into named node
CHECK (o4.isNamed());
CHECK ("baked beans" == o4.idi.getSym());
@ -202,7 +202,7 @@ namespace test{
++scope;
auto spam = *scope;
CHECK (!++scope);
CHECK ("ham" == spam.getType());
CHECK ("ham" == spam.data.get<Rec>().getType());
CHECK (spam.contains (GenNode("eggs")));
// but while o4 was based on o2,
@ -215,7 +215,7 @@ namespace test{
void
symbolReference()
{
GenNode ham = Rec().type("spam").attrib("τ", Time(23,42)).genNode("egg bacon sausage and spam");
GenNode ham = MakeRec().type("spam").attrib("τ", Time(23,42)).genNode("egg bacon sausage and spam");
GenNode::ID hamID(ham);
CHECK (hamID == ham.idi);