Chainable functor class for C++20
The
ChainableFunctor
class allows chaining of non-void two-argument functions the return and argument types of which are (const) value, (const) reference or rvalue reference types.NOTE: Return and argument types have to be the same regardless of the const specifier and the function signature is represented as
std::function<ReturnType(ArgumentType, AgrymentType)>
-
Adding
cpp-cf
to a projectTODO
-
Using the
ChainableFunctor
class in a projectTo be able to use the
ChainableFunctor
class you simply need to include a single header file:#include <cf/chainable_functor.hpp>
-
Initializing a
ChainableFunctor
objectThe
ChainableFunctor
class requires specyfying the type you want to wark with as well as the function return (RT
) and argument (AT
) types:NOTE: function return and argument types are
cf::value
by default, bu you can chose from:cf::value
cf::const_value
cf::reference
cf::const_reference
cf::rvalue_reference
You also need to pass in a function of a specified signature to the class contructor.
Optionally you can pass in a initial result as well (if not it will be initialized to the default value of the given type) - this is required for types which are not default initializable.
Examples:
cf::ChainableFunctor<int> adder{[](int x, int y) { return x + y; }};
cf::ChainableFunctor<std::unique_ptr<int>, cf::value, cf::const_reference> ptrAdder{ [](const std::unique_ptr<int>& a, const std::unique_ptr<int>& b) { return std::make_unique<int>(*a + *b); }, std::make_unique<int>() };
-
Chaining function calls
To properly chain the function calls you simply need to call the
ChainableFunctor
object as many times as you want (or as many times as your hardware allows you to 😉)To get the result of the chained function call you can:
- Implicitly convert the returned functor to your desired type (returns the stored result by value)
int chainResult = adder(1)(2)(3); std::cout << "Chain result: " << chainResult << std::endl;
- Use the
ChainableFunctor<T, RT, AT>::result()
method (forwards the stored result)
int chainResultFromFunc = adder.result(adder(1)(2)(3)(4)); std::cout << "Chain result (from function): " << chainResultFromFunc << std::endl;
-
An example program
Here is a very simple example program which demonstrates the usage of the
ChainableFunctor
class:// example.cpp #include <iostream> #include <memory> #include <cf/chainable_functor.hpp> int main(void) { cf::ChainableFunctor<int> adder{[](int x, int y) { return x + y; }}; int singelArgResult = adder(1); std::cout << "Single argument result: " << singelArgResult << std::endl; int chainResult = adder(1)(2)(3)(4); std::cout << "Chain result: " << chainResult << std::endl; int chainResultFromFunc = adder.result(adder(1)(2)(3)(4)(5)); std::cout << "Chain result (from function): " << chainResultFromFunc << std::endl; cf::ChainableFunctor<std::unique_ptr<int>, cf::value, cf::const_reference> ptrAdder{ [](const std::unique_ptr<int>& a, const std::unique_ptr<int>& b) { return std::make_unique<int>(*a + *b); }, std::make_unique<int>() }; auto aPtr = std::make_unique<int>(1); auto bPtr = std::make_unique<int>(2); auto cPtr = std::make_unique<int>(3); std::cout << std::endl << "Ptr chain result: " << *ptrAdder.result(ptrAdder(aPtr)(bPtr)(cPtr)) << std::endl; return 0; }
./example Single argument result: 1 Chain result: 10 Chain result (from function): 15 Ptr chain result: 6
-
Figure out how to chain function with different argument types
Maybe use std::function<ReturnType(ReturnType, ArgumentType)>
-
Add
()
operator overload forArgumentType... args
?