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.
 
 
 

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