hyperion::mpl::Value#
- group value
Hyperion provides
mpl::Value
as a metaprogramming type for storing, communicating, working with, and calculating compile-time values.Example#
#include <hyperion/mpl/value.h> using namespace hyperion::mpl; constexpr auto val1 = Value<4>{}; constexpr auto val2 = Value<2>{}; constexpr auto meaning_of_life = (val1 * 10_value) + val2; static_assert(meaning_of_life == 42);
Functions
-
template<char... TChars>
static inline constexpr auto operator""_value() noexcept# Numeric literal operator to create a compile-time
Value
.Value
represents a compile time value, storing that value in itsstatic constexpr
member variable,value
.- Template Parameters:
TChars – The characters of the numeric literal
-
template<auto TValue, typename TType = decltype(TValue)>
constexpr auto value_of(const Value<TValue, TType> &value) noexcept -> decltype(TValue)# Returns the compile-time value of the given
mpl::Value
- Template Parameters:
TValue – The compile-time value of
value
TType – The type of the compile-time value
- Parameters:
value – The
mpl::Value
to get the compile-time value of- Returns:
the compile-time value of the given
mpl::Value
-
template<MetaValue TType>
constexpr auto value_of(const TType &value) noexcept -> decltype(TType::value)# Returns the compile-time value of the given
mpl::Value
Requirements#
TType
must be anmpl::MetaValue
TType
must not be a specialization ofmpl::Value
- Template Parameters:
TType – The
mpl::MetaValue
storing the compile-time value- Parameters:
value – The
mpl::MetaValue
to get the compile-time value of- Returns:
the compile-time value of the given
mpl::Value
-
template<MetaValue TType>
constexpr auto as_value(const TType &value) noexcept -> Value<TType::value, std::remove_cvref_t<decltype(TType::value)>># Returns the given
mpl::MetaValue
into anmpl::Value
Requirements#
TType
must be anmpl::MetaValue
TType
must not be a specialization ofmpl::Value
- Template Parameters:
TType – The
mpl::MetaValue
storing the compile-time value- Parameters:
value – The
mpl::MetaValue
to get the compile-time value of- Returns:
the compile-time value of the given
mpl::Value
-
template<auto TValue, typename TType = decltype(TValue)>
constexpr auto operator+(const Value<TValue, TType> &value) noexcept -> Value<TValue># Unary plus operator for
mpl::Value
.Requirements#
The type of
TValue
must beUnaryPlusable
(it must support unaryoperator+
).
- Template Parameters:
TValue – The value of this
Value
TType – The type of
TValue
- Parameters:
value – The
mpl::Value
to +- Returns:
The
mpl::Value
representing+TValue
-
template<auto TValue, typename TType = decltype(TValue)>
constexpr auto operator-(const Value<TValue, TType> &value) noexcept -> Value<-TValue># Unary minus operator for
mpl::Value
.Requirements#
The type of
TValue
must beUnaryMinusable
(it must support unaryoperator-
).
- Template Parameters:
TValue – The value of this
Value
TType – The type of
TValue
- Parameters:
value – The
mpl::Value
to -- Returns:
The
mpl::Value
representing-TValue
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator+(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs + TRhs># Adds the two given
mpl::Value
s and returns the result as anothermpl::Value
specialization.Requirements#
TLhs
andTRhs
must be addable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to addrhs – The right-hand
mpl::Value
to add
- Returns:
The
mpl::Value
representingTLhs + TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator-(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs - TRhs># Subtracts
rhs
fromlhs
and returns the result as anothermpl::Value
specialization.Requirements#
TLhs
andTRhs
must be subtractable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to subtract fromrhs – The right-hand
mpl::Value
to subtract
- Returns:
The
mpl::Value
representingTLhs - TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator*(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs * TRhs># Multiplies the two given
mpl::Value
s and returns the result as anothermpl::Value
specialization.Requirements#
TLhs
andTRhs
must be multipliable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to addrhs – The right-hand
mpl::Value
to add
- Returns:
The
mpl::Value
representingTLhs * TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator/(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs / TRhs># Divides
lhs
byrhs
and returns the result as anothermpl::Value
specialization.Requirements#
TLhs
andTRhs
must be dividible
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to dividerhs – The right-hand
mpl::Value
to divide by
- Returns:
The
mpl::Value
representingTLhs / TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator&&(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs && TRhs># Performs the boolean and of
lhs
andrhs
Requirements#
TLhs
andTRhs
must be boolean andable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to andrhs – The right-hand
mpl::Value
to and
- Returns:
The
mpl::Value
representingTLhs && TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator||(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs || TRhs># Performs the boolean or of
lhs
andrhs
Requirements#
TLhs
andTRhs
must be boolean orable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to orrhs – The right-hand
mpl::Value
to or
- Returns:
The
mpl::Value
representingTLhs || TRhs
-
template<auto TValue, typename TType = decltype(TValue)>
constexpr auto operator!(const Value<TValue, TType> &value) noexcept -> Value<!TValue, TType># Performs the boolean not of
value
Requirements#
TValue
boolean notable
- Template Parameters:
TValue – The value of the
mpl::Value
TType – The type of
TValue
- Parameters:
value – The
mpl::Value
to not- Returns:
The
mpl::Value
representing!TLhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator&(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs & TRhs># Performs the binary and of
lhs
andrhs
Requirements#
TLhs
andTRhs
must be binary andable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to andrhs – The right-hand
mpl::Value
to and
- Returns:
The
mpl::Value
representingTLhs & TRhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator|(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs | TRhs># Performs the binary or of
lhs
andrhs
Requirements#
TLhs
andTRhs
must be binary orable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to orrhs – The right-hand
mpl::Value
to or
- Returns:
The
mpl::Value
representingTLhs | TRhs
-
template<auto TValue, typename TType = decltype(TValue)>
constexpr auto operator~(const Value<TValue, TType> &value) noexcept -> Value<~TValue, TType># Performs the binary not of
value
Requirements#
TValue
binary notable
- Template Parameters:
TValue – The value of the
mpl::Value
TType – The type of
TValue
- Parameters:
value – The
mpl::Value
to not- Returns:
The
mpl::Value
representing!TLhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator==(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs == TRhs># Equality comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be equality comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is equal to the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator!=(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs != TRhs># Inequality comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be inequality comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is not equal to the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator<=>(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<TLhs <=> TRhs># Three-way comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be three-way comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
The result of three-way comparing the value of
lhs
with the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator<(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<(TLhs < TRhs)># Less-than comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be less-than comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is less than the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator<=(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<(TLhs <= TRhs)># Less-than-or-equal comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be less-than-or-equal comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is less than or equal to the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator>(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<(TLhs > TRhs)># Greater-than comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be greater-than comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is greater than the value ofrhs
-
template<auto TLhs, auto TRhs, typename TTypeLhs = decltype(TLhs), typename TTypeRhs = decltype(TRhs)>
constexpr auto operator>=(const Value<TLhs, TTypeLhs> &lhs, const Value<TRhs, TTypeRhs> &rhs) noexcept -> Value<(TLhs >= TRhs)># Greater-than-or-equal comparison operator between two
mpl::Value
s.Requirements#
TLhs
andTRhs
must be greater-than-or-equal comparable
- Template Parameters:
TLhs – The value of the left-hand
mpl::Value
TRhs – The value of the right-hand
mpl::Value
TTypeLhs – The type of
TLhs
TTypeRhs – The type of
RLhs
- Parameters:
lhs – The left-hand
mpl::Value
to comparerhs – The right-hand
mpl::Value
to compare with
- Returns:
Whether the value of
lhs
is greater than or equal to the value ofrhs
-
template<auto TValue, typename TType = std::remove_cvref_t<decltype(TValue)>>
struct Value# - #include <hyperion/mpl/value.h>
Value
is Hyperion’s preferred metaprogramming value type.Value
represents a compile time value, storing that value in itsstatic constexpr
member variable,value
.- Template Parameters:
TValue – The value of this
Value
TType – The type of
TValue
. This can be manually specified to enforce thatTValue
is coerced toTType
(for example, in order to forceTValue
to be anint
, instead ofstd::size_t
)
Public Functions
-
inline constexpr operator TType() const noexcept#
Conversion operator to the
value
.- Returns:
The
value
of this specialization ofValue
-
inline constexpr auto operator()() const noexcept -> TType#
Call operator to get the
value
.- Returns:
The
value
of this specialization ofValue
-
inline explicit constexpr operator bool() const noexcept#
Conversion operator to
bool
. Converts thevalue
of this specialization ofValue
tobool
.Requirements#
TType
must be convertible tobool
TType
must not bebool
- Returns:
the
value
of this specialization ofValue
, converted tobool
-
inline constexpr auto value_of() const -> TType#
Returns the
value
of thisValue
specialization.- Returns:
value
-
template<template<typename> typename TMetaFunction>
inline constexpr auto apply() const noexcept -> detail::unwrap_inner_t<detail::convert_to_meta_t<TMetaFunction<Value>>># Applies the specified template metafunction to this specialization of
Value
.Applies
TMetaFunction
to this specialization ofValue
and returns the calculated result as a 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 TValue> struct add_one_typed { using type = Value<TValue::value + 1>; }; // `two` is `Value<2, usize>` constexpr auto two = (1_value).apply<add_one>(); static_assert(two == 2_value); template<typename TValue> struct add_one_typed { using type = Type<Value<TValue::value + 1>>; }; // `two_typed` is `Value<2, usize>` constexpr auto two_typed = (1_value).apply<add_one_typed>().inner(); static_assert(two_typed == 2_value);
- Template Parameters:
TMetaFunction – The template metafunction to apply to this
Value
- Returns:
The result of applying
TMetaFunction
-
template<template<auto> typename TMetaFunction>
inline constexpr auto apply() const noexcept -> detail::unwrap_inner_t<detail::convert_to_meta_t<TMetaFunction<value>>># Applies the specified template metafunction to this specialization of
Value
.Applies
TMetaFunction
to this specialization ofValue
and returns the calculated result as a 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
Example#
template<auto TValue> struct add_one { static inline constexpr auto value = TValue + 1>; }; constexpr auto two = (1_value).apply<add_one>(); // `two` is `Value<2, usize>` static_assert(two == 2_value); template<auto TValue> struct add_one_typed { using type = Type<Value<TValue + 1>>; }; // `two_typed` is `Value<2, usize>` constexpr auto two_typed = (1_value).apply<add_one_typed>().inner(); static_assert(two_typed == 2_value);
- Template Parameters:
TMetaFunction – The template metafunction to apply to this
Value
- Returns:
The result of applying
TMetaFunction
-
template<typename TFunction>
inline constexpr auto apply(TFunction &&func) const noexcept -> detail::unwrap_inner_t<detail::convert_to_meta_t<meta_result_t<TFunction, Value>>># Applies the given metafunction to this specialization of
Value
.Applies
func
to this specialization ofValue
and returns the calculated result as a metaprogramming type.Requirements#
TFunction
must be aMetaFunctionOf<Value>
type
Example#
constexpr auto add_one = [](MetaValue auto value) { return value + 1_value; }; // `two` is `Value<2, usize>` constexpr auto two = (1_value).apply(add_one_typed); static_assert(two == 2_value); constexpr auto add_one_typed = [](MetaValue auto value) { return decltype_(value + 1_value); }; // `two` is `Value<2, usize>` constexpr auto two_typed = (1_value).apply(add_one_typed).inner(); static_assert(two_typed == 2_value);
- Template Parameters:
TFunction – The type of the metafunction to apply
- Parameters:
func – The metafunction to apply
- Returns:
The result of applying
func
to thisValue
specialization
-
template<template<auto> typename TPredicate>
inline constexpr auto satisfies() const noexcept -> Value<TPredicate<value>::value># Checks to see if this
Value
specialization satisfies the given metafunction predicate,TPredicate
Requirements#
TPredicate
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
TPredicate<value>
must be aMetaValue
The type of the value of
TPredicate
,TPredicate<value>::value
, must be (possibly cv-ref qualified)bool
)
Example#
template<auto TValue> struct is_two { static inline constexpr auto value = TValue == 2; }; constexpr auto not_two = (1_value).satisfies<is_two>(); // `not_two` is // `Value<false, bool>` constexpr auto was_two = (2_value).satisfies<is_two>(); // `was_two` is // `Value<true, bool>`
-
template<template<typename> typename TPredicate>
inline constexpr auto satisfies() const noexcept -> Value<TPredicate<Value>::value># Checks to see if this
Value
specialization satisfies the given metafunction predicate,TPredicate
Requirements#
TPredicate
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
The type of the value of
TPredicate
,TPredicate<Value>::value
, must be (possibly cv-ref qualified)bool
)
Example#
template<MetaValue TValue> struct is_two { static inline constexpr auto value = TValue::value == 2; }; constexpr auto not_two = (1_value).satisfies<is_two>(); // `not_two` is // `Value<false, bool>` constexpr auto was_two = (2_value).satisfies<is_two>(); // `was_two` is // `Value<true, bool>`
-
template<typename TPredicate>
inline constexpr auto satisfies(TPredicate &&predicate) const noexcept# Checks to see if this
Value
specialization satisfies the given metafunction predicate,predicate
If
predicate
is not aMetaPredicateOf<Value>
type, returnsValue<false>
Example#
constexpr auto is_two = [](MetaValue auto value) -> Value<decltype(value)::value == 2> { return {}; }; constexpr auto not_two = (1_value).satisfies(is_two); // `not_two` is // `Value<false, bool>` constexpr auto was_two = (2_value).satisfies(is_two); // `was_two` is // `Value<true, bool>`
-
template<char... TChars>