unique.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. //
  12. // Copyright 2005 - 2007 Adobe Systems Incorporated
  13. // Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
  14. // or a copy at http://stlab.adobe.com/licenses.html)
  15. //===----------------------------------------------------------------------===//
  16. //
  17. // The LLVM Compiler Infrastructure
  18. //
  19. // This file is dual licensed under the MIT and the University of Illinois Open
  20. // Source Licenses. See LICENSE.TXT for details.
  21. //
  22. //===----------------------------------------------------------------------===//
  23. // Implementation based on the code in libc++
  24. // http://http://libcxx.llvm.org/
  25. #include <vector>
  26. #include <range/v3/core.hpp>
  27. #include <range/v3/algorithm/unique.hpp>
  28. #include "../simple_test.hpp"
  29. #include "../test_utils.hpp"
  30. #include "../test_iterators.hpp"
  31. /// Calls the iterator interface of the algorithm
  32. template<class Iter>
  33. struct iter_call
  34. {
  35. using begin_t = Iter;
  36. using sentinel_t = typename sentinel_type<Iter>::type;
  37. template<class B, class E, class... Args>
  38. auto operator()(B &&It, E &&e, Args &&... args) const
  39. -> decltype(ranges::unique(begin_t{It}, sentinel_t{e}, std::forward<Args>(args)...))
  40. {
  41. return ranges::unique(begin_t{It}, sentinel_t{e}, std::forward<Args>(args)...);
  42. }
  43. };
  44. /// Calls the range interface of the algorithm
  45. template<class Iter>
  46. struct range_call
  47. {
  48. using begin_t = Iter;
  49. using sentinel_t = typename sentinel_type<Iter>::type;
  50. template<class B, class E, class... Args>
  51. auto operator()(B &&It, E &&e, Args &&... args) const
  52. -> ranges::iterator_t<decltype(ranges::make_subrange(begin_t{It}, sentinel_t{e}))>
  53. {
  54. auto rng = ranges::make_subrange(begin_t{It}, sentinel_t{e});
  55. return ranges::unique(rng, std::forward<Args>(args)...);
  56. }
  57. };
  58. template<class T> using identity_t = T;
  59. template<class It, template<class> class FunT>
  60. void test()
  61. {
  62. using Fun = FunT<It>;
  63. {
  64. int a[] = {0};
  65. const unsigned sa = sizeof(a) / sizeof(a[0]);
  66. auto r = Fun{}(a, a + sa);
  67. CHECK(r == It(a + sa));
  68. CHECK(a[0] == 0);
  69. }
  70. {
  71. int a[] = {0, 1};
  72. const unsigned sa = sizeof(a) / sizeof(a[0]);
  73. auto r = Fun{}(a, a + sa);
  74. CHECK(r == It(a + sa));
  75. CHECK(a[0] == 0);
  76. CHECK(a[1] == 1);
  77. }
  78. {
  79. int a[] = {0, 0};
  80. const unsigned sa = sizeof(a) / sizeof(a[0]);
  81. auto r = Fun{}(a, a + sa);
  82. CHECK(r == It(a + 1));
  83. CHECK(a[0] == 0);
  84. }
  85. {
  86. int a[] = {0, 0, 1};
  87. const unsigned sa = sizeof(a) / sizeof(a[0]);
  88. auto r = Fun{}(a, a + sa);
  89. CHECK(r == It(a + 2));
  90. CHECK(a[0] == 0);
  91. CHECK(a[1] == 1);
  92. }
  93. {
  94. int a[] = {0, 0, 1, 0};
  95. const unsigned sa = sizeof(a) / sizeof(a[0]);
  96. auto r = Fun{}(a, a + sa);
  97. CHECK(r == It(a + 3));
  98. CHECK(a[0] == 0);
  99. CHECK(a[1] == 1);
  100. CHECK(a[2] == 0);
  101. }
  102. {
  103. int a[] = {0, 0, 1, 1};
  104. const unsigned sa = sizeof(a) / sizeof(a[0]);
  105. auto r = Fun{}(a, a + sa);
  106. CHECK(r == It(a + 2));
  107. CHECK(a[0] == 0);
  108. CHECK(a[1] == 1);
  109. }
  110. {
  111. int a[] = {0, 1, 1};
  112. const unsigned sa = sizeof(a) / sizeof(a[0]);
  113. auto r = Fun{}(a, a + sa);
  114. CHECK(r == It(a + 2));
  115. CHECK(a[0] == 0);
  116. CHECK(a[1] == 1);
  117. }
  118. {
  119. int a[] = {0, 1, 1, 1, 2, 2, 2};
  120. const unsigned sa = sizeof(a) / sizeof(a[0]);
  121. auto r = Fun{}(a, a + sa);
  122. CHECK(r == It(a + 3));
  123. CHECK(a[0] == 0);
  124. CHECK(a[1] == 1);
  125. CHECK(a[2] == 2);
  126. }
  127. }
  128. constexpr bool test_constexpr()
  129. {
  130. using namespace ranges;
  131. int a[] = {0, 1, 1, 1, 2, 2, 2};
  132. const unsigned sa = sizeof(a) / sizeof(a[0]);
  133. auto r = unique(a, a + sa);
  134. STATIC_CHECK_RETURN(r == a + 3);
  135. STATIC_CHECK_RETURN(a[0] == 0);
  136. STATIC_CHECK_RETURN(a[1] == 1);
  137. STATIC_CHECK_RETURN(a[2] == 2);
  138. return true;
  139. }
  140. int main()
  141. {
  142. test<ForwardIterator<int*>, iter_call>();
  143. test<BidirectionalIterator<int*>, iter_call>();
  144. test<RandomAccessIterator<int*>, iter_call>();
  145. test<int*, iter_call>();
  146. test<ForwardIterator<int*>, range_call>();
  147. test<BidirectionalIterator<int*>, range_call>();
  148. test<RandomAccessIterator<int*>, range_call>();
  149. test<int*, range_call>();
  150. // Test rvalue range
  151. {
  152. int a[] = {0, 1, 1, 1, 2, 2, 2};
  153. auto r = ranges::unique(ranges::views::all(a));
  154. CHECK(r == a + 3);
  155. CHECK(a[0] == 0);
  156. CHECK(a[1] == 1);
  157. CHECK(a[2] == 2);
  158. }
  159. {
  160. int a[] = {0, 1, 1, 1, 2, 2, 2};
  161. auto r = ranges::unique(std::move(a));
  162. #ifndef RANGES_WORKAROUND_MSVC_573728
  163. CHECK(::is_dangling(r));
  164. #endif // RANGES_WORKAROUND_MSVC_573728
  165. CHECK(a[0] == 0);
  166. CHECK(a[1] == 1);
  167. CHECK(a[2] == 2);
  168. }
  169. {
  170. std::vector<int> a{0, 1, 1, 1, 2, 2, 2};
  171. auto r = ranges::unique(std::move(a));
  172. CHECK(::is_dangling(r));
  173. CHECK(a[0] == 0);
  174. CHECK(a[1] == 1);
  175. CHECK(a[2] == 2);
  176. }
  177. {
  178. STATIC_CHECK(test_constexpr());
  179. }
  180. return ::test_result();
  181. }