pop_heap.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. #include <memory>
  24. #include <random>
  25. #include <algorithm>
  26. #include <functional>
  27. #include <range/v3/core.hpp>
  28. #include <range/v3/algorithm/heap_algorithm.hpp>
  29. #include "../array.hpp"
  30. #include "../simple_test.hpp"
  31. #include "../test_utils.hpp"
  32. #include "../test_iterators.hpp"
  33. RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
  34. RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
  35. namespace
  36. {
  37. std::mt19937 gen;
  38. void test_1(int N)
  39. {
  40. int* ia = new int[N];
  41. for (int i = 0; i < N; ++i)
  42. ia[i] = i;
  43. std::shuffle(ia, ia+N, gen);
  44. std::make_heap(ia, ia+N);
  45. for (int i = N; i > 0; --i)
  46. {
  47. CHECK(ranges::pop_heap(ia, ia+i) == ia+i);
  48. CHECK(std::is_heap(ia, ia+i-1));
  49. }
  50. CHECK(ranges::pop_heap(ia, ia) == ia);
  51. delete[] ia;
  52. }
  53. void test_2(int N)
  54. {
  55. int* ia = new int[N];
  56. for (int i = 0; i < N; ++i)
  57. ia[i] = i;
  58. std::shuffle(ia, ia+N, gen);
  59. std::make_heap(ia, ia+N);
  60. for (int i = N; i > 0; --i)
  61. {
  62. CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia+i)) == ia+i);
  63. CHECK(std::is_heap(ia, ia+i-1));
  64. }
  65. CHECK(ranges::pop_heap(ia, ia) == ia);
  66. delete[] ia;
  67. }
  68. void test_3(int N)
  69. {
  70. int* ia = new int[N];
  71. for (int i = 0; i < N; ++i)
  72. ia[i] = i;
  73. std::shuffle(ia, ia+N, gen);
  74. std::make_heap(ia, ia+N);
  75. for (int i = N; i > 0; --i)
  76. {
  77. CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, ia+i))) == ia+i);
  78. CHECK(std::is_heap(ia, ia+i-1));
  79. }
  80. std::shuffle(ia, ia+N, gen);
  81. std::make_heap(ia, ia+N);
  82. for (int i = N; i > 0; --i)
  83. {
  84. CHECK(ranges::pop_heap(ranges::make_subrange(ia, ia+i)) == ia+i);
  85. CHECK(std::is_heap(ia, ia+i-1));
  86. }
  87. CHECK(ranges::pop_heap(ia, ia) == ia);
  88. delete[] ia;
  89. }
  90. void test_4(int N)
  91. {
  92. int* ia = new int[N];
  93. for (int i = 0; i < N; ++i)
  94. ia[i] = i;
  95. std::shuffle(ia, ia+N, gen);
  96. std::make_heap(ia, ia+N);
  97. for (int i = N; i > 0; --i)
  98. {
  99. CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, Sentinel<int*>(ia+i)))) == ia+i);
  100. CHECK(std::is_heap(ia, ia+i-1));
  101. }
  102. std::shuffle(ia, ia+N, gen);
  103. std::make_heap(ia, ia+N);
  104. for (int i = N; i > 0; --i)
  105. {
  106. CHECK(ranges::pop_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+i))) == ia+i);
  107. CHECK(std::is_heap(ia, ia+i-1));
  108. }
  109. CHECK(ranges::pop_heap(ia, ia) == ia);
  110. delete[] ia;
  111. }
  112. void test_5(int N)
  113. {
  114. int* ia = new int[N];
  115. for (int i = 0; i < N; ++i)
  116. ia[i] = i;
  117. std::shuffle(ia, ia+N, gen);
  118. std::make_heap(ia, ia+N, std::greater<int>());
  119. for (int i = N; i > 0; --i)
  120. {
  121. CHECK(ranges::pop_heap(ia, ia+i, std::greater<int>()) == ia+i);
  122. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  123. }
  124. CHECK(ranges::pop_heap(ia, ia, std::greater<int>()) == ia);
  125. delete[] ia;
  126. }
  127. void test_6(int N)
  128. {
  129. int* ia = new int[N];
  130. for (int i = 0; i < N; ++i)
  131. ia[i] = i;
  132. std::shuffle(ia, ia+N, gen);
  133. std::make_heap(ia, ia+N, std::greater<int>());
  134. for (int i = N; i > 0; --i)
  135. {
  136. CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia+i), std::greater<int>()) == ia+i);
  137. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  138. }
  139. CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia), std::greater<int>()) == ia);
  140. delete[] ia;
  141. }
  142. void test_7(int N)
  143. {
  144. int* ia = new int[N];
  145. for (int i = 0; i < N; ++i)
  146. ia[i] = i;
  147. std::shuffle(ia, ia+N, gen);
  148. std::make_heap(ia, ia+N, std::greater<int>());
  149. for (int i = N; i > 0; --i)
  150. {
  151. CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, ia+i)), std::greater<int>()) == ia+i);
  152. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  153. }
  154. std::shuffle(ia, ia+N, gen);
  155. std::make_heap(ia, ia+N, std::greater<int>());
  156. for (int i = N; i > 0; --i)
  157. {
  158. CHECK(ranges::pop_heap(ranges::make_subrange(ia, ia+i), std::greater<int>()) == ia+i);
  159. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  160. }
  161. CHECK(ranges::pop_heap(ia, ia, std::greater<int>()) == ia);
  162. delete[] ia;
  163. }
  164. void test_8(int N)
  165. {
  166. int* ia = new int[N];
  167. for (int i = 0; i < N; ++i)
  168. ia[i] = i;
  169. std::shuffle(ia, ia+N, gen);
  170. std::make_heap(ia, ia+N, std::greater<int>());
  171. for (int i = N; i > 0; --i)
  172. {
  173. CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, Sentinel<int*>(ia+i))), std::greater<int>()) == ia+i);
  174. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  175. }
  176. std::shuffle(ia, ia+N, gen);
  177. std::make_heap(ia, ia+N, std::greater<int>());
  178. for (int i = N; i > 0; --i)
  179. {
  180. CHECK(ranges::pop_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+i)), std::greater<int>()) == ia+i);
  181. CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
  182. }
  183. CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia), std::greater<int>()) == ia);
  184. delete[] ia;
  185. }
  186. struct indirect_less
  187. {
  188. template<class P>
  189. bool operator()(const P& x, const P& y)
  190. {return *x < *y;}
  191. };
  192. void test_9(int N)
  193. {
  194. std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
  195. for (int i = 0; i < N; ++i)
  196. ia[i].reset(new int(i));
  197. std::shuffle(ia, ia+N, gen);
  198. std::make_heap(ia, ia+N, indirect_less());
  199. for (int i = N; i > 0; --i)
  200. {
  201. CHECK(ranges::pop_heap(ia, ia+i, indirect_less()) == ia+i);
  202. CHECK(std::is_heap(ia, ia+i-1, indirect_less()));
  203. }
  204. delete[] ia;
  205. }
  206. template<typename T>
  207. struct construct
  208. {
  209. template<typename ...Us>
  210. T operator()(Us &&... us) const
  211. {
  212. return T{((Us &&)us)...};
  213. }
  214. };
  215. struct S
  216. {
  217. int i;
  218. };
  219. void test_10(int N)
  220. {
  221. int* ia = new int[N];
  222. S* ib = new S[N];
  223. for (int i = 0; i < N; ++i)
  224. ia[i] = i;
  225. std::shuffle(ia, ia+N, gen);
  226. std::make_heap(ia, ia+N);
  227. std::transform(ia, ia+N, ib, construct<S>());
  228. for (int i = N; i > 0; --i)
  229. {
  230. CHECK(ranges::pop_heap(ib, ib+i, std::less<int>(), &S::i) == ib+i);
  231. std::transform(ib, ib+i, ia, std::mem_fn(&S::i));
  232. CHECK(std::is_heap(ia, ia+i-1));
  233. }
  234. CHECK(ranges::pop_heap(ib, ib, std::less<int>(), &S::i) == ib);
  235. delete[] ia;
  236. delete[] ib;
  237. }
  238. }
  239. constexpr bool test_constexpr()
  240. {
  241. using namespace ranges;
  242. constexpr int N = 100;
  243. test::array<int, N> ia{{0}};
  244. for(int i = 0; i < N; ++i)
  245. ia[i] = i;
  246. make_heap(ia);
  247. for(int i = N; i > 0; --i)
  248. {
  249. STATIC_CHECK_RETURN(pop_heap(make_subrange(begin(ia), begin(ia) + i), less{}) == begin(ia) + i);
  250. STATIC_CHECK_RETURN(is_heap(begin(ia), begin(ia) + i - 1));
  251. }
  252. STATIC_CHECK_RETURN(pop_heap(make_subrange(begin(ia), begin(ia)), less{}) == begin(ia));
  253. return true;
  254. }
  255. int main()
  256. {
  257. test_1(1000);
  258. test_2(1000);
  259. test_3(1000);
  260. test_4(1000);
  261. test_5(1000);
  262. test_6(1000);
  263. test_7(1000);
  264. test_8(1000);
  265. test_9(1000);
  266. test_10(1000);
  267. {
  268. STATIC_CHECK(test_constexpr());
  269. }
  270. return test_result();
  271. }