testCMExtEnumSet.cxx 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #include <cstdint>
  2. #include <initializer_list>
  3. #include <iostream>
  4. #include <iterator>
  5. #include <limits>
  6. #include <set>
  7. #include <type_traits>
  8. #include <utility>
  9. #include <cmext/enum_set>
  10. namespace {
  11. int failed = 0;
  12. void testDeclaration()
  13. {
  14. std::cout << "testDeclaration()" << std::endl;
  15. {
  16. enum class Test : std::uint8_t
  17. {
  18. A,
  19. B,
  20. C,
  21. D
  22. };
  23. cm::enum_set<Test> testSet1;
  24. cm::enum_set<Test> testSet2 = Test::A;
  25. cm::enum_set<Test> testSet3 = Test::A | Test::C;
  26. cm::enum_set<Test> testSet4 = Test::A + Test::C;
  27. cm::enum_set<Test> testSet5{ Test::A, Test::C };
  28. cm::enum_set<Test> testSet6 = testSet3;
  29. if (!testSet1.empty()) {
  30. ++failed;
  31. }
  32. if (testSet2.size() != 1) {
  33. ++failed;
  34. }
  35. if (testSet3.size() != 2 || testSet4.size() != 2 || testSet5.size() != 2 ||
  36. testSet6.size() != 2) {
  37. ++failed;
  38. }
  39. if (testSet3 != testSet4 || testSet4 != testSet5 || testSet5 != testSet6) {
  40. ++failed;
  41. }
  42. }
  43. {
  44. enum class Test : std::uint8_t
  45. {
  46. A,
  47. B,
  48. C,
  49. D
  50. };
  51. cm::enum_set<Test> testSet1;
  52. cm::enum_set<Test, 4> testSet2;
  53. if (testSet1.size() != 0 ||
  54. testSet1.max_size() !=
  55. std::numeric_limits<
  56. typename std::underlying_type<Test>::type>::digits) {
  57. ++failed;
  58. }
  59. if (testSet2.size() != 0 || testSet2.max_size() != 4) {
  60. ++failed;
  61. }
  62. }
  63. }
  64. void testIteration()
  65. {
  66. std::cout << "testIteration()" << std::endl;
  67. enum class Test : std::uint8_t
  68. {
  69. A,
  70. B,
  71. C,
  72. D
  73. };
  74. cm::enum_set<Test, 4> testSet{ Test::A, Test::C, Test::B };
  75. if (testSet.size() != 3) {
  76. ++failed;
  77. }
  78. std::set<std::uint8_t> reference{ static_cast<std::uint8_t>(Test::A),
  79. static_cast<std::uint8_t>(Test::B),
  80. static_cast<std::uint8_t>(Test::C) };
  81. std::set<std::uint8_t> s;
  82. for (auto e : testSet) {
  83. s.insert(static_cast<std::uint8_t>(e));
  84. }
  85. if (s != reference) {
  86. ++failed;
  87. }
  88. s.clear();
  89. for (auto rit = testSet.rbegin(); rit != testSet.rend(); rit++) {
  90. s.insert(static_cast<std::uint8_t>(*rit));
  91. }
  92. if (s != reference) {
  93. ++failed;
  94. }
  95. }
  96. void testEdition()
  97. {
  98. std::cout << "testEdition()" << std::endl;
  99. enum class Test : std::uint8_t
  100. {
  101. A,
  102. B,
  103. C,
  104. D,
  105. E
  106. };
  107. {
  108. cm::enum_set<Test> testSet{ Test::A, Test::C, Test::B };
  109. auto pos = testSet.insert(Test::E);
  110. if (!pos.second || testSet.size() != 4 || *(pos.first) != Test::E ||
  111. testSet.find(Test::E) == testSet.end()) {
  112. ++failed;
  113. }
  114. testSet.insert(Test::E);
  115. if (testSet.size() != 4 || testSet.find(Test::E) == testSet.end()) {
  116. ++failed;
  117. }
  118. testSet.erase(Test::A);
  119. if (testSet.size() != 3 || testSet.find(Test::A) != testSet.end()) {
  120. ++failed;
  121. }
  122. testSet.erase(Test::A);
  123. if (testSet.size() != 3 || testSet.find(Test::A) != testSet.end()) {
  124. ++failed;
  125. }
  126. }
  127. {
  128. cm::enum_set<Test> testSet{ Test::A, Test::C, Test::B };
  129. testSet += { Test::D, Test::E };
  130. std::set<std::uint8_t> reference{ static_cast<std::uint8_t>(Test::A),
  131. static_cast<std::uint8_t>(Test::B),
  132. static_cast<std::uint8_t>(Test::C),
  133. static_cast<std::uint8_t>(Test::D),
  134. static_cast<std::uint8_t>(Test::E) };
  135. std::set<std::uint8_t> s;
  136. for (auto e : testSet) {
  137. s.insert(static_cast<std::uint8_t>(e));
  138. }
  139. if (s != reference) {
  140. ++failed;
  141. }
  142. testSet -= { Test::D, Test::B };
  143. reference.erase(static_cast<std::uint8_t>(Test::D));
  144. reference.erase(static_cast<std::uint8_t>(Test::B));
  145. s.clear();
  146. for (auto e : testSet) {
  147. s.insert(static_cast<std::uint8_t>(e));
  148. }
  149. if (s != reference) {
  150. ++failed;
  151. }
  152. }
  153. {
  154. cm::enum_set<Test> testSet1{ Test::A, Test::C, Test::B };
  155. cm::enum_set<Test> testSet2{ Test::A, Test::D, Test::E };
  156. testSet1.insert(testSet2.cbegin(), testSet2.cend());
  157. std::set<std::uint8_t> reference{ static_cast<std::uint8_t>(Test::A),
  158. static_cast<std::uint8_t>(Test::B),
  159. static_cast<std::uint8_t>(Test::C),
  160. static_cast<std::uint8_t>(Test::D),
  161. static_cast<std::uint8_t>(Test::E) };
  162. std::set<std::uint8_t> s;
  163. for (auto e : testSet1) {
  164. s.insert(static_cast<std::uint8_t>(e));
  165. }
  166. if (s != reference) {
  167. ++failed;
  168. }
  169. testSet1.erase(testSet2);
  170. reference.erase(static_cast<std::uint8_t>(Test::A));
  171. reference.erase(static_cast<std::uint8_t>(Test::D));
  172. reference.erase(static_cast<std::uint8_t>(Test::E));
  173. s.clear();
  174. for (auto e : testSet1) {
  175. s.insert(static_cast<std::uint8_t>(e));
  176. }
  177. if (s != reference) {
  178. ++failed;
  179. }
  180. }
  181. {
  182. cm::enum_set<Test> testSet1{ Test::A, Test::C, Test::B };
  183. cm::enum_set<Test> testSet2{ Test::C, Test::E };
  184. testSet1.flip(Test::A);
  185. if (testSet1.size() != 2 || testSet1.contains(Test::A)) {
  186. ++failed;
  187. }
  188. testSet1.flip(testSet2);
  189. std::set<std::uint8_t> reference{ static_cast<std::uint8_t>(Test::B),
  190. static_cast<std::uint8_t>(Test::E) };
  191. std::set<std::uint8_t> s;
  192. for (auto e : testSet1) {
  193. s.insert(static_cast<std::uint8_t>(e));
  194. }
  195. if (s != reference) {
  196. ++failed;
  197. }
  198. }
  199. {
  200. cm::enum_set<Test> testSet1;
  201. auto testSet2 = Test::A + Test::C + Test::B;
  202. testSet1.set({ Test::A, Test::C, Test::B });
  203. if (testSet1.size() != 3 || testSet1 != testSet2) {
  204. ++failed;
  205. }
  206. testSet1.reset();
  207. testSet1.set(Test::A | Test::C | Test::B);
  208. if (testSet1.size() != 3 || testSet1 != testSet2) {
  209. ++failed;
  210. }
  211. testSet1.reset();
  212. testSet1.set(Test::A + Test::C + Test::B);
  213. if (testSet1.size() != 3 || testSet1 != testSet2) {
  214. ++failed;
  215. }
  216. testSet1.reset();
  217. testSet1 = { Test::A, Test::C, Test::B };
  218. if (testSet1.size() != 3 || testSet1 != testSet2) {
  219. ++failed;
  220. }
  221. testSet1.reset();
  222. testSet1 = Test::A | Test::C | Test::B;
  223. if (testSet1.size() != 3 || testSet1 != testSet2) {
  224. ++failed;
  225. }
  226. testSet1.clear();
  227. testSet1 = Test::A + Test::C + Test::B;
  228. if (testSet1.size() != 3 || testSet1 != testSet2) {
  229. ++failed;
  230. }
  231. testSet1.clear();
  232. testSet1 |= Test::A;
  233. testSet1 |= Test::C | Test::B;
  234. if (testSet1.size() != 3 || testSet1 != testSet2) {
  235. ++failed;
  236. }
  237. }
  238. {
  239. using ESet = cm::enum_set<Test, 5>;
  240. ESet testSet1;
  241. ESet testSet2{ Test::A, Test::C, Test::B };
  242. testSet1.set();
  243. if (testSet1.size() != 5 || testSet1.size() != testSet1.max_size()) {
  244. ++failed;
  245. }
  246. testSet1.flip({ Test::D, Test::E });
  247. if (testSet1.size() != 3 || testSet1 != testSet2) {
  248. ++failed;
  249. }
  250. testSet1.flip(Test::D | Test::E);
  251. testSet2 += Test::D + Test::E;
  252. if (testSet1.size() != 5 || testSet1 != testSet2) {
  253. ++failed;
  254. }
  255. testSet1.flip(Test::E);
  256. testSet2 -= Test::E;
  257. if (testSet1.size() != 4 || testSet1 != testSet2) {
  258. ++failed;
  259. }
  260. testSet1 ^= { Test::A, Test::B, Test::E, Test::D };
  261. testSet2 = { Test::C, Test::E };
  262. if (testSet1.size() != 2 || testSet1 != testSet2) {
  263. ++failed;
  264. }
  265. testSet1 ^= { Test::A, Test::B, Test::E };
  266. testSet2 = { Test::A, Test::B, Test::C };
  267. if (testSet1.size() != 3 || testSet1 != testSet2) {
  268. ++failed;
  269. }
  270. testSet2 = Test::A | Test::B | Test::C;
  271. if (testSet1.size() != 3 || testSet1 != testSet2) {
  272. ++failed;
  273. }
  274. }
  275. }
  276. void testChecks()
  277. {
  278. std::cout << "testChecks()" << std::endl;
  279. {
  280. enum class Test : std::uint8_t
  281. {
  282. A,
  283. B,
  284. C,
  285. D
  286. };
  287. cm::enum_set<Test> testSet;
  288. if (!testSet.empty()) {
  289. ++failed;
  290. }
  291. testSet = Test::A;
  292. if (testSet.empty()) {
  293. ++failed;
  294. }
  295. if (!testSet) {
  296. ++failed;
  297. }
  298. if (!testSet.contains(Test::A)) {
  299. ++failed;
  300. }
  301. if (testSet.find(Test::A) == testSet.end()) {
  302. ++failed;
  303. }
  304. if (testSet.find(Test::C) != testSet.end()) {
  305. ++failed;
  306. }
  307. }
  308. {
  309. enum class Test : std::uint8_t
  310. {
  311. A,
  312. B,
  313. C,
  314. D
  315. };
  316. cm::enum_set<Test, 4> testSet;
  317. if (!testSet.none()) {
  318. ++failed;
  319. }
  320. if (testSet.any() || testSet.all()) {
  321. ++failed;
  322. }
  323. testSet = Test::A;
  324. if (!testSet.any() || testSet.none() || testSet.all()) {
  325. ++failed;
  326. }
  327. testSet.set();
  328. if (!testSet.all() || !testSet.any() || testSet.none()) {
  329. ++failed;
  330. }
  331. }
  332. {
  333. enum class Test : std::uint8_t
  334. {
  335. A,
  336. B,
  337. C,
  338. D
  339. };
  340. cm::enum_set<Test> testSet1;
  341. cm::enum_set<Test> testSet2{ Test::A, Test::C };
  342. if (!testSet1.none_of(testSet2) || testSet1.any_of(testSet2) ||
  343. testSet1.all_of(testSet2)) {
  344. ++failed;
  345. }
  346. testSet1 = Test::A | Test::D;
  347. if (testSet1.none_of(testSet2) || !testSet1.any_of(testSet2) ||
  348. testSet1.all_of(testSet2)) {
  349. ++failed;
  350. }
  351. testSet1 |= Test::C;
  352. if (testSet1.none_of(testSet2) || !testSet1.any_of(testSet2) ||
  353. !testSet1.all_of(testSet2)) {
  354. ++failed;
  355. }
  356. }
  357. }
  358. }
  359. int testCMExtEnumSet(int /*unused*/, char* /*unused*/[])
  360. {
  361. testDeclaration();
  362. testIteration();
  363. testEdition();
  364. testChecks();
  365. return failed;
  366. }