flags_tests.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #include <catch.hpp>
  8. #include "base/flags.h"
  9. namespace MethodNamespace {
  10. template <typename Enum>
  11. void TestFlags(Enum a, Enum b, Enum c) {
  12. auto abc = a | b;
  13. abc |= c;
  14. auto test = abc != a;
  15. CHECK(abc != a);
  16. CHECK(abc != (a | b));
  17. CHECK((abc & a) == a);
  18. CHECK((abc & b) == b);
  19. CHECK((abc & c) == c);
  20. CHECK((abc & ~a) == (b | c));
  21. CHECK((abc & ~(b | c)) == a);
  22. CHECK((abc ^ a) == (abc & ~a));
  23. auto another = a | b;
  24. another |= c;
  25. CHECK(abc == another);
  26. another &= ~b;
  27. CHECK(another == (a | c));
  28. another ^= a;
  29. CHECK(another == c);
  30. another = 0;
  31. another = nullptr;
  32. auto is_zero = ((another & abc) == 0);
  33. CHECK(is_zero);
  34. CHECK(!(another & abc));
  35. auto more = a | another;
  36. auto just = a | 0;
  37. CHECK(more == just);
  38. CHECK(just);
  39. }
  40. } // namespace MethodNamespace
  41. namespace FlagsNamespace {
  42. enum class Flag : int {
  43. one = (1 << 0),
  44. two = (1 << 1),
  45. three = (1 << 2),
  46. };
  47. inline constexpr auto is_flag_type(Flag) { return true; }
  48. class Class {
  49. public:
  50. enum class Public : long {
  51. one = (1 << 2),
  52. two = (1 << 1),
  53. three = (1 << 0),
  54. };
  55. friend inline constexpr auto is_flag_type(Public) { return true; }
  56. static void TestPrivate();
  57. private:
  58. enum class Private : long {
  59. one = (1 << 0),
  60. two = (1 << 1),
  61. three = (1 << 2),
  62. };
  63. friend inline constexpr auto is_flag_type(Private) { return true; }
  64. };
  65. void Class::TestPrivate() {
  66. MethodNamespace::TestFlags(Private::one, Private::two, Private::three);
  67. }
  68. } // namespace FlagsNamespace
  69. namespace ExtendedNamespace {
  70. enum class Flag : int {
  71. one = (1 << 3),
  72. two = (1 << 4),
  73. three = (1 << 5),
  74. };
  75. } // namespace ExtendedNamespace
  76. namespace base {
  77. template<>
  78. struct extended_flags<ExtendedNamespace::Flag> {
  79. using type = FlagsNamespace::Flag;
  80. };
  81. } // namespace base
  82. TEST_CASE("flags operators on scoped enums", "[flags]") {
  83. SECTION("testing non-member flags") {
  84. MethodNamespace::TestFlags(
  85. FlagsNamespace::Flag::one,
  86. FlagsNamespace::Flag::two,
  87. FlagsNamespace::Flag::three);
  88. }
  89. SECTION("testing public member flags") {
  90. MethodNamespace::TestFlags(
  91. FlagsNamespace::Class::Public::one,
  92. FlagsNamespace::Class::Public::two,
  93. FlagsNamespace::Class::Public::three);
  94. }
  95. SECTION("testing private member flags") {
  96. FlagsNamespace::Class::TestPrivate();
  97. }
  98. SECTION("testing extended flags") {
  99. MethodNamespace::TestFlags(
  100. ExtendedNamespace::Flag::one,
  101. ExtendedNamespace::Flag::two,
  102. ExtendedNamespace::Flag::three);
  103. auto onetwo = FlagsNamespace::Flag::one | ExtendedNamespace::Flag::two;
  104. auto twoone = ExtendedNamespace::Flag::two | FlagsNamespace::Flag::one;
  105. CHECK(onetwo == twoone);
  106. }
  107. }