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.

ring_iterator.cpp 8.4 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*!
  2. * \file ring_iterator.cpp
  3. * \brief
  4. * Unit tests for ring_iterator
  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 <core/ring_iterator.h>
  32. #include <gtest/gtest.h>
  33. #include <array>
  34. #include <type_traits>
  35. namespace Tring_iterator {
  36. using namespace tbx;
  37. // Test construction
  38. TEST(Tring_iterator, construct) {
  39. int A[10];
  40. //default constructor
  41. ring_iterator<int*, 10> i1;
  42. EXPECT_EQ(nullptr, i1.base());
  43. EXPECT_EQ(nullptr, i1.iter());
  44. EXPECT_EQ(10UL, i1.size());
  45. // implementation specific (you can remove it freely)
  46. EXPECT_EQ(2*sizeof(int*), sizeof(i1));
  47. // basic
  48. ring_iterator<int*, 10> i2(A);
  49. EXPECT_EQ(A, i2.base());
  50. EXPECT_EQ(A, i2.iter());
  51. EXPECT_EQ(10UL, i2.size());
  52. // basic from assignment
  53. ring_iterator<int*, 10> i3 = A;
  54. EXPECT_EQ(A, i3.base());
  55. EXPECT_EQ(A, i3.iter());
  56. EXPECT_EQ(10UL, i3.size());
  57. // basic with offset
  58. ring_iterator<int*, 10> i4(A, 5);
  59. EXPECT_EQ(A, i4.base());
  60. EXPECT_EQ(&A[5], i4.iter());
  61. EXPECT_EQ(10UL, i4.size());
  62. // copy (Legacy iterator)
  63. auto i5 = i2;
  64. EXPECT_EQ(A, i5.base());
  65. EXPECT_EQ(A, i5.iter());
  66. EXPECT_EQ(10UL, i5.size());
  67. // arbitrary type
  68. struct TT { int a,b,c; };
  69. std::array<TT, 10> t;
  70. ring_iterator<TT*, 10> it(t.data(), 2);
  71. EXPECT_EQ(t.begin(), it.base());
  72. EXPECT_EQ(&t[2], it.iter());
  73. EXPECT_EQ(10UL, it.size());
  74. }
  75. // Legacy iterator
  76. TEST(Tring_iterator, LegacyIterator) {
  77. EXPECT_EQ(true, (std::is_same<int, typename ring_iterator<int*, 10>::value_type>::value));
  78. EXPECT_EQ(true, (std::is_same<std::ptrdiff_t, typename ring_iterator<int*, 10>::difference_type>::value));
  79. EXPECT_EQ(true, (std::is_same<int&, typename ring_iterator<int*, 10>::reference>::value));
  80. EXPECT_EQ(true, (std::is_same<int*, typename ring_iterator<int*, 10>::pointer>::value));
  81. EXPECT_EQ(true, (std::is_same<std::random_access_iterator_tag, typename ring_iterator<int*, 10>::iterator_category>::value));
  82. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  83. ring_iterator<int*, 10> i1(A);
  84. // copy constructible/assignable
  85. auto i2 = i1;
  86. EXPECT_EQ(A, i2.base());
  87. EXPECT_EQ(A, i2.iter());
  88. EXPECT_EQ(10UL, i2.size());
  89. // dereferenceable - incrementable
  90. ring_iterator<int*, 10> i3(A);
  91. EXPECT_EQ(true, (std::is_reference<decltype(*i3)>::value));
  92. EXPECT_EQ(true, (std::is_same<ring_iterator<int*, 10>&, decltype(++i3)>::value));
  93. EXPECT_EQ(true, (std::is_reference<decltype((*i3++))>::value));
  94. // more practical
  95. ring_iterator<int*, 10> i4(A);
  96. ring_iterator<int*, 10> i5(A, 9);
  97. EXPECT_EQ(A[0], *i4);
  98. EXPECT_EQ(&A[1], (++i4).iter());
  99. // check loop
  100. EXPECT_EQ(A[9], *i5);
  101. EXPECT_EQ(&A[0], (++i5).iter());
  102. }
  103. // Legacy input iterator
  104. TEST(Tring_iterator, LegacyInputIterator) {
  105. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  106. ring_iterator<int*, 10> i1(A), i2(A), i3(A, 1);
  107. struct T { int m; };
  108. T B[5] { {0}, {1}, {2}, {3}, {4}};
  109. ring_iterator<T*, 5> it(B);
  110. EXPECT_EQ (true, (std::is_same<bool, decltype(i1 == i2)>::value));
  111. EXPECT_EQ (true, (std::is_same<bool, decltype(i1 != i2)>::value));
  112. EXPECT_EQ (true, (std::is_same<int&, decltype(*i1)>::value));
  113. EXPECT_EQ (true, (std::is_same<int, decltype(it->m)>::value));
  114. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>&, decltype(++i1)>::value));
  115. EXPECT_EQ (true, (std::is_same<int&, decltype(*i1++)>::value));
  116. // more practical
  117. EXPECT_EQ (true, i1 == i2);
  118. EXPECT_EQ (true, i1 != i3);
  119. EXPECT_EQ (0, *i1);
  120. EXPECT_EQ (0, it->m);
  121. EXPECT_EQ (true, (++i1 == i3));
  122. EXPECT_EQ (1, *i1++);
  123. EXPECT_EQ (2, *i1);
  124. }
  125. // Legacy input iterator
  126. TEST(Tring_iterator, LegacyOutputIterator) {
  127. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  128. ring_iterator<int*, 10> it(A);
  129. EXPECT_EQ (true, (std::is_assignable<decltype(*it), int>::value));
  130. EXPECT_EQ (true, (std::is_assignable<decltype(*it++), int>::value));
  131. // more practical
  132. *it = 42;
  133. EXPECT_EQ (42, A[0]);
  134. *it++ = 7;
  135. EXPECT_EQ (7, A[0]);
  136. EXPECT_EQ (&A[1], it.iter());
  137. }
  138. // Legacy forward iterator
  139. TEST(Tring_iterator, LegacyForwardIterator)
  140. {
  141. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  142. ring_iterator<int*, 10> it(A);
  143. EXPECT_EQ (0, *it++);
  144. EXPECT_EQ (1, *it);
  145. }
  146. // Legacy bidirectional iterator
  147. TEST(Tring_iterator, LegacyBidirectionalIterator) {
  148. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  149. ring_iterator<int*, 10> it(A);
  150. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>&, decltype(--it)>::value));
  151. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>, decltype(it--)>::value));
  152. EXPECT_EQ (true, (std::is_same<int&, decltype(*it--)>::value));
  153. // more practical
  154. ring_iterator<int*, 10> i1(A), i2(A, 9);
  155. EXPECT_EQ (9, *i2--); // check loop also
  156. EXPECT_EQ (8, *i2);
  157. EXPECT_EQ (0, *i1--); // check loop also
  158. EXPECT_EQ (9, *i1);
  159. }
  160. // Legacy random access iterator
  161. TEST(Tring_iterator, LegacyRandomAccessIterator) {
  162. int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9};
  163. ring_iterator<int*, 10> it1(A), it2(A, 7);
  164. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>&, decltype(it1 += 7)>::value));
  165. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>, decltype(it1 + 7)>::value));
  166. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>, decltype(7 + it1)>::value));
  167. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>&, decltype(it1 -= 7)>::value));
  168. EXPECT_EQ (true, (std::is_same<ring_iterator<int*, 10>, decltype(it1 - 7)>::value));
  169. EXPECT_EQ (true, (std::is_same<std::ptrdiff_t, decltype(it1 - it2)>::value));
  170. EXPECT_EQ (true, (std::is_same<int&, decltype(it1[7])>::value));
  171. EXPECT_EQ (true, (std::is_same<bool, decltype(it1 < it2)>::value));
  172. EXPECT_EQ (true, (std::is_same<bool, decltype(it1 > it2)>::value));
  173. EXPECT_EQ (true, (std::is_same<bool, decltype(it1 <= it2)>::value));
  174. EXPECT_EQ (true, (std::is_same<bool, decltype(it1 >= it2)>::value));
  175. // more practical
  176. ring_iterator<int*, 10> i1(A), i2(A);
  177. i1 += 7;
  178. EXPECT_EQ (7, *i1);
  179. i1 -= 7;
  180. EXPECT_EQ (0, *i1);
  181. i1 += 11;
  182. EXPECT_EQ (1, *i1);
  183. i1 -= 2;
  184. EXPECT_EQ (9, *i1);
  185. EXPECT_EQ (7, *(i2+7));
  186. EXPECT_EQ (7, *(7+i2));
  187. EXPECT_EQ (1, *(i2+11));
  188. EXPECT_EQ (1, *(11+i2));
  189. EXPECT_EQ (7, *(i1-2));
  190. EXPECT_EQ (8, *(i2-2));
  191. EXPECT_EQ (9, (i1 - i2));
  192. EXPECT_EQ (1, (i2 - i1)); // loop
  193. }
  194. }