summaryrefslogtreecommitdiff
path: root/asl/base
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-05-08 00:15:26 +0200
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-05-08 00:15:26 +0200
commite1ba7dd7a976b2ce076b9361f761dd51cdf4b4ec (patch)
tree80c76c46ee2678aa39280220d1d6f82bed98ef1c /asl/base
parent837f696971677b4ed2263e744a9ce6d6d3865b11 (diff)
Add enum underlying utilities
Diffstat (limited to 'asl/base')
-rw-r--r--asl/base/meta.hpp2
-rw-r--r--asl/base/meta_tests.cpp7
-rw-r--r--asl/base/utility.hpp6
-rw-r--r--asl/base/utility_tests.cpp17
4 files changed, 32 insertions, 0 deletions
diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp
index c13439a..3675df3 100644
--- a/asl/base/meta.hpp
+++ b/asl/base/meta.hpp
@@ -309,6 +309,8 @@ template<is_unsigned_integer T> using as_signed_integer = _integer_traits<T>::
template<typename T> concept is_enum = __is_enum(T);
+template<is_enum T> using underlying_t = __underlying_type(T);
+
template<typename T> struct is_uniquely_represented : false_type {};
template<is_integer T> struct is_uniquely_represented<T> : true_type {};
template<is_enum T> struct is_uniquely_represented<T> : true_type {};
diff --git a/asl/base/meta_tests.cpp b/asl/base/meta_tests.cpp
index c221dcf..7bae295 100644
--- a/asl/base/meta_tests.cpp
+++ b/asl/base/meta_tests.cpp
@@ -372,3 +372,10 @@ static_assert(!asl::same_as<asl::decay_t<int[4][2]>, int*>);
static_assert(!asl::same_as<asl::decay_t<int[4][2]>, int**>);
static_assert(asl::same_as<asl::decay_t<int[4][2]>, int(*)[2]>);
static_assert(asl::same_as<asl::decay_t<int(int)>, int(*)(int)>);
+
+enum EnumU8 : uint8_t {};
+enum EnumI64 : int64_t {};
+
+static_assert(asl::same_as<asl::underlying_t<EnumU8>, uint8_t>);
+static_assert(asl::same_as<asl::underlying_t<EnumI64>, int64_t>);
+
diff --git a/asl/base/utility.hpp b/asl/base/utility.hpp
index f371ab4..c4801b1 100644
--- a/asl/base/utility.hpp
+++ b/asl/base/utility.hpp
@@ -69,6 +69,12 @@ constexpr U bit_cast(T value) requires (sizeof(T) == sizeof(U))
return __builtin_bit_cast(U, value);
}
+template<is_enum T>
+constexpr auto to_underlying(T value)
+{
+ return static_cast<underlying_t<T>>(value);
+}
+
// NOLINTBEGIN(*-macro-parentheses)
#define ASL_DELETE_COPY(T) \
T(const T&) = delete; \
diff --git a/asl/base/utility_tests.cpp b/asl/base/utility_tests.cpp
index 7e54bb2..ea3e7c6 100644
--- a/asl/base/utility_tests.cpp
+++ b/asl/base/utility_tests.cpp
@@ -81,3 +81,20 @@ ASL_TEST(forward_like)
ASL_TEST_EXPECT(test_fwd_like<int&&>(9) == 4);
}
+enum class Enum : int // NOLINT
+{
+ kOne = 1,
+ kTwo = 2,
+};
+
+enum Enum2 : int // NOLINT
+{
+ kOne = 1,
+ kTwo = 2,
+};
+
+static_assert(asl::to_underlying(Enum::kOne) == 1);
+static_assert(asl::to_underlying(Enum::kTwo) == 2);
+static_assert(asl::to_underlying(kOne) == 1);
+static_assert(asl::to_underlying(kTwo) == 2);
+