From 0c1128947b557c483c2268ec0418fe9dac93b414 Mon Sep 17 00:00:00 2001 From: terik23 Date: Thu, 11 Apr 2019 05:25:40 +0500 Subject: [PATCH] add integer_cast --- example/example.cpp | 12 ++++++++++++ include/magic_enum.hpp | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/example/example.cpp b/example/example.cpp index 86dde9e..5a84899 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -55,6 +55,18 @@ int main() { std::cout << "GREEN = " << c3.value() << std::endl; // GREEN = 10 } + // Enum value to integer value. + auto color_underlying = magic_enum::integer_cast(Color::RED); + if (color_underlying.has_value() && color_underlying.value() == static_cast>(Color::RED)) { + std::cout << "RED = " << color_underlying.value() << std::endl; // RED = -10 + } + + // Enum value to specific type integer value. + auto color_int = magic_enum::integer_cast(Color::RED); + if (color_int.has_value() && color_int.value() == static_cast(Color::RED)) { + std::cout << "RED = " << color_int.value() << std::endl; // RED = -10 + } + using namespace magic_enum::ops; // out-of-the-box stream operator for enums. // ostream operator for enum. std::cout << "Color: " << c1 << " " << c2 << " " << c3 << std::endl; // Color: RED BLUE GREEN diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index 12daaf2..226b1fa 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -242,6 +242,31 @@ template > } } +// Obtains integer value from enum value. +template , typename = detail::enable_if_enum_t> +[[nodiscard]] constexpr std::optional> integer_cast(E value) noexcept { + static_assert(std::is_enum_v, "magic_enum::integer_cast requires enum type."); + + if (detail::name_impl(static_cast(value)).empty()) { + return std::nullopt; // Invalid value or out of range. + } else { + return static_cast>(value); + } +} + +// Obtains specific type integer value from enum value. +template , typename = std::enable_if_t && std::is_arithmetic_v>> +[[nodiscard]] constexpr std::optional integer_cast(E value) noexcept { + static_assert(std::is_enum_v, "magic_enum::integer_cast requires enum type."); + static_assert(std::is_arithmetic_v, "magic_enum::integer_cast requires integer type."); + + if (detail::name_impl(static_cast(value)).empty() || static_cast(value) != static_cast>(value)) { + return std::nullopt; // Invalid value or out of range. + } else { + return static_cast(value); + } +} + // Returns enum value at specified index. // No bounds checking is performed: the behavior is undefined if index >= number of enum values. template>