Provides a more flexible argument passing to function and methods. More...
#include "concepts/stringconvert.h"#include "core/arg.h"#include "core/error.h"#include "util/constfor.h"#include "util/constforeach.h"#include "util/to_string_literal.h"#include "util/macro_util.h"#include "util/make_from.h"#include "util/named.h"Go to the source code of this file.
Classes | |
| struct | args< ARGS > |
| Forward declaration. More... | |
Namespaces | |
| namespace | bbm |
Macros | |
| #define | BBM_IMPORT_ARGS(ARGS, ...) |
| Macro for creating aliases of the arguments in args. | |
| #define | BBM_IMPORT_ARG(ARGS, ARGNAME) decltype(auto) ARGNAME = ARGS.value(#ARGNAME ## _arg); \ |
| Macro for creating an alias for a single arg in args. | |
| #define | BBM_FORWARD_ARGS(NAME, ...) BBM_CALL(_BBM_FORWARD_ARGS, NAME, , __VA_ARGS__) |
| Forward arguments (without {}) to a method with args. | |
| #define | BBM_FORWARD_ARGS_CONST(NAME, ...) BBM_CALL(_BBM_FORWARD_ARGS, NAME, const, __VA_ARGS__) |
| Forward arguments (without {}) to a const method with args. | |
| #define | BBM_FORWARD_CPP_ARGS(NAME, ...) BBM_CALL(_BBM_FORWARD_CPP_ARGS, NAME, , __VA_ARGS__) |
| Forward arguments via args to a method with CPP args. | |
| #define | BBM_FORWARD_CPP_ARGS_CONST(NAME, ...) BBM_CALL(_BBM_FORWARD_CPP_ARGS, NAME, const, __VA_ARGS__) |
| Forward arguments via args to a const method with CPP args. | |
| #define | BBM_CONSTRUCTOR_FORWARD_ARGS(...) BBM_CALL(_BBM_CONSTRUCTOR_FORWARD_ARGS, __VA_ARGS__) |
| Forward arguments (without {}) to a constructor with args. | |
| #define | BBM_CONSTRUCTOR_FORWARD_CPP_ARGS(...) BBM_CALL(_BBM_CONSTRUCTOR_FORWARD_CPP_ARGS, __VA_ARGS__) |
| Forward arguments (without {}) to a constructor with C++ args. | |
Typedefs | |
Create a bbm::args type from either a list of bbm::arg or an bbm::args. | |
| template<typename... Ts> | |
| using | add_args = detail::add_args_impl< Ts... > |
| template<typename... Ts> | |
| using | add_args_t = typename add_args< Ts... >::type |
Functions | |
| template<typename... ARGS> requires (bbm::is_arg_v<ARGS> && ...) | |
| std::ostream & | operator<< (std::ostream &s, const bbm::args< ARGS... > &args) |
| Print bbm::args. | |
type traits | |
@{ | |
| template<typename T > | |
| using | is_args = detail::is_args_impl< std::decay_t< T > > |
| template<typename T > | |
| constexpr bool | is_args_v = is_args<T>::value |
Provides a more flexible argument passing to function and methods.
Example:
defines a method foo that takes two arguments named "a" and "b" that each are a float. The basic way to call the method is:
note the additional enclosing curly brackets. See below for ways to remove the need for the brackets. If there are multiple specializations of 'foo' then it might be needed to specify the type of the arguments:
However, other methods for passing the arguments are also supported:
are also valid. Arguments can also be passed by their position in the args:
More complex forms are possible depending on the argument defintions (see below).
To acess the argument values in the method, one can use:
Alternative, a helper macro is provided to create alias variables:
In the above case, an 'a' and 'b' alias is created to args.value("a"_arg) and agrs.value("b"_arg).
Argument types can also be refernces (const and non-const):
In this case, "a" is a reference to a float, and setting "a = 10.0f" will have the expected result that the value of the referenced variable is affected outside the function body.
"b" is declared a const float& and supports the same functionality as in regular C++ calls. I.e., when an rvalue is passed, its scope is extended as long as 'args' scope is alive.
Arguments can also be given a default value with 'ArgDef':
In this case 'ArgDef' is macro that wraps the default value in a lambda function. This means that the default value cannot depend on run-time information.
Default values allow for other flexible method calling stratgies:
The algorithm for assigning arguments (implemented below in _find_index_arg) is that for each argument in args, the list of passed arguments is searched for a argument that matches one of the following rules (in order of precedence):
Note: a compile error will occur when:
An example of matching unique types is given below:
where 'uniqueA' and 'unqiueB' are unique types (i.e., uniqueA != uniqueB), such as differnt enum_types. In this case one can call 'foo' as:
Given an args definition, two helper static constexpr are defined to check whether a list of argument types is compatible:
The helper 'is_cpp_compatible' returns true if the argument list is compatible according to classic c++ argument passing rules.
To remove the curly brackets around the arguments, two helper macros are given: one for the case where the method is declared with an 'args' argument, and one where the method is declared in a classic C++ manner.
Case 1: the method 'foo' has an 'args' argument.
forwards the call to 'foo' to the version with 'args':
will forward to:
Note that the list of 'arg' needs to match the signature of the 'args' of 'foo' to forward too. A variant of this macro named 'BBM_FORWARD_ARGS_CONST' operates exactly the same except that it declares the forward method as 'const'.
Case 2: the method 'foo' has classic C++ style arguments:
thus exactly the same arguments as the previous case. Usage is exactly the same too. The provided arg list must exactly match the types of the original 'foo' method signature, including any default values! If not, the forwarding method will not be able to detect when to use the original function (with C++ arguments) or when it needs to use an intermediate 'args' forwarding call (i.e., using the is_cpp_compatible static constexpr). Similar as with the previous case, 'BBM_FORWARD_CPP_ARGS_CONST' declares the forwarding method as 'const'.
To forward constructor calls, two similar macros are defined:
| #define BBM_CONSTRUCTOR_FORWARD_ARGS | ( | ... | ) | BBM_CALL(_BBM_CONSTRUCTOR_FORWARD_ARGS, __VA_ARGS__) |
Forward arguments (without {}) to a constructor with args.
| #define BBM_CONSTRUCTOR_FORWARD_CPP_ARGS | ( | ... | ) | BBM_CALL(_BBM_CONSTRUCTOR_FORWARD_CPP_ARGS, __VA_ARGS__) |
Forward arguments (without {}) to a constructor with C++ args.
| #define BBM_FORWARD_ARGS | ( | NAME, | |
| ... | |||
| ) | BBM_CALL(_BBM_FORWARD_ARGS, NAME, , __VA_ARGS__) |
Forward arguments (without {}) to a method with args.
| #define BBM_FORWARD_ARGS_CONST | ( | NAME, | |
| ... | |||
| ) | BBM_CALL(_BBM_FORWARD_ARGS, NAME, const, __VA_ARGS__) |
Forward arguments (without {}) to a const method with args.
| #define BBM_FORWARD_CPP_ARGS | ( | NAME, | |
| ... | |||
| ) | BBM_CALL(_BBM_FORWARD_CPP_ARGS, NAME, , __VA_ARGS__) |
Forward arguments via args to a method with CPP args.
| #define BBM_FORWARD_CPP_ARGS_CONST | ( | NAME, | |
| ... | |||
| ) | BBM_CALL(_BBM_FORWARD_CPP_ARGS, NAME, const, __VA_ARGS__) |
Forward arguments via args to a const method with CPP args.
| #define BBM_IMPORT_ARG | ( | ARGS, | |
| ARGNAME | |||
| ) | decltype(auto) ARGNAME = ARGS.value(#ARGNAME ## _arg); \ |
Macro for creating an alias for a single arg in args.
| ARGS | = name of args |
| ARGNAME | = name of the arg to import (without "") |
| #define BBM_IMPORT_ARGS | ( | ARGS, | |
| ... | |||
| ) |
Macro for creating aliases of the arguments in args.
| ARGS | = name of args |
| ... | = comma separated list of argument names to import. |