@@ -3452,11 +3452,15 @@ namespace ranges
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
if constexpr (__detail::__is_normal_iterator<_Iter1>
- || __detail::__is_normal_iterator<_Iter2>)
- return (*this)(std::__niter_base(std::move(__first1)),
- std::__niter_base(std::move(__last1)),
- std::__niter_base(std::move(__first2)),
- std::__niter_base(std::move(__last2)),
+ && same_as<_Iter1, _Sent1>)
+ return (*this)(__first1.base(), __last1.base(),
+ std::move(__first2), std::move(__last2),
+ std::move(__comp),
+ std::move(__proj1), std::move(__proj2));
+ else if constexpr (__detail::__is_normal_iterator<_Iter2>
+ && same_as<_Iter2, _Sent2>)
+ return (*this)(std::move(__first1), std::move(__last1),
+ __first2.base(), __last2.base(),
std::move(__comp),
std::move(__proj1), std::move(__proj2));
else
@@ -85,11 +85,15 @@ namespace ranges
// TODO: implement more specializations to at least have parity with
// std::equal.
if constexpr (__detail::__is_normal_iterator<_Iter1>
- || __detail::__is_normal_iterator<_Iter2>)
- return (*this)(std::__niter_base(std::move(__first1)),
- std::__niter_base(std::move(__last1)),
- std::__niter_base(std::move(__first2)),
- std::__niter_base(std::move(__last2)),
+ && same_as<_Iter1, _Sent1>)
+ return (*this)(__first1.base(), __last1.base(),
+ std::move(__first2), std::move(__last2),
+ std::move(__pred),
+ std::move(__proj1), std::move(__proj2));
+ else if constexpr (__detail::__is_normal_iterator<_Iter2>
+ && same_as<_Iter2, _Sent2>)
+ return (*this)(std::move(__first1), std::move(__last1),
+ __first2.base(), __last2.base(),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
else if constexpr (sized_sentinel_for<_Sent1, _Iter1>
@@ -211,14 +215,10 @@ namespace ranges
{
// TODO: implement more specializations to be at least on par with
// std::copy/std::move.
- constexpr bool __normal_iterator_p
- = (__detail::__is_normal_iterator<_Iter>
- || __detail::__is_normal_iterator<_Out>);
- constexpr bool __reverse_p
- = (__detail::__is_reverse_iterator<_Iter>
- && __detail::__is_reverse_iterator<_Out>);
- constexpr bool __move_iterator_p = __detail::__is_move_iterator<_Iter>;
- if constexpr (__move_iterator_p)
+ using __detail::__is_move_iterator;
+ using __detail::__is_reverse_iterator;
+ using __detail::__is_normal_iterator;
+ if constexpr (__is_move_iterator<_Iter> && same_as<_Iter, _Sent>)
{
auto [__in, __out]
= ranges::__copy_or_move<true>(std::move(__first).base(),
@@ -226,23 +226,28 @@ namespace ranges
std::move(__result));
return {move_iterator{std::move(__in)}, std::move(__out)};
}
- else if constexpr (__reverse_p)
+ else if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent>
+ && __is_reverse_iterator<_Out>)
{
auto [__in,__out]
- = ranges::__copy_or_move_backward<_IsMove>(__last.base(),
- __first.base(),
- __result.base());
+ = ranges::__copy_or_move_backward<_IsMove>(std::move(__last).base(),
+ std::move(__first).base(),
+ std::move(__result).base());
return {reverse_iterator{std::move(__in)},
reverse_iterator{std::move(__out)}};
}
- else if constexpr (__normal_iterator_p)
+ else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>)
+ {
+ auto [__in,__out]
+ = ranges::__copy_or_move<_IsMove>(__first.base(), __last.base(),
+ __result);
+ return {decltype(__first){__in}, std::move(__out)};
+ }
+ else if constexpr (__is_normal_iterator<_Out>)
{
auto [__in,__out]
- = ranges::__copy_or_move<_IsMove>(std::__niter_base(__first),
- std::__niter_base(__last),
- std::__niter_base(__result));
- return {std::__niter_wrap(__first, std::move(__in)),
- std::__niter_wrap(__result, std::move(__out))};
+ = ranges::__copy_or_move<_IsMove>(__first, __last, __result.base());
+ return {std::move(__in), decltype(__result){__out}};
}
else if constexpr (sized_sentinel_for<_Sent, _Iter>)
{
@@ -353,30 +358,33 @@ namespace ranges
{
// TODO: implement more specializations to be at least on par with
// std::copy_backward/std::move_backward.
- constexpr bool __normal_iterator_p
- = (__detail::__is_normal_iterator<_Iter>
- || __detail::__is_normal_iterator<_Out>);
- constexpr bool __reverse_p
- = (__detail::__is_reverse_iterator<_Iter>
- && __detail::__is_reverse_iterator<_Out>);
- if constexpr (__reverse_p)
+ using __detail::__is_reverse_iterator;
+ using __detail::__is_normal_iterator;
+ if constexpr (__is_reverse_iterator<_Iter> && same_as<_Iter, _Sent>
+ && __is_reverse_iterator<_Out>)
{
auto [__in,__out]
- = ranges::__copy_or_move<_IsMove>(__last.base(),
- __first.base(),
- __result.base());
+ = ranges::__copy_or_move<_IsMove>(std::move(__last).base(),
+ std::move(__first).base(),
+ std::move(__result).base());
return {reverse_iterator{std::move(__in)},
reverse_iterator{std::move(__out)}};
}
- else if constexpr (__normal_iterator_p)
+ else if constexpr (__is_normal_iterator<_Iter> && same_as<_Iter, _Sent>)
{
auto [__in,__out]
- = ranges::__copy_or_move_backward<_IsMove>
- (std::__niter_base(__first),
- std::__niter_base(__last),
- std::__niter_base(__result));
- return {std::__niter_wrap(__first, std::move(__in)),
- std::__niter_wrap(__result, std::move(__out))};
+ = ranges::__copy_or_move_backward<_IsMove>(__first.base(),
+ __last.base(),
+ std::move(__result));
+ return {decltype(__first){__in}, std::move(__out)};
+ }
+ else if constexpr (__is_normal_iterator<_Out>)
+ {
+ auto [__in,__out]
+ = ranges::__copy_or_move_backward<_IsMove>(std::move(__first),
+ std::move(__last),
+ __result.base());
+ return {std::move(__in), decltype(__result){__out}};
}
else if constexpr (sized_sentinel_for<_Sent, _Iter>)
{
new file mode 100644
@@ -0,0 +1,74 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ ranges::copy(sr, w.begin());
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ ranges::copy(sr, reverse_iterator{w.end()});
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+void
+test03()
+{
+ using std::move_iterator;
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr
+ = {move_iterator{v.begin()}, sentinel{move_iterator{v.end()}}};
+ ranges::copy(sr, w.begin());
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
new file mode 100644
@@ -0,0 +1,62 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ ranges::copy_backward(sr, w.end());
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ ranges::copy_backward(sr, reverse_iterator{w.begin()});
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
new file mode 100644
@@ -0,0 +1,74 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ VERIFY( ranges::equal(sr, v) );
+ VERIFY( ranges::equal(v, sr) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ VERIFY( ranges::equal(sr, (int[]){5,4,3,2,1}) );
+ VERIFY( ranges::equal((int[]){5,4,3,2,1}, sr) );
+}
+
+void
+test03()
+{
+ using std::move_iterator;
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr
+ = {move_iterator{v.begin()}, sentinel{move_iterator{v.end()}}};
+ VERIFY( ranges::equal(sr, v) );
+ VERIFY( ranges::equal(v, sr) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
new file mode 100644
@@ -0,0 +1,74 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ VERIFY( ranges::lexicographical_compare(sr, (int[]){1,2,3,5,5}) );
+ VERIFY( !ranges::lexicographical_compare((int[]){1,2,3,5,5}, sr) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ VERIFY( ranges::lexicographical_compare(sr, (int[]){5,4,3,2,2}) );
+ VERIFY( !ranges::lexicographical_compare((int[]){5,4,3,2,2}, sr) );
+}
+
+void
+test03()
+{
+ using std::move_iterator;
+ std::vector<int> v = {1,2,3,4,5};
+ ranges::subrange sr
+ = {move_iterator{v.begin()}, sentinel{move_iterator{v.end()}}};
+ VERIFY( ranges::lexicographical_compare(sr, (int[]){1,2,3,5,5}) );
+ VERIFY( !ranges::lexicographical_compare((int[]){1,2,3,5,5}, sr) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
new file mode 100644
@@ -0,0 +1,62 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ ranges::move(sr, w.begin());
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ ranges::move(sr, reverse_iterator{w.end()});
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
new file mode 100644
@@ -0,0 +1,62 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+namespace ranges = std::ranges;
+
+template<typename It>
+struct sentinel
+{
+ It it;
+
+ friend bool
+ operator==(It x, sentinel y)
+ { return x == y.it; }
+};
+
+void
+test01()
+{
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr = {v.begin(), sentinel{v.end()}};
+ ranges::move_backward(sr, w.end());
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+void
+test02()
+{
+ using std::reverse_iterator;
+ std::vector<int> v = {1,2,3,4,5}, w = {0,0,0,0,0};
+ ranges::subrange sr
+ = {reverse_iterator{v.end()}, sentinel{reverse_iterator{v.begin()}}};
+ ranges::move_backward(sr, reverse_iterator{w.begin()});
+ VERIFY( ranges::equal(w, (int[]){1,2,3,4,5}) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}