Commit graph

28 commits

Author SHA1 Message Date
9e9c6c3ec6 TreeExplorer: solve refresh-problem when expanding children
We need a way for higher layers to discard their caching and re-evaluate,
once some expansion layer was invoked to replace the current element with
its (functionally defined) "children" -- otherwise the first child will
remain obscured by what was there beforehand.

Solution is to pass such manipulation calls through the full chain of
decorators, allowing them to refresh themselves when necessary. To achieve
that technially, we add a base layer to absorb any such call passed down
through the whole decorator chain -- since we can not assume that the
parent, the original source core implements those manipualation calls
like expandChildren()
2017-12-06 00:43:43 +01:00
b8cf274de6 Refactoring: extract new duck detectors
due to switching from ADL extension points to member functions,
we now need to detect a "state core" type in a different fashion.
The specific twist is that we can not spell out the full signature
in all cases, since the result type will be formed as a consequence
of this type detection. Thus there are now additional detectors to
probe for the presence of a specific function name only, and the
distinction between members and member functions has been sharpened.
2017-12-05 06:05:33 +01:00
52edf7d930 Refactoring: switch IterStateWrapper to member function based API
Considering the fact that we are bound to introduce yet another iteration control function,
because there is literally no other way to cause a refresh within the IterTreeExplorer-Layers,
it is indicated to reconsider the way how IterStateWrapper attaches to the
iteration control API.

As it turns out, we'll never need an ADL-free function here;
and it seems fully adequate to require all "state core" objects to expose
the API as argument less member function. Because these reflect precisely
the contract of a "state core", so why not have them as member functions.
And as a nice extra, the implementation becomes way more concise in
all the cases refactored with this changeset!

Yet still, we stick to the basic design, *not* relying on virtual functions.
So this is a typical example of a Type Class (or "Concept" in C++ terminology)
2017-12-05 03:28:00 +01:00
ca270028a9 TreeExplorer: transform-operation implemented and covered in test 2017-12-04 04:34:27 +01:00
b5453cc429 TreeExplorer: reimplementation with simpler design
- always layer the TreeExplorer (builder) on top of the stack
- always intersperse an IterableDecorator in between adjacent layers
- consequently...
  * each layer implementation is now a "state core"
  * and the source is now always a Lumiera Iterator

This greatly simplifies all the type rebindings and avoids the
ambiguities in argument converison. Basically now we can always convert
down, and we just need to pick the result type of the bound functor.

Downside is we have now always an adaptation wrapper in between,
but we can assume the compiler is able to optimise such inline
accessors away without overhead.
2017-12-04 04:34:26 +01:00
e58e4553f4 TreeExplorer: make the Core -> Core design work, kind of
...yet this seems like a rather bad idea,
it breeds various problems and requires arcane trickery to make it fly

==> abandon this design
==> always intersperse an IterableDecorator between each pair of Layers
2017-12-04 04:34:24 +01:00
c65c5f812b Library: put the new type rebinding trait into general use
Obsoletes and replaces the ad-hoc written type rebindings from
iter-adapter and friends. The new scheme is more consistent and does
less magic, which necessitates an additional remove_pointer<IT> within
the iterator adaptors. Rationale is, "pointer" is treated now just as
a primitive type without additional magic or unwrapping, since it is
impossible to tell generically if the pointer or the pointee was
meant to be the "value"
2017-12-02 02:51:51 +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
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
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
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