Commit graph

1653 commits

Author SHA1 Message Date
847593f18b Investigation: resolve the mystery and fix the problem
Oh well.
This kept me busy a whole day long -- and someone less stubborn like myself
would probably supect a "compiler bug" or put the blame on the language C++

So to stress this point: the compiler behaved CORRECT

Just SFINAE is dangerous stuff: the metafunction I concieved yesterday requires
a complete type, yet, under rather specific circumstances, when instantiating
mutually dependent templates (in our case lib::diff::Record<GenNode> is a
recursive type), the distinction between "complete" and "incomplete"
becomes blurry, and depends on the processing order. Which gave the
misleading impression as if there was a side-effect where the presence
of one definition changes the meaning of another one used in the same
program. What happened in fact was just that the evaluation order was
changed, causing the metafunction to fail silently, thus picking
another specialisation.
2017-12-02 02:51:51 +01:00
b104508685 Library: extract type diagnostics test helpers 2017-12-01 03:51:54 +01:00
674201f5ea Library: finish new form of the type rebinding trait 2017-12-01 03:25:51 +01:00
1047f2f245 Library: decide on the overall shape of the type rebinding helper
- we do strip references
- we delegate to nested typedefs

Hoever, we do *not* treat const or pointers in any way special --
if the user want to strip or level these, he has to do so explicitly.
Initially it seemed like a good idea to do something clever here, but
on the long run, such "special treatment" is just good for surprises
2017-12-01 02:43:27 +01:00
dce09ebe0d Library: better use a dedicated detector metafunction
...and check for presence of *all three* standard type bindings

 - value_type
 - reference
 - pointer
2017-11-30 23:41:12 +01:00
6bb288bf20 Library: search for a way to rebind to nested definitions
...automatically whenever those are present.
Up to now, we hat that as base case, which limited usage to those cases
where we already know such nested definitions are actually present
2017-11-30 23:28:00 +01:00
60301f7523 Library: need an augmented version of the iterator type rebinding helper
yet another quick-n-dirty hack turned into an useful everyday helper...

but at least I need it to be symmetric in and universally applyable
2017-11-30 21:02:36 +01:00
a3a64147c1 TreeExplorer: implementation draft for the transform-operation
attempt to re-use the same traits as much as possible

NOTE: new code not passing compiler yet, but refactored old code
      does, and still passes unit test
2017-11-30 03:52:32 +01:00
5b86b660ae TreeExplorer: draft functionality of transform-operation 2017-11-28 03:53:09 +01:00
884af619a1 Library: change IterStateWrapper to delayed start-of-evaluation
this is a subtle change which, given all interfaces were used in a logically
consistent way, should not cause any observable change to the yielded elements.
But it changes runtime behaviour, insofar now the evalutaion is initiated
lazily, when first requesting a result type. Prior to this change, the
constructor immediately issued a call to the yield() extension point,
which presumably has the side-effect of preparing the core and initiating
any embedded evaluation, in order to get at the first result; it might
even detect an empty state.

Given the fact that all access operations on the iterator front-end perform
an empty check (and possibly throw at that point), this call is redundant.
2017-11-27 05:56:03 +01:00
134821ca15 DOC: document some of the language limitations highlighted by this research 2017-11-27 05:39:47 +01:00
d8f7a22123 TreeExplorer: cover all the remaining cases supported for the expansion functor 2017-11-27 05:07:06 +01:00
86856390e1 TreeExplorer: cover expansion using a different result type
here using a lambda with side-effect and returning a reference to
a STL collection with the children, which is managed elsewhere.
2017-11-27 05:07:06 +01:00
77c3226948 TreeExplorer: identify yet another subtle type inference problem
surprising behaviour encountered while covering more cases

...obviously the return type of ExpandFunctor::operator()
was inferred as value, even while the invoked functor, from which
this type was deduced, clearly returns a reference.

Solution is simple not to rely on inference, moreover since we know
the exact type in the enclosing scope, thanks to the refactoring which
made this ExpandFunctor a nested class

NOTE:
as it turned out, this is not a compiler bug,
but works as defined by the language:
on return type inference, the detected type is decayed,
which usually helps to prevent returning a reference to a temporary
2017-11-27 05:02:57 +01:00
89005dbeb7 TreeExplorer: fix spurious copy of iterator (argument) on functor invocation
...since our iterators *always* yield a reference to the exposed element,
we can *always* get that referency into the nested yield to obtain the value
2017-11-26 22:29:51 +01:00
9e96ea8323 TreeExplorer: documentation of technicalities 2017-11-25 03:56:44 +01:00
76a11b3730 TreeExplorer: rename and refactor for readability
...while this implementation works now, it is still very complex and intricate.
I am still doubtful this is a good approach, but well, we need to try that route....
2017-11-25 03:54:41 +01:00
bb948bff34 TreeExplorer: working solution to accept generic lambda
but possible only for the iterator -> iterator case

Since we can not "probe" a generic lambda, we get only one shot:
we can try to bind it into a std::function with the assumed signature
2017-11-25 02:16:21 +01:00
4098e2024d TreeExplorer: Sketch how it might be possible to accept generic lambdas
...based on the research from yesterday
2017-11-24 23:48:56 +01:00
3614085ff7 Library: improve the function-signature detector to work as guard with enable_if
This is a consequence of the experiments with generic lambdas.
Up to now, lib::meta::_Fun<F> failed with a compilation error
when passing the decltype of such a generic lambda.

The new behaviour is to pick the empty specialisation (std::false_type) in such cases,
allowing to guard explicit specialisations when no suitable functor type
is passed
2017-11-24 23:48:56 +01:00
18553f22b2 TreeExplorer: cover both variants of functor signature by unit test (PASS) 2017-11-23 03:29:26 +01:00
c5311a116a TreeExplorer: concept how to generalise the expansion functor
Basically we want to support two distinct cases, just by slightly adapting
the invocation of the expansion functor:

Case-1: classical monadic flatMap:
        the Functor accepts a value yielded by the source iterator
        and builds a new "expaneded" iterator

Case-2: manipulation of opaque implementation state
        the Functor knows internal details of the source iterator
        and thus takes the source iterator as such as argument,
        performs some manipulation and then builds a new sub-iterator

A soulution to reconcile those two distinct cases can be built
with the help of a generic lambda
2017-11-23 03:06:02 +01:00
f10e66e4ae TreeExplorer: design a solution to handle expansion of children
this solution makes me feel somewhat queasy..
stacking several adaptors and wrappers and traits on top of each other.

Well, it type checks and passes the test, so let's trust functional programming
2017-11-20 01:03:44 +01:00
d10c5a4f77 TreeExplorer: draft the core (explore) operation
The plan is to use a monad-like scheme, but allow for a lot of leeway
with respect to the src and value types of the expand functor.
A key idea is to allow for a *different* state core than used in the source
2017-11-19 20:36:19 +01:00
cbb35d7161 TreeExplorer: add shortcut to adapt STL container automatically
...selecting the iterator or const iterator as apropriate
2017-11-19 17:35:00 +01:00
fd3d6fb60e TreeExplorer: first testcase, build either from Lumiera-Iterator or use StateCore
TODO: also wrap any suitable STL iterable.
we need a one-shot solution here
2017-11-19 02:28:48 +01:00
fe3feee67a Library: metafunction to detect support for a specific extension point
such a detector function can be used to enable some template specialisation
based on the fact that a target type exposes the desired extension point
2017-11-19 01:43:19 +01:00
9460f79039 WIP: draft how to figure out the kind of iterator
...but does not work as intended:
 * just forming an IterStateWrapper does not trigger SFINAE cleanly in all cases
 * IterStateWrapper can be formed, even when some of the extension points are missing;
   this will be uncovered only later, when actually using one of the operations

but beyond that, the basic type selection logic can work this way
2017-11-18 19:28:57 +01:00
a7bdc05091 WIP: draft first testcase
...just wrapping various kinds of iterators
2017-11-18 18:40:30 +01:00
c3b04af76f TreeExplorer: decide upon the steps towards implementation
Here, the tricky question remains, how to relate this evalutaion scheme
to the well known monadic handling of collections and iterators.

It seems, we can not yet decide upon that question, rather we should
first try to build a concrete implementation of the envisioned algorithm
and then reconsider the question later, to what extent this is "monadic"
2017-11-18 03:00:59 +01:00
782b4f949f TreeExplorer: extended analysis regarding tree expanding and backtracking computation (#1117)
This can be seen as a side track, but the hope is
by relying on some kind of monadic evaluation pattern, we'll be
able to to reconcile the IterExplorer draft from 2012 with the requirement
to keep the implementation of "tree position" entirely opaque.

The latter is mandatory in the use case here, since we must not intermingle
the algorithm to resolve UI-coordinates in any way with the code actually
navigating and accessing GTK widgets. Thus, we're forced to build some kind
of abstraction barrier, and this turns out to be surprisingly difficult.
2017-11-17 21:43:50 +01:00
e035dbc54a UI-Coordinates: support for truncating a given spec
...implemented within the builder.
Will shorten and discard extraneous storage,
but not expand and allocate new one
2017-10-30 02:59:56 +01:00
750b124f88 Library: complement the pseudo-iterator by a IterSource front-end 2017-10-29 15:31:34 +01:00
0682e449a3 Library: a pseudo-iterator to yield just a single value
...which can be helpful when a function usually returns a somewhat dressed-up iterator,
but needs to return a specific fixed value under some circumstances
2017-10-29 14:51:51 +01:00
7e241d9a11 Library: a little bit of modernising and overhaul
- fix some warnings due to uninitialised members
  (no real problem, since these members get assigned anyway)
- use a lambda as example function right in the test
- use move initialisation and the new util::join
2017-10-29 13:22:25 +01:00
16abe82cde LocationQuery: fix a segfault due to ill guided conversion path 2017-10-27 05:12:28 +02:00
1406aa5532 Library: allow Initialisiation of a GenNode from a Rec::Mutator
up to now, we allowed only initialisation with a precisely matching type.
But this special case seems worth supporting, since it typically occurs
within the "object builder" syntax based on Rec::Mutator
2017-10-24 03:51:06 +02:00
198dcc622a Bugfix Library: forward initialiser properly into GenNode
...to avoid unnecessary copy.
Especially relevant for initialising a sub-Record from the object builder syntay "MakeRec()"
2017-10-24 02:44:47 +02:00
d9555701ac UI-Coordinates: implement a partial "sub path" order 2017-10-02 23:06:23 +02:00
286b1829fe UI-Coordinates: implement path split and appending of multiple components
Unit test passes thus far
2017-10-02 06:49:50 +02:00
7826d6dc24 UI-Coordinates: implement low-level data manipulation incl. storage expansion 2017-10-02 06:45:45 +02:00
5097637f0d UI-Coordinates: basic unit test PASS 2017-10-01 21:54:35 +02:00
1079d51c7e UI-Coordinates: implement named component access 2017-10-01 21:37:04 +02:00
ac38f0f963 UI-Coordinates: implement string representation 2017-10-01 21:10:18 +02:00
3a8f639a12 UI-Coordinates: implement reverse lookup 2017-10-01 20:12:45 +02:00
6322f1bc3c UI-Coordinates: define next steps to cover 2017-10-01 20:04:12 +02:00
8c694b6ec0 UI-Coordinates: PathArray abstraction finished and unit test PASS 2017-10-01 06:08:54 +02:00
107e9008e5 UI-Coordinates: bugfix to pass unit test thus far
whew!
2017-10-01 03:58:42 +02:00
5dfd135595 Library: remove redundant checks from IterAdapter implementation
Explicitly assuming that those functions are called solely from IterAdapter
and that they are implemented in a typical standard style, we're able to elide
two redundant calls to the checkPoint() function. Since checkPoint typically performs
some non-trivial checks, this has the potential of a significant performance improvement

- we check (and throw ITER_EXHAUST) anyway from operator++, so we know that pos is valid
- the iterate() function ensures checkPoint is invoked right after iterNext,
  and thus the typical standard implementation of iterNext need not do the same
2017-10-01 03:25:33 +02:00
a08fba5880 UI-Coordinates: establish contract 2017-10-01 01:30:53 +02:00
294efb0321 UI-Coordinates: finish iteration control logic 2017-09-30 21:34:55 +02:00
d7dd01ad62 UI-Coordinates: change subscript to expose const& 2017-09-30 20:03:05 +02:00
21e2227d50 UI-Coordinates: simplify copy initialisation
deliberately skip calls to the default ctor, since we're copying anyway
2017-09-30 19:57:13 +02:00
0bef215350 UI-Coordinates: switch internal path array storage to Literal
...since that is what it meant to be.
To allow this chance, I've now added a default ctor to lib::Literal,
defaulting to the Symbol::EMPTY (the interned empty string)
2017-09-30 18:32:08 +02:00
dd45d6110d Library: Literal now default constructible to empty string
The class Literal is used as a thin wrapper to mark the fact that
some string parameter or value is assumed to be given *literally*

For the contract this indicates
- that storage is somewhere
- storage is not owned and managed by Literal
- yet storage guaranteed to exist during the whole lifetime of the program
- Literal can not be altered
- Literal is transparently convertible to const char *


Currently I am in the course of building some path abstraction, and for that
task it makes sense to hold an array of Literals (instead of pointers), just
because it expresses the intent way more clear. I do not see anything in the
above mentioned contract to prohibit a default constructed Literal, with the
empty string being the most obvious choice.

Note: there is the class Symbol, which derives from Literal. Symbol takes
arbitrary strings, but *interns* them into a static symbol table.
2017-09-30 17:45:38 +02:00
1138898989 UI-Coordinates: implement indexed access
...under the assumption that the content is normalised,
which means
- leading NULL is changed to Symbol::EMPTY
- missing elements in the middle are marked as "*"
- trailing NULL in extension storage is handled by adjusting nominal extension size
2017-09-30 02:48:25 +02:00
ab391d3dfa UI-Coordinates: implement size()
...which is the first step towards standard storage handling
2017-09-30 02:17:13 +02:00
9378badf6b UI-Coordinates: integrate the initialisation split
...as developed in during the metaprogramming investigation
2017-09-30 00:46:52 +02:00
a839cac02b UI-Coordinates: memory management for PathArray extension storage 2017-09-29 18:04:28 +02:00
73adcdf2e0 UI-Coordinates: initial draft for PathArray storage
after various fruitless attempts to rely somehow on the array variant of unique_ptr,
I ended up with a hand coded version of an heap allocated array, managed automatically
2017-09-29 15:03:14 +02:00
4348cd462c Metaprogramming: extend testcase and remould pickInit to support arbitrary arguments
as it turned out, the solution from yesterday works only with uniform argument lists,
but not with arbitrarily mixed types. Moreover the whole trickery with the
indices was shitty -- better use a predicate decision on template argument level.
This simple solution somehow just didn't occur to me...
2017-09-29 02:35:15 +02:00
636ab6e608 Metaprogramming: integrate the new facilities into the library 2017-09-29 00:51:13 +02:00
dc35a1a6e5 Investigation: add a solution for default initialisation of missing arguments
...still somewhat unsatisfactory, because
- no clear compile error message when invoking pickArg with insufficient arguments
- the default initialisation case in SelectVararg is duplicated and messy
2017-09-28 03:58:09 +02:00
3f9565a156 Investigation: augment index iterator to deal with insufficient arguments
basically we want "all the rest" of the arguments to go to the recursive delegate
2017-09-28 01:40:23 +02:00
3f8606c474 Metaprogramming(#987): extract some variadic sequence helpers
some time ago we abandoned our own tuple type in favour of std::tuple
Since then, the helpers and ported utilities provide some generic helpers
to deal with variadic argument sequences, especially to build index sequences,
which in turn can be used to "pick" individual arguments from a variadic parameter pack.

The expectation is for this part of the support library gradually to grow and
in parts to replace the existing type sequence processing helpers. The expectation
is that we'll retain the basic type sequence, lib::meta::Types, but retrofit it
to rely on variadic arguments
2017-09-28 00:19:52 +02:00
4b67521e26 Metaprogramming(#987): mark planned transition to variadic arguments
since the adoption of C++11, we gradually transition our metaprogramming helpers
to support and rely on variadic template parameters. For the time being,
we just augment existing facilities when it comes in handy, yet some more
heavyweight lifting and overall clean-up remains to be done eventually.
2017-09-28 00:10:45 +02:00
3ad3f11f1e Investigation: slightly improved similar solution 2017-09-27 02:46:01 +02:00
e5dc7ba2bc Investigation: dissect argument packs
start investigation on generic techniques to dissect an variadic argument pack
2017-09-26 19:23:03 +02:00
372512006f UI-Coordinates: use a recursive implementation layout
this is a more or less arbitrary guess regaring performance requirements
2017-09-25 00:26:19 +02:00
5e1c25aaf5 UI-Coordinates: extract PathArray base abstraction into a library class 2017-09-24 22:50:42 +02:00
4082526ec6 UI-Coordinates: stub basic path element iteration 2017-09-24 21:14:26 +02:00
937ad64596 DiffMessage: now uniformly plays the role of MutationMessage (closes #1066) 2017-08-13 07:25:32 +02:00
82a12115c3 DiffMessage: complete documentation 2017-08-13 07:25:32 +02:00
f7402ef89d Library: allow to consume an iterator while taking the snapshot 2017-08-13 07:25:32 +02:00
255958b23b Library: fix yet another misconception in iterator comparison
...again the situation when we want to use Lumiera iterators
in a stadard "for each" loop
2017-08-13 00:07:38 +02:00
7e9bb1fb5d DiffMessage: elaborate integration test... 2017-08-12 23:02:00 +02:00
b45ffe5cbe DiffMessage: fix insidious initialisation bug (related to #963)
basically DiffMessage has a "take everything" ctor, which happens
to match on type DiffMessage itslef, since the latter is obviously
a Lumiera Forward Operator. Unfortunately the compiler now considers
this "take everyting" ctor as copy constructor. Worse even, such a
template generated ctor qualifies as "best match".

The result was, when just returing a DiffMessage by value form a
function, this erroneous "copy" operation was invoked, thus wrapping
the existing implementation into a WrappedLumieraIterator.

The only tangible symptom of this unwanted storage bloat was the fact
that our already materialised diagnostics where seemingly "gone". Indee
they weren't gone for real, just covered up under yet another layer of
DiffMessage wrapping another Lumiera Forward Iterator
2017-08-12 18:16:06 +02:00
32f2d6ed9a IterSource: optimise hand-over at construction
by moving, we can avoid the generation of up to 3 additional shared copies
of the DataHandle. The whole invocation now works without touching any shared count
and thus without incurring a memory barrier...
2017-08-12 16:27:30 +02:00
06ff5c4e71 DiffMessage: complete test of diagnostic output 2017-08-12 14:33:26 +02:00
efc27fd07b DiffMessage: draft content diagnostics wrapper 2017-08-12 05:55:31 +02:00
d4ac2d78e2 C++11: improve moving and forwarding of iterators
this becomes more relevant now, since the actual MutationMessage iterators
are implemented in terms of a shared_ptr to IterSource. Thus, when building
processing pipelines, we most definitively want to move that smart-ptr into
the destination, since this avoids touching the shared count and thus avoids
generating unnecessary memory barriers.
2017-08-12 03:01:35 +02:00
4a2384e242 DiffMessage: add further convenience ctor for varargs
hey... all my dream constructors became true
2017-08-12 03:00:38 +02:00
380fa5bb38 DiffMessage: add further convenience ctors for STL containers 2017-08-11 22:23:51 +02:00
7dc0fdd67a DiffMessage: implement convenience ctor to build from Lumiera Iterator 2017-08-11 21:27:51 +02:00
9e4f3f3314 metaprogramming: switch util-foreach to variadic templates (#967)
...likewise low hanging fruit
2017-08-11 20:35:53 +02:00
a731b3caf4 metaprogramming: get rid of the remaining boost::enable_if usages
...low hanging fruit
2017-08-11 20:23:46 +02:00
8c1a43a6b3 metaprogramming: switch util-foreach to our own enable_if implementation
...allows us to get rid of quite some boost-includes
Incidentally, "our own" implementation is equivalent to both the
boost implementation and the implementation from C++14
It is just a bit more concise to write.
2017-08-11 20:02:37 +02:00
9ad0dd9918 DiffMessage: start with drafting the most simple test case
damn it!
why the hell is the C++ language so tedious to write....
even after years of practice you need hours to get the most basic stuff to fly
2017-08-11 18:34:23 +02:00
9d5d758f0c IterSource: use human readable source type diagnostics 2017-08-11 17:08:49 +02:00
dfd3dc1275 DiffMessage: reshape IterAdapter to allow for custom diagnostics
since we do not want to increase the footprint, we're bound to reuse
an existing VTable -- so IterAdapter itself is our only option.
Unfortunately we'll need to pass that through one additional
decoration layer, which is here the iterator; to be able to
add our string conversion there, we need to turn that into
a derived class and add a call to access the underlying
container, which gets us into element type definition mess....
2017-08-11 16:56:18 +02:00
f6baef16c5 DiffMessage: consider to unite the handling of mutation messages (#1066) 2017-08-11 15:23:33 +02:00
fdcf431a9b DiffMesage: use as payload within MutationMessage and pass Diff by RValue
now this highlights the unsettled decision still the more,
as can be seen by all that unnecessary copying. Basically we move the
Diff into the lambda-closure, from there into an anonymous instance,
from there into the embedded Buffer in MutationMessage, which again
just happens to sit in the closure storage when the action is invoked.
And all of this copying just to move the DiffMessage for consumption
into the TreeMutator...

thus by #1066 we should really get rid of the MutationMessage class altogether!
2017-08-11 02:00:54 +02:00
fd0a011ea4 DiffMessage: bold attempt towards a way to produce diffs (#1066)
actually I do not know much regarding the actual situation when,
within the Builder run, we're able to detect a change and generate
a diff description. However, as a first step, I'll pick IterSrouce
as a base interface and use a "generation context", which is to be
passed by shared-ptr
2017-08-11 00:59:10 +02:00
a7ad82c935 Library: can optimise IterStack pop()
...by moving out the element to be extracted;
because of RVO it will in fact be move constructed into
the storage of the caller
2017-08-07 00:20:55 +02:00
70e1a5b922 convert ScopedCollection to rely on C++11
- variadic templates
- type traits
- use uniqe_ptr to manage storage (instead of boost::scoped_array)
2017-08-06 18:21:25 +02:00
0b621e71c5 Library: fix a suptle misconception in the design of IterAdapter
again surprising how such fundamental bugs can hide for years...

Here the reason is that IterAdapter leaves the representation of "NIL" to
its instantiation / users; some users (here in for example the ScopedCollection)
can choose to allow for different representations of "NIL", but the comparison
provided by IterAdapter just compares the embedded pos by face value.
2017-08-06 16:58:22 +02:00
c96fcc1c6a UI-Dispatch: basic CallQueue implementation PASS 2017-08-05 17:59:55 +02:00
56def9f6d7 Library: expose some diagnostics on IterStack / IterQueue by default
seems like most usages will want to expose this kind of diagnostics for unit testing
and in fact the queue or stack nature is the primary nature of this entity,
while iterability comes as additional trait
2017-08-05 17:57:25 +02:00
3dea3c0fa0 UI-Dispatch: draft basic interface of a queue helper (#1098) 2017-08-05 17:36:32 +02:00
9b285a95c0 UI-Integration: plan the next steps to drive this topic ahead (#1099, #1098)
- concept for a first preliminary implementation of dispatch into the UI thread
 - define an integration effort to build a complete working communication chain
2017-08-05 17:36:32 +02:00