hyperion::mpl::Type#
- group Metaprogramming Type Manipulation Type
Hyperion provides
mpl::Typeas a metaprogramming type for storing, communicating, working with, and operating on types.Example#
#include <hyperion/mpl/type.h> using namespace hyperion::mpl; // alternatively, use `decltype_<int>()` constexpr auto type1 = Type<int>{}; constexpr auto type2 = Type<double>{}; static_assert(not type1.is(type2));
-
template<typename TType>
struct Type# - #include <hyperion/mpl/type.h>
Typeis a metaprogramming type wrapper used for storing, communicating, operating on, and otherwis working with types.Example#
#include <hyperion/mpl/type.h> using namespace hyperion::mpl; // alternatively, use `decltype_<int>()` constexpr auto type1 = Type<int>{}; constexpr auto type2 = Type<double>{}; static_assert(not type1.is(type2));
- Template Parameters:
TType – The type to metaprogram against
Public Functions
-
template<typename TDelay = type>
inline Type<TDelay> self() const noexcept# Returns another instance of this
specializationofType- Returns:
another instance of this
Typespecialization
-
template<typename TDelay = type>
inline TDelay inner() const noexcept# Returns the inner `
MetaValuetypeofthisType, ifthisTyperepresents aMetaValueRequirements#
typeis trivially default constructibletypeis aMetaValue
Example#
constexpr auto one_typed = delctype_(1_value); static_assert(one_typed.inner() == 1_value);
-
template<typename TDelay = type>
inline bool has_inner() const noexcept# Returns whether the
typeof thisTypeis also a metaprogramming type (i.e. aMetaValue), in which case you may callthis->inner()to obtain that an instance of that type.Example#
constexpr auto has_inner = decltype_(1_value); constexpr auto no_inner = decltype_<int>(); static_assert(has_inner.has_inner()); static_assert(not no_inner.has_inner());
- Returns:
Whether the
typeof thisTypeis also a metaprogramming type
-
template<template<typename> typename TMetaFunction>
inline detail::convert_to_meta_t<TMetaFunction<type>> apply() const noexcept# Applies the specified template metafunction to this specialization of
Type.Applies
TMetaFunctionto this specialization ofTypeand returns the calculated metaprogramming type.Requirements#
TMetaFunctionmust be aTypeMetaFunction:It must be a template taking a single type parameter,
It must have a
static constexprmember variable,value, or a using alias type,type
Example#
template<typename TType> struct is_const { using type = Value<std::is_const<std::remove_reference_t<TType>>, bool>; }; // Type<Value<true, bool>> constexpr auto is_const = decltype_<const int>().apply<is_const>(); static_assert(is_const.inner());
- Template Parameters:
TMetaFunction – The template metafunction to apply to this
Type- Returns:
The result of applying
TMetaFunction
-
template<template<auto> typename TMetaFunction, typename TDelay = type>
inline detail::convert_to_meta_t<TMetaFunction<TDelay::value>> apply() const noexcept# Applies the specified template metafunction to this specialization of
Type.Applies
TMetaFunctionto theValuespecialization thisTypespecialization represents, and returns the calculated metaprogramming type.Requirements#
TMetaFunctionmust be aValueMetaFunction:It must be a template taking a single value parameter,
It must have a
static constexprmember variable,value, or a using alias type,type
typemust be aMetaValue
Example#
template<auto TValue> struct is_two { using type = Value<TValue == 2, bool>; }; // `was_two` is `Type<Value<true, bool>>>` constexpr auto was_two = decltype_(2_value).apply<is_two>(); static_assert(was_two.inner());
- Template Parameters:
TMetaFunction – The template metafunction to apply to this
Type- Returns:
The result of applying
TMetaFunction
-
template<typename TFunction>
inline detail::convert_to_meta_t<meta_result_t<TFunction, Type<type>>> apply(TFunction &&func) const noexcept# Applies the given metafunction to this specialization of
Type.Applies
functo this specialization ofTypeand returns the calculated result as a metaprogramming type.Requirements#
Example#
constexpr auto add_const = [](MetaType auto type) { return type.as_const(); }; constexpr auto const_int = decltype_<int>().apply(add_const); // Type<const int> static_assert(const_int == decltype_<const int>()); constexpr auto get_size = [](MetaType auto value) { return value.sizeof_(); }; constexpr auto sizeof_int = decltype_<int>().apply(get_size); // Value<4, usize> static_assert(sizeof_int == 4_usize);
-
template<typename TFunction>
inline auto apply(TFunction &&func) const noexcept# Applies the given metafunction to the
typeof this specialization ofType.Given that
typeis aMetaValue, appliesfuncto theMetaValuetypeof this specialization ofType, as if bytype{}.apply(std::forward<TFunction>(func)).Requirements#
TFunctionmust be aMetaFunctionOf<type>typetypename meta_result_t<TFunction, type>::typemust not be aMetaTypetypemust be aMetaValue
Example#
constexpr auto is_two = [](MetaValue auto value) -> Value<decltype(value)::value == 2, bool> { return {}; }; constexpr auto was_two = decltype_(2_value).apply(is_two); // Value<true, bool> static_assert(was_two); constexpr auto is_two_typed = [](MetaValue auto value) -> Type<Value<decltype(value)::value == 2, bool>> { return {}; }; // Value<true, bool> constexpr auto was_two_typed = decltype_(2_value).apply(is_two_typed); static_assert(was_two_typed);
- Template Parameters:
TFunction – The type of the metafunction to apply
- Parameters:
func – The metafunction to apply
- Returns:
The result of applying
functo thisTypespecialization
-
template<template<typename> typename TPredicate>
inline Value<TPredicate<type>::value, bool> satisfies() const noexcept# Checks to see if this
Typespecialization satisfies the given template metafunction predicate,TPredicateRequirements#
TPredicatemust be aTypeMetaFunctionIt must be a template taking a single value parameter,
It must have a
static constexprmember variable,value, or a using alias type,type
TPredicate<type>must be aMetaValueThe type of the value of
TPredicate,TPredicate<type>::value, must be (possibly cv-ref qualified)bool)
Example#
template<typename TType> struct is_const { static inline constexpr auto value = std::is_const_v<std::remove_reference_t<TType>> == 2; }; // `not_const` is `Value<false, bool>` constexpr auto not_const = decltype_<int>().satisfies<is_const>(); // `was_const` is `Value<true, bool>` constexpr auto was_const = decltype_<const int>().satisfies<is_const>(); static_assert(was_const); static_assert(not not_const);
-
template<typename TPredicate>
auto satisfies(TPredicate &&predicate) const noexcept# Checks to see if this
Typespecialization satisfies the given metafunction predicate.Requirements#
If
typeis aMetaValue:If
predicateis invocable withtype:The value returned by invoking
predicatewithtypemust either be aMetaValue, or aTypespecialization representing aMetaValue.Using
TValueto represent thatMetaValuetype, the type of the value ofTValue, that isdecltype(TValue::value), must be of type (possibly cv-ref qualified)bool
If the above conditions on the return value of
predicateare not met, the program is ill-formed
If
predicateis not invocable withtype, see the case wherepredicateis invocable withType<type>
If
predicateis invocable withType<type>:The value returned by invoking
predicatewithType<type>must either be aMetaValue, or aTypespecialization representing aMetaValue.Using
TValueto represent thatMetaValuetype, the type of the value ofTValue, that isdecltype(TValue::value), must be of type (possibly cv-ref qualified)bool
If the above conditions on the return value of
predicateare not met, the program is ill-formed
If
predicateis not invocable withType<type>nortype, returnsValue<false>
Example#
constexpr auto is_const = [](MetaType auto type) { return type.is_const(); }; constexpr auto not_const = decltype_<int>().satisfies(is_const); constexpr auto was_const = decltype_<const int>().satisfies(is_const); static_assert(was_const); static_assert(not not_const);
- Template Parameters:
TPredicate – The type of the metafunction predicate to check with
- Parameters:
predicate – The metafunction predicate to check with, as a
Valuespecialization
-
template<typename TRhs>
inline Value<std::same_as<type, TRhs>, bool> is(const Type<TRhs> &rhs) const noexcept# Returns whether
thisTypespecialization is the same as the given one.Checks if
thisis an instance of the sameTypespecialization asrhs, that is, whetherstd::same_as<type, TRhs>, and returns the result as aValuespecialization.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto is_int = int_t.is(decltype_<int>()); constexpr auto is_const_int = int_t.is(decltype_<const int>()); static_assert(is_int); static_assert(not is_const_int);
-
template<typename TRhs>
inline auto is_qualification_of(const Type<TRhs> &rhs) const noexcept# Returns whether the
typeofthisTypespecialization is the same as, or a cv-ref qualification of, thetypeof the given one.Checks if the
typeofthisTypespecialization is the (possibly cv-ref qualification of the)typeof therhsspecialization, that is, whetherstd::same_as<std::remove_cvref_t<type>, TRhs>, and returns the result as aValuespecialization.Example#
constexpr auto int_t = decltype_<const int&>(); constexpr auto is_int = int_t.is_qualification_of(decltype_<int>()); constexpr auto is_const_int = int_t.is_qualification_of(decltype_<const int>()); constexpr auto is_constref_int = int_t.is_qualification_of(decltype_<const int&>()); constexpr auto is_double = int_t.is_qualification_of(decltype_<double>()); static_assert(is_int); static_assert(is_const_int); static_assert(is_constref_int); static_assert(not is_double);
-
inline Value<std::is_const_v<std::remove_reference_t<type>>, bool> is_const() const noexcept#
Returns whether the
typeofthisTypespecialization isconstExample#
constexpr auto int_t = decltype_<int>(); constexpr auto const_int_t = decltype_<const int>(); static_assert(not int_t.is_const()); static_assert(const_int_t.is_const());
- Returns:
Whether the
typeofthisisconst
-
inline Value<std::is_lvalue_reference_v<type>, bool> is_lvalue_reference() const noexcept#
Returns whether the
typeofthisTypespecialization is an lvalue reference.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto intref_t = decltype_<int&>(); static_assert(not int_t.is_lvalue_reference()); static_assert(intref_t.is_lvalue_reference());
- Returns:
Whether the
typeofthisis an lvalue reference
-
inline Value<std::is_rvalue_reference_v<type>, bool> is_rvalue_reference() const noexcept#
Returns whether the
typeofthisTypespecialization is an rvalue reference.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto intrefref_t = decltype_<int&&>(); static_assert(not int_t.is_rvalue_reference()); static_assert(intrefref_t.is_rvalue_reference());
- Returns:
Whether the
typeofthisis an rvalue reference
-
inline Value<std::is_volatile_v<std::remove_reference_t<type>>, bool> is_volatile() const noexcept#
Returns whether the
typeofthisTypespecialization isvolatileExample#
constexpr auto int_t = decltype_<int>(); constexpr auto volatile_int_t = decltype_<volatile int>(); static_assert(not int_t.is_volatile()); static_assert(volatile_int_t.is_volatile());
- Returns:
Whether the
typeofthisisvolatile
-
template<typename TDelay = type>
inline auto as_const() const noexcept# Returns a
Typespecialization representing theconst-qualified version of the typethisspecialization represents.The application of
constdoes not follow the same application as other mechanisms, likestd::add_const, and instead follows the “intuitive” expectation thatconstwould be applied through references. That is, whereasstd::add_const<int&>would yieldint&,decltype_<int&>().as_const()will yieldType<const int&>.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto const_int_t = int_t.as_const(); static_assert(const_int_t.is_const()); static_assert(const_int_t.is(decltype_<const int>()));
- Returns:
the
Typespecialization representingconst type
-
template<typename TDelay = type>
inline auto as_lvalue_reference() const noexcept# Returns a
Typespecialization representing the lvalue reference-qualified version of the typethisspecialization represents.The application of lvalue reference follows the same application as other mechanisms, like
std::add_lvalue_reference, That is, wherestd::add_lvalue_reference<int&&>would yieldint&,decltype_<int&&>().as_lvalue_reference()will also yieldType<int&>.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto intref_t = int_t.as_lvalue_reference(); static_assert(intref_t.is_lvalue_reference()); static_assert(intref_t.is(decltype_<int&>()));
- Returns:
the
Typespecialization representingtype&
-
template<typename TDelay = type>
inline auto as_rvalue_reference() const noexcept# Returns a
Typespecialization representing the rvalue reference-qualified version of the typethisspecialization represents.The application of rvalue reference does not follow the same application as other mechanisms, like
std::add_rvalue_reference, That is, wherestd::add_rvalue_reference<int&>would yieldint&,decltype_<int&>().as_rvalue_reference()will yieldType<int&&>.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto intrefref_t = int_t.as_rvalue_reference(); static_assert(intref_t.is_rvalue_reference()); static_assert(intrefref_t.is(decltype_<int&&>()));
- Returns:
the
Typespecialization representingtype&&
-
template<typename TDelay = type>
inline auto as_volatile() const noexcept# Returns a
Typespecialization representing thevolatile-qualified version of the typethisspecialization represents.The application of
volatiledoes not follow the same application as other mechanisms, likestd::add_volatile, and instead follows the “intuitive” expectation thatvolatilewould be applied through references. That is, whereasstd::add_volatile<int&>would yieldint&,decltype_<int&>().as_volatile()will yieldType<volatile int&>.Example#
constexpr auto int_t = decltype_<int>(); constexpr auto volatile_int_t = int_t.as_volatile(); static_assert(volatile_int_t.is_volatile()); static_assert(volatile_int_t.is(decltype_<volatile int>()));
- Returns:
the
Typespecialization representingvolatile type
-
template<typename TRhs>
inline Value<std::convertible_to<type, TRhs>, bool> is_convertible_to(const Type<TRhs> &rhs) const noexcept# Returns whether the type
thisTypespecialization represents is convertible to the typerhsrepresents, as aValuespecialization.Example#
struct not_convertible {}; constexpr auto int_t = decltype_<int>(); constexpr auto double_t = decltype_<double>(); constexpr auto not_convertible_t = decltype_<not_convertible>(); static_assert(int_t.is_convertible_to(double_t)); static_assert(double_t.is_convertible_to(int_t)); static_assert(not int_t.is_convertible_to(not_convertible_t)); static_assert(not not_convertible_t.is_convertible_to(int_t));
-
template<typename TRhs>
inline Value<std::derived_from<type, TRhs> && !std::same_as<type, TRhs>, bool> is_derived_from(const Type<TRhs> &rhs) const noexcept# Returns whether the type
thisTypespecialization represents is derived from the typerhsrepresents, as aValuespecialization.Example#
struct base {}; struct derived : base {}; constexpr auto int_t = decltype_<int>(); constexpr auto base_t = decltype_<base>(); constexpr auto derived_t = decltype_<base>(); static_assert(derived_t.is_derived_from(base_t)); static_assert(not base_t.is_derived_from(base_t)); static_assert(not int_t.is_derived_from(int_t)); static_assert(not int_t.is_derived_from(base_t));
- Template Parameters:
TRhs – The type that
rhsrepresents- Parameters:
rhs – The instance of the
Typespecialization representing the type to check thattypeis derived from- Returns:
whether the type
thisrepresents is derived from the typerhsrepresents, as aValuespecialization
Note
The application of this differs from
std::is_base_oforstd::derived_from, in that this isfalsewhen called against the same type. That is,decltype_<base>().is_derived_from(decltype_<base>()) == false.
-
template<typename TRhs>
inline Value<std::derived_from<TRhs, type> && !std::same_as<type, TRhs>, bool> is_base_of(const Type<TRhs> &rhs) const noexcept# Returns whether the type
thisTypespecialization represents is a base class of the typerhsrepresents, as aValuespecialization.Example#
struct base {}; struct derived : base {}; constexpr auto int_t = decltype_<int>(); constexpr auto base_t = decltype_<base>(); constexpr auto derived_t = decltype_<base>(); static_assert(base_t.is_base_of(derived_t)); static_assert(not base_t.is_base_of(base_t)); static_assert(not int_t.is_base_of(int_t)); static_assert(not int_t.is_base_of(base_t));
- Template Parameters:
TRhs – The type that
rhsrepresents- Parameters:
rhs – The instance of the
Typespecialization representing the type to check thattypeis a base of- Returns:
whether the type
thisrepresents is a base of the typerhsrepresents, as aValuespecialization
Note
The application of this differs from
std::is_base_oforstd::derived_from, in that this isfalsewhen called against the same type. That is,decltype_<base>().is_base_of(decltype_<base>()) == false.
-
template<template<typename...> typename TList, typename ...TTypes>
inline auto is_constructible_from(const TList<TTypes...> &list) const noexcept# Returns whether the type
thisTypespecialization represents is constructible from arguments of typesTTypes..., as aValuespecialization.Example#
template<typename... TTypes> struct list {}; struct tag {}; struct constructible { constructible(int, double, tag); }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); static_assert(constructible_t.is_constructible_from(list<int, double, tag>{})); static_assert(not constructible_t.is_constructible_from(list<double>{})); static_assert(not int_t.is_constructible_from(constructible));
- Template Parameters:
TList – The type-list type template representing the argument types to check with
TTypes – The list of argument types to check with
- Parameters:
list – The type-list representing the argument types to check with
- Returns:
whether the type
thisrepresents is constructible from arguments of typesTTypes..., as aValuespecialization
-
template<typename ...TTypes>
inline auto is_constructible_from(const Type<TTypes>&... list) const noexcept# Returns whether the type
thisTypespecialization represents is constructible from arguments of typesTTypes..., as aValuespecialization.Example#
template<typename... TTypes> struct list {}; struct tag {}; struct constructible { constructible(int, double, tag); }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); static_assert(constructible_t.is_constructible_from(decltype_<int>(), decltype_<double>(), decltype_<tag>())); static_assert(not constructible_t.is_constructible_from(decltype_<double>{})); static_assert(not int_t.is_constructible_from(constructible));
-
template<template<typename...> typename TList, typename ...TTypes>
inline auto is_noexcept_constructible_from(const TList<TTypes...> &list) const noexcept# Returns whether the type
thisTypespecialization represents isnoexceptconstructible from arguments of typesTTypes..., as aValuespecialization.Example#
template<typename... TTypes> struct list {}; struct tag {}; struct constructible { constructible(int, double, tag); constructible(int, tag, tag) noexcept; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); static_assert(constructible_t.is_noexcept_constructible_from(list<int, tag, tag>{})); static_assert(not constructible_t .is_noexcept_constructible_from(list<int, double, tag>{})); static_assert(not constructible_t.is_noexcept_constructible_from(list<double>{})); static_assert(not int_t.is_noexcept_constructible_from(constructible));
- Template Parameters:
TList – The type-list type template representing the argument types to check with
TTypes – The list of argument types to check with
- Parameters:
list – The type-list representing the argument types to check with
- Returns:
whether the type
thisrepresents isnoexceptconstructible from arguments of typesTTypes..., as aValuespecialization
-
template<typename ...TTypes>
inline auto is_noexcept_constructible_from(const Type<TTypes>&... list) const noexcept# Returns whether the type
thisTypespecialization represents isnoexceptconstructible from arguments of typesTTypes..., as aValuespecialization.Example#
template<typename... TTypes> struct list {}; struct tag {}; struct constructible { constructible(int, double, tag); constructible(int, tag, tag) noexcept; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); static_assert(constructible_t.is_noexcept_constructible_from(decltype_<int>(), decltype_<tag>(), decltype_<tag>())); static_assert(not constructible_t.is_noexcept_constructible_from(decltype_<int>(), decltype_<double>(), decltype_<tag>())); static_assert(not constructible_t.is_noexcept_constructible_from(decltype_<double>{})); static_assert(not int_t.is_noexcept_constructible_from(constructible));
-
inline auto is_default_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is default constructible, as aValuespecialization.Example#
struct constructible { constructible(); }; struct not_constructible { not_constructible() = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(constructible_t.is_default_constructible()); static_assert(int_t.is_default_constructible()); static_assert(not not_constructible_.is_default_constructible());
- Returns:
whether the type
thisrepresents is default constructible, as aValuespecialization
-
inline auto is_noexcept_default_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptdefault constructible, as aValuespecialization.Example#
struct constructible { constructible(); }; struct noexcept_constructible { noexcept_constructible() noexcept; }; struct not_constructible { not_constructible() = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto noexcept_constructible_t = decltype_<noexcept_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_noexcept_default_constructible()); static_assert(noexcept_constructible_t.is_noexcept_default_constructible()); static_assert(not constructible_t.is_noexcept_default_constructible()); static_assert(not not_constructible_.is_noexcept_default_constructible());
- Returns:
whether the type
thisrepresents isnoexceptdefault constructible, as aValuespecialization
-
inline auto is_trivially_default_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially default constructible, as aValuespecialization.Example#
struct constructible { constructible(); }; struct trivially_constructible { trivially_constructible() = default; }; struct not_constructible { not_constructible() = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto trivially_constructible_t = decltype_<trivially_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_trivially_default_constructible()); static_assert(trivially_constructible_t.is_trivially_default_constructible()); static_assert(not constructible_t.is_trivially_default_constructible()); static_assert(not not_constructible_.is_trivially_default_constructible());
- Returns:
whether the type
thisrepresents is trivially default constructible, as aValuespecialization
-
inline auto is_copy_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is copy constructible, as aValuespecialization.Example#
struct constructible { constructible(const constructible&); }; struct not_constructible { not_constructible(const not_constructible&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(constructible_t.is_copy_constructible()); static_assert(int_t.is_copy_constructible()); static_assert(not not_constructible_.is_copy_constructible());
- Returns:
whether the type
thisrepresents is copy constructible, as aValuespecialization
-
inline auto is_noexcept_copy_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptcopy constructible, as aValuespecialization.Example#
struct constructible { constructible(const constructible&); }; struct noexcept_constructible { noexcept_constructible(const noexcept_constructible&) noexcept; }; struct not_constructible { not_constructible(const not_constructible&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto noexcept_constructible_t = decltype_<noexcept_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_noexcept_copy_constructible()); static_assert(noexcept_constructible_t.is_noexcept_copy_constructible()); static_assert(not constructible_t.is_noexcept_copy_constructible()); static_assert(not not_constructible_.is_noexcept_copy_constructible());
- Returns:
whether the type
thisrepresents isnoexceptcopy constructible, as aValuespecialization
-
inline auto is_trivially_copy_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially copy constructible, as aValuespecialization.Example#
struct constructible { constructible(const constructible&); }; struct trivially_constructible { trivially_constructible(const trivially_constructible&) = default; }; struct not_constructible { not_constructible(const not_constructible&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto trivially_constructible_t = decltype_<trivially_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_trivially_copy_constructible()); static_assert(trivially_constructible_t.is_trivially_copy_constructible()); static_assert(not constructible_t.is_trivially_copy_constructible()); static_assert(not not_constructible_.is_trivially_copy_constructible());
- Returns:
whether the type
thisrepresents is trivially copy constructible, as aValuespecialization
-
inline auto is_move_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is move constructible, as aValuespecialization.Example#
struct constructible { constructible(constructible&&); }; struct not_constructible { not_constructible(not_constructible&&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(constructible_t.is_move_constructible()); static_assert(int_t.is_move_constructible()); static_assert(not not_constructible_.is_move_constructible());
- Returns:
whether the type
thisrepresents is move constructible, as aValuespecialization
-
inline auto is_noexcept_move_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptmove constructible, as aValuespecialization.Example#
struct constructible { constructible(constructible&&); }; struct noexcept_constructible { noexcept_constructible(noexcept_constructible&&) noexcept; }; struct not_constructible { not_constructible(not_constructible&&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto noexcept_constructible_t = decltype_<noexcept_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_noexcept_move_constructible()); static_assert(noexcept_constructible_t.is_noexcept_move_constructible()); static_assert(not constructible_t.is_noexcept_move_constructible()); static_assert(not not_constructible_.is_noexcept_move_constructible());
- Returns:
whether the type
thisrepresents isnoexceptmove constructible, as aValuespecialization
-
inline auto is_trivially_move_constructible() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially move constructible, as aValuespecialization.Example#
struct constructible { constructible(constructible&&); }; struct trivially_constructible { trivially_constructible(trivially_constructible&&) = default; }; struct not_constructible { not_constructible(not_constructible&&) = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto constructible_t = decltype_<constructible>(); constexpr auto trivially_constructible_t = decltype_<trivially_constructible>(); constexpr auto not_constructible_t = decltype_<not_constructible>(); static_assert(int_t.is_trivially_move_constructible()); static_assert(trivially_constructible_t.is_trivially_move_constructible()); static_assert(not constructible_t.is_trivially_move_constructible()); static_assert(not not_constructible_.is_trivially_move_constructible());
- Returns:
whether the type
thisrepresents is trivially move constructible, as aValuespecialization
-
inline auto is_copy_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents is copy assignable, as aValuespecialization.Example#
struct assignable { auto operator=(const assignable&) -> assignable&; }; struct not_assignable { auto operator=(const not_assignable&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(assignable_t.is_copy_assignable()); static_assert(int_t.is_copy_assignable()); static_assert(not not_assignable_.is_copy_assignable());
- Returns:
whether the type
thisrepresents is copy assignable, as aValuespecialization
-
inline auto is_noexcept_copy_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptcopy assignable, as aValuespecialization.Example#
struct assignable { auto operator=(const assignable&) -> assignable&; }; struct noexcept_assignable { auto operator=(const noexcept_assignable&) noexcept -> noexcept_assignable&; }; struct not_assignable { auto operator=(const not_assignable&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto noexcept_assignable_t = decltype_<noexcept_assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(int_t.is_noexcept_copy_assignable()); static_assert(noexcept_assignable_t.is_noexcept_copy_assignable()); static_assert(not assignable_t.is_noexcept_copy_assignable()); static_assert(not not_assignable_.is_noexcept_copy_assignable());
- Returns:
whether the type
thisrepresents isnoexceptcopy assignable, as aValuespecialization
-
inline auto is_trivially_copy_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially copy assignable, as aValuespecialization.Example#
struct assignable { auto operator=(const assignable&) -> assignable&; }; struct trivially_assignable { auto operator=(const trivially_assignable&) -> trivially_assignable& = default; }; struct not_assignable { auto operator=(const not_assignable&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto trivially_assignable_t = decltype_<trivially_assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(int_t.is_trivially_copy_assignable()); static_assert(trivially_assignable_t.is_trivially_copy_assignable()); static_assert(not assignable_t.is_trivially_copy_assignable()); static_assert(not not_assignable_.is_trivially_copy_assignable());
- Returns:
whether the type
thisrepresents is trivially copy assignable, as aValuespecialization
-
inline auto is_move_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents is move assignable, as aValuespecialization.Example#
struct assignable { auto operator=(assignable&&) -> assignable&; }; struct not_assignable { auto operator=(not_assignable&&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(assignable_t.is_move_assignable()); static_assert(int_t.is_move_assignable()); static_assert(not not_assignable_.is_move_assignable());
- Returns:
whether the type
thisrepresents is move assignable, as aValuespecialization
-
inline auto is_noexcept_move_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptmove assignable, as aValuespecialization.Example#
struct assignable { auto operator=(assignable&&) -> assignable&; }; struct noexcept_assignable { auto operator=(noexcept_assignable&&) noexcept -> noexcept_assignable&; }; struct not_assignable { auto operator=(not_assignable&&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto noexcept_assignable_t = decltype_<noexcept_assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(int_t.is_noexcept_move_assignable()); static_assert(noexcept_assignable_t.is_noexcept_move_assignable()); static_assert(not assignable_t.is_noexcept_move_assignable()); static_assert(not not_assignable_.is_noexcept_move_assignable());
- Returns:
whether the type
thisrepresents isnoexceptmove assignable, as aValuespecialization
-
inline auto is_trivially_move_assignable() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially move assignable, as aValuespecialization.Example#
struct assignable { auto operator=(assignable&&) -> assignable&; }; struct trivially_assignable { auto operator=(trivially_assignable&&) -> trivially_assignable& = default; }; struct not_assignable { auto operator=(not_assignable&&) -> not_assignable& = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto assignable_t = decltype_<assignable>(); constexpr auto trivially_assignable_t = decltype_<trivially_assignable>(); constexpr auto not_assignable_t = decltype_<not_assignable>(); static_assert(int_t.is_trivially_move_assignable()); static_assert(trivially_assignable_t.is_trivially_move_assignable()); static_assert(not assignable_t.is_trivially_move_assignable()); static_assert(not not_assignable_.is_trivially_move_assignable());
- Returns:
whether the type
thisrepresents is trivially move assignable, as aValuespecialization
-
inline auto is_destructible() const noexcept#
Returns whether the type
thisTypespecialization represents is destructible, as aValuespecialization.Example#
struct destructible { ~destructible(); }; struct not_destructible { ~not_destructible() = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto destructible_t = decltype_<destructible>(); constexpr auto not_destructible_t = decltype_<not_destructible>(); static_assert(destructible_t.is_destructible()); static_assert(int_t.is_destructible()); static_assert(not not_destructible_.is_destructible());
- Returns:
whether the type
thisrepresents is destructible, as aValuespecialization
-
inline auto is_noexcept_destructible() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptdestructible, as aValuespecialization.Example#
struct destructible { ~destructible(); }; struct noexcept_destructible { ~noexcept_destructible() noexcept; }; struct not_destructible { ~not_destructible() = delete; }; constexpr auto int_t = decltype_<int>(); constexpr auto destructible_t = decltype_<destructible>(); constexpr auto noexcept_destructible_t = decltype_<noexcept_destructible>(); constexpr auto not_destructible_t = decltype_<not_destructible>(); static_assert(int_t.is_noexcept_destructible()); static_assert(noexcept_destructible_t.is_noexcept_destructible()); static_assert(not destructible_t.is_noexcept_destructible()); static_assert(not not_destructible_.is_noexcept_destructible());
- Returns:
whether the type
thisrepresents isnoexceptdestructible, as aValuespecialization
-
inline auto is_trivially_destructible() const noexcept#
Returns whether the type
thisTypespecialization represents is trivially destructible, as aValuespecialization.Example#
struct destructible { ~destructible(); } struct trivially_destructible { ~trivially_destructible() = default; } struct not_destructible { ~not_destructible() = delete; } constexpr auto int_t = decltype_<int>(); constexpr auto destructible_t = decltype_<destructible>(); constexpr auto trivially_destructible_t = decltype_<trivially_destructible>(); constexpr auto not_destructible_t = decltype_<not_destructible>(); static_assert(int_t.is_trivially_destructible()); static_assert(trivially_destructible_t.is_trivially_destructible()); static_assert(not destructible_t.is_trivially_destructible()); static_assert(not not_destructible_.is_trivially_destructible());
- Returns:
whether the type
thisrepresents is trivially destructible, as aValuespecialization
-
inline auto is_swappable() const noexcept#
Returns whether the type
thisTypespecialization represents is swappable, as aValuespecialization.If
typeis swappable, i.e., givenlhsandrhsthat are bothtype&,std::swap(lhs, rhs)is well-formed, returnsValue<true>. Otherwise, returnsValue<false>.Example#
struct not_swappable { friend void swap(not_swappable&, not_swappable&) = delete; }; struct swappable { friend void swap(swappable&, swappable&); }; static constexpr auto swappable_t = decltype_<swappable>(); static constexpr auto not_swappable_t = decltype_<not_swappable>(); static_assert(swappable_t.is_swappable()); static_assert(not not_swappable_t.is_swappable());
- Returns:
whether the type
thisrepresents is swappable, as aValuespecialization
-
inline auto is_noexcept_swappable() const noexcept#
Returns whether the type
thisTypespecialization represents isnoexceptswappable, as aValuespecialization.If
typeisnoexceptswappable, i.e., givenlhsandrhsthat are bothtype&,std::swap(lhs, rhs)is both well-formed andnoexcept, returnsValue<true>. Otherwise, returnsValue<false>.Example#
struct not_swappable { friend void swap(not_swappable&, not_swappable&) = delete; }; struct swappable { friend void swap(swappable&, swappable&); }; struct noexcept_swappable { friend void swap(noexcept_swappable&, noexcept_swappable&) noexcept; }; static constexpr auto swappable_t = decltype_<swappable>(); static constexpr auto noexcept_swappable_t = decltype_<noexcept_swappable>(); static constexpr auto not_swappable_t = decltype_<not_swappable>(); static_assert(noexcept_swappable_t.is_noexcept_swappable()); static_assert(not swappable_t.is_noexcept_swappable()); static_assert(not not_swappable_t.is_noexcept_swappable());
- Returns:
whether the type
thisrepresents is swappable, as aValuespecialization
-
template<typename TRhs = type>
inline auto is_swappable_with(const Type<TRhs> &rhs = Type<TRhs>{}) const noexcept# Returns whether the type
thisTypespecialization represents is swappable with the typerhsrepresents, as aValuespecialization.If the type
thisrepresents is swappable with the typerhsrepresents, i.e., givenval1andval2that aretype&andTRhs&, respectively,std::swap(lhs, rhs)is well-formed, returnsValue<true>. Otherwise, returnsValue<false>.Example#
struct not_swappable { friend void swap(not_swappable&, int&) = delete; }; struct swappable { friend void swap(swappable&, int&); friend void swap(int&, swappable&); }; static constexpr auto swappable_t = decltype_<swappable>(); static constexpr auto not_swappable_t = decltype_<not_swappable>(); static_assert(swappable_t.is_swappable_with(decltype_<int>())); static_assert(not not_swappable_t.is_swappable_with(decltype_<int>()));
-
template<typename TRhs = type>
inline auto is_noexcept_swappable_with(const Type<TRhs> &rhs = Type<TRhs>{}) const noexcept# Returns whether the type
thisTypespecialization represents isnoexceptswappable with the typerhsrepresents, as aValuespecialization.If the type
thisrepresents isnoexceptswappable with the typerhsrepresents, i.e., givenval1andval2that aretype&andTRhs&, respectively,std::swap(lhs, rhs)is both well-formed andnoexcept, returnsValue<true>. Otherwise, returnsValue<false>.Example#
struct not_swappable { friend void swap(not_swappable&, int&) = delete; }; struct swappable { friend void swap(swappable&, int&); friend void swap(int&, swappable&); }; struct noexcept_swappable { friend void swap(swappable&, int&) noexcept; friend void swap(int&, swappable&) noexcept; }; static constexpr auto swappable_t = decltype_<swappable>(); static constexpr auto noexcept_swappable_t = decltype_<swappable>(); static constexpr auto not_swappable_t = decltype_<not_swappable>(); static_assert(noexcept_swappable_t.is_noexcept_swappable_with(decltype_<int>())); static_assert(not swappable_t.is_noexcept_swappable_with(decltype_<int>())); static_assert(not not_swappable_t.is_noexcept_swappable_with(decltype_<int>()));
- Template Parameters:
TRhs – The type to check that
typeisnoexceptswappable with- Parameters:
rhs – The
Typespecialization representing the type to check thattypeisnoexceptswappable with- Returns:
whether the type
thisrepresents isnoexceptswappable with the typerhsrepresents, as aValuespecialization
-
template<typename TType>