constrained.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright (C) 2020-2022 Free Software Foundation, Inc.
  2. //
  3. // This file is part of the GNU ISO C++ Library. This library is free
  4. // software; you can redistribute it and/or modify it under the
  5. // terms of the GNU General Public License as published by the
  6. // Free Software Foundation; either version 3, or (at your option)
  7. // any later version.
  8. // This library is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. // You should have received a copy of the GNU General Public License along
  13. // with this library; see the file COPYING3. If not see
  14. // <http://www.gnu.org/licenses/>.
  15. // { dg-options "-std=gnu++2a" }
  16. // { dg-do run { target c++2a } }
  17. #include <algorithm>
  18. #include <vector>
  19. #include <testsuite_hooks.h>
  20. #include <testsuite_iterators.h>
  21. using __gnu_test::test_container;
  22. using __gnu_test::test_range;
  23. using __gnu_test::input_iterator_wrapper;
  24. using __gnu_test::input_iterator_wrapper_nocopy;
  25. using __gnu_test::output_iterator_wrapper;
  26. using __gnu_test::forward_iterator_wrapper;
  27. namespace ranges = std::ranges;
  28. struct X
  29. {
  30. int i;
  31. int moved = 0;
  32. constexpr X() : i(0) { }
  33. constexpr X(int a) : i(a) { }
  34. constexpr X(const X&) = delete;
  35. constexpr X& operator=(const X&) = delete;
  36. constexpr X(X&& other)
  37. {
  38. *this = std::move(other);
  39. }
  40. constexpr X&
  41. operator=(X&& other)
  42. {
  43. other.moved++;
  44. i = other.i;
  45. return *this;
  46. }
  47. friend constexpr bool
  48. operator==(const X& a, const X& b)
  49. { return a.i == b.i; }
  50. };
  51. void
  52. test01()
  53. {
  54. {
  55. X x[7] = { 1, 2, 3, 4, 5, 6, 7 };
  56. X y[7] = { 0, 0, 0, 0, 0, 0, 0 };
  57. X z[7] = { 1, 2, 3, 4, 5, 6, 7 };
  58. auto [in, out] = ranges::move(x, y);
  59. VERIFY( ranges::equal(x, y) && in == x+7 && out == y+7 );
  60. VERIFY( ranges::equal(x, z) );
  61. }
  62. {
  63. int x[3] = { 1, 2, 3 };
  64. char y[4] = { 0 };
  65. int z[3] = { 1, 2, 3 };
  66. test_container<int, forward_iterator_wrapper> cx(x);
  67. test_container<char, forward_iterator_wrapper> cy(y);
  68. auto [in, out] = ranges::move(cx, cy.begin());
  69. VERIFY( ranges::equal(x, x+3, y, y+3) && in.ptr == x+3 && out.ptr == y+3 );
  70. VERIFY( ranges::equal(x, z) );
  71. }
  72. {
  73. char x[3] = { 1, 2, 3 };
  74. int y[4] = { 0 };
  75. int z[3] = { 1, 2, 3 };
  76. test_range<char, input_iterator_wrapper> cx(x);
  77. test_range<int, output_iterator_wrapper> cy(y);
  78. auto [in, out] = ranges::move(cx, ranges::begin(cy));
  79. VERIFY( ranges::equal(x, x+3, y, y+3) && in.ptr == x+3 && out.ptr == y+3 );
  80. VERIFY( ranges::equal(x, z) );
  81. }
  82. {
  83. std::vector<char> x= {1,2,3};
  84. std::vector<int> y(3);
  85. const int z[3] = { 1, 2, 3 };
  86. auto [in, out] = ranges::move(x, ranges::begin(y));
  87. VERIFY( in == x.begin()+3 );
  88. VERIFY( out == y.begin()+3 );
  89. VERIFY( ranges::equal(y, z) && ranges::equal(x, z) );
  90. }
  91. {
  92. std::vector<int> x = {1,2,3};
  93. std::vector<int> y(3);
  94. const int z[3] = { 1, 2, 3 };
  95. auto [in, out] = ranges::move(x, ranges::begin(y));
  96. VERIFY( in == x.begin()+3 );
  97. VERIFY( out == y.begin()+3 );
  98. VERIFY( ranges::equal(y, z) && ranges::equal(x, z) );
  99. }
  100. {
  101. std::vector<int> x = {1,2,3};
  102. std::vector<int> y(3);
  103. const int z[3] = { 1, 2, 3 };
  104. auto [in,out] = ranges::move(make_reverse_iterator(x.end()),
  105. make_reverse_iterator(x.begin()),
  106. make_reverse_iterator(y.end()));
  107. VERIFY( in.base() == x.begin()+3 );
  108. VERIFY( out.base() == y.begin() );
  109. VERIFY( ranges::equal(y, z) && ranges::equal(x, z) );
  110. }
  111. {
  112. std::vector<char> x = {1,2,3};
  113. std::vector<int> y(3);
  114. const int z[3] = { 1, 2, 3 };
  115. auto [in,out] = ranges::move(make_reverse_iterator(x.end()),
  116. make_reverse_iterator(x.begin()),
  117. make_reverse_iterator(y.end()));
  118. VERIFY( in.base() == x.begin()+3 );
  119. VERIFY( out.base() == y.begin() );
  120. VERIFY( ranges::equal(y, z) && ranges::equal(x, z) );
  121. }
  122. }
  123. void
  124. test02()
  125. {
  126. X x[] = { {2}, {2}, {6}, {8}, {10} };
  127. X y[] = { {2}, {6}, {8}, {10}, {11}, {2} };
  128. X z[] = { {2}, {2}, {6}, {8}, {10} };
  129. auto [in, out] = ranges::move(x, y);
  130. VERIFY( ranges::equal(x, x+5, y, y+5) );
  131. VERIFY( in == x+5 );
  132. VERIFY( out == y+5 );
  133. VERIFY( y[5].i == 2 );
  134. VERIFY( ranges::equal(x, z) );
  135. VERIFY( ranges::count(x, 1, &X::moved) == 5 );
  136. VERIFY( ranges::count(y, 0, &X::moved) == 6 );
  137. }
  138. constexpr bool
  139. test03()
  140. {
  141. bool ok = true;
  142. X x[] = { {2}, {2}, {6}, {8}, {10} };
  143. X y[] = { {2}, {6}, {8}, {10}, {11}, {2} };
  144. X z[] = { {2}, {2}, {6}, {8}, {10} };
  145. auto [in, out] = ranges::move(x, y);
  146. ok &= ranges::equal(x, x+5, y, y+5);
  147. ok &= (in == x+5);
  148. ok &= (out == y+5);
  149. ok &= (y[5].i == 2);
  150. ok &= ranges::equal(x, z);
  151. ok &= ranges::count(x, 1, &X::moved) == 5;
  152. ok &= ranges::count(y, 0, &X::moved) == 6;
  153. return ok;
  154. }
  155. void
  156. test04()
  157. {
  158. X x[] = { {2}, {2}, {6}, {8}, {10} };
  159. X y[] = { {2}, {6}, {8}, {10}, {11}, {2} };
  160. X z[] = { {2}, {2}, {6}, {8}, {10} };
  161. test_range<X, input_iterator_wrapper> rx(x);
  162. auto [in, out] = ranges::move(std::move_iterator{ranges::begin(rx)},
  163. std::move_sentinel{ranges::end(rx)},
  164. ranges::begin(y));
  165. VERIFY( ranges::equal(x, x+5, y, y+5) );
  166. VERIFY( std::move(in).base().ptr == x+5 );
  167. VERIFY( out == y+5 );
  168. VERIFY( y[5].i == 2 );
  169. VERIFY( ranges::equal(x, z) );
  170. VERIFY( ranges::count(x, 1, &X::moved) == 5 );
  171. VERIFY( ranges::count(y, 0, &X::moved) == 6 );
  172. }
  173. void
  174. test05()
  175. {
  176. // PR libstdc++/101599
  177. int x[] = {1,2,3};
  178. test_range<int, input_iterator_wrapper_nocopy> rx(x);
  179. std::vector<int> v(4, 0);
  180. ranges::move(rx, v.begin());
  181. VERIFY( ranges::equal(v, (int[]){1,2,3,0}) );
  182. }
  183. int
  184. main()
  185. {
  186. test01();
  187. test02();
  188. static_assert(test03());
  189. test04();
  190. test05();
  191. }