Commit graph

163 commits

Author SHA1 Message Date
fe10ab92dc DI: adjust codebase to the new DependInject configuration API 2018-03-31 01:06:10 +02:00
80207ea224 DI: (WIP) switch to totally rewritten new implementation of lib::Depend (#1086)
- state-of-the-art implementation of access with Double Checked Locking + Atomics
- improved design for configuration of dependencies. Now at the provider, not the consumer
- support for exposing services with a lifecycle through the lib::Depend<SRV> front-end
2018-03-31 01:06:06 +02:00
7a250ca9e5 DI: benchmark atomic locking 2018-03-24 11:02:44 +01:00
f05ec78e08 DI: benchmark Double-Checked-Locking with Mutex
This is essentially the solution we used since start of the Lumiera project.
This solution is not entirely correct in theory, because the assignment to the
instance pointer can be visible prior to releasing the Mutex -- so another thread
might see a partially initialised object
2018-03-24 11:02:44 +01:00
ff256d9e57 DI: benchmark naive lock protected access
...which gives us the dramatic numbers we'd expect.
Especially the multithreaded variant contends drastically
2018-03-24 11:02:43 +01:00
d2dababf5c DI: benchmark dependency-factory with unprotected lazy init
NOT threadsafe.
Indeed, crashed several times during the multithreaded benchmark runs
2018-03-24 08:29:39 +01:00
69f21d96af DI: prepare benchmark of reference cases
_not_ using the dependency factory, rather direct access

 - to a shared object in the enclosing stack frame
 - to a heap allocated existing object accessed through uniqe_ptr
2018-03-24 07:48:59 +01:00
31539f00c8 Library: a function for performing multithreaded microbenchmarks 2018-03-24 01:58:34 +01:00
3104016cf2 DI: set up framework for investigation of performance impact
We are about to switch to Double Checked Locking with C++11 atomics,
and we want some rough numbers regarding the Impact
2018-03-23 23:42:10 +01:00
364dcd5291 DI: verify and improve static sanity checks
esp. for subclass instance creation from within a lambda
2018-03-22 21:43:19 +01:00
83476b3ef1 DI: Reworked dependency-factory implementation draft complete -- move into library headers
This is a complete makeover of our lib::Depend and lib::DependencyFactory templates.
While retaining the basic idea, the configuration has been completely rewritten
to favour configuration at the point where a service is provided rather,
than at the point where a dependency is used.

Note: we use differently named headers, so the entire Lumiera
code base still uses the old implementation. Next step will be
to switch the tests (which should be drop-in)
2018-03-19 03:46:49 +01:00
957e7ff54c DI: extract testcode into new unit test 2018-03-19 03:46:43 +01:00
debd7c1797 DI: fix indentation
...want to retain the git history
2018-03-19 01:55:17 +01:00
f66d452c56 DI: refurbish internal access for the configuration handles
explicit friendship seems adequate here
DependInject<SRV> becomes more or less a hidden part of Depend<SRV>,
but I prefer to bundle all those quite technical details in a separate
header, and close to the usage
2018-03-19 01:14:52 +01:00
b776ce568f DI: fix inspiring Segfault
a bloody closure that bangs itself away....
2018-03-19 00:44:26 +01:00
f0c8928301 DI: draft implementation for testmock support 2018-03-19 00:05:02 +01:00
786f051132 DI: problem of misconfiguration for service access
This is a tricky problem an an immediate consequence of the dynamic configuration
favoured by this design. We avoid a centralised configuration and thus there
are no automatic rules to enforce consistency. It would thus be possible
to start using a dependency in singleton style, but to switch to service
style later, after the fact.

An attempt was made to prevent such a mismatch by static initialisiation;
basically the presence of any Depend<SRV>::ServiceInstance<X> would disable
any usage of Depend<SRV> in singleton style. However, such a mechanism
was found to be fragile at best. It seems more apropriate just to fail
when establishing a ServiceInstance on a dependency already actively in
use (and to lock usage after destroying the ServiceInstance).

This issue is considered rather an architectural one, which can not be
solved by any mechanism at implementation level ever
2018-03-18 17:19:30 +01:00
5516700523 DI: draft configuration for using a service implementation created elsewhere 2018-03-18 02:11:46 +01:00
9f93154f62 DI: draft configuration for using a subclass Singleton 2018-03-18 01:30:51 +01:00
e1ca9f447b DI: draft syntax for special dependency injection configuration 2018-03-18 00:57:25 +01:00
eebe31aa7e DI: change to heap allocation for singletons
up to now we used placement into a static buffer.
While this approach is somewhat cool, I can't see much practical benefit anymore,
given that we use an elaborate framework which rules out the use of Meyers Singleton.
And given that with C++11 we're able just to use std::unique_ptr to do all work.

Moreover, the intended configurability will become much simpler by relying
on a _closure_ to produce a heap-allocated instance for all cases likewise.

The only possible problem I can see is that critical infrastructure might
rely on failsafe creation of some singleton. Up to now this scenario
remains theoretical however
2018-03-17 23:41:56 +01:00
e393d44e92 DI: replace Meyers Singleton by an explicitly managed buffer
Meyers Singleton is elegant and fast and considered the default solution
However...

 - we want an "instance" pointer that can be rebound and reset,
   and thus we are forced to use an explicit Mutex and an atomic variable.
   And the situation is such that the optimiser can not detect/verify this usage
   and thus generates a spurious additional lock for Meyers Singleton

 - we want the option to destroy our singletons explicitly
 - we need to create an abstracted closure for the ctor invocation
 - we need a compiletime-branch to exclude code generation for invoking
   the ctor of an abstract baseclass or interface

All those points would be somehow manageable, but would counterfeit the
simplicity of Meyers Singleton
2018-03-17 17:30:28 +01:00
261049e04d DI: minimalistic design for service access
Problems:
 - using Meyers Singleton plus a ClassLock;
   This is wasteful, since the compiler will emit additional synchronisation
   and will likely not be able to detect the presence of our explicit locking guard

 - what happens if the Meyers Singleton can not even be instantiated, e.g. for
   an abstract baseclass? We are required to install an explicit subclass configuration
   in that case, but the compiler is not able to see this will happen, when just
   compiling the lib::Depend
2018-03-17 03:36:58 +01:00
28176c58ed DI: drafts towards a new dependency factory design 2018-03-16 03:57:02 +01:00
533ed45d8b DI: expand the concept of our dependency factory to handle service instances (#1086)
Most dependencies within Lumiera are singletons and this approach remains adequate.
Singletons are not "EVIL" per se. But in some cases, there is an explicit
lifecycle, managed by some subsystem. E.g. some GUI services are only available
while the GTK event loop is running.

This special case can be integrated transparently into our lib::Depend<TY> front-end,
which defaults to creating a singleton otherwise.
2018-03-11 03:20:21 +01:00
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
2c53dc2e57 Investigation: failure to detect nested typedef
a metafunction to detect nested typedefs worked perfectly in the test setup,
but failed once included into application code.
2017-12-02 02:51:37 +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
8bdd9e7d66 Research: build "anything function-like" trait
...with the sole exception that such a trait can not detect
a templated or overloaded function call operator
2017-11-24 23:48:56 +01:00
2533565f83 Research: probing a generic lambda is not possible
...since all those metaprogramming techniques rely on SFINAE,
but *instantiating* a template means to compile it, which is more
than just substituate a type into the signature

If forming the signature fails -> SFINAE, try next one
If instantiating a template fails -> compile error, abort
2017-11-24 23:48:56 +01:00
01937f9736 Research: possiblity to detect a generic Lambda? 2017-11-24 23:48:56 +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
8f865183e3 Research: how to build a meta predicate to perform this detection 2017-11-19 00:35:38 +01:00
2345d76138 Research: how to detect that a type in question exposes a free function extension point
The key trick is to form an expression with the free function, using a declval of the type to probe.
What is somewhat tricky is the fact that functions can be void, so we need just to pick up
the type and use it in another type expression
2017-11-19 00:35:38 +01:00
636ab6e608 Metaprogramming: integrate the new facilities into the library 2017-09-29 00:51:13 +02:00
b5af8dbb51 Investigation: cleaner solution for default initialisation
Handle corner cases within the front-end functions,
either by static assert or direct branching;
keeps the variadic implementation template clean
2017-09-28 04:51:25 +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
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
3da370000c Investigation: likely the only way to get it to work
seems to be impossible to get rid of the intermediary argument repackaging delegate call.
As always the reason is that argument packs are no real first class types
2017-09-27 20:07:51 +02:00
5e3088c45b Investigation: need to limit the scope of the quest
there is the danger to get into building a fully generic solution, which is
- quite hard / challenging
- counterfeits the goal of writing easy-to-read code

This is the very reason why I do not want to use boost::MPL,
because in our usage situation, their abstractions are not worth
the price in terms of hard to read code.
2017-09-27 18:39:47 +02:00
3ad3f11f1e Investigation: slightly improved similar solution 2017-09-27 02:46:01 +02:00
23cc0597b5 Investigation: basically working yet convoluted solution draft 2017-09-27 00:26:04 +02:00
97727a6283 Investigation: draft intended call structure
using function calls here, but in the end, what we want is to invoke
some ctor with part of the provided argument sequence
2017-09-26 20:44:27 +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
9a0b72e8ca Function-Tools: include the investigation code as unit test
...since there is not any test coverage for this trait, which
turned out to be quite deeply rooted in the system by now and
handles several rather subtle special cases
2017-03-19 02:29:39 +01:00
efad48c831 Function-Tools: new improved function signature trait including lambda support (#994)
move the reworked solution in place,
replacing the existing workarounds, partial solutions and variations
2017-03-19 02:07:18 +01:00
e2c4dec015 Function-Tools: verify coverage of reference and rvalue reference types
the usual suspects...
turns out we need specialisations for those too, even while in most cases
those special reference type won't make it far, and just degrade to function pointer
2017-03-19 01:26:48 +01:00
f8f8cc02d1 Function-Tools: simplify and modernise the main cases
...to not rely on the old-style signature templates anymore,
i.e. get rid of typename FunctionSignature<function<RET(ARGS...)>>

now, most cases just delegate to the "plain signature" case
2017-03-19 00:56:52 +01:00
f19fabfa3a Function-Tools: thus change behaviour for member-pointer-to-function
...to not include the "this" argument anymore
2017-03-19 00:40:10 +01:00
dfea57fd02 Function-Tools: switch tail-call to variadic template
..otherwise unchanged.

NOTE: we need two variants, since lambdas are always const functions,
      while a member pointer to (non)const function would not be captured
      by that overload and thus recurse into the main case and fail there
      with "has no operator()"
2017-03-19 00:27:59 +01:00
0b7559ce9a Function-Tools: include lambdas into the investigation
...and move the tail-call of the template instantiation into try.cpp


This experiment clearly shows the discrepancy now:
 - binding a member pointer directly into a function object will expand the argument list
 - but binding a similar lambda into a function object won't
   (it is not necessary due to the context capture)

The result is that we need to drop support for one of those cases,
and it is clear that the member poiter will be the looser...
2017-03-19 00:19:07 +01:00
c5bff75bc2 Function-Tools: start investigation regarding Signatures and member pointers
It is not clear what would be the 'right' way to handle a member pointer to function
within the function-trait _Fun. The existing implementation choose to inject
an additional parameter for the enclosing class ("this"), which seems to collide
with the intention to use this overload with the "decltype trick" to integrate
support for lambdas.

As it turns out, this specific code path of the existing _Fun trait was not
yet used, fortunately, so we're free to search for the proper design here...
2017-03-18 23:31:10 +01:00
47ce7ad96b research finished: build a (compiletime) tuple from runtime sequence
...should document this by a unit-test
2016-01-28 15:37:35 +01:00
ae7912dc99 refactoring: move new library helpers into final destination 2016-01-28 15:19:09 +01:00
e748473b77 refactoring: a reworked version of init argument mapper
...used in function-closure.hpp to fabricate an argument tuple
for std::bind, for partially closing some function.

This is an attempt to rewrite this somewhat convoluted helper
in a way to fit in with the tuple element picking mechanism
just defined here. Not sure if it's better readable now;
at least it is significantly shorter and omits some
partial specicalisations
2016-01-28 00:28:56 +01:00
803292dda5 refactoring: towards a more generic formulation
because this element picking mechanism for tuples
looks like an instance of something generic.

At least I've written almost the same just some days ago
for the revised version of function-closure, where the
task was to replace a stretch of type arguments in
a given tuple type with a stretch of placeholder types
and then to build a modified ctor, which just fills
in the remaining arguments, while default constructing
the placeholder types. And if we look into the GNU
implementation of std::bind, they're using a similar
concept (with the difference that they're building
a functor object, where we use a type converter)


This refactoring also integrates some generally useful
bits into our standard metaprogramming helper collection
2016-01-27 12:38:16 +01:00
1cbebb1fab research: investigate narrowing conversion problem
as it turns out, this is a Bug in GCC 4.9 (resolved in 5.x)
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63723

Problem is, GCC emits a warning on narrowing conversions,
while the standard actually disallows them when building
objects from brace-enclosed initialisers.

Unfortunately GCC also emits such a warning from within
a SFINAE context, instead of letting those spurious dangerous
cases fail. So we end up with additional visitor double dispatch
paths, and a lot of additional warnings.

Temporary solution is to hack a custom trait, which
explicitly declares some conversions paths as "narrowing".
Probably this can be implemented in a way more intelligent
way (using std::numeric_limits), but this doesn't seem
worth the effort, since the problem will go away through
compiler evolution eventually.
2016-01-24 13:44:12 +01:00
f4bcdcf4e8 research: full solution, including double-dispatch converter stack
now we're able to construct suitable parameter values from the
arguments passed embedded in the GenNodes, as is demonstrated with the
EntryID<long> constructed from an ID-string. We really need a full-blown
double-dispatch, since the content type of the concrete GenNode is only
known at runtime (encoded in the RTTI)

There is still the problem with generating some spurions additional
conversion pathes, some of which are narrowing (and thus dangerous).
The copiler emits several warnings here, and all of them are justified.

E.g. it would be possible to pass an int64_t in the GenNode and initialise
a short from it. This might be convenient at times, but I tend rather to
be prohibitive here and thus consider to built in distinct limitations
on the allowed conversions.
2016-01-24 00:15:19 +01:00
02b84cd6dc research: solution skeleton, without type conversion
working with those variadic index sequences is quite nasty!
Seemingly you'd always need a 2-step type rebinding,
tried several hours now to avoid that, sorry.


What still needs to be settled is the actual problem
of type conversions; we do not want to be confined
just to the small selection of types allowed within
GenNode, rather we want automatic type promotion
when it comes to extracting values into ctor args!
2016-01-23 17:30:43 +01:00
a95103eb3b research: define new metaprogramming task
need to bridge between generic typing of tuples
and the DOM-like typing of UI-Bus messages
2016-01-23 11:57:19 +01:00
c4adc234b4 experiment: now bind a Proc-Layer command to these fabricated functions
yeah! it works.

some problems though.
- problem-A : reference arguments
  * we're storing the parameters as-is
  * for not-yet-bound commands we need to store default constructed values
  * together this means we can not handle reference arguments
- problem-B : noncopyable arguments
  * especially our Time values are noncopyable.
  * this is going to become a huge problem for sure!
2016-01-15 23:55:44 +01:00
9c346ca914 experiment: generate both the functor and the handling function
this pinpoints a compatibility problem:

our lib::meta::Types<...> type sequence is not compatible
with variadic template parameters, since it uses a fixed
list of NullType default arguments to absorb the variable
number of types.

--> TODO: switch lib::meta::Types to variadic arguments!
2016-01-15 23:42:49 +01:00
6ae8ad5d0b experiment: bind function to fabricated signature
...and this is cool, since our command framework
already provides a nice type constructor / rebinding template,
so it's easy to pick up just some arbitrary function signature
and fabricate the corresponding "capture" and "undo" signatures.

Starting from there, we can construct std::function objects
with those specifically tailored signatures, and then bind
the actual variadic functions to these.


Bottom line is: it seems feasible to create a variadic
handler function, and then to emulate command invocations
through this function. For one this allows us to build
a debugging facility, and besides that it shows a path
how to solve the other binding problem GenNode -> command
2016-01-15 22:51:17 +01:00
5906ce1e1a experiment: can std::function bind to a variadic function?
yes, we can!
2016-01-15 22:09:15 +01:00
3672873ae6 unit-test(#985): preserve this problem solution as unit test
This clean-up action for Ticket #985 started out as search
for a lightweight generic solution. What is left from this
search now, after including the actual utility code into
our support library, might serve to document this new
feature for later referral
2016-01-09 22:23:50 +01:00
99c478768c generic-toString(#985): define streamlined converter
...based on all the clean-up and reorganisation done thus far,
we're now able to rebuild the util::str in a more direct and
sane way, and thus to disentangle the header inclusion problem.
2016-01-08 09:17:58 +01:00
2c20d407fc mass clean-up: adapt usage of std::cout pretty much everywhere
- remove unnecessary includes
- expunge all remaining usages of boost::format
- able to leave out the expliti string(elm) in output
- drop various operator<<, since we're now picking up
  custom string conversions automatically
- delete diagnostics headers, which are now largely superfluous
- use newer helper functions occasionally

I didn't blindly change any usage of <iostream> though;
sometimes, just using the output streams right away
seems adequate.
2016-01-07 20:12:46 +01:00
6ae8dc62c7 supplement: a "Make P" free function for our smart-ptr
the usual drill...
only when wrapped into a factory function, RAII is really
airtight, even when used from within expression evaluation.

Thanks C++11 we're now able to provide such en passant
2016-01-07 00:38:20 +01:00
ed92b92158 formatting(#985): use custom string conversion with smart-ptr
our lib::P smart-pointer is built on top of std::shared_ptr,
while additionally delegating comparisons to the pointee.

In a similar vein, I've now added a custom string conversion,
delegating to the pointee, with a type-string as fallback.

Together with the built-in string conversion for output streams,
we should now be able to remove most of the explicit string
conversions and calls to util::str in all of our test code.

This removes the last roadblock towards disentangling the
pretty-printing header includes, which in turn should allow
us to remove any conditional code in the built-in string
conversion of GenNode, Variant and the like. Which basically
was the objective for ticket #985
2016-01-06 06:24:02 +01:00
ee52a83cb2 stream-output(#985): use custom string conversions
provide a generic overload for the stream inserter operator<<
to use custom string conversions when applicable.

The overload will be disabled when a direct lexical conversion
is possible (which means, we can expect the output stream to
know allready how to print those values, like e.g. all kinds
of numbers).

Additionally, we provide a pretty-printing mechansim for pointers,
to show the address and possibly invoke a custom string conversion
on the pointee
2016-01-06 04:36:53 +01:00
1814b1fc69 type-traits(#985): rework and clean-up our type-traits
include the improved facility to detect the ability
for lexical cast. Also remove the boost dependency
and switch entirely to standard <type_traits>
2016-01-06 02:41:58 +01:00
e443fd79fd type-traits(#985): better solution to detect string-like types
we need this to branch into lexical conversion, which
should always take precedence over a string conversion.

The existing solution overlooked both the conversion paths
for char*, as well as the fact that chars and c-strings
can be handled directly (pass-through) by lexical conversion
2016-01-06 01:48:34 +01:00
5be35a407f toString(#985): new minimal string-conversion facility
now placed into the very basic header lib/meta/util.hpp
2016-01-05 23:55:18 +01:00
0c4495a451 reorganisation(#985): move basic typeString implementation into lib::meta
- simple function to pick up the mangled type
- pretty-printing is implemented in format-obj.cpp
- also move the demangleCxx()-Function to that location,
  it starts to be used for real, outside the test framework
2016-01-05 23:34:53 +01:00
c104e28ebf inline(#985): provide our own minimal variant of enable_if
this is a stripped-down and very leightweight variant
of the well-known enable_if metaprogramming trick.

Providing this standard variant in a header with minimal
dependencies will allow us to phase out boost inclusions
from many further headers. As a plus, our own variant
is written such as to be more conciese in usage
(no "typename" and no acces of an embedded "::type" menber)
2016-01-05 22:00:53 +01:00
fec0a88753 investigation(#985): solution concept for generic stringify
this includes a reorganisation concept for the header includes,
a minimal version (with minimal include dependencies), and
a generic ostream inserter operator<<
2016-01-05 03:32:24 +01:00
d09a5846d4 basically a working solution for toString in ostream
...and learned a lot about the new type_traits on the way.

As it seems, it is not possible to get a clean error message
when passing an "object" with no custom string conversion;
instead, some overload for an rvalue-ostream kicks in.

probably I'll go for shoing a type string in these cases
2016-01-04 22:21:09 +01:00
9f8ab48c51 reduce headers (unnecessary for this solution) 2016-01-04 04:09:47 +01:00
7ed07ce3c5 solution for a minimal toString-invocator
when leaving out the lexical-cast part
and when inlining the boost::enable_if solution,
we can get basically at zero inclusion overhead
2016-01-04 04:01:34 +01:00
3acd4e5c03 investigation(#985): outline what I want to build for format support
the goal is to get rid of most direct invocations of util::str
and rather to integrate it with generic support facilities
2016-01-04 02:58:58 +01: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
daace8527a investigation: Segfault in GDB (IV) (related to #946)
now isolated the problem.
It is triggered by a std::function bound to a lambda
where some argument type is picked up from the
template parameter of the enclosing function.
2015-08-16 01:17:35 +02:00
f041e974c6 investigation: Segfault in GDB (III)
narrow down involved parts...
2015-08-16 01:16:20 +02:00
28d117820a investigation: Segfault in GDB (II)
narrow down involved parts
2015-08-16 01:16:20 +02:00
a203cfaf20 investigation: Segfault in GDB (I)
after upgrading my system to Debian/Jessie,
I get a segfault in gdb, on attempt to launch the test-suite.

By reducing the modules linked into the test-suite, I could
narrow down the problematic code. It should be noted though,
that this code is not the only problematic object, rather it
is one of several ways to make gdb crash. I picked this example,
as it is rather recent code and lookes fairly straight forward.

Next step was to extract the first segment of the unit test
and plant it into a simple executable with a main function
and without any fancy loading of dynamic libraries.
So it turns out that shared object loading is *not* involved.

But some "interesting" new C++11 constructs are involved,
like passing a local function-ref into a lambda, which later
on will be wrapped into a Lumiera Iterator and then evaluated
through a range-for-loop. Sounds interesting
2015-08-16 01:16:20 +02: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
4145452397 factor out a diagnostics helper for variadic templates
a nice offspring of this investigation
2014-09-22 03:37:07 +02:00
6fa8b41e1d Research: gotcha!
the alledged compiler error turned out to be
just plain flat lack of attention on my side.

I forgot to revert an previous experimental change:
The "wrapper" in the factory takes the argument by-value
(I forgot to add he && back in, which I removed while
fighting with other compilation problems)
2014-09-22 01:16:46 +02:00
e676eb6da8 Research: extend to variadic template calls
also improve the diagnostics to show pass-by LRef or RRef

but unfortunately not able to reproduce the problematic case yet
2014-09-21 19:26:35 +02:00
264b7e8e0f Research: corner cases of "perfect forwarding" 2014-09-21 02:54:54 +02:00
f00450a06c ..and use this trait to build an automatic bridge from boost::hash to std::hash
this completes the exploration; we should now be able to use
any type with boost hash support in the std unordered containers
without much ado.

I wasn't able to come up with a completely modular solution, since
the std::hash template has only one template parameter, which
defeats using enable_if. But since we're controling the default
implementation after the Hijacking anyway, we can as well go
ahead directly to forward to an existing boost::hash function
2014-08-17 03:23:35 +02:00
60b40de3d8 construct a trait to detect boost hash compatibility
this turns out to be quite tough, since boost::hash
just requires a free function 'hash_value' to be
"somehow" present, which might be just through ADL.

My solution is to inject an fallback declaration of such a function,
but only in the namespace where the trait template is defined.
Hopefully this never interferes with real hash functions defined
for use by boost::hash
2014-08-16 04:54:31 +02:00
7391d02c35 investigate the hijacking trick proposed by "enobayram"
...push away the definition from the standard library
and plant our own definition instead -- with a marker
typedef for metaprogramming
2014-08-16 02:04:29 +02:00
e205e1e1a0 investigation of hash function extension points (#722)
start a systematic research about the coexistence of
std::hash and boost::hash. The goal is to build an
automatic bridge function -- but this is hampered by
the unfortunate standard implementation of std::hash

Since meanwhile even the GCC people seem to have realized
this wasn't a good idea, I am geared towards using a hack
to work around this problem, which can be expected to go
away with GCC 4.8.x

A possible idea how to construct such a workaround is
http://stackoverflow.com/questions/12753997/check-if-type-is-hashable


I start this investigation by defining two custom types,
each with his own extension point for hashing. The goal
would then be to use both in a standard hashtable container.
2014-08-13 04:18:38 +02:00
faf62cf8af DOC: start a page with C++11 notes (here: about type conversion)
note down some results found out during the C++11 transition.
There is now a clear distinction between automatic type conversion
and the ability to construct a new instance
2014-08-13 03:08:00 +02:00
a205653cad C++ uses a more precise meaning of 'convertiblity' now
Conversion means automatic conversion. In our case,
what we need ist the ability to *construct* a bool from
our (function) object -- while functors aren't automatically
convertible to bool. Thus we use one of the new predicates
from <type_traits>
2014-05-09 00:56:31 +02:00
7be1b7d35d Switch from TR1 preveiw to the new standard headers
- functional
- memory
- unordered collections
2014-04-03 22:42:48 +02:00