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:
parent
d92878876a
commit
d14c502ea9
3 changed files with 35 additions and 55 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue