TestDistinctNumeric.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * Copyright (c) 2020, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibTest/TestCase.h>
  7. #include <AK/DistinctNumeric.h>
  8. template<typename T>
  9. class ForType {
  10. public:
  11. static void check_size()
  12. {
  13. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, TheNumeric);
  14. EXPECT_EQ(sizeof(T), sizeof(TheNumeric));
  15. }
  16. };
  17. TEST_CASE(check_size)
  18. {
  19. #define CHECK_SIZE_FOR_SIGNABLE(T) \
  20. do { \
  21. ForType<signed T>::check_size(); \
  22. ForType<unsigned T>::check_size(); \
  23. } while (false)
  24. CHECK_SIZE_FOR_SIGNABLE(char);
  25. CHECK_SIZE_FOR_SIGNABLE(short);
  26. CHECK_SIZE_FOR_SIGNABLE(int);
  27. CHECK_SIZE_FOR_SIGNABLE(long);
  28. CHECK_SIZE_FOR_SIGNABLE(long long);
  29. ForType<float>::check_size();
  30. ForType<double>::check_size();
  31. }
  32. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, BareNumeric);
  33. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, IncrNumeric, Increment);
  34. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, CmpNumeric, Comparison);
  35. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, BoolNumeric, CastToBool);
  36. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, FlagsNumeric, Flags);
  37. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, ShiftNumeric, Shift);
  38. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, ArithNumeric, Arithmetic);
  39. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(int, GeneralNumeric, Arithmetic, CastToBool, Comparison, Flags, Increment, Shift);
  40. TEST_CASE(address_identity)
  41. {
  42. BareNumeric a = 4;
  43. BareNumeric b = 5;
  44. EXPECT_EQ(&a == &a, true);
  45. EXPECT_EQ(&a == &b, false);
  46. EXPECT_EQ(&a != &a, false);
  47. EXPECT_EQ(&a != &b, true);
  48. }
  49. TEST_CASE(operator_identity)
  50. {
  51. BareNumeric a = 4;
  52. BareNumeric b = 5;
  53. EXPECT_EQ(a == a, true);
  54. EXPECT_EQ(a == b, false);
  55. EXPECT_EQ(a != a, false);
  56. EXPECT_EQ(a != b, true);
  57. }
  58. TEST_CASE(operator_incr)
  59. {
  60. IncrNumeric a = 4;
  61. IncrNumeric b = 5;
  62. IncrNumeric c = 6;
  63. EXPECT_EQ(++a, b);
  64. EXPECT_EQ(a++, b);
  65. EXPECT_EQ(a, c);
  66. EXPECT_EQ(--a, b);
  67. EXPECT_EQ(a--, b);
  68. EXPECT(a != b);
  69. }
  70. TEST_CASE(operator_cmp)
  71. {
  72. CmpNumeric a = 4;
  73. CmpNumeric b = 5;
  74. CmpNumeric c = 5;
  75. EXPECT_EQ(a > b, false);
  76. EXPECT_EQ(a < b, true);
  77. EXPECT_EQ(a >= b, false);
  78. EXPECT_EQ(a <= b, true);
  79. EXPECT_EQ(b > a, true);
  80. EXPECT_EQ(b < a, false);
  81. EXPECT_EQ(b >= a, true);
  82. EXPECT_EQ(b <= a, false);
  83. EXPECT_EQ(b > c, false);
  84. EXPECT_EQ(b < c, false);
  85. EXPECT_EQ(b >= c, true);
  86. EXPECT_EQ(b <= c, true);
  87. }
  88. TEST_CASE(operator_bool)
  89. {
  90. BoolNumeric a = 0;
  91. BoolNumeric b = 42;
  92. BoolNumeric c = 1337;
  93. EXPECT_EQ(!a, true);
  94. EXPECT_EQ(!b, false);
  95. EXPECT_EQ(!c, false);
  96. }
  97. TEST_CASE(operator_flags)
  98. {
  99. FlagsNumeric a = 0;
  100. FlagsNumeric b = 0xA60;
  101. FlagsNumeric c = 0x03B;
  102. EXPECT_EQ(~a, FlagsNumeric(~0x0));
  103. EXPECT_EQ(~b, FlagsNumeric(~0xA60));
  104. EXPECT_EQ(~c, FlagsNumeric(~0x03B));
  105. EXPECT_EQ(a & b, b & a);
  106. EXPECT_EQ(a & c, c & a);
  107. EXPECT_EQ(b & c, c & b);
  108. EXPECT_EQ(a | b, b | a);
  109. EXPECT_EQ(a | c, c | a);
  110. EXPECT_EQ(b | c, c | b);
  111. EXPECT_EQ(a ^ b, b ^ a);
  112. EXPECT_EQ(a ^ c, c ^ a);
  113. EXPECT_EQ(b ^ c, c ^ b);
  114. EXPECT_EQ(a & b, FlagsNumeric(0x000));
  115. EXPECT_EQ(a & c, FlagsNumeric(0x000));
  116. EXPECT_EQ(b & c, FlagsNumeric(0x020));
  117. EXPECT_EQ(a | b, FlagsNumeric(0xA60));
  118. EXPECT_EQ(a | c, FlagsNumeric(0x03B));
  119. EXPECT_EQ(b | c, FlagsNumeric(0xA7B));
  120. EXPECT_EQ(a ^ b, FlagsNumeric(0xA60));
  121. EXPECT_EQ(a ^ c, FlagsNumeric(0x03B));
  122. EXPECT_EQ(b ^ c, FlagsNumeric(0xA5B));
  123. EXPECT_EQ(a &= b, FlagsNumeric(0x000));
  124. EXPECT_EQ(a, FlagsNumeric(0x000));
  125. EXPECT_EQ(a |= b, FlagsNumeric(0xA60));
  126. EXPECT_EQ(a, FlagsNumeric(0xA60));
  127. EXPECT_EQ(a &= c, FlagsNumeric(0x020));
  128. EXPECT_EQ(a, FlagsNumeric(0x020));
  129. EXPECT_EQ(a ^= b, FlagsNumeric(0xA40));
  130. EXPECT_EQ(a, FlagsNumeric(0xA40));
  131. EXPECT_EQ(b, FlagsNumeric(0xA60));
  132. EXPECT_EQ(c, FlagsNumeric(0x03B));
  133. }
  134. TEST_CASE(operator_shift)
  135. {
  136. ShiftNumeric a = 0x040;
  137. EXPECT_EQ(a << ShiftNumeric(0), ShiftNumeric(0x040));
  138. EXPECT_EQ(a << ShiftNumeric(1), ShiftNumeric(0x080));
  139. EXPECT_EQ(a << ShiftNumeric(2), ShiftNumeric(0x100));
  140. EXPECT_EQ(a >> ShiftNumeric(0), ShiftNumeric(0x040));
  141. EXPECT_EQ(a >> ShiftNumeric(1), ShiftNumeric(0x020));
  142. EXPECT_EQ(a >> ShiftNumeric(2), ShiftNumeric(0x010));
  143. EXPECT_EQ(a <<= ShiftNumeric(5), ShiftNumeric(0x800));
  144. EXPECT_EQ(a, ShiftNumeric(0x800));
  145. EXPECT_EQ(a >>= ShiftNumeric(8), ShiftNumeric(0x008));
  146. EXPECT_EQ(a, ShiftNumeric(0x008));
  147. }
  148. TEST_CASE(operator_arith)
  149. {
  150. ArithNumeric a = 12;
  151. ArithNumeric b = 345;
  152. EXPECT_EQ(a + b, ArithNumeric(357));
  153. EXPECT_EQ(b + a, ArithNumeric(357));
  154. EXPECT_EQ(a - b, ArithNumeric(-333));
  155. EXPECT_EQ(b - a, ArithNumeric(333));
  156. EXPECT_EQ(+a, ArithNumeric(12));
  157. EXPECT_EQ(-a, ArithNumeric(-12));
  158. EXPECT_EQ(a * b, ArithNumeric(4140));
  159. EXPECT_EQ(b * a, ArithNumeric(4140));
  160. EXPECT_EQ(a / b, ArithNumeric(0));
  161. EXPECT_EQ(b / a, ArithNumeric(28));
  162. EXPECT_EQ(a % b, ArithNumeric(12));
  163. EXPECT_EQ(b % a, ArithNumeric(9));
  164. EXPECT_EQ(a += a, ArithNumeric(24));
  165. EXPECT_EQ(a, ArithNumeric(24));
  166. EXPECT_EQ(a *= a, ArithNumeric(576));
  167. EXPECT_EQ(a, ArithNumeric(576));
  168. EXPECT_EQ(a /= a, ArithNumeric(1));
  169. EXPECT_EQ(a, ArithNumeric(1));
  170. EXPECT_EQ(a %= a, ArithNumeric(0));
  171. EXPECT_EQ(a, ArithNumeric(0));
  172. }
  173. TEST_CASE(composability)
  174. {
  175. GeneralNumeric a = 0;
  176. GeneralNumeric b = 1;
  177. // Ident
  178. EXPECT_EQ(a == a, true);
  179. EXPECT_EQ(a == b, false);
  180. // Incr
  181. EXPECT_EQ(++a, b);
  182. EXPECT_EQ(a--, b);
  183. EXPECT_EQ(a == b, false);
  184. // Cmp
  185. EXPECT_EQ(a < b, true);
  186. EXPECT_EQ(a >= b, false);
  187. // Bool
  188. EXPECT_EQ(!a, true);
  189. // Flags
  190. EXPECT_EQ(a & b, GeneralNumeric(0));
  191. EXPECT_EQ(a | b, GeneralNumeric(1));
  192. // Shift
  193. EXPECT_EQ(b << GeneralNumeric(4), GeneralNumeric(0x10));
  194. EXPECT_EQ(b >> b, GeneralNumeric(0));
  195. // Arith
  196. EXPECT_EQ(-b, GeneralNumeric(-1));
  197. EXPECT_EQ(a + b, b);
  198. EXPECT_EQ(b * GeneralNumeric(42), GeneralNumeric(42));
  199. }
  200. /*
  201. * FIXME: These `negative_*` tests should cause precisely one compilation error
  202. * each, and always for the specified reason. Currently we do not have a harness
  203. * for that, so in order to run the test you need to set the #define to 1, compile
  204. * it, and check the error messages manually.
  205. */
  206. #define COMPILE_NEGATIVE_TESTS 0
  207. #if COMPILE_NEGATIVE_TESTS
  208. TEST_CASE(negative_incr)
  209. {
  210. BareNumeric a = 12;
  211. a++;
  212. // error: static assertion failed: 'a++' is only available for DistinctNumeric types with 'Increment'.
  213. }
  214. TEST_CASE(negative_cmp)
  215. {
  216. BareNumeric a = 12;
  217. [[maybe_unused]] auto res = (a < a);
  218. // error: static assertion failed: 'a<b' is only available for DistinctNumeric types with 'Comparison'.
  219. }
  220. TEST_CASE(negative_bool)
  221. {
  222. BareNumeric a = 12;
  223. [[maybe_unused]] auto res = !a;
  224. // error: static assertion failed: '!a', 'a&&b', 'a||b' and similar operators are only available for DistinctNumeric types with 'CastToBool'.
  225. }
  226. TEST_CASE(negative_flags)
  227. {
  228. BareNumeric a = 12;
  229. [[maybe_unused]] auto res = (a & a);
  230. // error: static assertion failed: 'a&b' is only available for DistinctNumeric types with 'Flags'.
  231. }
  232. TEST_CASE(negative_shift)
  233. {
  234. BareNumeric a = 12;
  235. [[maybe_unused]] auto res = (a << a);
  236. // error: static assertion failed: 'a<<b' is only available for DistinctNumeric types with 'Shift'.
  237. }
  238. TEST_CASE(negative_arith)
  239. {
  240. BareNumeric a = 12;
  241. [[maybe_unused]] auto res = (a + a);
  242. // error: static assertion failed: 'a+b' is only available for DistinctNumeric types with 'Arithmetic'.
  243. }
  244. TEST_CASE(negative_incompatible)
  245. {
  246. GeneralNumeric a = 12;
  247. ArithNumeric b = 345;
  248. // And this is the entire point of `DistinctNumeric`:
  249. // Theoretically, the operation *could* be supported, but we declared those int types incompatible.
  250. [[maybe_unused]] auto res = (a + b);
  251. // error: no match for ‘operator+’ (operand types are ‘GeneralNumeric’ {aka ‘AK::DistinctNumeric<int, true, true, true, true, true, true, 64, 64>’} and ‘ArithNumeric’ {aka ‘AK::DistinctNumeric<int, false, false, false, false, false, true, 64, 63>’})
  252. // 313 | [[maybe_unused]] auto res = (a + b);
  253. // | ~ ^ ~
  254. // | | |
  255. // | | DistinctNumeric<[...],false,false,false,false,false,[...],[...],63>
  256. // | DistinctNumeric<[...],true,true,true,true,true,[...],[...],64>
  257. }
  258. #endif /* COMPILE_NEGATIVE_TESTS */