Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /*!
  2. * \file deque.cpp
  3. * \brief
  4. * Unit tests for edeque
  5. *
  6. * \copyright Copyright (C) 2020 Christos Choutouridis <christos@choutouridis.net>
  7. *
  8. * <dl class=\"section copyright\"><dt>License</dt><dd>
  9. * The MIT License (MIT)
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy
  12. * of this software and associated documentation files (the "Software"), to deal
  13. * in the Software without restriction, including without limitation the rights
  14. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. * copies of the Software, and to permit persons to whom the Software is
  16. * furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in all
  19. * copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  27. * SOFTWARE.
  28. * </dd></dl>
  29. *
  30. */
  31. #include <utl/container/edeque.h>
  32. #include <gtest/gtest.h>
  33. #include <functional>
  34. namespace Tedeque {
  35. using namespace utl;
  36. int global_flag =0;
  37. // Callable mocks
  38. void vfun(void) { ++global_flag; }
  39. struct vfoo {
  40. void operator() (void) { ++global_flag; }
  41. };
  42. TEST (Tedeque, construct) {
  43. using Edeque = edeque<int, 8>;
  44. struct T { int a,b; };
  45. int local{};
  46. Edeque e1(Edeque::size_match::GE, 3, [](){
  47. ++global_flag;
  48. });
  49. Edeque e2(Edeque::size_match::GE, 3, [&](){
  50. ++local;
  51. });
  52. Edeque e3(Edeque::size_match::EQ, 7, vfun);
  53. edeque<T, 8> e4(edeque<T, 8>::size_match::EQ, 2, vfoo{});
  54. edeque<int, 8> q1;
  55. edeque<int, 8> q2(edeque<int, 8>::size_match::DISABLED, 0, nullptr);
  56. EXPECT_EQ (8UL, e1.capacity());
  57. EXPECT_EQ (8UL, e2.capacity());
  58. EXPECT_EQ (8UL, e3.capacity());
  59. EXPECT_EQ (8UL, e4.capacity());
  60. EXPECT_EQ (8UL, q1.capacity());
  61. EXPECT_EQ (8UL, q2.capacity());
  62. }
  63. TEST (Tedeque, base_class) {
  64. using Edeque = edeque<int, 8>;
  65. Edeque e1(Edeque::size_match::GE, 3, [](){
  66. ++global_flag;
  67. });
  68. // Access of base class functionality
  69. EXPECT_EQ (8UL, e1.capacity());
  70. EXPECT_EQ (0UL, e1.size());
  71. EXPECT_EQ (true, e1.empty());
  72. EXPECT_EQ (false, e1.full());
  73. e1.push_back(7);
  74. EXPECT_EQ (7, e1.front());
  75. EXPECT_EQ (7, e1.back());
  76. EXPECT_EQ (7, e1.pop_front());
  77. e1.push_front(42);
  78. EXPECT_EQ (42, e1.front());
  79. EXPECT_EQ (42, e1.back());
  80. EXPECT_EQ (42, e1.pop_back());
  81. e1.push_back(1);
  82. e1.push_back(2);
  83. e1.push_back(3);
  84. int check_it=1;
  85. for (auto it = e1.begin() ; it != e1.end() ; ++it)
  86. EXPECT_EQ(*it, check_it++);
  87. EXPECT_EQ(4, check_it); // run through all
  88. }
  89. TEST (Tedeque, set_clear_check_trigger) {
  90. using Edeque = edeque<int, 8>;
  91. bool flag{};
  92. Edeque e1(Edeque::size_match::GE, 1, [&](){ flag = true; });
  93. flag = false;
  94. e1.clear_trigger();
  95. EXPECT_EQ (false, flag);
  96. e1.push_back(1); // 1, no-trigger cleared
  97. EXPECT_EQ (false, flag);
  98. flag = false;
  99. e1.clear();
  100. e1.clear_trigger();
  101. EXPECT_EQ (false, flag); // no spurious triggers
  102. e1.push_back(1); // 1
  103. e1.push_back(2); // 2
  104. e1.set_trigger(Edeque::size_match::GE, 1, [&](){ flag = true; });
  105. EXPECT_EQ (false, flag); // no spurious triggers
  106. e1.check_trigger(); // manual trigger
  107. EXPECT_EQ (true, flag);
  108. flag = false;
  109. e1.check_trigger(); // manual trigger attempt
  110. EXPECT_EQ (false, flag); // [SIZE triggers are auto clear]
  111. Edeque e2(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  112. flag = false;
  113. e2.clear_trigger();
  114. EXPECT_EQ (false, flag);
  115. e2.push_back(42); // push 42, no-trigger cleared
  116. EXPECT_EQ (false, flag);
  117. e2.set_trigger(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  118. EXPECT_EQ (false, flag); // no spurious triggers
  119. e2.push_back(42); // push 42, trigger
  120. EXPECT_EQ (true, flag);
  121. flag = false;
  122. e2.push_back(42); // push 42, re-trigger [DATA re-triggers]
  123. EXPECT_EQ (true, flag);
  124. }
  125. TEST (Tedeque, size_triggers) {
  126. using Edeque = edeque<int, 8>;
  127. bool flag{};
  128. // size_match::GE (size()>= 2)
  129. Edeque ee(Edeque::size_match::GE, 2, [&](){ flag = true; });
  130. flag = false;
  131. ee.clear();
  132. ee.push_back(1); // 1
  133. EXPECT_EQ (false, flag);
  134. ee.push_back(2); // 2, trigger
  135. EXPECT_EQ (true, flag);
  136. flag = false;
  137. ee.push_back(3); // 3, no-trigger cleared
  138. EXPECT_EQ (false, flag);
  139. // size_match::GT (size()> 1)
  140. flag = false;
  141. ee.clear();
  142. ee.set_trigger(Edeque::size_match::GT, 1, [&](){ flag = true; });
  143. ee.push_back(1); // 1
  144. EXPECT_EQ (false, flag);
  145. ee.push_back(2); // 2, trigger
  146. EXPECT_EQ (true, flag);
  147. flag = false;
  148. ee.push_back(3); // 3, no-trigger cleared
  149. EXPECT_EQ (false, flag);
  150. // size_match::LE (size()<= 1)
  151. flag = false;
  152. ee.clear();
  153. ee.push_back(1); // 1
  154. ee.push_back(2); // 2
  155. ee.push_back(3); // 3
  156. ee.set_trigger(Edeque::size_match::LE, 1, [&](){ flag = true; });
  157. ee.pop_front(); // 2
  158. EXPECT_EQ (false, flag);
  159. ee.pop_front(); // 1, trigger
  160. EXPECT_EQ (true, flag);
  161. flag = false;
  162. ee.pop_front(); // 0, no-trigger cleared
  163. EXPECT_EQ (false, flag);
  164. // size_match::LT (size()< 2)
  165. flag = false;
  166. ee.clear();
  167. ee.push_back(1); // 1
  168. ee.push_back(2); // 2
  169. ee.push_back(3); // 3
  170. ee.set_trigger(Edeque::size_match::LT, 2, [&](){ flag = true; });
  171. ee.pop_front(); // 2
  172. EXPECT_EQ (false, flag);
  173. ee.pop_front(); // 1, trigger
  174. EXPECT_EQ (true, flag);
  175. flag = false;
  176. ee.pop_front(); // 0, no-trigger cleared
  177. EXPECT_EQ (false, flag);
  178. // size_match::EQ (size()== 2)
  179. flag = false;
  180. ee.clear();
  181. ee.set_trigger(Edeque::size_match::EQ, 2, [&](){ flag = true; });
  182. ee.push_back(1); // 1
  183. EXPECT_EQ (false, flag);
  184. ee.push_back(2); // 2, trigger
  185. EXPECT_EQ (true, flag);
  186. flag = false;
  187. ee.push_back(3); // 3
  188. ee.pop_front(); // 2, no-trigger cleared
  189. EXPECT_EQ (false, flag);
  190. // size_match::NE (size()!= 0)
  191. flag = false;
  192. ee.clear();
  193. ee.set_trigger(Edeque::size_match::NE, 0, [&](){ flag = true; });
  194. EXPECT_EQ (false, flag);
  195. ee.push_back(1); // 1, trigger
  196. EXPECT_EQ (true, flag);
  197. flag = false;
  198. ee.push_back(2); // 2, no-trigger
  199. EXPECT_EQ (false, flag);
  200. }
  201. TEST (Tedeque, data_triggers) {
  202. using Edeque = edeque<int, 8>;
  203. bool flag{};
  204. // data_match::MATCH_PUSH (item == 42)
  205. Edeque ee(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  206. flag = false;
  207. ee.push_back(7); // 7
  208. EXPECT_EQ (false, flag);
  209. ee.push_back(42); // push:42, trigger
  210. EXPECT_EQ (true, flag);
  211. flag = false;
  212. ee.pop_back(); // pop:42, no-trigger
  213. EXPECT_EQ (false, flag);
  214. ee.push_back(42); // push:42, re-trigger
  215. EXPECT_EQ (true, flag);
  216. // data_match::MATCH_POP (item == 42)
  217. flag = false;
  218. ee.clear_trigger();
  219. ee.set_trigger(Edeque::data_match::MATCH_POP, 42, [&](){ flag = true; });
  220. ee.push_back(7); // 7
  221. EXPECT_EQ (false, flag);
  222. ee.push_back(42); // push:42, no-trigger
  223. EXPECT_EQ (false, flag);
  224. ee.pop_back(); // pop:42, trigger
  225. EXPECT_EQ (true, flag);
  226. // data_match::MISMATCH_PUSH (item != 42)
  227. flag = false;
  228. ee.clear();
  229. ee.clear_trigger();
  230. ee.push_back(7); // 7
  231. ee.set_trigger(Edeque::data_match::MISMATCH_PUSH, 42, [&](){ flag = true; });
  232. EXPECT_EQ (false, flag); // no spurious triggers
  233. ee.push_back(42); // 42, no-trigger
  234. EXPECT_EQ (false, flag);
  235. ee.push_back(0); // 0, trigger
  236. EXPECT_EQ (true, flag);
  237. flag = false;
  238. ee.push_back(1); // 1, re-trigger
  239. EXPECT_EQ (true, flag);
  240. // data_match::MISMATCH_POP (item != 42)
  241. flag = false;
  242. ee.clear();
  243. ee.clear_trigger();
  244. ee.push_back(7); // ->7
  245. ee.pop_back(); // <-7
  246. ee.set_trigger(Edeque::data_match::MISMATCH_POP, 42, [&](){ flag = true; });
  247. EXPECT_EQ (false, flag); // no spurious triggers
  248. ee.push_back(42); // ->42, no-trigger
  249. EXPECT_EQ (false, flag);
  250. ee.push_back(0); // ->0, no-trigger
  251. EXPECT_EQ (false, flag);
  252. ee.pop_back(); // pop:0, trigger
  253. EXPECT_EQ (true, flag);
  254. flag = false;
  255. ee.push_back(0);
  256. ee.pop_back(); // pop:0, re-trigger
  257. EXPECT_EQ (true, flag);
  258. }
  259. // atomic
  260. TEST (Tedeque, construct_atomic) {
  261. using Edeque = edeque<int, 8, true>;
  262. struct T { int a,b; };
  263. int local{};
  264. Edeque e1(Edeque::size_match::GE, 3, [](){
  265. ++global_flag;
  266. });
  267. Edeque e2(Edeque::size_match::GE, 3, [&](){
  268. ++local;
  269. });
  270. Edeque e3(Edeque::size_match::EQ, 7, vfun);
  271. edeque<T, 8> e4(edeque<T, 8>::size_match::EQ, 2, vfoo{});
  272. edeque<int, 8, true> q1;
  273. edeque<int, 8, true> q2(edeque<int, 8, true>::size_match::DISABLED, 0, nullptr);
  274. EXPECT_EQ (8UL, e1.capacity());
  275. EXPECT_EQ (8UL, e2.capacity());
  276. EXPECT_EQ (8UL, e3.capacity());
  277. EXPECT_EQ (8UL, e4.capacity());
  278. EXPECT_EQ (8UL, q1.capacity());
  279. EXPECT_EQ (8UL, q2.capacity());
  280. }
  281. TEST (Tedeque, base_class_atomic) {
  282. using Edeque = edeque<int, 8, true>;
  283. Edeque e1(Edeque::size_match::GE, 3, [](){
  284. ++global_flag;
  285. });
  286. // Access of base class functionality
  287. EXPECT_EQ (8UL, e1.capacity());
  288. EXPECT_EQ (0UL, e1.size());
  289. EXPECT_EQ (true, e1.empty());
  290. EXPECT_EQ (false, e1.full());
  291. e1.push_back(7);
  292. EXPECT_EQ (7, e1.front());
  293. EXPECT_EQ (7, e1.back());
  294. EXPECT_EQ (7, e1.pop_front());
  295. e1.push_front(42);
  296. EXPECT_EQ (42, e1.front());
  297. EXPECT_EQ (42, e1.back());
  298. EXPECT_EQ (42, e1.pop_back());
  299. e1.push_back(1);
  300. e1.push_back(2);
  301. e1.push_back(3);
  302. int check_it=1;
  303. for (auto it = e1.begin() ; it != e1.end() ; ++it)
  304. EXPECT_EQ(*it, check_it++);
  305. EXPECT_EQ(4, check_it); // run through all
  306. }
  307. TEST (Tedeque, set_clear_check_trigger_atomic) {
  308. using Edeque = edeque<int, 8, true>;
  309. bool flag{};
  310. Edeque e1(Edeque::size_match::GE, 1, [&](){ flag = true; });
  311. flag = false;
  312. e1.clear_trigger();
  313. EXPECT_EQ (false, flag);
  314. e1.push_back(1); // 1, no-trigger cleared
  315. EXPECT_EQ (false, flag);
  316. flag = false;
  317. e1.clear();
  318. e1.clear_trigger();
  319. EXPECT_EQ (false, flag); // no spurious triggers
  320. e1.push_back(1); // 1
  321. e1.push_back(2); // 2
  322. e1.set_trigger(Edeque::size_match::GE, 1, [&](){ flag = true; });
  323. EXPECT_EQ (false, flag); // no spurious triggers
  324. e1.check_trigger(); // manual trigger
  325. EXPECT_EQ (true, flag);
  326. flag = false;
  327. e1.check_trigger(); // manual trigger attempt
  328. EXPECT_EQ (false, flag); // [SIZE triggers are auto clear]
  329. Edeque e2(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  330. flag = false;
  331. e2.clear_trigger();
  332. EXPECT_EQ (false, flag);
  333. e2.push_back(42); // push 42, no-trigger cleared
  334. EXPECT_EQ (false, flag);
  335. e2.set_trigger(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  336. EXPECT_EQ (false, flag); // no spurious triggers
  337. e2.push_back(42); // push 42, trigger
  338. EXPECT_EQ (true, flag);
  339. flag = false;
  340. e2.push_back(42); // push 42, re-trigger [DATA re-triggers]
  341. EXPECT_EQ (true, flag);
  342. }
  343. TEST (Tedeque, size_triggers_atomic) {
  344. using Edeque = edeque<int, 8, true>;
  345. bool flag{};
  346. // size_match::GE (size()>= 2)
  347. Edeque ee(Edeque::size_match::GE, 2, [&](){ flag = true; });
  348. flag = false;
  349. ee.clear();
  350. ee.push_back(1); // 1
  351. EXPECT_EQ (false, flag);
  352. ee.push_back(2); // 2, trigger
  353. EXPECT_EQ (true, flag);
  354. flag = false;
  355. ee.push_back(3); // 3, no-trigger cleared
  356. EXPECT_EQ (false, flag);
  357. // size_match::GT (size()> 1)
  358. flag = false;
  359. ee.clear();
  360. ee.set_trigger(Edeque::size_match::GT, 1, [&](){ flag = true; });
  361. ee.push_back(1); // 1
  362. EXPECT_EQ (false, flag);
  363. ee.push_back(2); // 2, trigger
  364. EXPECT_EQ (true, flag);
  365. flag = false;
  366. ee.push_back(3); // 3, no-trigger cleared
  367. EXPECT_EQ (false, flag);
  368. // size_match::LE (size()<= 1)
  369. flag = false;
  370. ee.clear();
  371. ee.push_back(1); // 1
  372. ee.push_back(2); // 2
  373. ee.push_back(3); // 3
  374. ee.set_trigger(Edeque::size_match::LE, 1, [&](){ flag = true; });
  375. ee.pop_front(); // 2
  376. EXPECT_EQ (false, flag);
  377. ee.pop_front(); // 1, trigger
  378. EXPECT_EQ (true, flag);
  379. flag = false;
  380. ee.pop_front(); // 0, no-trigger cleared
  381. EXPECT_EQ (false, flag);
  382. // size_match::LT (size()< 2)
  383. flag = false;
  384. ee.clear();
  385. ee.push_back(1); // 1
  386. ee.push_back(2); // 2
  387. ee.push_back(3); // 3
  388. ee.set_trigger(Edeque::size_match::LT, 2, [&](){ flag = true; });
  389. ee.pop_front(); // 2
  390. EXPECT_EQ (false, flag);
  391. ee.pop_front(); // 1, trigger
  392. EXPECT_EQ (true, flag);
  393. flag = false;
  394. ee.pop_front(); // 0, no-trigger cleared
  395. EXPECT_EQ (false, flag);
  396. // size_match::EQ (size()== 2)
  397. flag = false;
  398. ee.clear();
  399. ee.set_trigger(Edeque::size_match::EQ, 2, [&](){ flag = true; });
  400. ee.push_back(1); // 1
  401. EXPECT_EQ (false, flag);
  402. ee.push_back(2); // 2, trigger
  403. EXPECT_EQ (true, flag);
  404. flag = false;
  405. ee.push_back(3); // 3
  406. ee.pop_front(); // 2, no-trigger cleared
  407. EXPECT_EQ (false, flag);
  408. // size_match::NE (size()!= 0)
  409. flag = false;
  410. ee.clear();
  411. ee.set_trigger(Edeque::size_match::NE, 0, [&](){ flag = true; });
  412. EXPECT_EQ (false, flag);
  413. ee.push_back(1); // 1, trigger
  414. EXPECT_EQ (true, flag);
  415. flag = false;
  416. ee.push_back(2); // 2, no-trigger
  417. EXPECT_EQ (false, flag);
  418. }
  419. TEST (Tedeque, data_triggers_atomic) {
  420. using Edeque = edeque<int, 8, true>;
  421. bool flag{};
  422. // data_match::MATCH_PUSH (item == 42)
  423. Edeque ee(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; });
  424. flag = false;
  425. ee.push_back(7); // 7
  426. EXPECT_EQ (false, flag);
  427. ee.push_back(42); // push:42, trigger
  428. EXPECT_EQ (true, flag);
  429. flag = false;
  430. ee.pop_back(); // pop:42, no-trigger
  431. EXPECT_EQ (false, flag);
  432. ee.push_back(42); // push:42, re-trigger
  433. EXPECT_EQ (true, flag);
  434. // data_match::MATCH_POP (item == 42)
  435. flag = false;
  436. ee.clear_trigger();
  437. ee.set_trigger(Edeque::data_match::MATCH_POP, 42, [&](){ flag = true; });
  438. ee.push_back(7); // 7
  439. EXPECT_EQ (false, flag);
  440. ee.push_back(42); // push:42, no-trigger
  441. EXPECT_EQ (false, flag);
  442. ee.pop_back(); // pop:42, trigger
  443. EXPECT_EQ (true, flag);
  444. // data_match::MISMATCH_PUSH (item != 42)
  445. flag = false;
  446. ee.clear();
  447. ee.clear_trigger();
  448. ee.push_back(7); // 7
  449. ee.set_trigger(Edeque::data_match::MISMATCH_PUSH, 42, [&](){ flag = true; });
  450. EXPECT_EQ (false, flag); // no spurious triggers
  451. ee.push_back(42); // 42, no-trigger
  452. EXPECT_EQ (false, flag);
  453. ee.push_back(0); // 0, trigger
  454. EXPECT_EQ (true, flag);
  455. flag = false;
  456. ee.push_back(1); // 1, re-trigger
  457. EXPECT_EQ (true, flag);
  458. // data_match::MISMATCH_POP (item != 42)
  459. flag = false;
  460. ee.clear();
  461. ee.clear_trigger();
  462. ee.push_back(7); // ->7
  463. ee.pop_back(); // <-7
  464. ee.set_trigger(Edeque::data_match::MISMATCH_POP, 42, [&](){ flag = true; });
  465. EXPECT_EQ (false, flag); // no spurious triggers
  466. ee.push_back(42); // ->42, no-trigger
  467. EXPECT_EQ (false, flag);
  468. ee.push_back(0); // ->0, no-trigger
  469. EXPECT_EQ (false, flag);
  470. ee.pop_back(); // pop:0, trigger
  471. EXPECT_EQ (true, flag);
  472. flag = false;
  473. ee.push_back(0);
  474. ee.pop_back(); // pop:0, re-trigger
  475. EXPECT_EQ (true, flag);
  476. }
  477. }