From e7749da06b7fd5c2de32f2428decd0fa2924f3de Mon Sep 17 00:00:00 2001 From: neargye Date: Mon, 12 Jun 2023 17:43:19 +0400 Subject: [PATCH] add MAGIC_ENUM_NO_ASSERT --- include/magic_enum.hpp | 28 +++++++++++++--------- include/magic_enum_containers.hpp | 40 +++++++++++++++---------------- include/magic_enum_fuse.hpp | 2 +- test/test.cpp | 30 +++++++++++------------ test/test_containers.cpp | 8 ------- test/test_flags.cpp | 6 ++--- test/test_wchar_t.cpp | 6 ++--- 7 files changed, 59 insertions(+), 61 deletions(-) diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index 227bdcf..b629d33 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -37,7 +37,6 @@ #define MAGIC_ENUM_VERSION_PATCH 2 #include -#include #include #include #include @@ -46,17 +45,24 @@ #include #if defined(MAGIC_ENUM_CONFIG_FILE) -#include MAGIC_ENUM_CONFIG_FILE +# include MAGIC_ENUM_CONFIG_FILE #endif #if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) -#include +# include #endif #if !defined(MAGIC_ENUM_USING_ALIAS_STRING) -#include +# include #endif #if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) -#include +# include +#endif + +#if defined(MAGIC_ENUM_NO_ASSERT) +# define MAGIC_ENUM_ASSERT(...) static_cast(0) +#else +# include +# define MAGIC_ENUM_ASSERT(...) assert((__VA_ARGS__)) #endif #if defined(__clang__) @@ -182,7 +188,7 @@ class customize_t : public std::pair { constexpr customize_t(string_view srt) : std::pair{detail::customize_tag::custom_tag, srt} {} constexpr customize_t(const char_type* srt) : customize_t{string_view{srt}} {} constexpr customize_t(detail::customize_tag tag) : std::pair{tag, string_view{}} { - assert(tag != detail::customize_tag::custom_tag); + MAGIC_ENUM_ASSERT(tag != detail::customize_tag::custom_tag); } }; @@ -248,11 +254,11 @@ template class static_str { public: constexpr explicit static_str(str_view str) noexcept : static_str{str.str_, std::make_integer_sequence{}} { - assert(str.size_ == N); + MAGIC_ENUM_ASSERT(str.size_ == N); } constexpr explicit static_str(string_view str) noexcept : static_str{str.data(), std::make_integer_sequence{}} { - assert(str.size() == N); + MAGIC_ENUM_ASSERT(str.size() == N); } constexpr const char_type* data() const noexcept { return chars_; } @@ -387,7 +393,7 @@ constexpr I log2(I value) noexcept { static_assert(std::is_integral_v, "magic_enum::detail::log2 requires integral type."); if constexpr (std::is_same_v) { // bool special case - return assert(false), value; + return MAGIC_ENUM_ASSERT(false), value; } else { auto ret = I{0}; for (; value > I{1}; value >>= I{1}, ++ret) {} @@ -1155,11 +1161,11 @@ template > using D = std::decay_t; if constexpr (detail::is_sparse_v) { - return assert((index < detail::count_v)), detail::values_v[index]; + return MAGIC_ENUM_ASSERT(index < detail::count_v), detail::values_v[index]; } else { constexpr auto min = (S == detail::enum_subtype::flags) ? detail::log2(detail::min_v) : detail::min_v; - return assert((index < detail::count_v)), detail::value(index); + return MAGIC_ENUM_ASSERT(index < detail::count_v), detail::value(index); } } diff --git a/include/magic_enum_containers.hpp b/include/magic_enum_containers.hpp index af5994c..dcd7012 100644 --- a/include/magic_enum_containers.hpp +++ b/include/magic_enum_containers.hpp @@ -398,7 +398,7 @@ struct array { } constexpr void swap(array& other) noexcept(std::is_nothrow_swappable_v) { - for (std::size_t i{}; i < a.size(); ++i) { + for (std::size_t i = 0; i < a.size(); ++i) { auto v = std::move(other.a[i]); other.a[i] = std::move(a[i]); a[i] = std::move(v); @@ -514,7 +514,7 @@ class bitset { [[nodiscard]] constexpr T to_(detail::raw_access_t) const { T res{}; T flag{1}; - for (std::size_t i{}; i < size(); ++i, flag <<= 1) { + for (std::size_t i = 0; i < size(); ++i, flag <<= 1) { if (const_reference{this, i}) { if (i >= sizeof(T) * 8) { throw std::overflow_error("cannot represent enum in this type"); @@ -535,7 +535,7 @@ class bitset { constexpr explicit bitset(detail::raw_access_t, unsigned long long val) : a{{}} { unsigned long long bit{1}; - for (std::size_t i{}; i < (sizeof(val) * 8); ++i, bit <<= 1) { + for (std::size_t i = 0; i < (sizeof(val) * 8); ++i, bit <<= 1) { if ((val & bit) > 0) { if (i >= enum_count()) { throw std::out_of_range("enum bitset::constructor: Upper bit set in raw number"); @@ -548,21 +548,21 @@ class bitset { constexpr explicit bitset(detail::raw_access_t, string_view sv, string_view::size_type pos = 0, string_view::size_type n = string_view::npos, char_type zero = static_cast('0'), char_type one = static_cast('1')) : a{{}} { - std::size_t i{}; + std::size_t i = 0; for (auto c : sv.substr(pos, n)) { if (c == one) { if (i >= enum_count()) { - throw std::out_of_range("enum bitset::constructor: Upper bit set in raw string"); + MAGIC_ENUM_THROW(std::out_of_range("enum bitset::constructor: Upper bit set in raw string")); } reference{this, i} = true; } else if (c != zero) { - throw std::invalid_argument("enum bitset::constructor: unrecognized character in raw string"); + MAGIC_ENUM_THROW(std::invalid_argument("enum bitset::constructor: unrecognized character in raw string")); } ++i; } } - constexpr explicit bitset(detail::raw_access_t, const char_type* str, std::size_t n = ~std::size_t{}, char_type zero = static_cast('0'), char_type one = static_cast('1')) + constexpr explicit bitset(detail::raw_access_t, const char_type* str, std::size_t n = ~std::size_t{0}, char_type zero = static_cast('0'), char_type one = static_cast('1')) : bitset(string_view{str, (std::min)(std::char_traits::length(str), n)}, 0, n, zero, one) {} constexpr bitset(std::initializer_list starters) : a{{}} { @@ -592,7 +592,7 @@ class bitset { template > constexpr explicit bitset(string_view sv, Cmp&& cmp = {}, char_type sep = static_cast('|')) { - for (std::size_t to{}; (to = magic_enum::detail::find(sv, sep)) != string_view::npos; sv.remove_prefix(to + 1)) { + for (std::size_t to = 0; (to = magic_enum::detail::find(sv, sep)) != string_view::npos; sv.remove_prefix(to + 1)) { if (auto v = enum_cast(sv.substr(0, to), cmp)) { set(v); } else { @@ -628,7 +628,7 @@ class bitset { return true; } - for (std::size_t i{}; i < base_type_count - (not_interested > 0); ++i) { + for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { auto check = ~a[i]; if (check) { return false; @@ -652,7 +652,7 @@ class bitset { [[nodiscard]] constexpr bool none() const noexcept { return !any(); } [[nodiscard]] constexpr std::size_t count() const noexcept { - std::size_t c{}; + std::size_t c = 0; for (auto& v : a) { c += detail::popcount(v); } @@ -664,21 +664,21 @@ class bitset { [[nodiscard]] constexpr std::size_t max_size() const noexcept { return enum_count(); } constexpr bitset& operator&=(const bitset& other) noexcept { - for (std::size_t i{}; i < base_type_count; ++i) { + for (std::size_t i = 0; i < base_type_count; ++i) { a[i] &= other.a[i]; } return *this; } constexpr bitset& operator|=(const bitset& other) noexcept { - for (std::size_t i{}; i < base_type_count; ++i) { + for (std::size_t i = 0; i < base_type_count; ++i) { a[i] |= other.a[i]; } return *this; } constexpr bitset& operator^=(const bitset& other) noexcept { - for (std::size_t i{}; i < base_type_count; ++i) { + for (std::size_t i = 0; i < base_type_count; ++i) { a[i] ^= other.a[i]; } return *this; @@ -686,7 +686,7 @@ class bitset { [[nodiscard]] constexpr bitset operator~() const noexcept { bitset res; - for (std::size_t i{}; i < base_type_count - (not_interested > 0); ++i) { + for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { res.a[i] = ~a[i]; } @@ -697,8 +697,8 @@ class bitset { } constexpr bitset& set() noexcept { - for (std::size_t i{}; i < base_type_count - (not_interested > 0); ++i) { - a[i] = ~base_type{}; + for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { + a[i] = ~base_type{0}; } if constexpr (not_interested > 0) { @@ -774,7 +774,7 @@ class bitset { [[nodiscard]] string to_string(detail::raw_access_t, char_type zero = static_cast('0'), char_type one = static_cast('1')) const { string name; name.reserve(size()); - for (std::size_t i{}; i < size(); ++i) { + for (std::size_t i = 0; i < size(); ++i) { name.append(1, const_reference{this, i} ? one : zero); } return name; @@ -964,7 +964,7 @@ class set { template constexpr std::enable_if_t, size_type> erase(K&& x) noexcept { - size_type c{}; + size_type c = 0; for (auto [first, last] = detail::equal_range(index_type::values_v->begin(), index_type::values_v->end(), x, key_compare{}); first != last;) { c += erase(*first++); } @@ -981,7 +981,7 @@ class set { template [[nodiscard]] constexpr std::enable_if_t, size_type> count(const K& x) const { - size_type c{}; + size_type c = 0; for (auto [first, last] = detail::equal_range(index_type::values_v->begin(), index_type::values_v->end(), x, key_compare{}); first != last; ++first) { c += count(*first); } @@ -1091,7 +1091,7 @@ class set { private: container_type a; - std::size_t s{}; + std::size_t s = 0; }; template diff --git a/include/magic_enum_fuse.hpp b/include/magic_enum_fuse.hpp index 52543d5..e2e4315 100644 --- a/include/magic_enum_fuse.hpp +++ b/include/magic_enum_fuse.hpp @@ -84,7 +84,7 @@ template #else const auto fuse = detail::typesafe_fuse_enum...>(values...); #endif - return assert(fuse), fuse; + return MAGIC_ENUM_ASSERT(fuse), fuse; } // Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements. diff --git a/test/test.cpp b/test/test.cpp index 17b1f2c..bb826b9 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -140,14 +140,14 @@ TEST_CASE("enum_cast") { REQUIRE_FALSE(enum_cast("four").has_value()); REQUIRE_FALSE(enum_cast("None").has_value()); - REQUIRE(magic_enum::enum_cast("b5a7b602ab754d7ab30fb42c4fb28d82").has_value()); - REQUIRE_FALSE(magic_enum::enum_cast("d19f2e9e82d14b96be4fa12b8a27ee9f").has_value()); + REQUIRE(enum_cast("b5a7b602ab754d7ab30fb42c4fb28d82").has_value()); + REQUIRE_FALSE(enum_cast("d19f2e9e82d14b96be4fa12b8a27ee9f").has_value()); - constexpr auto crc = magic_enum::enum_cast("b5a7b602ab754d7ab30fb42c4fb28d82"); + constexpr auto crc = enum_cast("b5a7b602ab754d7ab30fb42c4fb28d82"); REQUIRE(crc.value() == crc_hack_2::b5a7b602ab754d7ab30fb42c4fb28d82); - REQUIRE(magic_enum::enum_cast("d19f2e9e82d14b96be4fa12b8a27ee9f").value() == crc_hack_2::d19f2e9e82d14b96be4fa12b8a27ee9f); + REQUIRE(enum_cast("d19f2e9e82d14b96be4fa12b8a27ee9f").value() == crc_hack_2::d19f2e9e82d14b96be4fa12b8a27ee9f); - REQUIRE(magic_enum::enum_cast("Nay").has_value()); + REQUIRE(enum_cast("Nay").has_value()); } SECTION("integer") { @@ -408,7 +408,7 @@ TEST_CASE("enum_value") { } TEST_CASE("enum_values") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_values(); REQUIRE(s1 == std::array{{Color::RED, Color::GREEN, Color::BLUE}}); @@ -648,7 +648,7 @@ TEST_CASE("enum_name") { } TEST_CASE("enum_names") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_names(); REQUIRE(s1 == std::array{{"red", "GREEN", "BLUE"}}); @@ -664,7 +664,7 @@ TEST_CASE("enum_names") { } TEST_CASE("enum_entries") { - REQUIRE(std::is_same_v()), const std::array, 3>&>); + REQUIRE(std::is_same_v()), const std::array, 3>&>); constexpr auto& s1 = enum_entries(); REQUIRE(s1 == std::array, 3>{{{Color::RED, "red"}, {Color::GREEN, "GREEN"}, {Color::BLUE, "BLUE"}}}); @@ -879,7 +879,7 @@ TEST_CASE("extrema") { }; REQUIRE(magic_enum::enum_name(BadColor::NONE).empty()); - REQUIRE_FALSE(magic_enum::enum_cast(std::numeric_limits::max()).has_value()); + REQUIRE_FALSE(enum_cast(std::numeric_limits::max()).has_value()); REQUIRE_FALSE(magic_enum::enum_contains(std::numeric_limits::max())); REQUIRE_FALSE(magic_enum::enum_contains(BadColor::NONE)); @@ -1090,10 +1090,10 @@ TEST_CASE("constexpr_for") { #endif static int switch_case_2d(Color color, Directions direction) { - switch (magic_enum::enum_fuse(color, direction).value()) { - case magic_enum::enum_fuse(Color::RED, Directions::Up).value(): + switch (enum_fuse(color, direction).value()) { + case enum_fuse(Color::RED, Directions::Up).value(): return 1; - case magic_enum::enum_fuse(Color::BLUE, Directions::Down).value(): + case enum_fuse(Color::BLUE, Directions::Down).value(): return 2; default: return 0; @@ -1103,10 +1103,10 @@ static int switch_case_2d(Color color, Directions direction) { enum class Index { zero = 0, one = 1, two = 2 }; static int switch_case_3d(Color color, Directions direction, Index index) { - switch (magic_enum::enum_fuse(color, direction, index).value()) { - case magic_enum::enum_fuse(Color::RED, Directions::Up, Index::zero).value(): + switch (enum_fuse(color, direction, index).value()) { + case enum_fuse(Color::RED, Directions::Up, Index::zero).value(): return 1; - case magic_enum::enum_fuse(Color::BLUE, Directions::Up, Index::zero).value(): + case enum_fuse(Color::BLUE, Directions::Up, Index::zero).value(): return 2; default: return 0; diff --git a/test/test_containers.cpp b/test/test_containers.cpp index 7b7d44c..e9cbf4b 100644 --- a/test/test_containers.cpp +++ b/test/test_containers.cpp @@ -295,14 +295,6 @@ TEST_CASE("containers_set") { REQUIRE_FALSE(magic_enum::enum_count() == color_set_not_const.size()); } -TEST_CASE("containers_flat_set") { - - // constexpr magic_enum::containers::flat_set color_flat_set_filled = {Color::RED, Color::GREEN, Color::BLUE}; - // REQUIRE_FALSE(color_flat_set_filled.empty()); - // REQUIRE(color_flat_set_filled.size() == 3); - // REQUIRE(magic_enum::enum_count() == color_flat_set_filled.size()); -} - TEST_CASE("map_like_container") { using namespace magic_enum::ostream_operators; diff --git a/test/test_flags.cpp b/test/test_flags.cpp index 37e9796..199f67d 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -390,7 +390,7 @@ TEST_CASE("enum_value") { } TEST_CASE("enum_values") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_values(); REQUIRE(s1 == std::array{{Color::RED, Color::GREEN, Color::BLUE}}); @@ -506,7 +506,7 @@ TEST_CASE("enum_flags_name") { } TEST_CASE("enum_names") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_names(); REQUIRE(s1 == std::array{{"RED", "GREEN", "BLUE"}}); @@ -522,7 +522,7 @@ TEST_CASE("enum_names") { } TEST_CASE("enum_entries") { - REQUIRE(std::is_same_v()), const std::array, 3>&>); + REQUIRE(std::is_same_v()), const std::array, 3>&>); constexpr auto& s1 = enum_entries(); REQUIRE(s1 == std::array, 3>{{{Color::RED, "RED"}, {Color::GREEN, "GREEN"}, {Color::BLUE, "BLUE"}}}); diff --git a/test/test_wchar_t.cpp b/test/test_wchar_t.cpp index 4f13c6a..8542bd7 100644 --- a/test/test_wchar_t.cpp +++ b/test/test_wchar_t.cpp @@ -68,7 +68,7 @@ TEST_CASE("enum_cast") { } TEST_CASE("enum_values") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_values(); REQUIRE(s1 == std::array{{Color::RED, Color::GREEN, Color::BLUE}}); @@ -103,14 +103,14 @@ TEST_CASE("enum_name") { } TEST_CASE("enum_names") { - REQUIRE(std::is_same_v()), const std::array&>); + REQUIRE(std::is_same_v()), const std::array&>); constexpr auto& s1 = enum_names(); REQUIRE(s1 == std::array{{L"red", L"GREEN", L"BLUE"}}); } TEST_CASE("enum_entries") { - REQUIRE(std::is_same_v()), const std::array, 3>&>); + REQUIRE(std::is_same_v()), const std::array, 3>&>); constexpr auto& s1 = enum_entries(); REQUIRE(s1 == std::array, 3>{{{Color::RED, L"red"}, {Color::GREEN, L"GREEN"}, {Color::BLUE, L"BLUE"}}});