aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/kstd/kstd/bitfield_enum.tests.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/libs/kstd/kstd/bitfield_enum.tests.cpp b/libs/kstd/kstd/bitfield_enum.tests.cpp
new file mode 100644
index 00000000..e0673269
--- /dev/null
+++ b/libs/kstd/kstd/bitfield_enum.tests.cpp
@@ -0,0 +1,159 @@
+#include <kstd/bitfield_enum.hpp>
+
+#include <catch2/catch_test_macros.hpp>
+
+#include <cstdint>
+#include <type_traits>
+#include <utility>
+
+namespace
+{
+
+ enum struct test_enum : std::uint8_t
+ {
+ none = 0,
+ flag_a = 1,
+ flag_b = 2,
+ // INTENTIONAL HOLE
+ flag_c = 8,
+ flag_d = 16
+ };
+
+} // namespace
+
+template<>
+struct kstd::is_bitfield_enum<test_enum> : std::true_type
+{
+};
+
+SCENARIO("Bitfield Enum operations")
+{
+ GIVEN("Two enumerator values")
+ {
+ auto value_one = test_enum::flag_a;
+ auto value_two = test_enum::flag_b;
+
+ WHEN("combining them using bitwise or")
+ {
+ auto result = value_one | value_two;
+
+ THEN("the underlying value is the bitwise combination of the two underlying values")
+ {
+ REQUIRE(std::to_underlying(result) ==
+ (std::to_underlying(test_enum::flag_a) | std::to_underlying(test_enum::flag_b)));
+ }
+ }
+
+ WHEN("combining them using bitwise or-assign")
+ {
+ auto result = value_one;
+ result |= value_two;
+
+ THEN("the assigned to value is the bitwise combination of hte two values")
+ {
+ REQUIRE(result == (value_one | value_two));
+ }
+ }
+
+ WHEN("masking a combination using bitwise and and a present flag")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b | test_enum::flag_c;
+ auto result = combination & test_enum::flag_b;
+
+ THEN("the single flag is extracted")
+ {
+ REQUIRE(result == test_enum::flag_b);
+ }
+ }
+
+ WHEN("masking a combination using bitwise and and a non-present flag")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b | test_enum::flag_c;
+ auto result = combination & test_enum::flag_d;
+
+ THEN("the single flag is extracted")
+ {
+ REQUIRE(result == test_enum::none);
+ }
+ }
+
+ WHEN("masking a combination using bitwise and-assign and a present flag")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b | test_enum::flag_c;
+ combination &= test_enum::flag_b;
+
+ THEN("the single flag is extracted")
+ {
+ REQUIRE(combination == test_enum::flag_b);
+ }
+ }
+
+ WHEN("masking a combination using bitwise and-assign and a non-present flag")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b | test_enum::flag_c;
+ combination &= test_enum::flag_d;
+
+ THEN("the single flag is extracted")
+ {
+ REQUIRE(combination == test_enum::none);
+ }
+ }
+
+ WHEN("toggling a flag in a combination using bitwise xor")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b;
+ auto result_absent = combination ^ test_enum::flag_c;
+ auto result_present = combination ^ test_enum::flag_b;
+
+ THEN("the flag is set if it wasn't before")
+ {
+ CHECK((combination & test_enum::flag_c) == test_enum::none);
+ REQUIRE((result_absent & test_enum::flag_c) == test_enum::flag_c);
+ }
+
+ THEN("the flag is not set if it was before")
+ {
+ CHECK((combination & test_enum::flag_b) == test_enum::flag_b);
+ REQUIRE_FALSE((result_present & test_enum::flag_b) == test_enum::flag_b);
+ }
+ }
+
+ WHEN("toggling a flag in a combination using bitwise xor-assign")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_b;
+ auto result = combination;
+ result ^= test_enum::flag_c;
+ result ^= test_enum::flag_b;
+
+ THEN("the flag is set if it wasn't before")
+ {
+ CHECK((combination & test_enum::flag_c) == test_enum::none);
+ REQUIRE((result & test_enum::flag_c) == test_enum::flag_c);
+ }
+
+ THEN("the flag is not set if it was before")
+ {
+ CHECK((combination & test_enum::flag_b) == test_enum::flag_b);
+ REQUIRE_FALSE((result & test_enum::flag_b) == test_enum::flag_b);
+ }
+ }
+
+ WHEN("inverting a combination using bitwise negation")
+ {
+ auto combination = test_enum::flag_a | test_enum::flag_c;
+ auto result = ~combination;
+
+ THEN("all previously set flags are unset")
+ {
+ REQUIRE_FALSE((result & test_enum::flag_a) == test_enum::flag_a);
+ REQUIRE_FALSE((result & test_enum::flag_c) == test_enum::flag_c);
+ }
+
+ THEN("all previously unset flags are set")
+ {
+ REQUIRE((result & test_enum::flag_b) == test_enum::flag_b);
+ REQUIRE((result & test_enum::flag_d) == test_enum::flag_d);
+ }
+ }
+ }
+}