diff --git a/include/stdx/bitset.hpp b/include/stdx/bitset.hpp index 50ab7b2..7dd548b 100644 --- a/include/stdx/bitset.hpp +++ b/include/stdx/bitset.hpp @@ -104,6 +104,10 @@ class bitset { using iter_arg_t = conditional_t, decltype(Size), std::size_t>; + template CONSTEVAL static auto admissible_enum() { + return not std::is_enum_v or std::is_same_v; + } + template constexpr auto for_each(F &&f) const -> F { std::size_t i = 0; for (auto e : storage) { @@ -216,6 +220,9 @@ class bitset { template [[nodiscard]] constexpr auto operator[](T idx) const -> bool { + static_assert(admissible_enum() or + stdx::always_false_v, + "T is not the required enumeration type"); auto const pos = static_cast(to_underlying(idx)); auto const [index, offset] = indices(pos); return (storage[index] & (bit << offset)) != 0; @@ -223,6 +230,9 @@ class bitset { template constexpr auto set(T idx, bool value = true) LIFETIMEBOUND -> bitset & { + static_assert(admissible_enum() or + stdx::always_false_v, + "T is not the required enumeration type"); auto const pos = static_cast(to_underlying(idx)); auto const [index, offset] = indices(pos); if (value) { @@ -278,6 +288,9 @@ class bitset { template constexpr auto reset(T idx) LIFETIMEBOUND -> bitset & { + static_assert(admissible_enum() or + stdx::always_false_v, + "T is not the required enumeration type"); auto const pos = static_cast(to_underlying(idx)); auto const [index, offset] = indices(pos); storage[index] &= static_cast(~(bit << offset)); @@ -300,6 +313,9 @@ class bitset { } template constexpr auto flip(T idx) LIFETIMEBOUND -> bitset & { + static_assert(admissible_enum() or + stdx::always_false_v, + "T is not the required enumeration type"); auto const pos = static_cast(to_underlying(idx)); auto const [index, offset] = indices(pos); storage[index] ^= static_cast(bit << offset); diff --git a/test/fail/CMakeLists.txt b/test/fail/CMakeLists.txt index 00abcc0..d0999ad 100644 --- a/test/fail/CMakeLists.txt +++ b/test/fail/CMakeLists.txt @@ -7,8 +7,9 @@ endfunction() add_fail_tests( as_signed_bool as_unsigned_bool - bitset_signed_storage + bitset_mixed_enumeration bitset_nonintegral_bit_places + bitset_signed_storage bitset_to_uint64_over_64_bits for_each_n_args_bad_size optional_without_tombstone diff --git a/test/fail/bitset_mixed_enumeration.cpp b/test/fail/bitset_mixed_enumeration.cpp new file mode 100644 index 0000000..9861fce --- /dev/null +++ b/test/fail/bitset_mixed_enumeration.cpp @@ -0,0 +1,11 @@ +#include + +// EXPECT: T is not the required enumeration type + +enum struct E1 { A, B, C, MAX }; +enum struct E2 { X, Y, Z }; + +auto main() -> int { + auto b = stdx::bitset{}; + b.set(E2::X); +}