Commit graph

2813 commits

Author SHA1 Message Date
8794aec35a fix a warning after C++11 transition (#898)
it is still questionable why GCC emits the warning
"enumeral and non enumeral constant in comparison"
since both arguments of the comparison are enum constants.


I've asked that question on stackoverflow....
http://stackoverflow.com/questions/29685367/reasoning-behind-enumeral-and-non-enumeral-type-in-conditional-expression
2015-04-17 03:12:08 +02:00
413a6a5d48 outline and stub the API functions. 2015-04-16 23:04:36 +02:00
4092feb3c8 TICKET #738: move asside existing variant implementation
this was an immature first desgin attempt; we need a lightweight
Variant (typesafe union) implementation, so now is the time for
a second attempt. The existing Variant is used only once, and this
usage as such is in a questionable context, likely to be reworked
when we actually start coding up the builder. So I'll just move
it away and mark it @deprecated for the time being.
2015-04-16 18:38:35 +02:00
8a13a5092c switch to static_assert (C++11) 2015-04-16 02:27:03 +02:00
51cdc85e58 back from LAC2015: re-read and simplify the code draft 2015-04-13 15:49:38 +02:00
2e1df16bdc settle on a concrete implementation approach based on inheritance chain
After some reconsideration, I decide to stick to the approach with the closures,
but to use a metaprotramming technique to build an inheritance chain.
While I can not decide on the real world impact of storing all those closures,
in theory this approach should enable the compiler to remove all of the
storage overhead. Since, when storing the result into an auto variable
right within scope (as demonstrated in the test), the compiler
sees the concrete type and might be able to boil down the actual
generated virtual function implementations, thereby inlining the
given closures.

Whereas, on the other hand, if we'd go the obvious conventional route
and place the closures into a Map allocated on the stack, I wouldn't
expect the compiler to do data flow analysis to prove this allocation
is not necessary and inline it away.


NOTE: there is now guarantee this inlining trick will ever work.
And, moreover, we don't know anything regarding the runtime effect.
The whole picture is way more involved as it might seem at first sight.
Even if we go the completely conventional route and require every
participating object to supply an implementation of some kind of
"Serializable" interface, we'll end up with a (hand written!)
implementation class for each participating setup, which takes
up space in the code segment of the executable. While the closure
based approach chosen here, consumes data segment (or heap) space
per instance for the functors (or function pointers) representing
the closures, plus code segment space for the closures, but the
latter with a way higher potential for inlining, since the closure
code and the generated virtual functions are necessarily emitted
within the same compilation unit and within a local (inline, not
publickly exposed) scope.
2015-04-05 18:26:49 +02:00
723d1e0164 settle architectural considerations regarding the TreeMuator concept
so yes, it is complicated, and inevitably involves three layers
of indirection. The alternative seems to bind the GUI direcly to
the Session interface -- is there a middle gound?

For the messages from GUI to Proc, we have our commands, based
on PlacementRef entities. But for feeding model updates to the
GUI, whatever I consider, I end up either with diff messages or
an synchronised access to Session attributes, which ties the
responsiveness of the GUI to the Builder operation.
2015-04-03 20:10:22 +02:00
e4a1261849 initial syntax draft
the envisioned DSL syntax for installing the binding closures
into a generic tree mutator object seems to work out
2015-04-02 03:30:20 +02:00
b051845835 identify and decide on some of the insidious questions of design
- how to deal with typing
- how to relate equality and mutations
2015-03-21 19:23:41 +01:00
f5ddfa0dbe decide on the foundations of tree diff representation
- we use a GenNode element
- this holds a polymorphic value known as DataCap
- besides simple attribute values, this may hold collections of GenNode sub elements
- a special kind of GenNode collection, the Record, is used to represent objects

The purpose of this setup is to enable an external model representation
which is only loosely coupled to the interndal data representation
through the exchange of (tree)diff messages
2015-03-21 02:00:55 +01:00
9a9e17578c extended planning to define the operation of UI-Bus and model update
this includes a decision about the tree diff representation and handling format
2015-01-17 16:08:56 +01:00
28d18a7326 refactoring: better name for the query focus shifting operation
previously this operation was named 'attach', which an be confused
with attching an object to this location. Indeed, the session interface
even offers such an attach function. By renaming the focus moving
operation into QueryFocus::shift(Scope), this ambiguity is resolved
2015-01-08 15:13:27 +01:00
7bd3eafd46 adjust gui code indentation 2015-01-07 00:53:03 +01:00
8b6177a1c5 Design: Backbone of the GUI
This is the first step towards a generic backbone to connect
any GUI elements to the session within Proc-Layer.

It is based on a spefic understanding of Model-View-Controller,
which turns the Model-Controller interactions into messages.
2015-01-06 23:44:58 +01:00
371c13f790 add TODO markers regarding #959
Some parts of the GUI model will be remoulded
2015-01-05 15:47:23 +01:00
55b2c79aad Implementation of List Diff detection finished. Unit Test PASS 2015-01-04 15:13:16 +01:00
a12a739f05 allow for iterative access to the snapshot data in the lookup table 2015-01-04 14:23:12 +01:00
a8d1cd9c8b trivial implementation of index / snapshot table
lots of room for improvement here :)
2015-01-04 14:01:07 +01:00
80eec4132b factor out index table helper and define its contract 2015-01-04 13:23:57 +01:00
d0dcccbd1b move and split drafted code to the acutal library headers 2015-01-04 12:36:13 +01:00
eb8ad8ed11 code up the actual list diff generator algorithm
sans the implementation of the index lookup table(s)

The algorithm is KISS, a variant of insertion sort, i.e.
worst time quadratic, but known to perform well on small data sets.
The mere generation of the diff description is O(n log n), since
we do not verify that we can "find" out of order elements. We leave
this to the consumer of the diff, which at this point has to scan
into the rest of the data sequence (leading to quadratic complexity)
2015-01-04 12:02:41 +01:00
5427d659d7 definition reordering and comments 2015-01-04 09:26:25 +01:00
97c63e0472 solution how to place and use the diff token constructors
finally....
The problem is that the C++ "dependent types" defeat the typical
DSL usage, where you define some helper function in a generic
language setup class and mix this language in as superclass.
This is, C++ requires us to refer explicitly to any dependent type,
since, due to possible template specialisations, the parser
can't know if a given symbol is a inherited type or a field.

As a solution, we place the token constructor functors into a
static struct "token", which allows to write e.g. token.insert(xyz)
2015-01-04 09:08:36 +01:00
5c818aff69 better typename 2015-01-03 12:52:09 +01:00
5bae84392a implementation of demand-driven diff generating iterator
TODO: actual decision tree
2015-01-03 02:37:33 +01:00
25646337cd change list diff language to rely on 'find' instead of 'push'
As decided in beb57cde
this changeset switches our basic list diff language to work
in the style of an insertion sort. Rather than 'pushing back'
out-of-order elements, we scan and bring forward missing elements.

Later, when passing the original location of the elements
fetched this way, a 'skip' verb will help to clean up
possible leftowers, so implementation is possible
(and indeed acomplished) without shifting any other elements.
2015-01-02 13:18:25 +01:00
a3d89e304f minor style fix 2015-01-02 11:48:02 +01:00
ee941996c4 DSL tokens need to be equality comparable
and this adds a twist: conceptually, we identify the token
with the abstract handler function it represents. But C++
does not allow us to compare member pointers to virtual functions,
for good reason: even two pointers with the "same offset" into
the VTable might end up referring to different implementations,
when bound to instances of different subclasses. This is what
polymorphism is all about.

At this point it seems reasonably, albeit a bit uggly, to use the
diagnostic ID as placeholder instead, and just compare these IDs
instead. We assume that in practice tokens will be defined through
the provided helper macro, which ensures unique identifiers.
2015-01-02 11:31:29 +01:00
cd85b3425e fix: neat a dedicated translation unit for definitions
...yes, sometimes we even want to emit code ;-)
2015-01-02 11:26:27 +01:00
14849c2df0 convenicence shortcut to expose a container snapshot as iterator
basically just a function to pick up the container and element type automatically.
The actual implementation is delegated to the exisiting lib::iter_stl::IterSnapshot
2014-12-15 03:22:36 +01:00
9707a8982c Diff Handling and Diff Application: framework and definitions
factored out of the concept test built last week.
2014-12-15 03:21:19 +01:00
658698407e use the successful concept test as starting point for a diff handling system
...basically move code from test to various headers
2014-12-15 01:27:03 +01:00
746fba98d5 DSL verb token: move to distinct definition header
concept finished thus far
2014-11-28 12:50:58 +01:00
088e4422fb Test helper to show demangled C++ names
Heureka! found out that the C++ standard library exposes a
cross vendor C++ ABI, which amongst others allows to show
object code names and type-IDs in the language-level, human
readable unmangeld form.

Of course, actual application code should not rely on such a
internal representation, yet it is of tremendous help when
writing and debugging unit tests.

Signed-off-by: Ichthyostega <prg@ichthyostega.de>
2014-11-22 03:31:59 +01:00
639fd224db Lib: helper to deal with malloced memory automatically
basically just a dressed-up std::unique_ptr
2014-11-16 04:26:12 +01:00
09e7e1f8f5 WIP: pondering diff representation variants
Actually I arried at the conclusion, that the *receiving* of
a diff representation is actually a typical double-dispatch situation.
This leads to the attempt to come up with a specialised visitor
as standard pattern to handle and apply a diff. Obviously,
we do not want the classical GoF-Visitor, but (yes, we had
that discussion allready) -- well in terms of runtime cost,
we have to deal with at least two indirections anyway;
so now I'm exploring the idea to implement one of these
indirections through a functor object, which at the same time
acts as "Tag" in the diff representation language (instead
of using an enum as tag)
2014-11-10 04:00:39 +01:00
41ad41d1f1 clean-up: sourcefile layout and spell checking
Uniform sequence at start of source files
- copyright claim
- license
- file comment
- header guard
- lumiera includes
- library / system includes

Lumiera uses Brittish spelling. Add an according note to the styleguide.
2014-10-23 23:04:35 +02:00
3dccb77245 clean-up: use dashes in filenames 2014-10-23 23:04:33 +02:00
41a711120c planning the access structure to session content
initial considerations; there is a concurrency problem, since
all of session handling within Proc is deliberately not threadsafe.
Thus the decision is to make this the gui::model::SessionFacade's responsibility
2014-10-19 05:54:20 +02:00
92b06e2f03 fix segfault at plugin-deregistration (due to #864)
The actual problem is not resolved; the pluginloader
should detect the duplicate and not add the handle
to the database initially. Or it should add it
as "duplicate" or "alternate implementation"

Which probably means we need to coder some additional
corner cases. But certainly not now, we have other
more important stuff to do first... we've already
lost the battle against Duke Nukem Forever :-P
2014-10-18 04:57:48 +02:00
e02a9d213d enable special unit-tests to link against the gui 2014-10-18 04:27:07 +02:00
b6d131bc35 Start remoulding the Timeline display: mark deprecation (#955)
Mark parts of the timeline state handling which will certainly
not be retained: any part where the GUI widgets "hold" some kind
of model. GUI widgets shall be *mapped upon* a model representation
and *wired* with callbacks.

Especially I am suspicious when GUI presentation code "reaches into"
any kind of model data structure to find out something. It should
be the other way round (dont call us, we call you)
2014-10-17 03:01:11 +02:00
994a0e718b WIP mark the point where we lost the draw() callback during GTK3-transition
actually we should make our timeline a real custom widget,
and do it according to the letter. I.e. really implement
all those callbacks which are recommended, but no other
callbacks.

This has the additional benefit of being able to retrieve
the drawing style in the official way, and define our own
CSS classes, which can be styled by the user in a systematic way.
2014-10-14 04:20:15 +02:00
819a81d86d Suppress GUI shutdown crashes(#937, #172)
This is not really a solution, but kind of narrowes down the problem.
Our GUI uses an obsolete C-ish approach at releasing resources at
several points. This is probably a left-over from earlier days.

Especially since we started out with libGDL without C++ wrappers.
And at that time, we didn't use smart-pointers, as we should do,
but we tried to do things manually, which is an approach which never
works in an event driven and condition based environment. Goto fail.


Here I just commented out the manual clean-up code from several dtors.
The real solution would be not to allocate these resources through
the raw C calls at first place, but rather use the mm-wrappers
and leave it to them to unwind at the right moment.

TODO:

- scan the GUI code for *every* instance where we still muck around with gobjects
  and either replace that by a mm-wrapper, or wrap it in a smart handle.
- make sure that *all* dtors are either empty, or really airtight and EX_FREE
2014-10-14 04:17:56 +02:00
964a372d67 Fix re-entrance in Application shutdown(#954)
doh...
this happens when you draft some quite intricate logic and then
get sidelined with other tasks for several years. Mind me, I didn't
even recall that I had treated this whole issue and created
a clean-up thread.

A full fledged implementation would have a real lifecycle and
thus detect the re-entrance; but since none of the components
to be managed by the OutputDirector is even remotely planned
or even coded, the functions were just drafted as stubs.

Which caused us happily to create yet another clean-up thread
whenever the subsystem-runner signalled "please shut down".
2014-10-14 04:10:54 +02:00
4ef4f2bdc5 Protect against re-entrance(#954)
This is a safety guard and should never be activated.
2014-10-14 03:46:12 +02:00
afaad7044c Identified possible GUI shutdown crasher. To be investigated
Our GUI shutdown logic looks rather confused. Why the hell do
some widgets "unregister" themselves in a dtor. This should never
be necessary. Maybe it's a leftover from C-style programming
and obsolete now, after the switch to GDLmm
2014-10-13 02:44:15 +02:00
1596f83266 subsystem-runner: signal should not be kalled "kill"
...since it doesn't kill, rather ask to terminate.
2014-10-13 02:21:14 +02:00
5b6ebeaa5f stylesheet: finish definition of a base style
- text entry colours
- hover / mouse over
- disabled entries
- ensure consistent menu styling
2014-10-09 03:44:02 +02:00
5fdee24bf5 stylesheet: default borders and entry appearance
the problem seems to be the interplay with the installed user
theme; what looks well with one theme is messed up with another
one, quite insidious.

Attempt to settle down on a set of default definitions
for borders and element background colors, which make the
Lumiera Gui "dark" but still respect the user's theme
for geometry and widget style
2014-10-08 05:16:43 +02:00
51b81640eb first round of style porting: basic background colours 2014-10-07 04:56:05 +02:00
1c01192872 load a CSS style sheet and install it globally
verified: basically works
todo: better handling of parse errors.
Currently this is treated as an unexpected exception and just
terminates the whole application, without any suitable diagnostics.
This makes working on the stylesheet somewhat brittle. GTK-3 actually
offers a signal to be invoked in case of CSS parsing errors

(see #953)
2014-10-07 03:13:58 +02:00
f5a995514f publish the new GTK-3 style under a GPL 2+ or CC-By-SA dual license 2014-10-07 01:19:50 +02:00
38bc139778 GTK-stylesheet: change name to gtk-lumiera.css
the mechanism for configuring and locating this file is just fine
and can be retained. Of course, the content of the stylesheet
remains to be ported
2014-10-07 00:59:03 +02:00
8a817f1ab7 Make Video Widget NOP; GDK Drawing no longer supported (#950)
Comment out the active part of the GdkDisplayer implementation,
but retain the class, to make compilation pass.

With the Switch to GTK-3, only Cairo drawing is supported.
We need a new solution for video display...
2014-10-05 09:32:06 +02:00
Michael Fisher
ea8358c661 is_visible to get_visible (gtkmm3) 2014-10-05 08:40:55 +02:00
Michael Fisher
ac3ef9f469 Project: join GTK-3 and GDLmm port 2014-10-05 08:38:38 +02:00
Michael Fisher
c63e7f9b6e Adapt Pannel Button
Panel Button implementing the MenuButton::get() API
to retrieve MenuItems.

Fixed broken Panel Menu's 'Lock' ability due to GTK move
2014-10-05 08:16:59 +02:00
Michael Fisher
a86f3bf497 Adding support to append Separator Items for MenuButton
Updated PanelBar to use this API
2014-10-05 08:16:59 +02:00
Michael Fisher
00f29ea3d5 Aggressive code pruning in the ButtonBar.
Again, default event handlers appear to be working better
than the previous overrides. Subject to re-implementation
2014-10-05 08:16:59 +02:00
Michael Fisher
cf3a0b49ce Commenting test code 2014-10-05 08:16:59 +02:00
Michael Fisher
0315931eba Upgrade the MenuBar
Implement new MenuBar::append API (partial).
Also adding if 0's and Gtk3 FIXME annotations
2014-10-05 08:16:59 +02:00
Michael Fisher
0c03e01ce6 Updating MenuButton to use Gtk::UIManager for menu creation 2014-10-05 08:16:59 +02:00
Michael Fisher
ed86ab0807 Aggressive code pruning.
Note: Default event handlers for Gtk::Box appear to be working better
than our previous overrides. Subject to re-implementation
2014-10-05 07:49:57 +02:00
Michael Fisher
53124624f0 PanelBar Gtk3 maybe update. GtkRequisition related 2014-10-05 07:49:57 +02:00
Michael Fisher
a629d8a9f1 Button Bar Gtk3 fixes (round 1). 2014-10-05 07:49:57 +02:00
Michael Fisher
f365791047 Annotating for removal. No Gtk3 support 2014-10-05 07:49:57 +02:00
Michael Fisher
7e6eff9e6a gtk3: timeline widget uses 'get_visible' instead of 'is_visible' 2014-10-05 07:49:57 +02:00
Michael Fisher
b1293b130f Updating legacy functions to GTK-3
Updating legacy Gtkmm 'set_flags(Gtk::NO_WINDOW)' calls
to use set_has_window(bool) in timeline custom widgets
2014-10-05 07:49:57 +02:00
Michael Fisher
c64de14fbf Changes to allow the gtk3 GUI to at least build.
Lots off commented out blocks of code
but most issues are related to simple function name changes,
set/get_flags calls, anything that has to do with a Gtk::Style...

Plan of attack from here is to go one-by one of each commented-out or code and update to gtk3 specs.
2014-10-05 07:49:57 +02:00
Michael Fisher
af5a44997b Project: switch GUI environment to GTK-3 / gtkmm-3.0 2014-10-05 07:49:53 +02:00
Michael Fisher
fd95c74bb8 Assertion to investigate GLib warnings
trying to track down where these messages

  GLib-GObject-CRITICAL **: g_object_unref: assertion G_IS_OBJECT (object) failed

are coming from.  These appear when iconifying panels.
2014-10-05 05:34:25 +02:00
Michael Fisher
708c977d57 Remove unused GDL headers 2014-10-05 05:34:19 +02:00
Michael R. Fisher
13a27a8fd8 Comment problematic code 2014-10-05 04:37:34 +02:00
Michael R. Fisher
d42d917b4c House Cleaning 2014-10-05 04:37:34 +02:00
Michael R. Fisher
2d8805c554 Gdlmm port nuances. Signals/Containers etc... 2014-10-05 04:37:34 +02:00
Michael R. Fisher
68c6cef003 Individual Panels initial Gdlmm port 2014-10-05 04:37:34 +02:00
Michael R. Fisher
eb4cdcd975 Panel Manager ported to Gdlmm-1.0 2014-10-05 04:37:30 +02:00
30686fdf82 fix argument passing for MultiFact(#388)
as always, it turned out that the alledged "compiler bug"
rather was my own sloppyness: I forgot properly to undo a change
I made while fighting with compilation problems: the wrapper in
the factory didn't use std::forward, resulting in a plain flat
slicing copy. This, rightfully, triggered the assertion in the
session query resolver (since a sliced Goal can not be dynamic cast
to a specific Query subclass).
2014-09-23 03:37:28 +02:00
059dbd8c75 fix and finish the diagnostics helper
there was still a subtle bug in this helper.
testing your own test fixture is sometimes a good idea ;-)
2014-09-23 03:37:28 +02:00
4145452397 factor out a diagnostics helper for variadic templates
a nice offspring of this investigation
2014-09-22 03:37:07 +02:00
9dfd3fc981 phase out some use of auto_ptr
TODO: the toolfactory needs a redesign anyway,
this was just placeholder code added in a very early
state of the Lumiera project. We have way better memory
managing facilities at hand now
2014-09-15 02:03:10 +02:00
d064623bab Reworked MultiFact(#388): switch in the new implementation 2014-09-14 23:58:05 +02:00
9a5d9873c8 WIP: prepare switch to the reworked MultiFac implementation #388 2014-09-14 22:38:58 +02:00
591e6d9775 MultiFact: implement the last and most complex usage case
the use of a custom finisihing functor, which is applied
to any generated product. This can be used for registration,
memory management or similar framework aspects
2014-09-14 22:25:12 +02:00
932d49fd95 MultiFact: how I learned to love the Bomb
C++11 is just incredibly cool. It is so easy to
support a flexible yet specific set of arguments
2014-09-14 02:06:58 +02:00
372edbfc85 MultiFact: implement second use case (smart pointers) 2014-09-14 00:36:36 +02:00
0ff5c50030 MultiFact: implement simple usage pattern. NOTE: breaks CLang 3.0
Implement the first simple usage scenario for the
unified MultiFact template, using variadic templates.

NOTE:
 - the obvious solution based on std::forward
   triggers strange behaviour in GCC-4.7
 - the inline lambda in the test case traps the
   CLang-3.0 parster with a segfault. Horay!
2014-09-13 02:50:14 +02:00
a1bb9178f5 Ticket #388: start investigation of MultiFact design
needs overhaul, since current design leads to problems
with GCC 4.8 onwards (and is messed up anyway)
2014-09-11 00:10:59 +02:00
b2b75fbe43 attempt to make factory invocation more evident in the code
...but the whole design looks still overengineered. See #388

- should get rid of the explicit specialisation
- always use a function signature and thus have arguments?
- why inheriting from the wrapper?
2014-09-08 03:37:41 +02:00
21079f3145 re-reading and rewording comments
still puzzled why this instantiation of MultiFact fails to compile with GCC 4.8

so I'm bound to understand why the types involved
need indeed to be are structured the way they are right now.
2014-09-08 02:52:38 +02:00
7faa2e784d CLang-Compatibility: zero argument ctor now treated as function definition
previous versions used to resolve this ambiguity in favour of a ctor call,
but now the compiler treats such constructs as function definition;
this is reasonable, since C++11 introduced the notion of a "generalised
initialisation", which is always written as a (possibly empty) list
in braces.

In these specific cases here, we just omit the empty parens
2014-08-26 03:31:03 +02:00
685f4327f5 Fix: remove explicitly given hash function, use the automatic bridge instead
Since we have now a generic bridge to supply std::hash functions based on
an exisiting boost::hash function, we removed the explicit std::hash
specialisation for "Placement-ID".

This caused the PlacementIndex implementation to fail at compilation
with a quite obscure error, which in fact seems to be caused by the
absence of any specific specialisation. The symptom is that a iterator
range could not be assigned to the predefined iterator type of
std::unordered_multimap, due to a mismatch in the embedded traits type

__umap_traits<__cache_default<_Key, _Hash>::value>>

While I didn't track down that problem entirely, to verify my hypothesis,
the problem can be avoided by using the default -- which is now to
pick up an existing boost::hash function for this type and use this
to generate the std::hash function.
2014-08-26 03:04:14 +02:00
05042d96cd document the hash bridge with a unit test 2014-08-17 08:39:46 +02:00
e35a45a65e tricky header reordering to support a hackish-workaround (#944)
right now we have to defeat an unfortunate static assertion in
the standard library, which is expected to go away in the future.
We use a hack to hijack the problematic definition with the preprocessor,
which requires our header to be first.
2014-08-17 08:03:21 +02:00
9a95beda32 Library: automatic bridge to use boost::hash functions for std::hash
NOTE: this header contains a potentially dangerous, temporary workaround
to defeat the static assertion in the default implementation of std::hash,
as shipped with GCC 4.7.x

This assertion turns out to be detrimental all kinds of metaprogramming
based solutions, since it defeats SFINAE. It is expected to be removed
in GCC 4.8
2014-08-17 07:15:47 +02:00
f02481bb90 fix include order in GUI headers
the rules are:
- our own headers go before any library headers
- all headers need to be spelled relative to include root
- ensure that gtk is always included via gui/gtk-base.hpp
2014-08-17 07:02:48 +02:00
561e036e0b remove any remaining use of boost::lambda
obsolete now, we can use the lambdas of the stock language
2014-05-12 01:12:45 +02:00
c2ea15695e amend harmless PlacementIndex test failures. Test Suite PASS
c++11 uses another hashtable implementation.
This uncovered some poorly written tests, which relied on
objects being returned in a specific order. As far as poissible,
we're using generic query functions now to get our test objects.

But these tests still rely on a specifically crafted test index content,
which as such is acceptable IMHO. The only remaining problem is
that we check the order of generated output in some tests, and this
order is still implementation dependent.
2014-05-11 02:08:53 +02:00
4acb7de682 half hearted fix: order of hashmap entries is implementation dependent
a real fix would be to rewrite the test to collect the retrieved
values and do a structural verification of the results. This
would mean to write a lot of code for such a marginal topic,
which was implemented just for sake of completenes anyway.

Hopefully my lack of "motivation" doesn't backfire eventually ;-)
2014-05-09 01:45:10 +02:00