<xstd/misc/utility/to_underlying.hpp>¶
xstd::to_underlying¶
// (1)
template<class Enum>
constexpr auto to_underlying(Enum value) noexcept -> underlying_type_t<Enum>;
// (2)
template<class Enum, Enum N>
requires is_enum_v<Enum>
constexpr auto to_underlying(integral_constant<Enum, N>) noexcept;
// (3)
template<proxy_reference R>
constexpr auto to_underlying(R ref) noexcept(see below) -> underlying_type_t<iter_value_t<decltype(&ref)>>;
Converts an enumerator to its underlying type.
std::to_underlying, for an enumerator.- For an enumerator kept at the type level, in an
integral_constant. - For a proxy reference to an enumerator, such as an element of a container of packed enumerators.
Parameters¶
| Parameter | Meaning |
|---|---|
value |
an enumerator |
ref |
a proxy reference whose value type V is an enumeration |
Return value¶
static_cast<underlying_type_t<Enum>>(value), the Returns element of [utility.underlying]/1.integral_constant<underlying_type_t<Enum>, to_underlying(N)>(), the value kept at the type level.to_underlying(static_cast<V>(ref)), whereVis the value type ofref's address.
Exceptions¶
noexcept.noexcept.noexcept(is_nothrow_convertible_v<R, V>).
Remarks¶
- A type
Enumthat is not an enumeration is a substitution failure, sinceunderlying_type_t<Enum>names no type for it. - A non-enumeration constant is a substitution failure.
- Constraints:
Rmodelsproxy_reference. A value typeVthat is not an enumeration is a substitution failure, through the return typeunderlying_type_t<V>.
Notes¶
A read-only proxy, such as a set's element, models only proxy_semi_reference: convert it first, as
to_underlying(static_cast<E>(key)).
Example¶
Adapted from the example of std::to_underlying on
cppreference.com, at
revision 158870, by
cppreference.com contributors. This example is under
CC-BY-SA 3.0 and the GFDL, as cppreference.com's content is; the rest of this
page is under the Boost Software License.
#include <xstd/misc/utility/to_underlying.hpp> // to_underlying
#include <cstdint> // uint32_t
#include <iomanip> // setfill, setw
#include <iostream> // cout, hex, uppercase
#include <type_traits> // integral_constant, is_same_v, underlying_type_t
enum class E1 : char
{
e
};
static_assert(std::is_same_v<char, decltype(xstd::to_underlying(E1::e))>);
enum struct E2 : long
{
e
};
static_assert(std::is_same_v<long, decltype(xstd::to_underlying(E2::e))>);
enum E3 : unsigned
{
e
};
static_assert(std::is_same_v<unsigned, decltype(xstd::to_underlying(e))>);
// An enumerator kept at the type level converts to a value kept at the type level.
static_assert(std::is_same_v<std::integral_constant<char, 0>, decltype(xstd::to_underlying(std::integral_constant<E1, E1::e>()))>);
auto main() -> int
{
enum class ColorMask : std::uint32_t
{
red = 0xFF,
green = (red << 8),
blue = (green << 8),
alpha = (blue << 8)
};
std::cout << std::hex << std::uppercase << std::setfill('0')
<< std::setw(8) << xstd::to_underlying(ColorMask::red) << '\n'
<< std::setw(8) << xstd::to_underlying(ColorMask::green) << '\n'
<< std::setw(8) << xstd::to_underlying(ColorMask::blue) << '\n'
<< std::setw(8) << xstd::to_underlying(ColorMask::alpha) << '\n';
// std::underlying_type_t<ColorMask> x = ColorMask::alpha; // Error: no known conversion
[[maybe_unused]] std::underlying_type_t<ColorMask> const y = xstd::to_underlying(ColorMask::alpha); // OK
}
Output:
000000FF
0000FF00
00FF0000
FF000000
See also¶
| Entity | Relation |
|---|---|
std::to_underlying |
the standard's function, which (1) is |
proxy_reference |
what (3) asks of its argument |
proxy_semi_reference |
what a read-only proxy models instead |