this bit of Sed magic relies on the fact that we happen to write
the almost correct class name of a test into the header comment.
HOWTO:
for F in $(find tests -type f \( -name '*.cpp' \) -exec egrep -q '§§TODO§§' {} \; -print);
do sed -r -i -e'
2 {h;x;s/\s+(.+)\(Test\).*$/\\ref \1_test/;x};
/§§TODO§§/ {s/§§TODO§§//;G;s/\n//}'
$F;
done
Doxygen will only process files with a @file documentation comment.
Up to now, none of our test code has such a comment, preventing the
cross-links to unit tests from working.
This is unfortunate, since unit tests, and even the code comments there,
can be considered as the most useful form of technical documentation.
Thus I'll start an initiative to fill in those missing comments automatically
reason is, only files with a @file comment will be processed
with further documentation commands. For this reason, our Doxygen
documentation is lacking a lot of entries.
HOWTO:
find src -type f \( -name '*.cpp' -or -name '*.hpp' \) -not -exec egrep -q '\*.+@file' {} \; -print -exec sed -i -r -e'\_\*/_,$ { 1,+0 a\
\
\
/** @file §§§\
** TODO §§§\
*/
}' {} \;
Damn sideeffect of the suppport for move-only types: since we're
moving our binding now into place /after/ construction, in some cases
the end() iterator (embedded in RangeIter) becomes invalid. Indeed this
was always broken, but didn't hurt, as long as we only used vectors.
Solution: use a dedicated init() hook, which needs to be invoked
*after* the TreeMutator has been constructed and moved into the final
location in the stack buffer.
at first, this seemed like a good idea, but it caused already
numerous quirks and headache all over the place. And now, with
the intent to switch to the TreeMutator based implementation,
it would be damn hard to retain these features, if at all
possible.
Thus let's ditch those in time and forget about it!
this is a subtle change in the semantics of the diff language,
actually IMHO a change towards the better. It was prompted by the
desire to integrate diff application onto GenNode-trees into the
implementation framework based on TreeMutator, and do away with
the dedicated implementation.
Now it is a matter of the *selector* to decide if a given layer
is responsible for "attributes". If so, then *all* elements within
this layer count as "attribute" and an after(Ref::ATTRIBS) verb
will fast forward behind *the end of this layer*
Note that the meta token Ref::ATTRIBS is a named GenNode,
and thus trivially responds to isNamed() == true
needed to use a forward function declaration within the
lambda for recursive scope mutator building, since otherwise
everything is inline and thus the compilation fails when it
comes to deducing the auto return type of the builder.
Other than that, the whole mechanics seem to work out of the box!
similar reordering for the third part.
This time most operations are either passed down anyway,
or are NOP, since attribute binding has no notion of 'order'
as said, I try to use the same underlying sequence of diff verbs both
for the high-level and the low-level test. Thus, since the high-level test
requires an adjustment to the test definition, we'll have to re-order
all of the low-level tests likewise. This is part-1 of this re-ordering
...during implementation of the binding, I decided to be more strict
with the interpretation of "reshaping" of attributes: since my onion-layer
for attribute binding works without the notion of any 'position' or 'ordering',
I made up my mind that it's best outright to reject any diff verbs attempting
to re-order or delete attributes. The rationale is that otherwise the same diff
might lead to substantially different results when applied to a Rec<GenNode>
as when applied to a target data structure bound via TreeMutator.
Consequently, the previously established test diff sequence would raise an error::Logic
in the second segment, since it attempts to re-order attributes. Instead of this,
I've now introduced a after(Ref::ATTRIBS) verb and I'm re-ordering children
rather than attributes.
Unfortunately this also prompts me to re-adjust all of the TreeMutatorBinding_tests,
since these detail tests are intended to play the same sequence on low level.
This is not a fundamental problem, though, just laborious. CHECK (target.showContent() == "α = 1, γ = 3.45, γ = 3.45, β = 2, Rec(), 78:56:34.012, b");
In Theory, acceptSrc and skipSrc are to operate symmetrically,
with the sole difference that skipSrc does not move anything
into the new content.
BUT, since skipSrc is also used to implement the `skip` verb,
which serves to discard garbage left back by a preceeding `find`,
we cannot touch the data found in the src position without risk
of SEGFAULT. For this reason, there is a dedicated matchSrc operation,
which shall be used to generate the verification step to properly
implement the `del` verb.
I've spent quite some time to verify the logic of predicate evaluation.
It seems to be OK: whenever the SELECTOR applies, then we'll perform
the local match, and then also we'll perform the skipSrc. Otherwise,
we'll delegate both operations likewise to the next lower layer,
without touching anything here.
--> now it becomes obvious that we've mostly
missed to integrate the Selector predicate properly
in most bindings defined thus far. Which now causes
the sub-object binding to kick in, while actually
the sub-value collection should have handled
the nested values CHILD_B and CHILD_T
OMG, this is intricate stuff....
Questionable if anyone (other than myself) will be able
to get those bindings right???
Probably we'll need yet another abstraction layer to handle
the most common binding situations automatically, so that people
can use the diff framework without intricate knowledge of
TreeMutator construction.
This is the first skeleton to combine all the building blocks,
and it passes compilation, while of course most of the binding
implementation still needs to be filled in...
- default recommendation is to implement DiffMutable interface
- ability to pick up similar non-virtual method on target
- for anything else client shall provide free function mutatorBinding(subject)
PERSONAL NOTE: this is the first commit after an extended leave,
where I was in hospital to get an abdominal cancer removed.
Right now it looks like surgery was successful.
this is at the core of the integration problem: how do we expose
the ability of some opaque data structure to create a TreeMutator?
The idea is
- to use a marker/capability interface
- to use template specialisation to fabricate an instance of that interface
based on the given access point to the opaque data structure
but unfortunately this runs straight into a tough problem,
which I tried to avoid and circumvent all the time:
At some point, we're bound to reveal the concrete type
of the Mutator -- at least to such an extent that we're
able to determine the size of an allocator buffer.
Moreover, by the design chosen thus far, the active
TreeMutator instance (subclass) is assumed to live within
the top-level of a Stack, which means that we need to
place-construct it into that location. Thus, either
we know the type, or we need to move it into place.
the idea is to demonstrate the typical situation
of some implementation class, which offers to create
a binding for diff messages. This alone is sufficient
to allow mapping onto our "External Tree Description"
this is done to help with understanding these quite technical matters:
in the integration test, we use a specific diff sequence and
apply it against an opaque data structure, which is bound using
the TreeMutator::Builder
On the other hand, the TreeMutatorBinding_test covers the
elementary building blocks available to construct such a TreeMutator;
here again we assume the precisely same sequence of diff verbs
in all test cases, but actually we're issuing here those interface
actions on the TreeMutator API, which *would* be issued to
consume this diff sequence. Of course, there need to be
slight variations, since not any kind of binding can
handle all operations, but in principle the result
on the target data structure should be semantically
equivalent in all cases
initially, even the diff applicator was meant to be a
"throwaway" object. But then, on writing some tests,
it seemed natural to allow re-using a single applicator,
after having attached it to some target.
With that change, I failed to care for the garbage
left back in the "old" sequence after applying one diff;
since in the typical usage sequence, the first use builds
content from scratch, this problem starts to show up only
with the third usage, where the garbage left from the input
of the second usage appears at the begin of the "new sequence"
Solution is to throw away that garbage explicitly on re-entrance
the plan is to put together an integration test
of diff application to opaque data through the TreeMutator,
using the now roughly finished binding primitives.
moreover, the idea is to apply precisely the same diff sequence,
as was used in the detail test (TreeMutatorBinding_test).
NOTE: right now, the existing placehoder code applies this sequence
onto a Rec<GenNode>. This should work already -- and it does,
BUT the result of the third step is wrong. Really have to
investigate this accidental finding, because this highlights
a conceptual mismatch in the handling of mixed scopes.