36#ifndef _UTILS_OPTIONALARGS_HXX_
37#define _UTILS_OPTIONALARGS_HXX_
41template <
typename DATA_TYPE,
int N>
class Fetcher
51template <
typename DATA_TYPE,
int N, DATA_TYPE defval>
class Specifier
86#define DECLARE_OPTIONALARG(SpecName, function_name, DataType, N, DEF) \
87 using SpecName = Specifier<DataType, N, (DEF)>; \
88 using SpecName##Get = Fetcher<DataType, N>; \
89 static constexpr int check_arguments_are_valid(const SpecName s) \
100#define DEFINE_OPTIONALARG(SpecName, function_name, DataType) \
101 constexpr DataType function_name() const \
103 return get(SpecName##Get()); \
105 constexpr bool has_##function_name() const \
107 return has(SpecName##Get()); \
126 template <
typename... Args>
128 : check_(check_all_args(args...))
134 template <
class FF>
constexpr FF
get(
const FF f)
const
136 return tried_to_get_unknown_argument() ? f : FF();
141 template <
class FF>
constexpr bool has(
const FF f)
const
143 return tried_to_get_unknown_argument();
147 using Decl::check_arguments_are_valid;
155 template <
typename A,
typename... Args>
158 return check_arguments_are_valid(a) + check_all_args(args...);
186template <
typename Decl,
typename Specifier,
typename... TArgs>
202 template <
typename... Args>
205 , d_(GetFromArgs(args...))
206 , has_(HasFromArgs(args...))
236 template <
typename... Args>
245 template <
typename... Args>
254 template <
typename U,
typename... Args>
255 static constexpr typename std::enable_if<
256 std::is_convertible<typename std::add_lvalue_reference<U>::type,
257 typename std::add_lvalue_reference<Base>::type>::value,
265 template <
typename U,
typename... Args>
266 static constexpr typename std::enable_if<
267 std::is_convertible<typename std::add_lvalue_reference<U>::type,
268 typename std::add_lvalue_reference<Base>::type>::value,
280 template <
typename T,
typename... Args>
281 static constexpr typename std::enable_if<
282 !std::is_convertible<typename std::add_lvalue_reference<T>::type,
283 typename std::add_lvalue_reference<Base>::type>::value,
287 return GetFromArgs(args...);
293 template <
typename T,
typename... Args>
294 static constexpr typename std::enable_if<
295 !std::is_convertible<typename std::add_lvalue_reference<T>::type,
296 typename std::add_lvalue_reference<Base>::type>::value,
300 return HasFromArgs(args...);
306 return specifier_type::default_value();
Used as an argument to the get(Fetcher) function in the OptionalArg implementation to select which en...
constexpr OptionalArg()
Constructor ending the recursion.
static constexpr data_type GetFromArgs(const specifier_type spec, Args... args)
This template gets instantiated when the first argument is for us.
constexpr OptionalArg(Args... args)
Constructor.
static constexpr data_type GetFromArgs()
If we've run out of all arguments, we take the default value.
bool has_
Whether the user has specified the value or not.
static constexpr std::enable_if<!std::is_convertible< typenamestd::add_lvalue_reference< T >::type, typenamestd::add_lvalue_reference< Base >::type >::value, bool >::type HasFromArgs(const T t, Args... args)
This template gets instantiated only if the argument is not an OptionalArg (hence not called from the...
Specifier::FetcherType fetcher_type
This is the type we use internally to tag and fetch the value.
Specifier specifier_type
This is the type used by the customer to set the value in the initializer list.
static constexpr std::enable_if< std::is_convertible< typenamestd::add_lvalue_reference< U >::type, typenamestd::add_lvalue_reference< Base >::type >::value, data_type >::type GetFromArgs(const U me, Args... args)
This template gets instantiated for a copy constructor: when the argument is already an OptionalArg (...
static constexpr std::enable_if<!std::is_convertible< typenamestd::add_lvalue_reference< T >::type, typenamestd::add_lvalue_reference< Base >::type >::value, data_type >::type GetFromArgs(const T t, Args... args)
This template gets instantiated only if the argument is not an OptionalArg (hence not called from the...
Specifier::data_type data_type
The type of the actually stored data. Should be POD.
constexpr data_type get(const fetcher_type) const
data_type d_
Data that the user specified (or the default).
static constexpr bool HasFromArgs(const specifier_type spec, Args... args)
Decides whether we have the current argument (from the original list or arguments).
constexpr bool has(const fetcher_type) const
static constexpr std::enable_if< std::is_convertible< typenamestd::add_lvalue_reference< U >::type, typenamestd::add_lvalue_reference< Base >::type >::value, bool >::type HasFromArgs(const U me, Args... args)
This template gets instantiated for a copy constructor: when the argument is already an OptionalArg (...
static constexpr bool HasFromArgs()
If we've run out of all arguments, there is no specifier.
static constexpr int check_all_args(const A a, Args... args)
Beginning of recursion..
static bool tried_to_get_unknown_argument()
unimplemented, causes a link error. Do not ever implement it.
static constexpr int check_arguments_are_valid(const OptionalArg &a)
End of recursion with no leftover arguments.
constexpr FF get(const FF f) const
End of template recursion.
const int check_
This is here only to force computing the check_all_args at compile time (constexpr!...
constexpr OptionalArg(Args... args)
Constructor.
constexpr bool has(const FF f) const
End of template recursion.
static constexpr int check_all_args()
End of recursion.
Declares that a recursive class template is coming.
Used as an argument to the constructor of the OptionalArg implementation to represent that a specific...
static constexpr DATA_TYPE default_value()
Default value when the customer does not specify it.
DATA_TYPE d_
Shuttled argument value.
DATA_TYPE data_type
Type of data held internally.
constexpr Specifier(const DATA_TYPE d)
Constructor.
Fetcher< DATA_TYPE, N > FetcherType
Type link to the respective fetcher.