hyperion::mpl::Type#
- group type
Hyperion provides
mpl::Type
as 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>
Type
is 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 constexpr auto self() const noexcept -> Type<TDelay># Returns another instance of this
specialization
ofType
- Returns:
another instance of this
Type
specialization
-
template<typename TDelay = type>
inline constexpr auto inner() const noexcept -> TDelay# Returns the inner `
MetaValue
type
ofthis
Type
, ifthis
Type
represents aMetaValue
Requirements#
type
is trivially default constructibletype
is aMetaValue
Example#
constexpr auto one_typed = delctype_(1_value); static_assert(one_typed.inner() == 1_value);
-
template<typename TDelay = type>
inline constexpr auto has_inner() const noexcept -> bool# Returns whether the
type
of thisType
is 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
type
of thisType
is also a metaprogramming type
-
template<template<typename> typename TMetaFunction>
inline constexpr auto apply() const noexcept -> detail::convert_to_meta_t<TMetaFunction<type>># Applies the specified template metafunction to this specialization of
Type
.Applies
TMetaFunction
to this specialization ofType
and returns the calculated metaprogramming type.Requirements#
TMetaFunction
must be aTypeMetaFunction
:It must be a template taking a single type parameter,
It must have a
static constexpr
member 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 constexpr auto apply() const noexcept -> detail::convert_to_meta_t<TMetaFunction<TDelay::value>># Applies the specified template metafunction to this specialization of
Type
.Applies
TMetaFunction
to theValue
specialization thisType
specialization represents, and returns the calculated metaprogramming type.Requirements#
TMetaFunction
must be aValueMetaFunction
:It must be a template taking a single value parameter,
It must have a
static constexpr
member variable,value
, or a using alias type,type
type
must 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 constexpr auto apply(TFunction &&func) const noexcept -> detail::convert_to_meta_t<meta_result_t<TFunction, Type<type>>># Applies the given metafunction to this specialization of
Type
.Applies
func
to this specialization ofType
and returns the calculated result as a metaprogramming type.Requirements#
TFunction
must be aMetaFunctionOf<Type>
type
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 constexpr auto apply(TFunction &&func) const noexcept# Applies the given metafunction to the
type
of this specialization ofType
.Given that
type
is aMetaValue
, appliesfunc
to theMetaValue
type
of this specialization ofType
, as if bytype{}.apply(std::forward<TFunction>(func))
.Requirements#
TFunction
must be aMetaFunctionOf<type>
typetypename meta_result_t<TFunction, type>::type
must not be aMetaType
type
must 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
func
to thisType
specialization
-
template<template<typename> typename TPredicate>
constexpr auto satisfies() const noexcept -> std::enable_if_t<TypeMetaFunction<TPredicate> && MetaValue<TPredicate<type>> && std::same_as<std::remove_const_t<decltype(TPredicate<type>::value)>, bool>, Value<TPredicate<type>::value, bool>># Checks to see if this
Type
specialization satisfies the given template metafunction predicate,TPredicate
Requirements#
TPredicate
must be aTypeMetaFunction
It must be a template taking a single value parameter,
It must have a
static constexpr
member variable,value
, or a using alias type,type
TPredicate<type>
must be aMetaValue
The 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>
constexpr auto satisfies(TPredicate &&predicate) const noexcept# Checks to see if this
Type
specialization satisfies the given metafunction predicate.Requirements#
If
type
is aMetaValue
:If
predicate
is invocable withtype
:The value returned by invoking
predicate
withtype
must either be aMetaValue
, or aType
specialization representing aMetaValue
.Using
TValue
to represent thatMetaValue
type, 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
predicate
are not met, the program is ill-formed
If
predicate
is not invocable withtype
, see the case wherepredicate
is invocable withType<type>
If
predicate
is invocable withType<type>
:The value returned by invoking
predicate
withType<type>
must either be aMetaValue
, or aType
specialization representing aMetaValue
.Using
TValue
to represent thatMetaValue
type, 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
predicate
are not met, the program is ill-formed
If
predicate
is 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
Value
specialization
-
template<typename TRhs>
constexpr auto is(const Type<TRhs> &rhs) const noexcept -> Value<std::same_as<type, TRhs>, bool># Returns whether
this
Type
specialization is the same as the given one.Checks if
this
is an instance of the sameType
specialization asrhs
, that is, whetherstd::same_as<type, TRhs>
, and returns the result as aValue
specialization.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 constexpr auto is_qualification_of(const Type<TRhs> &rhs) const noexcept# Returns whether the
type
ofthis
Type
specialization is the same as, or a cv-ref qualification of, thetype
of the given one.Checks if the
type
ofthis
Type
specialization is the (possibly cv-ref qualification of the)type
of therhs
specialization, that is, whetherstd::same_as<std::remove_cvref_t<type>, TRhs>
, and returns the result as aValue
specialization.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);
-
template<typename TDelay = type>
constexpr auto is_const() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_const_v<std::remove_reference_t<TDelay>>, bool>># Returns whether the
type
ofthis
Type
specialization isconst
Example#
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
type
ofthis
isconst
-
template<typename TDelay = type>
constexpr auto is_lvalue_reference() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_lvalue_reference_v<TDelay>, bool>># Returns whether the
type
ofthis
Type
specialization 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
type
ofthis
is an lvalue reference
-
template<typename TDelay = type>
constexpr auto is_rvalue_reference() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_rvalue_reference_v<TDelay>, bool>># Returns whether the
type
ofthis
Type
specialization 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
type
ofthis
is an rvalue reference
-
template<typename TDelay = type>
constexpr auto is_volatile() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_volatile_v<std::remove_reference_t<TDelay>>, bool>># Returns whether the
type
ofthis
Type
specialization isvolatile
Example#
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
type
ofthis
isvolatile
-
template<typename TDelay = type>
inline constexpr auto as_const() const noexcept# Returns a
Type
specialization representing theconst
-qualified version of the typethis
specialization represents.The application of
const
does not follow the same application as other mechanisms, likestd::add_const
, and instead follows the “intuitive” expectation thatconst
would 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
Type
specialization representingconst type
-
template<typename TDelay = type>
inline constexpr auto as_lvalue_reference() const noexcept# Returns a
Type
specialization representing the lvalue reference-qualified version of the typethis
specialization 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
Type
specialization representingtype&
-
template<typename TDelay = type>
inline constexpr auto as_rvalue_reference() const noexcept# Returns a
Type
specialization representing the rvalue reference-qualified version of the typethis
specialization 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
Type
specialization representingtype&&
-
template<typename TDelay = type>
inline constexpr auto as_volatile() const noexcept# Returns a
Type
specialization representing thevolatile
-qualified version of the typethis
specialization represents.The application of
volatile
does not follow the same application as other mechanisms, likestd::add_volatile
, and instead follows the “intuitive” expectation thatvolatile
would 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
Type
specialization representingvolatile type
-
template<typename TRhs>
constexpr auto is_convertible_to(const Type<TRhs> &rhs) const noexcept -> Value<std::convertible_to<type, TRhs>, bool># Returns whether the type
this
Type
specialization represents is convertible to the typerhs
represents, as aValue
specialization.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>
constexpr auto is_derived_from(const Type<TRhs> &rhs) const noexcept -> Value<std::derived_from<type, TRhs> && !std::same_as<type, TRhs>, bool># Returns whether the type
this
Type
specialization represents is derived from the typerhs
represents, as aValue
specialization.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
rhs
represents- Parameters:
rhs – The instance of the
Type
specialization representing the type to check thattype
is derived from- Returns:
whether the type
this
represents is derived from the typerhs
represents, as aValue
specialization
Note
The application of this differs from
std::is_base_of
orstd::derived_from
, in that this isfalse
when called against the same type. That is,decltype_<base>().is_derived_from(decltype_<base>()) == false
.
-
template<typename TRhs>
constexpr auto is_base_of(const Type<TRhs> &rhs) const noexcept -> Value<std::derived_from<TRhs, type> && !std::same_as<type, TRhs>, bool># Returns whether the type
this
Type
specialization represents is a base class of the typerhs
represents, as aValue
specialization.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
rhs
represents- Parameters:
rhs – The instance of the
Type
specialization representing the type to check thattype
is a base of- Returns:
whether the type
this
represents is a base of the typerhs
represents, as aValue
specialization
Note
The application of this differs from
std::is_base_of
orstd::derived_from
, in that this isfalse
when called against the same type. That is,decltype_<base>().is_base_of(decltype_<base>()) == false
.
-
template<template<typename...> typename TList, typename ...TTypes>
constexpr auto is_constructible_from(const TList<TTypes...> &list) const noexcept -> std::enable_if_t<!MetaType<TList<TTypes...>>, Value<std::is_constructible_v<type, detail::convert_to_raw_t<TTypes>...>, bool>># Returns whether the type
this
Type
specialization represents is constructible from arguments of typesTTypes...
, as aValue
specialization.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
this
represents is constructible from arguments of typesTTypes...
, as aValue
specialization
-
template<typename ...TTypes>
constexpr auto is_constructible_from(const Type<TTypes>&... list) const noexcept -> Value<std::is_constructible_v<type, TTypes...>, bool># Returns whether the type
this
Type
specialization represents is constructible from arguments of typesTTypes...
, as aValue
specialization.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>
constexpr auto is_noexcept_constructible_from(const TList<TTypes...> &list) const noexcept -> std::enable_if_t<!MetaType<TList<TTypes...>>, Value<std::is_nothrow_constructible_v<type, detail::convert_to_raw_t<TTypes>...>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
constructible from arguments of typesTTypes...
, as aValue
specialization.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
this
represents isnoexcept
constructible from arguments of typesTTypes...
, as aValue
specialization
-
template<typename ...TTypes>
constexpr auto is_noexcept_constructible_from(const Type<TTypes>&... list) const noexcept -> Value<std::is_nothrow_constructible_v<type, TTypes...>, bool># Returns whether the type
this
Type
specialization represents isnoexcept
constructible from arguments of typesTTypes...
, as aValue
specialization.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));
-
template<typename TDelay = type>
constexpr auto is_default_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_default_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is default constructible, as aValue
specialization.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
this
represents is default constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_default_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_default_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
default constructible, as aValue
specialization.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
this
represents isnoexcept
default constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_default_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_default_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially default constructible, as aValue
specialization.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
this
represents is trivially default constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_copy_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_copy_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is copy constructible, as aValue
specialization.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
this
represents is copy constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_copy_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_copy_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
copy constructible, as aValue
specialization.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
this
represents isnoexcept
copy constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_copy_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_copy_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially copy constructible, as aValue
specialization.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
this
represents is trivially copy constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_move_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_move_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is move constructible, as aValue
specialization.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
this
represents is move constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_move_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_move_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
move constructible, as aValue
specialization.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
this
represents isnoexcept
move constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_move_constructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_move_constructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially move constructible, as aValue
specialization.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
this
represents is trivially move constructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_copy_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_copy_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is copy assignable, as aValue
specialization.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
this
represents is copy assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_copy_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_copy_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
copy assignable, as aValue
specialization.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
this
represents isnoexcept
copy assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_copy_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_copy_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially copy assignable, as aValue
specialization.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
this
represents is trivially copy assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_move_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_move_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is move assignable, as aValue
specialization.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
this
represents is move assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_move_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_move_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
move assignable, as aValue
specialization.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
this
represents isnoexcept
move assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_move_assignable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_move_assignable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially move assignable, as aValue
specialization.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
this
represents is trivially move assignable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_destructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_destructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is destructible, as aValue
specialization.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
this
represents is destructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_destructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_destructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
destructible, as aValue
specialization.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
this
represents isnoexcept
destructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_trivially_destructible() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_trivially_destructible_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is trivially destructible, as aValue
specialization.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
this
represents is trivially destructible, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_swappable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_swappable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents is swappable, as aValue
specialization.If
type
is swappable, i.e., givenlhs
andrhs
that 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
this
represents is swappable, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto is_noexcept_swappable() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<std::is_nothrow_swappable_v<TDelay>, bool>># Returns whether the type
this
Type
specialization represents isnoexcept
swappable, as aValue
specialization.If
type
isnoexcept
swappable, i.e., givenlhs
andrhs
that 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
this
represents is swappable, as aValue
specialization
-
template<typename TRhs = type>
constexpr auto is_swappable_with(const Type<TRhs> &rhs = Type<TRhs>{}) const noexcept -> Value<std::is_swappable_with_v<std::conditional_t<std::is_reference_v<type>, type, std::add_lvalue_reference_t<type>>, std::conditional_t<std::is_reference_v<TRhs>, TRhs, std::add_lvalue_reference_t<TRhs>>>, bool># Returns whether the type
this
Type
specialization represents is swappable with the typerhs
represents, as aValue
specialization.If the type
this
represents is swappable with the typerhs
represents, i.e., givenval1
andval2
that 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>
constexpr auto is_noexcept_swappable_with(const Type<TRhs> &rhs = Type<TRhs>{}) const noexcept -> Value<std::is_nothrow_swappable_with_v<std::conditional_t<std::is_reference_v<type>, type, std::add_lvalue_reference_t<type>>, std::conditional_t<std::is_reference_v<TRhs>, TRhs, std::add_lvalue_reference_t<TRhs>>>, bool># Returns whether the type
this
Type
specialization represents isnoexcept
swappable with the typerhs
represents, as aValue
specialization.If the type
this
represents isnoexcept
swappable with the typerhs
represents, i.e., givenval1
andval2
that 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
type
isnoexcept
swappable with- Parameters:
rhs – The
Type
specialization representing the type to check thattype
isnoexcept
swappable with- Returns:
whether the type
this
represents isnoexcept
swappable with the typerhs
represents, as aValue
specialization
-
template<typename TDelay = type>
constexpr auto sizeof_() const noexcept -> std::enable_if_t<std::same_as<TDelay, type>, Value<sizeof(TDelay), usize>># Returns the
sizeof
the typethis
Type
specialization represents, as aValue
specialization.- Returns:
the
sizeof
the typethis
represents, as aValue
specialization
-
template<typename TType>