Commit graph

4210 commits

Author SHA1 Message Date
8e8a67e6df test fixes up to (not including) the iteration scope bracketing
...since for the latter I'll actually chose quite another
approach, based on the HierarchyOrientationIndicator
2015-09-17 19:39:34 +02:00
269ef07655 introduce special treatment for RecRef payload
The intention is to allow a Ref to "stand-in" for
a GenNode holding a full Record inline
2015-09-17 19:00:55 +02:00
7f2e328ab3 generalise containment check to anything that matches the GenNode
Whooa!
Templates are powerful.
programming this way is really fun.

under the assumption that the parts are logical,
all conceivable combinations of theses parts are bound to be correct
2015-09-11 20:25:39 +02:00
07f45a58de implement containment check based on iteration 2015-09-11 20:12:26 +02:00
3576b30cd2 formally complete implementation of GenNode iteration
it passes compilation, but the test still fails, since
I've changed the expected semantics of the iteration,
in the light of the insights I've gained during
re-investigation of the IterExplorer.

What I now actually intend is rather to embed a
HierarchyOrientationIndicator into the iterator,
instead of returning a special "bracket" marker
reference to indicate return from a nested scope.
2015-09-11 20:00:36 +02:00
823b4fd322 WIP: implement the recursive scope expansion
Only a Record payload constitutes a nested scope.
For all other (primitive) values, we return an empty iterator.
When used within ScopeExplorer, this implementation will just
lead to exposing any simple value once, while delving into
iteration of nested scopes
2015-09-11 19:23:40 +02:00
3f91997cf1 WIP: rearrange types to make the recursive iteration work
The only substantial change (besides compilation fixes) is
to confine the iteration to *const access*

This is a good thing; the whole Record/GenNode structure
was designed to represent immutable data, necessitating
a dedicated *Mutator* for any reshaping.
2015-09-11 18:41:18 +02:00
82ef5964ba Fix to use IterAdapter with generic "position" types
seemingly the operator-> was not yet used in any real scenario.
The whole point with IterAdapter is that it uses an opaque "location type",
which is owned by the controlling container. In many cases this will
actually be just a pointer into the container storage, but we
must not assume it is this way. Thus the only way to obtain a
(language) pointer is to dereference the "position type" and
take the address of the result
2015-09-11 18:32:08 +02:00
0d10e62851 WIP: draft a monad-like scope expanding iterator implementation
Initially I intended just to supply an addapter to use
the monadic IterExplorer for this recursive expansion
of GenNode contents. Investigating this approach was
relevant to highlight the minimum requirements for
such an evaluation mechanics: since our GenNode
is an hierarchical structure without back-links,
we are bound to use a stack at some point. And
since an Iterator is a materialised continuation,
we can not use the processor stack and are forced
to represent this stack in memory.

Yet, on second thought, we do not need the full power
of the IterExplorer monad; especially we do not need
to bind arbitrary functions into the monad, just one
single scope exploring function, implemented as
Variant visitor. Based on these observations, we can
"inline" the monad structure into a double nested
iterator, where the outer capsule carries a stack
of scopes to be explored.
2015-09-11 04:06:51 +02:00
25459028cc extend and adjust semantics of the HierarchyOrientationIndicator
This helper was drafted for the Job / JobPlanning and Scheduler
interface in 2013, but seemingly not yet put into action. While
in the original use case, we have a genuine measuerment for the
tree depth (given by the depth of the processing stack), in other
use cases we want to use to offset embedded within the indicator
itself for keeping track of the depth. Thus I add a second
mark operation, which usess the current offset to set a new
reference level. This has the consequence that the offset
has now to reflect the new reference point immediately
2015-09-04 22:15:44 +02:00
9e35ed0e49 IterExplorer: remove the hard wired safeguard value copy
Since C++ is not a real functional programming language and
has unsafe unmanaged pointers, it is not difficult to produce
dangling references within an extended evaluation pipeline
involving transient objects and pass-by-reference.

In the initial implementation, I built in a safeguard copy
into the signature of the Explorer function, to make sure even
a transiently dressed-up input value gets materialised before
proceeding with the source sequence. Unfortunately this safeguard
turns out as a roadblock now; we might as well take the input
by reference and return an "expanded" state by value. We might
even want to do the full "expansion" on referred state, when
we're able to ensure the source values remain in memory
until consumption.

Thus now the full power of decision is placed on the signature
of the explorer function. The expansion strategies of IterExplorer
will no longer attempt to "sanitise" the signature of the passed-in
function to prevent desaster; I've added some warnings into the
documentation to highlight that danger. Basically, if you want
to be clever, then you're bound to read and understand inticacies
of the implementation.

If in doubt, use values and copying. C++ is optimised for that.
2015-09-04 17:55:34 +02:00
794e70a64b augment function type rebinding helper
allow to pick the bare function signature from any "function like" entity

Note: we're still unsing our own Typelist construct to represent
the function argument types. Since we're now using C++11, this
could be replaced by varargs, and we could get rid of those
various overloads for different numbers of arguments.
Unfortunately this transition is linked to the usage of
argument tuples in our command framework (which could then be
replaced by std::tuple), and this is still a bit of rather
technical work, which I do not want to spend much time on
right now
2015-09-04 17:14:11 +02:00
e77bc625d6 fix typo in strategy name 2015-09-02 01:49:09 +02:00
be70e58441 considering how to implement the GenNode sequence iteration
remembered that some years ago I had to deal with a very similar problem
for planning the frame rendering jobs. It turned out, that the
iterator monad developed for this looks promising for our task at hand
2015-08-31 03:34:23 +02:00
2ba7978ce7 draft behaviour of the GenNode sequence iteration
this design is rather into the blue,
not sure what we actually need for diff generation
and object serialisation. Anyhow, I considered including
a bracketing construct a good idea, and I considered it
sensible to expose inner nodes, not only the leaf nodes.

Obviously, this is not a real monad iteration then.
2015-08-30 17:47:20 +02:00
bcd6308dee reorganise compilation units
this really turned into an implementation part of GenNode
2015-08-30 04:57:32 +02:00
a56ca7308f implement the data matching predicate on GenNode
TODO: need built-in special treatment for RecRef
2015-08-30 04:44:20 +02:00
efe97b9174 util: epsilon comparison for doubles
add the usual standard implementation to compare floating point numbers
based on the machine epsilon and the magnitude of the involved numbers
2015-08-30 04:14:28 +02:00
25f78bfa83 draft a more premissive matching predicate
the intention is to combine this with content iteration
to build containment check and find operations
2015-08-30 00:00:41 +02:00
b0368a6d2b full unit test coverage of equality
horay!
seems like madness?
well -- found and squashed a bug: equality on RecordRef
implicitly converted to GenNode(RecordRef), which always
generates new (distinct) IDs and so never succeeds. What
we really want is equality test on the references
2015-08-29 21:27:33 +02:00
261b51998a rewrite equality on GenNode to rely on the new Predicate-Visitor 2015-08-29 19:14:42 +02:00
11ca89a2fd cover usage of predicate in unit test 2015-08-29 19:07:51 +02:00
4c59e16f06 add the visitor-predicate as a second option
contrary to the Visitor, accepting a Predicate is const,
and -- of course -- the Predicate invocation returns bool.

This can be used to implement comparison operators or
search functions on Variant based data structures.
2015-08-29 18:56:19 +02:00
de3726c856 integrate the new construction just to replace the existing visitor 2015-08-29 18:34:34 +02:00
d6e9d5b3a4 Design: extend the Variant::Visitor (3)
specialise to a predicate working on const types.

This is the complete draft we want to integrate into
the existing Visitor code
2015-08-29 18:10:18 +02:00
92b779c6b8 Design: extend the Variant::Visitor (2)
extend to arbitrary return values
2015-08-29 17:31:42 +02:00
24762eda89 Design: extend the Variant::Visitor (1)
replicate the existing setup for this design study
2015-08-29 17:09:03 +02:00
a05c9f81a6 Segfault: one move to much
the temporary was destroyed before moving it out.
2015-08-29 01:46:24 +02:00
bb92b49340 GenNode diagnostics -- debugging 2015-08-28 23:09:10 +02:00
33a6294a9b implement the remaining attribute handling functions for Record<GenNode>
There is no generic implementation for these functions, since
they are highly dependent on the payload used within Record<TY>
Here we use Record<GenNode>, which turns the whole setup into an
recursive data type; we especially rely on the fact that each
GenNode has an embedded symbolic ID, and we use this ID to encode
the 'key' for named attributes
2015-08-28 18:27:23 +02:00
96791d4a45 fix omission in generic ID functions and add unit test
while in debugging, it turned out that the short type-prefix
was implemented in a too simplistic way; it fails on stuff
like 'lib::diff::Record<lib::diff::GenNode>'


while I must add, that the whole purpose of these ID functions
is somewhat unclear and needs to reveal itself as we move forward
2015-08-28 17:18:52 +02:00
aa96cb6dd1 implement full data-based equality for GenNode
initially my intention was to use the ID for equality test.
But on a second thought, this seemed like a bad idea, since
it confuses the concepts of equality and identity.

Note: at the moment, I do not know if we even need an equality test,
so it is provided here rather for sake of completeness. And this
means even more that we want an 'equality' implementation that
does what one would naively expect: compare the object identity
*and* compare the contents.
2015-08-28 16:12:04 +02:00
1024cea2c8 fix a mistake 2015-08-28 13:40:57 +02:00
cc989d171f investigate hash collisions on 32bit platform
...while on the train back from FrOSCon.
still the same old problem: we need a better hash function
for generating our Entry-IDs. The default hash function from Boost performs
poor on strings with common prefix and trailing number.

We use a hackish workaround, which is sufficient to avoid collisions
among the first 10000 numbers.
2015-08-27 23:48:39 +02:00
da43d7f00f follow-up to the bugfix: just plain int is yet more readable
basically the 32/64bit problem was caused by things like 23L, which creates a long.
Unfortunately on 64bit platforms, this is aliased to int64_t,
while on 32bit i386, it is a distinct data type, but just 32bit,
like int.

The code in question here is just test / demonstration code
and actually just needs "some integer number". So let's stick
to good old boring int then.
2015-08-27 23:46:12 +02:00
4b2f7ef3ad fix a 32/64 bug
the obnoxious problem with long, which is
only 32bit on 32bit platforms.

incidentally, sitting here at FrOSCon 15
in the Lumiera developers room
2015-08-22 22:20:58 +02:00
a56226f297 Record "object" representation now finished and passes Test 2015-08-17 22:13:36 +02:00
0bff4f21d5 Record References: fix copy and assignment handling
not entirely sure about the design, but lets try this approach:
they can be "cloned" and likewise move-assigned, but we do not
allow the regular assignment, because this would enable to use
references like pointers (what we deliberately do not want)
2015-08-17 20:56:40 +02:00
7650b36f1e Generic Record: finish implementation of Mutator
especially setting (changing) attributes turned out to be tricky,
since in case of a GenNode this would mean to re-bind the hash ID;
we can not possibly do that properly without knowing the type of the payload,
and by design this payload type is opaque (erased).

As resort, I changed the semantics of the assign operation:
now it rather builds a new payload element, with a given initialiser.
In case of the strings, this ends up being the same operation,
while in case of GenNode, this is now something entirely different:
we can now build a new GenNode "in place" of the old one, and both
will have the same symbolic ID (attribute key). Incidentally,
our Variant implementation will reject such a re-building operatinon
when this means to change the (opaque) payload type.

in addition, I created a new API function on the Mutator,
allowing to move-in a complete attribute object. Actually this
new function became the working implementation. This way, it is
still possible to emplace a new attribute efficiently (consider
this to be a whole object graph!). But only, if the key (ID)
embedded in the attribute object is already what is the intended
key for this attribute. This way, we elegantly circumvent the
problem of having to re-bind a hash ID without knowing the type seed
2015-08-17 20:31:07 +02:00
46bfc0638f Generic Record: settle type handling
initially, the intention was to inject the type as a magic attribute.
But this turned out to make the implementation brittle, asymmetric
and either quite demanding, or inefficient.

The only sane approach would be to introduce a third collection,
the metadata attributes. Then it would be possible to handle these
automatically, but expose them through the iterator.

In the end I decided against it, just the type attribute
allone does not justify that effort. So now the type is an
special magic field and kept apart from any object data.
2015-08-17 06:34:51 +02:00
0cde55a67f Generic Record: finish basic implementation 2015-08-17 03:59:53 +02:00
657f0031f4 Generic Record: reorganise type configuration
this solves the problem how to deal with value access
- for the simple default (string) implementation,
  we use a 'key = val' syntax and thus have to split strings,
  which means we need to return contents by value
- for the actual relevant use case we have GenNode entries,
  which may recursively hold further Records. For dealing
  with diff messages over this data struture, its a good
  idea to allow for const& value access (otherwise we'd
  end up copying large subtrees for trivial operaions)
2015-08-17 02:40:57 +02:00
61b6868bff pick up work where I left one month ago
OMG, what was all this about?
OK... this cant possibly work this way.
At least we need to trim after splitting the attributes.
But this is not enough, we want the value, which implies
to make the type flexible (since we cant return a const& to
a substring extracted on-the-fly)
2015-08-17 01:22:01 +02:00
8dcdce1a58 Doxygen: adjust ignores
now using Doxygen 1.8.8 -- which generates a SQLite-DB
2015-08-17 01:14:33 +02:00
80e78492d2 Reference platform for Lumeira is now Debian/Jessie 2015-08-16 02:49:53 +02:00
c2d5896a3b Project: switch to C++14
This means we have rather tight compiler requirements now.
Beyond that, we expect no serious impact; the most notable
C++14 feature we're likely to use soon is type inference
on lambda arguments.
2015-08-16 01:43:04 +02:00
24d7f55935 Merge Platform upgrade and Diff-Framework development 2015-08-16 01:42:26 +02:00
40decd68d4 partial revert of preceding: rejected by GCC
this was an half hearted attempt to satisfy CLang,
but GCC as keen as a razor insists on these inherited
functions not being accessible --

seems like the time is over, when GCC used to be forgiving
and CLang briliantly precise...

So the conclusion of this "round trip" is: whenever GCC
also starts whining about shadowed overloaded virtual functions,
we'll just switch to "-Wno-overloaded-virtual" and be done with
that pointless discussion.

Since C++11, we have the Java style override specifier,
which does a way better job at spotting signature mismatches
2015-08-16 01:37:04 +02:00
9ff79b86cf fix warnings found by CLang (3.5)
Note: not fixing all relevant warnings.

Especially, the "-Woverloaded-virtual" of Clang defeats the whole purpose
of generated generic interfaces. For example, our Variant type is instantiated
with a list of types the variant can hold. Through metaprogramming, this
instantiation generates also an embedded Visitor interface, which has
virtual 'handle(TY)' functions for all the types in question

The client now may implement, or even partially implement this Visitor,
to retrieve specific data out of given Variant instance with unknown conent.
To complain that some other virtual overload is now shaddowed is besides the point,
so we might consider to disable this warning altogether
2015-08-16 01:37:04 +02:00
266cce9abe fix for compiling with CLang (3.5) 2015-08-16 01:35:31 +02:00