equal.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. //
  13. // The LLVM Compiler Infrastructure
  14. //
  15. // This file is dual licensed under the MIT and the University of Illinois Open
  16. // Source Licenses. See LICENSE.TXT for details.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include <range/v3/core.hpp>
  20. #include <range/v3/algorithm/equal.hpp>
  21. #include <range/v3/view/unbounded.hpp>
  22. #include "../simple_test.hpp"
  23. #include "../test_iterators.hpp"
  24. RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
  25. void test()
  26. {
  27. using namespace ranges;
  28. int ia[] = {0, 1, 2, 3, 4, 5};
  29. constexpr auto s = size(ia);
  30. int ib[s] = {0, 1, 2, 5, 4, 5};
  31. CHECK(equal(InputIterator<const int*>(ia),
  32. Sentinel<const int*>(ia+s),
  33. InputIterator<const int*>(ia)));
  34. CHECK(equal(InputIterator<const int*>(ia),
  35. Sentinel<const int*>(ia+s),
  36. InputIterator<const int*>(ia),
  37. Sentinel<const int*>(ia+s)));
  38. CHECK(equal(RandomAccessIterator<const int*>(ia),
  39. RandomAccessIterator<const int*>(ia+s),
  40. RandomAccessIterator<const int*>(ia),
  41. RandomAccessIterator<const int*>(ia + s)));
  42. CHECK(equal(RandomAccessIterator<const int*>(ia),
  43. Sentinel<const int*>(ia+s),
  44. RandomAccessIterator<const int*>(ia),
  45. Sentinel<const int*>(ia + s)));
  46. CHECK(!equal(InputIterator<const int*>(ia),
  47. Sentinel<const int*>(ia+s),
  48. InputIterator<const int*>(ib)));
  49. CHECK(!equal(InputIterator<const int*>(ia),
  50. Sentinel<const int*>(ia+s),
  51. InputIterator<const int*>(ib),
  52. Sentinel<const int*>(ib + s)));
  53. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  54. RandomAccessIterator<const int*>(ia+s),
  55. RandomAccessIterator<const int*>(ib),
  56. RandomAccessIterator<const int*>(ib+s)));
  57. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  58. Sentinel<const int*>(ia+s),
  59. RandomAccessIterator<const int*>(ib),
  60. Sentinel<const int*>(ib + s)));
  61. CHECK(!equal(InputIterator<const int*>(ia),
  62. Sentinel<const int*>(ia+s),
  63. InputIterator<const int*>(ia),
  64. Sentinel<const int*>(ia + s - 1)));
  65. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  66. RandomAccessIterator<const int*>(ia+s),
  67. RandomAccessIterator<const int*>(ia),
  68. RandomAccessIterator<const int*>(ia+s-1)));
  69. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  70. Sentinel<const int*>(ia+s),
  71. RandomAccessIterator<const int*>(ia),
  72. Sentinel<const int*>(ia + s - 1)));
  73. }
  74. void test_rng()
  75. {
  76. using namespace ranges;
  77. int ia[] = {0, 1, 2, 3, 4, 5};
  78. constexpr auto s = size(ia);
  79. int ib[s] = {0, 1, 2, 5, 4, 5};
  80. CHECK(equal(make_subrange(InputIterator<const int*>(ia),
  81. Sentinel<const int*>(ia+s)),
  82. InputIterator<const int*>(ia)));
  83. CHECK(equal(make_subrange(InputIterator<const int*>(ia),
  84. Sentinel<const int*>(ia+s)),
  85. make_subrange(InputIterator<const int*>(ia),
  86. Sentinel<const int*>(ia+s))));
  87. CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
  88. RandomAccessIterator<const int*>(ia+s)),
  89. make_subrange(RandomAccessIterator<const int*>(ia),
  90. RandomAccessIterator<const int*>(ia + s))));
  91. CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
  92. Sentinel<const int*>(ia+s)),
  93. make_subrange(RandomAccessIterator<const int*>(ia),
  94. Sentinel<const int*>(ia + s))));
  95. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  96. Sentinel<const int*>(ia+s)),
  97. InputIterator<const int*>(ib)));
  98. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  99. Sentinel<const int*>(ia+s)),
  100. make_subrange(InputIterator<const int*>(ib),
  101. Sentinel<const int*>(ib + s))));
  102. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  103. RandomAccessIterator<const int*>(ia+s)),
  104. make_subrange(RandomAccessIterator<const int*>(ib),
  105. RandomAccessIterator<const int*>(ib+s))));
  106. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  107. Sentinel<const int*>(ia+s)),
  108. make_subrange(RandomAccessIterator<const int*>(ib),
  109. Sentinel<const int*>(ib + s))));
  110. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  111. Sentinel<const int*>(ia+s)),
  112. make_subrange(InputIterator<const int*>(ia),
  113. Sentinel<const int*>(ia + s - 1))));
  114. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  115. RandomAccessIterator<const int*>(ia+s)),
  116. make_subrange(RandomAccessIterator<const int*>(ia),
  117. RandomAccessIterator<const int*>(ia+s-1))));
  118. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  119. Sentinel<const int*>(ia+s)),
  120. make_subrange(RandomAccessIterator<const int*>(ia),
  121. Sentinel<const int*>(ia + s - 1))));
  122. }
  123. int comparison_count = 0;
  124. template<typename T>
  125. bool counting_equals(const T &a, const T &b)
  126. {
  127. ++comparison_count;
  128. return a == b;
  129. }
  130. void test_pred()
  131. {
  132. using namespace ranges;
  133. int ia[] = {0, 1, 2, 3, 4, 5};
  134. constexpr auto s = size(ia);
  135. int ib[s] = {0, 1, 2, 5, 4, 5};
  136. CHECK(equal(InputIterator<const int*>(ia),
  137. Sentinel<const int*>(ia+s),
  138. InputIterator<const int*>(ia),
  139. std::equal_to<int>()));
  140. CHECK(equal(InputIterator<const int*>(ia),
  141. Sentinel<const int*>(ia+s),
  142. InputIterator<const int*>(ia),
  143. Sentinel<const int*>(ia + s),
  144. std::equal_to<int>()));
  145. CHECK(equal(RandomAccessIterator<const int*>(ia),
  146. RandomAccessIterator<const int*>(ia+s),
  147. RandomAccessIterator<const int*>(ia),
  148. RandomAccessIterator<const int*>(ia+s),
  149. std::equal_to<int>()));
  150. CHECK(equal(RandomAccessIterator<const int*>(ia),
  151. Sentinel<const int*>(ia+s),
  152. RandomAccessIterator<const int*>(ia),
  153. Sentinel<const int*>(ia + s),
  154. std::equal_to<int>()));
  155. comparison_count = 0;
  156. CHECK(!equal(InputIterator<const int*>(ia),
  157. Sentinel<const int*>(ia+s),
  158. InputIterator<const int*>(ia),
  159. Sentinel<const int*>(ia + s - 1),
  160. counting_equals<int>));
  161. CHECK(comparison_count > 0);
  162. comparison_count = 0;
  163. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  164. RandomAccessIterator<const int*>(ia+s),
  165. RandomAccessIterator<const int*>(ia),
  166. RandomAccessIterator<const int*>(ia+s-1),
  167. counting_equals<int>));
  168. CHECK(comparison_count == 0);
  169. comparison_count = 0;
  170. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  171. Sentinel<const int*>(ia+s),
  172. RandomAccessIterator<const int*>(ia),
  173. Sentinel<const int*>(ia + s - 1),
  174. counting_equals<int>));
  175. CHECK(comparison_count > 0);
  176. CHECK(!equal(InputIterator<const int*>(ia),
  177. Sentinel<const int*>(ia+s),
  178. InputIterator<const int*>(ib),
  179. std::equal_to<int>()));
  180. CHECK(!equal(InputIterator<const int*>(ia),
  181. Sentinel<const int*>(ia+s),
  182. InputIterator<const int*>(ib),
  183. Sentinel<const int*>(ib + s),
  184. std::equal_to<int>()));
  185. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  186. RandomAccessIterator<const int*>(ia+s),
  187. RandomAccessIterator<const int*>(ib),
  188. RandomAccessIterator<const int*>(ib+s),
  189. std::equal_to<int>()));
  190. CHECK(!equal(RandomAccessIterator<const int*>(ia),
  191. Sentinel<const int*>(ia+s),
  192. RandomAccessIterator<const int*>(ib),
  193. Sentinel<const int*>(ib + s),
  194. std::equal_to<int>()));
  195. }
  196. void test_rng_pred()
  197. {
  198. using namespace ranges;
  199. int ia[] = {0, 1, 2, 3, 4, 5};
  200. constexpr auto s = size(ia);
  201. int ib[s] = {0, 1, 2, 5, 4, 5};
  202. CHECK(equal(make_subrange(InputIterator<const int*>(ia),
  203. Sentinel<const int*>(ia+s)),
  204. InputIterator<const int*>(ia),
  205. std::equal_to<int>()));
  206. CHECK(equal(make_subrange(InputIterator<const int*>(ia),
  207. Sentinel<const int*>(ia+s)),
  208. make_subrange(InputIterator<const int*>(ia),
  209. Sentinel<const int*>(ia + s)),
  210. std::equal_to<int>()));
  211. CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
  212. RandomAccessIterator<const int*>(ia+s)),
  213. make_subrange(RandomAccessIterator<const int*>(ia),
  214. RandomAccessIterator<const int*>(ia+s)),
  215. std::equal_to<int>()));
  216. CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
  217. Sentinel<const int*>(ia+s)),
  218. make_subrange(RandomAccessIterator<const int*>(ia),
  219. Sentinel<const int*>(ia + s)),
  220. std::equal_to<int>()));
  221. comparison_count = 0;
  222. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  223. Sentinel<const int*>(ia+s)),
  224. make_subrange(InputIterator<const int*>(ia),
  225. Sentinel<const int*>(ia + s - 1)),
  226. counting_equals<int>));
  227. CHECK(comparison_count > 0);
  228. comparison_count = 0;
  229. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  230. RandomAccessIterator<const int*>(ia+s)),
  231. make_subrange(RandomAccessIterator<const int*>(ia),
  232. RandomAccessIterator<const int*>(ia+s-1)),
  233. counting_equals<int>));
  234. CHECK(comparison_count == 0);
  235. comparison_count = 0;
  236. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  237. Sentinel<const int*>(ia+s)),
  238. make_subrange(RandomAccessIterator<const int*>(ia),
  239. Sentinel<const int*>(ia + s - 1)),
  240. counting_equals<int>));
  241. CHECK(comparison_count > 0);
  242. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  243. Sentinel<const int*>(ia+s)),
  244. InputIterator<const int*>(ib),
  245. std::equal_to<int>()));
  246. CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
  247. Sentinel<const int*>(ia+s)),
  248. make_subrange(InputIterator<const int*>(ib),
  249. Sentinel<const int*>(ib + s)),
  250. std::equal_to<int>()));
  251. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  252. RandomAccessIterator<const int*>(ia+s)),
  253. make_subrange(RandomAccessIterator<const int*>(ib),
  254. RandomAccessIterator<const int*>(ib+s)),
  255. std::equal_to<int>()));
  256. CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
  257. Sentinel<const int*>(ia+s)),
  258. make_subrange(RandomAccessIterator<const int*>(ib),
  259. Sentinel<const int*>(ib + s)),
  260. std::equal_to<int>()));
  261. }
  262. int main()
  263. {
  264. ::test();
  265. ::test_rng();
  266. ::test_pred();
  267. ::test_rng_pred();
  268. using IL = std::initializer_list<int>;
  269. int *p = nullptr;
  270. static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, p))>::value, "");
  271. static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3, 4}))>::value, "");
  272. static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, ranges::views::unbounded(p)))>::value, "");
  273. #if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_14 && RANGES_CONSTEXPR_INVOKE
  274. static_assert(ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3, 4}), "");
  275. static_assert(!ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3}), "");
  276. static_assert(!ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 4, 3}), "");
  277. static_assert(ranges::equal(IL{}, IL{}), "");
  278. #endif
  279. return ::test_result();
  280. }