A C++ toolbox repo until the pair uTL/dTL arives
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

414 lines
12 KiB

  1. /*!
  2. * \file deque.cpp
  3. * \brief
  4. * Unit tests for deque
  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 <cont/deque.h>
  32. #include <cont/span.h>
  33. #include <gtest/gtest.h>
  34. #include <array>
  35. #include <type_traits>
  36. namespace Tdeque {
  37. using namespace tbx;
  38. template <typename>
  39. struct is_span : std::false_type {};
  40. template <typename T, std::size_t S>
  41. struct is_span<tbx::span<T, S>> : std::true_type {};
  42. template <typename>
  43. struct is_std_array : std::false_type {};
  44. template <typename T, std::size_t N>
  45. struct is_std_array<std::array<T, N>> : std::true_type {};
  46. template <typename, typename = void>
  47. struct has_size_and_data : std::false_type {};
  48. template <typename T>
  49. struct has_size_and_data<T, std::void_t<decltype(std::declval<T>().size()),
  50. decltype(std::declval<T>().data())>>
  51. : std::true_type {};
  52. // Concept
  53. TEST(Tdeque, concept) {
  54. using deque_t = deque<int, 8>;
  55. EXPECT_EQ (true, !is_span<deque_t>::value);
  56. EXPECT_EQ (true, !is_std_array<deque_t>::value);
  57. EXPECT_EQ (true, !std::is_array<deque_t>::value);
  58. EXPECT_EQ (true, has_size_and_data<deque_t>::value);
  59. }
  60. // Test construction
  61. TEST(Tdeque, contruct) {
  62. deque<int, 8> q1;
  63. deque<int, 8> q2{1, 2, 3, 4, 5, 6, 7, 8};
  64. deque<int, 8> q3{1, 2, 3, 4, 5};
  65. EXPECT_EQ (8UL, q1.capacity());
  66. EXPECT_EQ (0UL, q1.size());
  67. EXPECT_EQ (8UL, q2.capacity());
  68. EXPECT_EQ (8UL, q2.size());
  69. EXPECT_EQ (8UL, q3.capacity());
  70. EXPECT_EQ (5UL, q3.size());
  71. }
  72. // simple push-pop functionality
  73. TEST(Tdeque, push_pop) {
  74. deque<int, 8> q1;
  75. deque<int, 8> q2{1, 2, 3, 4, 5, 6, 7, 8};
  76. q1.push_front(1);
  77. q1.push_front(2);
  78. EXPECT_EQ (1, q1.pop_back());
  79. EXPECT_EQ (2, q1.pop_back());
  80. q1.push_back(1);
  81. q1.push_back(2);
  82. EXPECT_EQ (1, q1.pop_front());
  83. EXPECT_EQ (2, q1.pop_front());
  84. q1.push_front(2);
  85. q1.push_back(3);
  86. q1.push_front(1);
  87. q1.push_back(4);
  88. for (int i=1 ; i<= 4 ; ++i)
  89. EXPECT_EQ ((int)i, q1.pop_front());
  90. }
  91. // front-back
  92. TEST(Tdeque, front_back) {
  93. deque<int, 8> q1;
  94. deque<int, 8> q2{1, 2, 3, 4, 5, 6, 7, 8};
  95. q1.push_front(2);
  96. q1.push_front(1);
  97. q1.push_back(3);
  98. q1.push_back(4);
  99. EXPECT_EQ (1, q1.front());
  100. EXPECT_EQ (4, q1.back());
  101. EXPECT_EQ (1, q2.front());
  102. EXPECT_EQ (8, q2.back());
  103. }
  104. // capacity
  105. TEST(Tdeque, capacity) {
  106. deque<int, 8> q1;
  107. deque<int, 8> q2{1, 2, 3, 4, 5, 6, 7, 8};
  108. q1.push_back(1);
  109. q1.clear();
  110. EXPECT_EQ (true, q1.empty());
  111. EXPECT_EQ (true, q2.full());
  112. EXPECT_EQ (8UL, q1.capacity());
  113. EXPECT_EQ (8UL, q2.capacity());
  114. EXPECT_EQ (0UL, q1.size());
  115. EXPECT_EQ (8UL, q2.size());
  116. q1.push_back(2);
  117. EXPECT_EQ (1UL, q1.size());
  118. q1.push_front(1);
  119. EXPECT_EQ (2UL, q1.size());
  120. q1.pop_back();
  121. EXPECT_EQ (1UL, q1.size());
  122. q1.pop_front();
  123. EXPECT_EQ (0UL, q1.size());
  124. }
  125. // push-pop limits
  126. TEST (Tdeque, push_pop_limits) {
  127. deque<int, 8> q1;
  128. deque<int, 8> q2{1, 2, 3, 4, 5, 6, 7, 8};
  129. EXPECT_EQ (int{}, q1.pop_back());
  130. EXPECT_EQ (0UL, q1.size());
  131. EXPECT_EQ (true, q1.empty());
  132. EXPECT_EQ (false, q1.full());
  133. EXPECT_EQ (int{}, q1.pop_front());
  134. EXPECT_EQ (0UL, q1.size());
  135. EXPECT_EQ (true, q1.empty());
  136. EXPECT_EQ (false, q1.full());
  137. q2.push_front(0);
  138. EXPECT_EQ (1, q2.front());
  139. EXPECT_EQ (8, q2.back());
  140. EXPECT_EQ (8UL, q2.size());
  141. EXPECT_EQ (false, q2.empty());
  142. EXPECT_EQ (true, q2.full());
  143. q2.push_back(9);
  144. EXPECT_EQ (1, q2.front());
  145. EXPECT_EQ (8, q2.back());
  146. EXPECT_EQ (8UL, q2.size());
  147. EXPECT_EQ (false, q2.empty());
  148. EXPECT_EQ (true, q2.full());
  149. }
  150. // iterators
  151. TEST (Tdeque, iterators) {
  152. deque<int, 8> q1{1, 2, 3, 4, 5, 6, 7, 8};
  153. int check_it=1;
  154. EXPECT_EQ (q1.begin().base(), q1.end().base());
  155. EXPECT_NE (q1.begin().iter(), q1.end().iter());
  156. EXPECT_EQ (1, *q1.begin());
  157. EXPECT_EQ (true, (q1.begin() == ++q1.end())); // loop edge iterators
  158. for (auto it = q1.begin() ; it != q1.end() ; ++it)
  159. EXPECT_EQ(*it, check_it++);
  160. EXPECT_EQ(9, check_it); // run through all
  161. EXPECT_EQ (1, q1.front()); // queue stays intact
  162. EXPECT_EQ (8, q1.back());
  163. EXPECT_EQ (8UL, q1.size());
  164. EXPECT_EQ (false, q1.empty());
  165. EXPECT_EQ (true, q1.full());
  166. q1.pop_front();
  167. q1.pop_back();
  168. check_it=2;
  169. for (auto& it : q1)
  170. EXPECT_EQ(it, check_it++);
  171. EXPECT_EQ(8, check_it); // run through all
  172. EXPECT_EQ (2, q1.front()); // queue stays intact
  173. EXPECT_EQ (7, q1.back());
  174. EXPECT_EQ (6UL, q1.size());
  175. EXPECT_EQ (false, q1.empty());
  176. EXPECT_EQ (false, q1.full());
  177. deque<int, 8> q2;
  178. q2.push_front(2);
  179. q2.push_front(1);
  180. q2.push_back(3);
  181. q2.push_back(4);
  182. q2.push_back(5);
  183. check_it =1;
  184. for (auto& it : q2)
  185. EXPECT_EQ(it, check_it++);
  186. EXPECT_EQ(6, check_it); // run through all
  187. }
  188. TEST (Tdeque, range) {
  189. deque<int, 8> q1{1, 2, 3, 4, 5, 6, 7, 8};
  190. int check_it=1;
  191. for (auto& it : q1.contents())
  192. EXPECT_EQ(it, check_it++);
  193. EXPECT_EQ(9, check_it); // run through all
  194. }
  195. // Concept
  196. TEST(Tdeque, concept_atomic) {
  197. using deque_t = deque<int, 8, true>;
  198. EXPECT_EQ (true, !is_span<deque_t>::value);
  199. EXPECT_EQ (true, !is_std_array<deque_t>::value);
  200. EXPECT_EQ (true, !std::is_array<deque_t>::value);
  201. EXPECT_EQ (true, has_size_and_data<deque_t>::value);
  202. }
  203. // Test construction
  204. TEST(Tdeque, contruct_atomic) {
  205. deque<int, 8, true> q1;
  206. deque<int, 8, true> q2{1, 2, 3, 4, 5, 6, 7, 8};
  207. deque<int, 8, true> q3{1, 2, 3, 4, 5};
  208. EXPECT_EQ (8UL, q1.capacity());
  209. EXPECT_EQ (0UL, q1.size());
  210. EXPECT_EQ (8UL, q2.capacity());
  211. EXPECT_EQ (8UL, q2.size());
  212. EXPECT_EQ (8UL, q3.capacity());
  213. EXPECT_EQ (5UL, q3.size());
  214. }
  215. // simple push-pop functionality
  216. TEST(Tdeque, push_pop_atomic) {
  217. deque<int, 8, true> q1;
  218. deque<int, 8, true> q2{1, 2, 3, 4, 5, 6, 7, 8};
  219. q1.push_front(1);
  220. q1.push_front(2);
  221. EXPECT_EQ (1, q1.pop_back());
  222. EXPECT_EQ (2, q1.pop_back());
  223. q1.push_back(1);
  224. q1.push_back(2);
  225. EXPECT_EQ (1, q1.pop_front());
  226. EXPECT_EQ (2, q1.pop_front());
  227. q1.push_front(2);
  228. q1.push_back(3);
  229. q1.push_front(1);
  230. q1.push_back(4);
  231. for (int i=1 ; i<= 4 ; ++i)
  232. EXPECT_EQ ((int)i, q1.pop_front());
  233. }
  234. // front-back
  235. TEST(Tdeque, front_back_atomic) {
  236. deque<int, 8, true> q1;
  237. deque<int, 8, true> q2{1, 2, 3, 4, 5, 6, 7, 8};
  238. q1.push_front(2);
  239. q1.push_front(1);
  240. q1.push_back(3);
  241. q1.push_back(4);
  242. EXPECT_EQ (1, q1.front());
  243. EXPECT_EQ (4, q1.back());
  244. EXPECT_EQ (1, q2.front());
  245. EXPECT_EQ (8, q2.back());
  246. }
  247. // capacity
  248. TEST(Tdeque, capacity_atomic) {
  249. deque<int, 8, true> q1;
  250. deque<int, 8, true> q2{1, 2, 3, 4, 5, 6, 7, 8};
  251. q1.push_back(1);
  252. q1.clear();
  253. EXPECT_EQ (true, q1.empty());
  254. EXPECT_EQ (true, q2.full());
  255. EXPECT_EQ (8UL, q1.capacity());
  256. EXPECT_EQ (8UL, q2.capacity());
  257. EXPECT_EQ (0UL, q1.size());
  258. EXPECT_EQ (8UL, q2.size());
  259. q1.push_back(2);
  260. EXPECT_EQ (1UL, q1.size());
  261. q1.push_front(1);
  262. EXPECT_EQ (2UL, q1.size());
  263. q1.pop_back();
  264. EXPECT_EQ (1UL, q1.size());
  265. q1.pop_front();
  266. EXPECT_EQ (0UL, q1.size());
  267. }
  268. // push-pop limits
  269. TEST (Tdeque, push_pop_limits_atomic) {
  270. deque<int, 8, true> q1;
  271. deque<int, 8, true> q2{1, 2, 3, 4, 5, 6, 7, 8};
  272. EXPECT_EQ (int{}, q1.pop_back());
  273. EXPECT_EQ (0UL, q1.size());
  274. EXPECT_EQ (true, q1.empty());
  275. EXPECT_EQ (false, q1.full());
  276. EXPECT_EQ (int{}, q1.pop_front());
  277. EXPECT_EQ (0UL, q1.size());
  278. EXPECT_EQ (true, q1.empty());
  279. EXPECT_EQ (false, q1.full());
  280. q2.push_front(0);
  281. EXPECT_EQ (1, q2.front());
  282. EXPECT_EQ (8, q2.back());
  283. EXPECT_EQ (8UL, q2.size());
  284. EXPECT_EQ (false, q2.empty());
  285. EXPECT_EQ (true, q2.full());
  286. q2.push_back(9);
  287. EXPECT_EQ (1, q2.front());
  288. EXPECT_EQ (8, q2.back());
  289. EXPECT_EQ (8UL, q2.size());
  290. EXPECT_EQ (false, q2.empty());
  291. EXPECT_EQ (true, q2.full());
  292. }
  293. // iterators
  294. TEST (Tdeque, iterators_atomic) {
  295. deque<int, 8, true> q1{1, 2, 3, 4, 5, 6, 7, 8};
  296. int check_it=1;
  297. EXPECT_EQ (q1.begin().base(), q1.end().base());
  298. EXPECT_NE (q1.begin().iter(), q1.end().iter());
  299. EXPECT_EQ (1, *q1.begin());
  300. EXPECT_EQ (true, (q1.begin() == ++q1.end())); // loop edge iterators
  301. for (auto it = q1.begin() ; it != q1.end() ; ++it)
  302. EXPECT_EQ(*it, check_it++);
  303. EXPECT_EQ(9, check_it); // run through all
  304. EXPECT_EQ (1, q1.front()); // queue stays intact
  305. EXPECT_EQ (8, q1.back());
  306. EXPECT_EQ (8UL, q1.size());
  307. EXPECT_EQ (false, q1.empty());
  308. EXPECT_EQ (true, q1.full());
  309. q1.pop_front();
  310. q1.pop_back();
  311. check_it=2;
  312. for (auto& it : q1)
  313. EXPECT_EQ(it, check_it++);
  314. EXPECT_EQ(8, check_it); // run through all
  315. EXPECT_EQ (2, q1.front()); // queue stays intact
  316. EXPECT_EQ (7, q1.back());
  317. EXPECT_EQ (6UL, q1.size());
  318. EXPECT_EQ (false, q1.empty());
  319. EXPECT_EQ (false, q1.full());
  320. deque<int, 8, true> q2;
  321. q2.push_front(2);
  322. q2.push_front(1);
  323. q2.push_back(3);
  324. q2.push_back(4);
  325. q2.push_back(5);
  326. check_it =1;
  327. for (auto& it : q2)
  328. EXPECT_EQ(it, check_it++);
  329. EXPECT_EQ(6, check_it); // run through all
  330. }
  331. TEST (Tdeque, range_atomic) {
  332. deque<int, 8, true> q1{1, 2, 3, 4, 5, 6, 7, 8};
  333. int check_it=1;
  334. for (auto& it : q1.contents())
  335. EXPECT_EQ(it, check_it++);
  336. EXPECT_EQ(9, check_it); // run through all
  337. }
  338. }