ltl is the namespace for all traits and utilities in function_traits.
Pronounce it as you like; LTL as in STL or 'litl' as 'little Italy' said fast.
- Traits prefixed with
function_are defined for C++ function types only - Traits prefixed with
is_are defined for any C++ type ('safe' predicates)
List of traits (total 50, or 86 including _t or _v variants)
// Key
// ===
template <typename T> // Indicates trait is defined for all C++ types T
template <Function F> // Indicates trait is defined for function types F
// *only* (concept Function = is_function_v<F>)
P // P is the predicate of a predicate trait; type -> bool
P<T>, P<F> // The predicate P evaluated on type T or function type F
predicate_base<P,T> // An empty struct for non-function type T, or
predicate_base<P,F> // bool_constant<P<F>> for function type F
FuncTr // FuncTr is the function type modifier of a function trait
FuncTr<F> // The modified function type result of the function trait
// (may take Args: FuncTr<F,Args...> : F -> F' function type)
RefQual<T> // 3-valued ref_qual; is T lval-ref, rval-ref or not a ref
FuncRefQual<F> // 3-valued ref_qual; has func F lval, rval or no ref qual
function_traits<F> // A class containing public member 'type' alias for F
// using type = F;// 'Top level' predicate traits is_*function<T>, is_*function_v<T>
// ============================
template <typename T> struct is_*function : bool_constant<P<T>> {};
template <typename T>
inline constexpr bool is_*function_v = bool{P<T>>};
is_function // equivalent to std::is_function
is_free_function // true for a non-cvref-qualified function type// Function predicate traits is_function_*<T>
// =========================
template <typename T> struct is_function_* : predicate_base<P,T> {};
is_function_const
is_function_volatile
is_function_cv
is_function_reference
is_function_reference_lvalue
is_function_reference_rvalue
is_function_cvref
is_function_noexcept
is_function_variadic// Function predicate traits function_is_*<F>
// =========================
template <Function F> using function_is_* = bool_constant<P<F>>;
template <Function F>
inline constexpr bool function_is_*_v = bool{<P<F>>};
function_is_const
function_is_volatile
function_is_cv
function_is_reference
function_is_reference_lvalue
function_is_reference_rvalue
function_is_cvref
function_is_noexcept
function_is_variadic// Reference qualifier value traits *reference_v<T>
// ================================
template <typename T>
inline constexpr ref_qual reference_v = RefQual<T>;
template <Function F>
inline constexpr ref_qual function_reference_v = FuncRefQual<F>;
reference_v<T> // Ordinary top level reference qualifier value
function_reference_v<F> // Function reference qualifier value// Function signature traits
// =========================
template <typename F> using function_return_type_t = /* Return type of F */
template <typename F> struct function_return_type /* class typedef type */
template <typename F, template <typename...> typename T = ltl::arg_types>
using function_arg_types = T<P...>; // P... arg types
function_return_type_t // alias to the return type R of F
function_return_type // class containing public member type alias for R
function_arg_types // a typelist (arg_types default) of F's arg types// Function modifying traits taking no arguments
// =========================
template <Function F> using function_**_t = FuncTr<F>;
template <Function F> using function_** = function_traits<FuncTr<F>>;
function_signature // could be 'function_remove_cvref_noexcept'
function_add_const function_remove_const
function_add_volatile function_remove_volatile
/* *** no add_cv *** */ function_remove_cv
function_add_noexcept function_remove_noexcept
function_add_variadic function_remove_variadic
function_remove_reference
function_set_reference_lvalue
function_set_reference_rvalue
function_remove_cvref// Function modifying traits taking arguments
// =========================
template <Function F, Args...> using function_**_t = FuncTr<F,Args...>;
template <Function F, Args...> using function_** = function_traits<
FuncTr<F,Args...>>;
function_add_reference <F, ref_qual ref> // add does reference-collapse
function_set_reference <F, ref_qual ref> // set does not ref-collapse
function_set_const <F, bool C>
function_set_volatile <F, bool V>
function_set_noexcept <F, bool NX>
function_set_variadic <F, bool Varg>
function_set_cv <F, bool C, bool V>
function_set_cvref <F, bool C, bool V, ref_qual ref>
function_set_return_type <F, R> // requires R = valid return type
function_set_signature <F, FuncSig> // requires FuncSig = a signature
function_set_cvref_as <F, Function FuncSource>Following std convention, there are _t or _v variants as appropriate
-
Top level predicate traits classify C++ function types among all C++ types
is_function<T>equivalent tostd::is_function<T>
is_free_function<T>true forTa non-cvref-qualified function type -
Function predicate traits:
is_function_*<T>,function_is_*<F>
For*inconst,volatile,cv,cvref,noexcept,variadic,
reference,reference_lvalue,reference_rvalue -
Reference value traits: evaluate to a value of enum type
ltl::ref_qual
function_reference_v<F>for function type reference qualification
reference_v<T>for ordinary top-level reference qualification -
Signature type traits: 'getters' for function return type and arg types
function_return_type<F>returns the return type of F
function_arg_types<F>returns a type-list of parameter types of F
function_signature<F>returns just theR(P...)orR(P...,...)
'signature' (so could be calledfunction_remove_cvref_noexcept) -
Add / remove traits:
function_add_*<F>,function_remove_*<F>
(with no Args) For*inconst,volatile,noexcept,variadic
(with no Args)function_remove_cvref<F>(no add; remove only)
(with no Args)function_remove_reference<F>(remove only)
(one ref Arg)function_add_reference<F,ref_qual>(ref-collapse) -
Set traits: (property 'setters'):
function_set_*<F,Args...>
(with no Args) For*inreference_lvalue,reference_rvalue
(one bool Arg) For*inconst,volatile,noexcept,variadic
(two bool Args, C,V)function_set_cv<F,C,V>
(one ref_qual Arg)function_set_reference<F,ref_qual>
(two bool, one ref)function_set_cvref<F,C,V,ref_qual>
(one ret-type arg)function_set_return_type<F,R>
(one signature Arg)function_set_signature<F,FuncSig> -
Copy trait:
function_set_cvref_as<F,G>
(function_set_signaturecan copy cvref and noexcept)
(individual qualifiers can be copied usingfunction_set_*traits)
| function subtype name | has cvref qualifiers[ const] [volatile] [&|&&] |
is noexcepti.e. noexcept(true) |
|---|---|---|
| 'function' type (general function type) |
don't care (if it has qualifiers or not) |
don't care |
| 'free' function type ('normal', 'ordinary', 'plain') |
NO | don't care |
| function 'signature' type (a free function subtype) |
NO | NO ==noexcept(false) |
| 'abominable' function type (cvref-qualified function type) |
YES | don't care |
'free' indicates that these subtypes are the valid types of free functions.
'signature', as used here, is chosen to exclude any exception spec.
'abominable' is a recognised, colloquial, term for 'cvref-qualified'.
See the Readme material and reference P0172R0 for an introduction.
All the properties of a C++ function type are on one level - its signature,
cvref qualifiers and exception specification are all equally part of its type.
For the purposes of this API a function type is broken down as:
- Return type
Rand parameter typesP... - 'Flags' for its c,v,ref and noexcept properties, and variadic-ness
Function property 'flags':
- A pair of
boolflags forconst,volatile - A
ref_qualflag for [&|&&]
(ref_qualis a 3-valued enum;null_ref_v,lval_ref_v,rval_ref_v) - A
boolflag fornoexcept(bool) - A
boolflag forR(P...)orR(P...,...)
(non-variadic or variadic function signature).
Function properties are modified by 'add', 'remove' and 'set' traits.
Generally, 'add' and 'remove' traits modify a fully named property, so take no
extra arguments, while 'set' traits take arguments for property 'flag' values to set.
Reference qualifiers are the exception, because 'add' implies reference-collapse
(which is not necessarily a natural semantics for function reference qualifiers).
The 'no argument' traits are called 'set' (rather than 'add') with name ordered
as 'set_reference_lvalue' to make clear it "sets reference flag to lval-ref".
There is both an 'add' and a 'set' trait taking a single ref_qual argument,
which the 'add' trait implementing reference collapse behaviour:
function_remove_reference<F> // no ambiguity with 'remove'
function_set_reference_lvalue<F> // not 'set_lvalue_reference'
function_set_reference_rvalue<F>
function_add_reference<F, ref_qual ref> // reference-collapse
function_set_reference<F, ref_qual ref> // no ref-collapse
Predicate traits test a true-or-false property of a type
'Top level' predicates, is_function and is_free_function evaluate true | false
for any C++ type
(type trait inherits from std::true_type | std::false_type).
The remaining function predicate traits treat non-function types differently:
is_function_*<T>return an empty type for non-function typeTfunction_is_*<T>cause a compile error on non-function typeT
(is_function_* is the 'safe' or 'SFINAE-friendly' version of function_is_*)
(is_function_* has no _v suffix variant - use equivalent function_is_*_v).
A pair of 'top level' predicate traits classify C++ function types among all C++ types:
ltl::is_function<T>equivalent tostd::is_functionltl::is_free_function<T>true forTa non-cvref-qualified function type
template <typename T> struct is_*function : bool_constant<P<T>> {};
template <typename T>
inline constexpr bool is_*function_v = bool{P<T>>};Use ltl::is_function in preference to std::is_function in a condition
guarding instantiation of a function trait (because it saves redundant work)
(for example, see implementation of is_free_function_v next).
Checks if the argument type is a free function type:
trueifFis a function type without cvref qualifiers
falseifFis not a function type or is a cvref qualified function type
Example implementation of is_free_function_v
template <typename F>
inline constexpr bool is_free_function_v = []{
if constexpr (is_function_v<F>)
return !function_is_cvref_v<F>;
return false; }();// predicate_base<P,T> // An empty struct for non-function type T, or
// predicate_base<P,F> // bool_constant<P<F>> for function type F
template <typename T> struct is_function_* : predicate_base<P,T> {};Note: no _v suffix variant - use equivalent function_is_*_v
is_function_constis_function_volatileis_function_cvis_function_referenceis_function_reference_lvalueis_function_reference_rvalueis_function_cvrefis_function_noexceptis_function_variadic
template <Function F> using function_is_* = bool_constant<P<F>>;
template <Function F>
inline constexpr bool function_is_*_v = bool{<P<F>>};As type trait, alias to
stdtrue_type/false_type
As value trait_v, evaluate true | false
Compile fail for non-function type arguments.
function_is_constfunction_is_volatilefunction_is_cvfunction_is_referencefunction_is_reference_lvaluefunction_is_reference_rvaluefunction_is_cvreffunction_is_noexceptfunction_is_variadic
Reflect reference qualification of a type by returning an enumerated value.
function_reference_v<F>for function type reference qualificationreference_v<T>for ordinary top-level reference qualification
Evaluate to a value of enum type ltl::ref_qual
enum ref_qual { null_ref_v, rval_ref_v, lval_ref_v };
template <typename T>
inline constexpr ref_qual reference_v = RefQual<T>;
template <Function F>
inline constexpr ref_qual function_reference_v = FuncRefQual<F>;The addition operator for ref_qual values is defined to do reference collapse:
constexpr ref_qual operator+( ref_qual a, ref_qual b);These traits are 'getters' for function return type and arg types:
function_return_type<F>returns the return type of Ffunction_arg_types<F>returns a type-list of parameter types of F
template <typename F> using function_return_type_t = /* Return type of F */
template <typename F> struct function_return_type {
using type = function_return_type_t<F>;
};
template <typename F, template <typename...> typename T = ltl::arg_types>
using function_arg_types = T<P...>; // P... arg typesFor example, to get the parameter types of a function type in a std::tuple:
ltl::function_arg_types< int(char, bool[4]), std::tuple >;
// Evaluates to std::tuple< char, bool* >
// Note the usual decay in array type function argumentsThere is no corresponding '
set' trait to set the argument types (instead, construct
and set the function signature, including return type and possible varargs).
The function signature getter could be called function_remove_cvref_noexcept
(and so included in the next section on add and remove traits)
function_signature<F>returns just theR(P...)orR(P...,...)
template <typename F> using function_signature_t = /* function signature */
template <typename F>
using function_signature = function_traits<function_signature_t<F>>;function_add/remove_constfunction_add/remove_volatilefunction_add/remove_noexceptfunction_add/remove_variadic
Remove-only:
function_remove_referencefunction_remove_cvref
template <Function F> using function_**_t = FuncTr<F>;
template <Function F> using function_** = function_traits<FuncTr<F>>;The above are all modifying traits that take no arguments.
The trait to 'add' a reference qualifier takes an argument of type ref_qual
and 'adds' it to any existing reference qualifier, performing reference collapse:
function_add_reference<F,ref_qual>(ref-collapse)
template <typename F, ref_qual R>
using function_add_reference =
function_set_reference<F, function_reference_v<F> + R>;
template <typename F, ref_qual R>
using function_add_reference_t =
function_set_reference_t<F, function_reference_v<F> + R>;template <Function F, Args...> using function_**_t = FuncTr<F,Args...>;
template <Function F, Args...> using function_** = function_traits<
FuncTr<F,Args...>>;Reference qualifier setter, takes one ref_qual Arg. No reference collapse
(see function_add_reference above for trait with reference collapse):
One ref_qual Arg:
function_set_reference <F, ref_qual ref>
One bool Arg:
function_set_const <F, bool C>function_set_volatile <F, bool V>function_set_noexcept <F, bool NX>function_set_variadic <F, bool Varg>
Two bool Args:
function_set_cv <F, bool C, bool V>
Two bool, one ref_qual Arg:
function_set_cvref <F, bool C, bool V, ref_qual ref>
Other Args:
function_set_return_type <F, R>function_set_signature <F, FuncSig>
Setting return type requires a valid return type (not array or function type).
Setting signature requires FuncSig is a simple function signature argument.
function_set_cvref_as <F, Function FuncSource>
This is a particular case of the previous section "Set traits".
It is provided for convenience in copying cvref qualifiers from a
source to a target function type:
template <Function F, Function S>
using function_set_cvref_as =
function_set_cvref<F, function_is_const_v<S>,
function_is_volatile_v<S>,
function_reference_v<S>>;with similar implementation for function_set_cvref_as_t alias trait.
Clearly, individual properties can be copied in the same way as above, using
function_set_* traits and predicates or 'getter' traits for the properties.
function_set_signature, in particular, can copy cvref and noexcept
from a source to a target function type:
function_set_signature<S, function_signature_t<F>>effectively copies S's cvref qualifiers and exception spec to F's signature
(note the reversed Args - it actually copies F's signature to S)
template <Function F, Function S>
using function_set_cvref_noexcept_as =
function_set_signature<S, function_signature_t<F>>;