Commit graph

33 commits

Author SHA1 Message Date
20f3252892 Upgrade: down with typename!!
Yet another chainsaw massacre.

One of the most obnoxious annoyances with C++ metaprogramming
is the need to insert `typename` and `template` qualifiers into
most definitions, to help the compiler to cope with the syntax,
which is not context-free.

The recent standards adds several clarifications, so that most
of these qualifiers are redundant now, at least at places where
it is unambiguously clear that only a type can be given.

GCC already supports most of these relaxing rules
(Clang unfortunately lags way behind with support of newer language features...)
2025-07-06 01:19:08 +02:00
20392eee1c clean-up: successfully replaced the old fixed type sequence (closes: #987)
This resolves an intricate problem related to metaprogramming with
variadic templates and function signatures. Due to exceptional complexity,
a direct solution was blocked for several years, and required a better
organisation of the support code involved; several workarounds were
developed, gradually leading to a transition path, which could now
be completed in an focused clean-up effort over the last week.

Metaprogramming with sequences of types is organised into three layers:
- simple tasks can be solved with the standard facilities of the language,
  using pattern match with variadic template specialisations
- the ''type-sequence'' construct `Types<T...>` takes the centre stage
  for the explicit definition of collections of types; it can be re-bound
  to other variadic templates and supports simple direct manipulation
- for more elaborate and advanced processing tasks, a ''Loki-style type list''
  can be obtained from a type-sequence, allowing to perform recursive
  list processing task with a technique similar to LISP.
2025-06-07 18:04:59 +02:00
7aa1698a95 clean-up: prepare for variadic Type-Sequences (see #987)
Attempting to reduce the remaining pre-C++11 workarounds before upgrade to C++20...

As a first step: rename the old type-sequence implementation into `TyOLD`
to make it clearly distinguishable; a new variadic implementation `TySeq`
was already introduced as partial workaround, and the next steps
will be to switch over essential parts of the type-sequence library.
2025-06-02 03:24:44 +02:00
fbf7a792a8 Library: a step towards variadic type sequences (see #987)
Likely the most widely used facility, which enters into meta-programming
with type sequences, is our function-signature-detector `_Fun<X>`,
which returns a argument type-sequence.

After adding some bridges for cross-compatibility,
function-arguments are now extracted as a new-style,
''variadic sequence'' without trailing `NullType`.

Doing so required to augment some of the most widely used
sequence-processing helpers to work seamlessly also with the
new-style variadic sequences with a definition variant based
on variadics, which typically will later-on obsolete the original
solution, which at that time needed to be tediously coded as a
series of explicit specialisations for N arguments.
2025-02-16 21:10:06 +01:00
a477c5953b Invocation: expand capabilities in existing code
This is an attempt to rework gradually while keeping the existing code valid.
For the simple reason that the existing code is quite elaborate and difficult to re-orient.

Thus using a ''second branch,'' and sharing the traits template while expanding its capabilities
2024-12-15 23:25:01 +01:00
806db414dd Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
 * there is no entity "Lumiera.org" which holds any copyrights
 * Lumiera source code is provided under the GPL Version 2+

== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''

The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!

The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
fe6f2af7bb Chain-Load: combine all exit-hashes into a single global hash
...during development of the Chain-Load, it became clear that we'll often
need a collection of small trees rather than one huge graph. Thus a rule
for pruning nodes and finishing graphs was added. This has the consequence
that there might now be several exit nodes scattered all over the graph;
we still want one single global hash value to verify computations,
thus those exit hashes must now be picked up from the nodes and
combined into a single value.

All existing hash values hard coded into tests must be updated
2023-12-09 02:36:14 +01:00
dbe71029b7 Chain-Load: now able to define RandomDraw rules
...all existing tests reproduced
...yet notation is hopefully more readable

Old:
  graph.expansionRule([](size_t h,double){ return Cap{8, h%16, 63}; })

New:
  graph.expansionRule(graph.rule().probability(0.5).maxVal(4))
2023-11-26 03:04:59 +01:00
32b740cd40 Library: RandomDraw - dynamic configuration requires partial application
Investigation in test setup reveals that the intended solution
for dynamic configuration of the RandomDraw can not possibly work.
The reason is: the processing function binds back into the object instance.
This implies that RandomDraw must be *non-copyable*.

So we have to go full circle.
We need a way to pass the current instance to the configuration function.
And the most obvious and clear way would be to pass it as function argument.
Which however requires to *partially apply* this function.

So -- again -- we have to resort to one of the functor utilities
written several years ago; and while doing so, we must modernise
these tools further, to support perfect forwarding and binding
of reference arguments.
2023-12-03 04:59:17 +01:00
d67c62b02f Scheduler: solve difficulties with member function signature
The approach to provide the ExecutionCtx seems to work out well;
after some investigation I found a solution how to code a generic
signature-check for "any kind of function-like member"...

(the trick is to pass a pointer or member-pointer, which happens
to be syntactically the same and can be handled with our existing
function signature helper after some minor tweaks)
2023-10-22 00:42:57 +02:00
7b25609896 Library: test coverage for self-managed thread
...extract and improve the tuple-rewriting function
...improve instance tracking test dummy objects
...complete test coverage and verify proper memory handling
2023-10-11 21:06:56 +02:00
8b3f9e17cd Library: scaffolding to install thread lifecycle hooks
to cover the identified use-cases a wide variety of functors
must be accepted and adapted appropriately. A special twist arises
from the fact that the complete thread-wrapper component stack works
without RTTI; a derived class can not access the thread-wrapper internals
while the policy component to handle those hooks can not directly downcast
to some derived user provided class. But obviously at usage site it
can be expected to access both realms from such a callback.

The solution is to detect the argument type of the given functor
and to build a two step path for a safe static cast.
2023-10-10 19:47:39 +02:00
1f83e5209b Library: relocate signature-detection macro
This macro has turned out to be quite useful in cases
where a generic setup / algorithm / builder need to be customised
with λ adaptors for binding to local or custom types. It relies
on the metafunctions defined in lib/meta/function.hpp to match
the signature of "anything function-like"; so this seems the
proper place to provide that macro alongside
2023-05-04 12:35:23 +02:00
f393780845 Lib: fix a bug with diagnostic output
The header "format-cout.hpp" offers a convenience function
to print pretty much any object or data in human readable form.
However, the formatter for pointers used within this framework
switched std::cout into hexadecimal display of numbers and failed
to clean-up this state.

Since the "stickyness" of IOS stream manipulators is generally a problem,
we now provide a RAII helper to capture the previous stream state and
automatically restore it when leaving the scope.
2022-09-27 01:51:21 +02:00
00c9ecb659 C++17: fix detector for function signatures
failure was likewise caused by `noexcept` being part of the signature type now
2020-02-21 20:16:59 +01:00
d6786870f3 DI: port the old Singleton unit tests
all these tests are ported by drop-in replacement
and should work afterwards exactly as before (and they do indeed)

A minor twist was spotted though (nice to have more unit tests indeed!):
Sometimes we want to pass a custom constructor *not* as modern-style lambda,
but rather as direct function reference, function pointer or even member
function pointer. However, we can not store those types into the closure
for later lazy invocation. This is basically the same twist I run into
yesterday, when modernising the thread-wrapper. And the solution is
similar. Our traits class _Fun<FUN> has a new typedef Functor
with a suitable functor type to be instantiated and copied. In case of
the Lambda this is the (anonymous) lamda class itself, but in case of
a function reference or pointer it is a std::function.
2018-03-26 07:54:16 +02:00
8cb67fd9fa Library: inline the thread operation when possible
The Lumiera thread-wrapper accepts the operation to be performed
within the new thread as a function object, function reference or lambda.
Some of these types can be directly instantiated in the threadMain
function, and thus possibly inlined altogether. This is especially
relevant for Lambdas. OTOH, we can not instantiate function references
or bound member functions; in those cases we fall back to using a
std::function object, possibly incurring heap allocations.
2018-03-24 02:19:49 +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
58898997d8 Function-Tools: get rid of the old-style FunctionSignature template
...it is now completely redundant, even superseded by the new _Fun
signature trait (which additionally also handles lambdas)
2017-03-19 04:09:24 +01: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
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
4ff07b62f1 Functor-Tools: reshape generic function signature trait to integrate Lambdas (#994)
As a first step towards a gradual rework of our function metaprogramming helpers,
this change prepends a generic case for all kinds of functors to our existing
solution, which up to now was entirely based on explicit specialisations.

C++11 supplied the new language construct 'decltype(EXPR)', which allows us
to capture any class with an function operator, which also includes the Lambdas.

The solution was proposed 2011 on StackOverflow
http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda/7943765#7943765

We used it already with success within our TreeMutator.
But obviously the goal should be to unite all the function trait / metaprogramming helpers,
which unfortunately is a more expensive undertaking, since it also involves
to get rid of the explicit specialisations and retrofit our Types<XXX...> helper
to rely on variadic templates rather than on loki-style typelists.


This first step here is rather conservative, since we'll still rely on our
explicit specialisations in most cases. Only the Lambdas will go through the
new, generic case, and from there invoke the specialisation for member functions.
The latter need to be rectified as well, which is subject of the next changeset...
2017-03-18 22:06:44 +01:00
1a4b6545a0 maximum munch
...feels like X-mas
2016-12-23 04:23:03 +01:00
1bf0753854 mark where function signature helpers should be refactored (#994) 2016-03-25 19:58:09 +01:00
794e70a64b augment function type rebinding helper
allow to pick the bare function signature from any "function like" entity

Note: we're still unsing our own Typelist construct to represent
the function argument types. Since we're now using C++11, this
could be replaced by varargs, and we could get rid of those
various overloads for different numbers of arguments.
Unfortunately this transition is linked to the usage of
argument tuples in our command framework (which could then be
replaced by std::tuple), and this is still a bit of rather
technical work, which I do not want to spend much time on
right now
2015-09-04 17:14:11 +02:00
7be1b7d35d Switch from TR1 preveiw to the new standard headers
- functional
- memory
- unordered collections
2014-04-03 22:42:48 +02:00
062e1bbdc1 explicate the JobPlanningSequence definition
..causing the compiler to instantiate the
involved templates, i.e. get the complete
pipeline definition through the compiler
2012-10-10 05:20:22 +02:00
0e3821abeb refatcor function meta programming headers
the template _Fun started as an internal helper
for function-closure, but seems to be of
general use. Thus move it into meta/function.hpp
(function-closure.hpp is heavyweight)
2012-10-10 05:20:19 +02:00
d9f84a9bfd clean up lib/meta namespaces 2011-12-03 03:15:59 +01:00
3f1b7651e9 GPL header whitespace 2010-12-17 23:28:49 +01:00
d1b425aba9 finish and tidy the extracted headers 2009-06-17 06:55:18 +02:00
ab4b4c71e6 WIP: start extacting new headers 2009-06-16 11:39:36 +02:00