Commit graph

163 commits

Author SHA1 Message Date
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
cdb3d3045a BUG: Clang shows a problem when accessing templated static variable through separate compilation units
this is really creepy: the same(!) instance of the singleton factory
sees different addresses of the class static variable, depending on
the compilation unit.

Please note that the type of the concrete factory function is *erased*
when exiting the constructor function of ConfigurableHolder
2013-10-06 23:17:18 +02:00
4bd9eeb8ee bughunt: re-create the whole 2nd layer with a configurable product type --> HIT
Now we've reprduced the problematic situation in isolation
2013-10-06 23:17:18 +02:00
675b2070ce bughunt: attempt to rebuild the problematic structure stand-alone... --> MISS
this is only a stripped-down version of the basic singleton, without
the indirection. Unsurprisingly, this doesn't exhibit the problem yet
2013-10-06 23:17:18 +02:00
0e8a1f1e08 bughunt: use a single SingletonSub instance in two compilation units --> HIT
basically this reproduces the problem in a simplified setup.
Especially note that we're going through a single instance of the factory,
yet still this single instance 'sees' two different locations of the
class static variable
2013-10-06 23:17:18 +02:00
72bd94e141 bughunt: replace the ConfigResolver with a direct instantiation of Singleton -> MISS
thus not lib::Singleton is the culprit, it must be lib::SingletonSubclass
2013-10-06 23:17:18 +02:00
10a511d29c bughunt: build testcase statically linked
...but still dynamically linking against the core lib
But the actual template instantiations happen now within the two
compilation units, which are linked statically.

When looking into the symbol table, we can see that the static
field is emitted two times

readelf -W target/clang-static-init -s | c++filt |less
2013-10-06 23:17:18 +02:00
cec78fdc58 bughunt: extract a call sequence leading to a strange init error with Clang
Observations:
 - the initial observation was that we get two instances of the config rules service
 - obviously this it is *not* the initialisation of a static variable accessed from
    multiple compilation units. But the access from two compilation units is crucial
 - we can exclude the effect of all other initialisation. It *is* in SingletonSubclass
 - we can exclude the effect of dynamic linking. Even two translation units
    linked statically exhibit the same problem

rebuild this test case in the research area, to be able to verify with various compilers
2013-10-06 23:17:18 +02:00
d2f83523ca join recent player subsystem work, SCons overhaul and documentation 2012-01-11 07:54:43 +01:00
f84da63e11 use import/export instead of passing an artefacts map 2012-01-11 07:05:00 +01:00
9bba366763 investigate partial application of member functions 2012-01-07 03:28:12 +01:00
c134026502 for experimenting with -O3 2012-01-07 02:53:07 +01:00
e054c272b6 research: detecting the possibility of a string conversion
find out about the corner cases of this
simplistic implementation
2011-12-31 06:46:50 +01:00
07002ab3af SCons: new build target for experimental code 2011-12-03 06:10:12 +01:00