...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Components to call functions and function objects and to make Fusion code callable through a function object interface.
/functional.hpp>
What is a function call?
f (a,b,c)
It is a name and a tuple written next to each other, left-to-right.
Although the C++ syntax does not allow to replace (a,b,c)
with some Fusion Sequence, introducing
yet another function provides a solution:
invoke(f,my_sequence)
Alternatively it is possible to apply a simple transformation to f
in order to achieve the same effect:
f tuple <=> f' (tuple)
Now, f'
is an unary function that takes the arguments to
f
as a tuple; f'
is the fused form of f
.
Reading the above equivalence right-to-left to get the inverse transformation,
f
is the unfused
form of f'
.
Having generic C++ code call back arbitrary functions provided by the client used to be a heavily repetitive task, as different functions can differ in arity, invocation syntax and other properties that might be part of the type. Transporting arguments as Fusion sequences and factoring out the invocation makes Fusion algorithms applicable to function arguments and also reduces the problem to one invocation syntax and a fixed arity (instead of an arbitrary number of arbitrary arguments times several syntactic variants times additional properties).
Transforming an unfused function into its fused counterpart allows n-ary calls from an algorithm that invokes an unary Polymorphic Function Object with Sequence arguments.
The library provides several function templates to invoke different kinds of functions and adapters to transform them into fused form, respectively. Every variant has a corresponding generator function template that returns an adapter instance for the given argument.
Transforming a fused function into its unfused counterpart allows to create function objects to accept arbitrary calls. In other words, an unary function object can be implemented instead of (maybe heavily overloaded) function templates or function call operators.
The library provides several adapter variants that implement this transformation, ranging from strictly typed to fully generic. The latter provides a reusable, approximate solution to The Forwarding Problem. Every generic variant has a corresponding generator function template that returns an adapter instance for the given argument.