Partial implementation of C++20 of <ranges> header
authorJonathan Wakely <jwakely@redhat.com>
Thu, 31 Oct 2019 21:42:18 +0000 (21:42 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 31 Oct 2019 21:42:18 +0000 (21:42 +0000)
* doc/doxygen/user.cfg.in: Add new header.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include new header.
* include/std/ranges: New header.
(ranges::sentinel_t, ranges::range_value_t, ranges::range_reference_t)
(ranges::range_rvalue_reference_t, ranges::sized_range)
(ranges::output_range, ranges::input_ranges, ranges::forward_range)
(ranges::bidirectional_range, ranges::random_access_range)
(ranges::contiguous_range, ranges::common::range): Define.
* testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: Check
that disabled_sized_sentinel can be specialized.
* testsuite/std/ranges/access/begin.cc: Include <ranges> instead of
<iterator>.
* testsuite/std/ranges/access/cbegin.cc: Likewise.
* testsuite/std/ranges/access/cdata.cc: Likewise.
* testsuite/std/ranges/access/cend.cc: Likewise.
* testsuite/std/ranges/access/crbegin.cc: Likewise.
* testsuite/std/ranges/access/crend.cc: Likewise.
* testsuite/std/ranges/access/data.cc: Likewise.
* testsuite/std/ranges/access/empty.cc: Likewise.
* testsuite/std/ranges/access/end.cc: Likewise.
* testsuite/std/ranges/access/end_neg.cc: Likewise.
* testsuite/std/ranges/access/rbegin.cc: Likewise.
* testsuite/std/ranges/access/rend.cc: Likewise.
* testsuite/std/ranges/access/size.cc: Likewise.
* testsuite/std/ranges/access/size_neg.cc: Likewise.
* testsuite/std/ranges/headers/ranges/synopsis.cc: New test.
* testsuite/std/ranges/range.cc: New test.
* testsuite/std/ranges/refinements.cc: New test.
* testsuite/std/ranges/sized.cc: New test.
* testsuite/util/testsuite_iterators.h: Add aliases for range types.
(output_iterator_wrapper::WritableObject::operator=): Add const
qualifier so that output_iterator_wrapper satisfies writable.

From-SVN: r277697

26 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/doc/doxygen/user.cfg.in
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/precompiled/stdc++.h
libstdc++-v3/include/std/ranges [new file with mode: 0644]
libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
libstdc++-v3/testsuite/std/ranges/access/begin.cc
libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
libstdc++-v3/testsuite/std/ranges/access/cdata.cc
libstdc++-v3/testsuite/std/ranges/access/cend.cc
libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
libstdc++-v3/testsuite/std/ranges/access/crend.cc
libstdc++-v3/testsuite/std/ranges/access/data.cc
libstdc++-v3/testsuite/std/ranges/access/empty.cc
libstdc++-v3/testsuite/std/ranges/access/end.cc
libstdc++-v3/testsuite/std/ranges/access/end_neg.cc
libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
libstdc++-v3/testsuite/std/ranges/access/rend.cc
libstdc++-v3/testsuite/std/ranges/access/size.cc
libstdc++-v3/testsuite/std/ranges/access/size_neg.cc
libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc [new file with mode: 0644]
libstdc++-v3/testsuite/std/ranges/range.cc [new file with mode: 0644]
libstdc++-v3/testsuite/std/ranges/refinements.cc [new file with mode: 0644]
libstdc++-v3/testsuite/std/ranges/sized.cc [new file with mode: 0644]
libstdc++-v3/testsuite/util/testsuite_iterators.h

index 2a47289511704eb39cb1dee827d646b33e05bea4..1004d76a77d4e1f652a465cbdbb3007944e322a8 100644 (file)
@@ -1,5 +1,40 @@
 2019-10-31  Jonathan Wakely  <jwakely@redhat.com>
 
+       * doc/doxygen/user.cfg.in: Add new header.
+       * include/Makefile.am: Add new header.
+       * include/Makefile.in: Regenerate.
+       * include/precompiled/stdc++.h: Include new header.
+       * include/std/ranges: New header.
+       (ranges::sentinel_t, ranges::range_value_t, ranges::range_reference_t)
+       (ranges::range_rvalue_reference_t, ranges::sized_range)
+       (ranges::output_range, ranges::input_ranges, ranges::forward_range)
+       (ranges::bidirectional_range, ranges::random_access_range)
+       (ranges::contiguous_range, ranges::common::range): Define.
+       * testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: Check
+       that disabled_sized_sentinel can be specialized.
+       * testsuite/std/ranges/access/begin.cc: Include <ranges> instead of
+       <iterator>.
+       * testsuite/std/ranges/access/cbegin.cc: Likewise.
+       * testsuite/std/ranges/access/cdata.cc: Likewise.
+       * testsuite/std/ranges/access/cend.cc: Likewise.
+       * testsuite/std/ranges/access/crbegin.cc: Likewise.
+       * testsuite/std/ranges/access/crend.cc: Likewise.
+       * testsuite/std/ranges/access/data.cc: Likewise.
+       * testsuite/std/ranges/access/empty.cc: Likewise.
+       * testsuite/std/ranges/access/end.cc: Likewise.
+       * testsuite/std/ranges/access/end_neg.cc: Likewise.
+       * testsuite/std/ranges/access/rbegin.cc: Likewise.
+       * testsuite/std/ranges/access/rend.cc: Likewise.
+       * testsuite/std/ranges/access/size.cc: Likewise.
+       * testsuite/std/ranges/access/size_neg.cc: Likewise.
+       * testsuite/std/ranges/headers/ranges/synopsis.cc: New test.
+       * testsuite/std/ranges/range.cc: New test.
+       * testsuite/std/ranges/refinements.cc: New test.
+       * testsuite/std/ranges/sized.cc: New test.
+       * testsuite/util/testsuite_iterators.h: Add aliases for range types.
+       (output_iterator_wrapper::WritableObject::operator=): Add const
+       qualifier so that output_iterator_wrapper satisfies writable.
+
        * testsuite/20_util/add_pointer/value.cc: Check void types.
 
        * include/bits/range_access.h (__sizable): Rename to __sentinel_size.
index 3c0295d99a5b8d205dafeee8ba06c942079598cc..420010167213994eac91a1088f552415a78392a7 100644 (file)
@@ -829,6 +829,7 @@ INPUT                  = @srcdir@/doc/doxygen/doxygroups.cc \
                          include/ostream \
                          include/queue \
                          include/random \
+                         include/ranges \
                          include/ratio \
                          include/regex \
                          include/scoped_allocator \
index 401c87ad103ca0b8bfedb3726ef90bebc71cd1b4..3e526dc14b74121959995c15f988c130dac772b2 100644 (file)
@@ -64,6 +64,7 @@ std_headers = \
        ${std_srcdir}/ostream \
        ${std_srcdir}/queue \
        ${std_srcdir}/random \
+       ${std_srcdir}/ranges \
        ${std_srcdir}/ratio \
        ${std_srcdir}/regex \
        ${std_srcdir}/scoped_allocator \
index e0a749635471c68e5dd1d1225428de6b46902d5a..d9eb306a21340ba50a4b4c986462bece544493eb 100644 (file)
@@ -408,6 +408,7 @@ std_headers = \
        ${std_srcdir}/ostream \
        ${std_srcdir}/queue \
        ${std_srcdir}/random \
+       ${std_srcdir}/ranges \
        ${std_srcdir}/ratio \
        ${std_srcdir}/regex \
        ${std_srcdir}/scoped_allocator \
index fefd6e76845a03d4f3b64cc3cf316b08416022da..57c3e2e32ee5801862e4f2e9ae5e6796fb7fb810 100644 (file)
 // #include <compare>
 #include <concepts>
 #include <numbers>
-// #include <ranges>
+#include <ranges>
 #include <span>
 // #include <syncstream>
 #include <version>
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
new file mode 100644 (file)
index 0000000..884fa1d
--- /dev/null
@@ -0,0 +1,112 @@
+// <ranges> -*- C++ -*-
+
+// Copyright (C) 2019 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received __a copy of the GNU General Public License and
+// __a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/ranges
+ *  This is a Standard C++ Library header.
+ *  @ingroup concepts
+ */
+
+#ifndef _GLIBCXX_RANGES
+#define _GLIBCXX_RANGES 1
+
+#if __cplusplus > 201703L
+
+#pragma GCC system_header
+
+#include <concepts>
+
+#if __cpp_lib_concepts
+
+#include <iterator>
+
+/**
+ * @defgroup ranges Ranges
+ *
+ * Components for dealing with ranges of elements.
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace ranges
+{
+  // [range.range] The range concept.
+  // Defined in <bits/range_iterator.h>
+  // template<typename> concept range;
+
+  template<range _Range>
+    using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
+
+  template<range _Range>
+    using range_value_t = iter_value_t<iterator_t<_Range>>;
+
+  template<range _Range>
+    using range_reference_t = iter_reference_t<iterator_t<_Range>>;
+
+  template<range _Range>
+    using range_rvalue_reference_t
+      = iter_rvalue_reference_t<iterator_t<_Range>>;
+
+  // [range.sized] The sized_range concept.
+  // Defined in <bits/range_iterator.h>
+  // template<typename> concept sized_range;
+
+  // [range.refinements]
+
+  template<typename _Range, typename _Tp>
+    concept output_range
+      = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
+
+  template<typename _Tp>
+    concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
+
+  template<typename _Tp>
+    concept forward_range
+      = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
+
+  template<typename _Tp>
+    concept bidirectional_range
+      = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
+
+  template<typename _Tp>
+    concept random_access_range
+      = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
+
+  template<typename _Tp>
+    concept contiguous_range
+      = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
+      && requires(_Tp& __t)
+      {
+       { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
+      };
+
+  template<typename _Tp>
+    concept common_range
+      = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
+} // namespace ranges
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // library concepts
+#endif // C++2a
+#endif /* _GLIBCXX_RANGES */
index 2dbfb767fdb4dd54bfc40bf48717099a721c95a1..824b0b4f38cc8cb1b7ea68a89396919c812f2c7f 100644 (file)
@@ -78,6 +78,9 @@ namespace std
   struct unreachable_sentinel_t;
 }
 
+struct I { };
+template<> constexpr bool std::disable_sized_sentinel<I, I> = true;
+
 namespace __gnu_test
 {
   // customization points
index 100dcf69c6ec8538aa0958f2133b0bb55b1931a0..e4c245a76bb82660d4916831ce7522d6c259974c 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index 34dd7fec3c658b93ca586d48c20c90191761dc21..54db3658896419120cd50df8b504fe316130dc1f 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 #include <testsuite_hooks.h>
 using std::same_as;
 
index 9a1ab5b96079cfeea4dcd20a1c5573dda62b56ae..b16c99607a58cfd1870097d444fa75b3bc54f3dd 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 
 void
index 94349c35d5141117778dd6f0ac49fe68c13d1987..3b57b3dbcaf9ea7fe8ca8498f6c6658a8be7f7cd 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 #include <testsuite_hooks.h>
 
 using std::same_as;
index 24939ac658e5451181a3728a99a77efed5dbbb47..d9e5b0cbef7691c36eedd30cfc89905faf3a96c1 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index ef0fb0e6b09e803dde8b823cc06757388d4325f1..e56491973b25f2c33257a440c46a6db74c4e5d85 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index d9129d055fcc5540c6537febdcf7ea1d21ffeb8c..4932164018257c9c59833c09f15b1ff07d806a8c 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index 64b1e1b5e1b705ab7e800898dbe1fcb414d11234..9d6aa282142977f800efd2bc54233efa0c5d2501 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index 6638bb35721d5aa33e37a425251c0fb02ad44710..ed269c5433f5f0f5b1ca98bf6341bd49a1fdb4e7 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index a2a8fb05f922f0d2b41d06e7be28c6f8eb02b5dc..0b40d2745679b791be47d3432e789303ac1b7e74 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do compile { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 
 extern int unbounded[];
 
index 6cfc1a38122e5351ff7222b839ef8058d2fec435..067ddd7ced61fbb3249f7fd7bfbf78de7d4f6dd3 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index 2192825708a332c6e776574847d917d5c189f9fd..17caa9fb31a71e23c9af182cd1294af20d397dc4 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index b0a27ca2a8746337370ebcc46df91dfafef9d1fd..6e9af7942ec0fb0675af1b2ba09de0c411d6537e 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <iterator>
+#include <ranges>
 #include <testsuite_hooks.h>
 #include <testsuite_iterators.h>
 
index 0ba8d81874ff20dc2c1c2ffecb9b66c959d19e19..65fce104ff6b896a6c6091f49a58fb321aa3d2cf 100644 (file)
@@ -18,7 +18,7 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do compile { target c++2a } }
 
-#include <iterator> // N.B. should be <ranges>
+#include <ranges>
 
 extern int unbounded[];
 
diff --git a/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc
new file mode 100644 (file)
index 0000000..d4596cc
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2019 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 compile { target c++2a } }
+
+#include <ranges>
+
+struct R { };
+template<> constexpr bool std::ranges::disable_sized_range<R> = true;
+
+namespace __gnu_test
+{
+  constexpr const bool* disable_sized_range
+    = &std::ranges::disable_sized_range<void>;
+  constexpr auto* begin = &std::ranges::begin;
+  constexpr auto* end = &std::ranges::end;
+  constexpr auto* cbegin = &std::ranges::cbegin;
+  constexpr auto* cend = &std::ranges::cend;
+  constexpr auto* rbegin = &std::ranges::rbegin;
+  constexpr auto* rend = &std::ranges::rend;
+  constexpr auto* crbegin = &std::ranges::crbegin;
+  constexpr auto* crend = &std::ranges::crend;
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/range.cc b/libstdc++-v3/testsuite/std/ranges/range.cc
new file mode 100644 (file)
index 0000000..44869de
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2019 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 compile { target c++2a } }
+
+#include <ranges>
+#include <testsuite_iterators.h>
+
+static_assert( std::ranges::range<int(&)[1]> );
+static_assert( std::ranges::range<const int(&)[1]> );
+static_assert( std::ranges::range<int[1]> );
+static_assert( !std::ranges::range<int*> );
+
+using namespace __gnu_test;
+
+static_assert( std::ranges::range<test_contiguous_range<int>> );
+static_assert( std::ranges::range<test_contiguous_range<int>&> );
+static_assert( std::ranges::range<test_random_access_range<int>> );
+static_assert( std::ranges::range<test_random_access_range<int>&> );
+static_assert( std::ranges::range<test_bidirectional_range<int>> );
+static_assert( std::ranges::range<test_bidirectional_range<int>&> );
+static_assert( std::ranges::range<test_forward_range<int>> );
+static_assert( std::ranges::range<test_forward_range<int>&> );
+static_assert( std::ranges::range<test_input_range<int>> );
+static_assert( std::ranges::range<test_input_range<int>&> );
+static_assert( std::ranges::range<test_output_range<int>> );
+static_assert( std::ranges::range<test_output_range<int>&> );
+
+static_assert( std::ranges::range<test_contiguous_sized_range<int>> );
+static_assert( std::ranges::range<test_contiguous_sized_range<int>&> );
+static_assert( std::ranges::range<test_random_access_sized_range<int>> );
+static_assert( std::ranges::range<test_random_access_sized_range<int>&> );
+static_assert( std::ranges::range<test_bidirectional_sized_range<int>> );
+static_assert( std::ranges::range<test_bidirectional_sized_range<int>&> );
+static_assert( std::ranges::range<test_forward_sized_range<int>> );
+static_assert( std::ranges::range<test_forward_sized_range<int>&> );
+static_assert( std::ranges::range<test_input_sized_range<int>> );
+static_assert( std::ranges::range<test_input_sized_range<int>&> );
+static_assert( std::ranges::range<test_output_sized_range<int>> );
+static_assert( std::ranges::range<test_output_sized_range<int>&> );
+
+using std::same_as;
+
+using C = test_contiguous_range<char>;
+using I = test_input_range<char>;
+using O = test_output_range<char>;
+
+static_assert( same_as<std::ranges::iterator_t<C>,
+                      contiguous_iterator_wrapper<char>> );
+static_assert( same_as<std::ranges::iterator_t<O>,
+                      decltype(std::declval<O&>().begin())> );
+
+static_assert( same_as<std::ranges::sentinel_t<C>,
+                      contiguous_iterator_wrapper<char>> );
+static_assert( same_as<std::ranges::sentinel_t<O>,
+                      decltype(std::declval<O&>().end())> );
+
+static_assert( same_as<std::ranges::range_difference_t<C>,
+                      std::ptrdiff_t> );
+static_assert( same_as<std::ranges::range_difference_t<O>,
+                      std::ptrdiff_t> );
+
+static_assert( same_as<std::ranges::range_value_t<O>,
+                      char> );
+
+static_assert( same_as<std::ranges::range_reference_t<I>,
+                      char&> );
+static_assert( same_as<std::ranges::range_reference_t<O>,
+                      WritableObject<char>> );
+
+static_assert( same_as<std::ranges::range_rvalue_reference_t<I>,
+                      char&&> );
+static_assert( same_as<std::ranges::range_rvalue_reference_t<O>,
+                     WritableObject<char>> );
diff --git a/libstdc++-v3/testsuite/std/ranges/refinements.cc b/libstdc++-v3/testsuite/std/ranges/refinements.cc
new file mode 100644 (file)
index 0000000..0b31539
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2019 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 compile { target c++2a } }
+
+#include <ranges>
+#include <testsuite_iterators.h>
+
+static_assert( std::ranges::output_range<int(&)[1], int> );
+static_assert( ! std::ranges::output_range<const int(&)[1], int> );
+static_assert( std::ranges::output_range<int[1], int> );
+static_assert( ! std::ranges::output_range<int[1], int*> );
+
+static_assert( std::ranges::input_range<int(&)[1]> );
+static_assert( std::ranges::input_range<const int(&)[1]> );
+static_assert( std::ranges::input_range<int[1]> );
+
+static_assert( std::ranges::contiguous_range<int(&)[1]> );
+static_assert( std::ranges::contiguous_range<const int(&)[1]> );
+static_assert( std::ranges::contiguous_range<int[1]> );
+
+using namespace __gnu_test;
+
+static_assert( std::ranges::output_range<test_contiguous_range<int>, int> );
+static_assert( std::ranges::output_range<test_random_access_range<int>, int> );
+static_assert( std::ranges::output_range<test_bidirectional_range<int>, int> );
+static_assert( std::ranges::output_range<test_forward_range<int>, int> );
+static_assert( ! std::ranges::output_range<test_input_range<int>, int> );
+static_assert( std::ranges::output_range<test_output_range<int>, int> );
+
+static_assert( std::ranges::input_range<test_contiguous_range<int>> );
+static_assert( std::ranges::input_range<test_random_access_range<int>> );
+static_assert( std::ranges::input_range<test_bidirectional_range<int>> );
+static_assert( std::ranges::input_range<test_forward_range<int>> );
+static_assert( std::ranges::input_range<test_input_range<int>> );
+static_assert( ! std::ranges::input_range<test_output_range<int>> );
+
+static_assert( std::ranges::forward_range<test_contiguous_range<int>> );
+static_assert( std::ranges::forward_range<test_random_access_range<int>> );
+static_assert( std::ranges::forward_range<test_bidirectional_range<int>> );
+static_assert( std::ranges::forward_range<test_forward_range<int>> );
+static_assert( ! std::ranges::forward_range<test_input_range<int>> );
+static_assert( ! std::ranges::forward_range<test_output_range<int>> );
+
+static_assert( std::ranges::bidirectional_range<test_contiguous_range<int>> );
+static_assert( std::ranges::bidirectional_range<test_random_access_range<int>>);
+static_assert( std::ranges::bidirectional_range<test_bidirectional_range<int>>);
+static_assert( ! std::ranges::bidirectional_range<test_forward_range<int>> );
+static_assert( ! std::ranges::bidirectional_range<test_input_range<int>> );
+static_assert( ! std::ranges::bidirectional_range<test_output_range<int>> );
+
+static_assert( std::ranges::random_access_range<test_contiguous_range<int>> );
+static_assert( std::ranges::random_access_range<test_random_access_range<int>>);
+static_assert( ! std::ranges::random_access_range<test_bidirectional_range<int>>);
+static_assert( ! std::ranges::random_access_range<test_forward_range<int>> );
+static_assert( ! std::ranges::random_access_range<test_input_range<int>> );
+static_assert( ! std::ranges::random_access_range<test_output_range<int>> );
+
+static_assert( std::ranges::contiguous_range<test_contiguous_range<int>> );
+static_assert( ! std::ranges::contiguous_range<test_random_access_range<int>>);
+static_assert( ! std::ranges::contiguous_range<test_bidirectional_range<int>>);
+static_assert( ! std::ranges::contiguous_range<test_forward_range<int>> );
+static_assert( ! std::ranges::contiguous_range<test_input_range<int>> );
+static_assert( ! std::ranges::contiguous_range<test_output_range<int>> );
diff --git a/libstdc++-v3/testsuite/std/ranges/sized.cc b/libstdc++-v3/testsuite/std/ranges/sized.cc
new file mode 100644 (file)
index 0000000..dd685c7
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) 2019 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 compile { target c++2a } }
+
+#include <ranges>
+#include <testsuite_iterators.h>
+
+static_assert( std::ranges::sized_range<int(&)[1]> );
+static_assert( std::ranges::sized_range<const int(&)[1]> );
+static_assert( std::ranges::sized_range<int[1]> );
+static_assert( !std::ranges::sized_range<int*> );
+
+using namespace __gnu_test;
+
+// ranges::size(r) uses (end(r) - begin(r))
+static_assert( std::ranges::sized_range<test_contiguous_range<int>> );
+static_assert( std::ranges::sized_range<test_contiguous_range<int>&> );
+static_assert( std::ranges::sized_range<test_random_access_range<int>> );
+static_assert( std::ranges::sized_range<test_random_access_range<int>&> );
+// ranges::size(r) is invalid, (end(r) - begin(r)) requires sized sentinel
+static_assert(!std::ranges::sized_range<test_bidirectional_range<int>> );
+static_assert(!std::ranges::sized_range<test_bidirectional_range<int>&> );
+static_assert(!std::ranges::sized_range<test_forward_range<int>> );
+static_assert(!std::ranges::sized_range<test_forward_range<int>&> );
+static_assert(!std::ranges::sized_range<test_input_range<int>> );
+static_assert(!std::ranges::sized_range<test_input_range<int>&> );
+static_assert(!std::ranges::sized_range<test_output_range<int>> );
+static_assert(!std::ranges::sized_range<test_output_range<int>&> );
+
+// ranges::size(r) uses r.size()
+static_assert( std::ranges::sized_range<test_contiguous_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_contiguous_sized_range<int>&> );
+static_assert( std::ranges::sized_range<test_random_access_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_random_access_sized_range<int>&> );
+static_assert( std::ranges::sized_range<test_bidirectional_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_bidirectional_sized_range<int>&> );
+static_assert( std::ranges::sized_range<test_forward_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_forward_sized_range<int>&> );
+static_assert( std::ranges::sized_range<test_input_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_input_sized_range<int>&> );
+static_assert( std::ranges::sized_range<test_output_sized_range<int>> );
+static_assert( std::ranges::sized_range<test_output_sized_range<int>&> );
+
+using long_range = __gnu_test::test_random_access_sized_range<long>;
+template<> constexpr bool std::ranges::disable_sized_range<long_range> = true;
+
+// Despite being disabled, this is still a sized_range because ranges::size(r)
+// works, by using (ranges::end(r) - ranges::begin(r)).
+static_assert( std::ranges::sized_range<long_range> );
+static_assert( std::ranges::sized_range<long_range&> );
+
+using short_range = __gnu_test::test_bidirectional_sized_range<short>;
+template<> constexpr bool std::ranges::disable_sized_range<short_range> = true;
+
+// This is not a sized range because ranges::size(r) cannot use member size,
+// or ADL size, and (ranges::end(r) - ranges::begin(r)) is ill-formed for
+// bidirectional iterators.
+static_assert( !std::ranges::sized_range<short_range> );
+static_assert( !std::ranges::sized_range<short_range&> );
index c5ae5b123fea7ded57eaa129e98f32f64117b352..d20257c1b3105dd36c7b1d365be78090d3a96de9 100644 (file)
@@ -95,7 +95,7 @@ namespace __gnu_test
 #if __cplusplus >= 201103L
       template<class U>
       typename std::enable_if<std::is_assignable<T&, U>::value>::type
-      operator=(U&& new_val)
+      operator=(U&& new_val) const
       {
        ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
        SharedInfo->writtento[ptr - SharedInfo->first] = 1;
@@ -720,6 +720,25 @@ namespace __gnu_test
       typename Iter<T>::ContainerType bounds;
     };
 
+  template<typename T>
+    using test_contiguous_range
+      = test_range<T, contiguous_iterator_wrapper>;
+  template<typename T>
+    using test_random_access_range
+      = test_range<T, random_access_iterator_wrapper>;
+  template<typename T>
+    using test_bidirectional_range
+      = test_range<T, bidirectional_iterator_wrapper>;
+  template<typename T>
+    using test_forward_range
+      = test_range<T, forward_iterator_wrapper>;
+  template<typename T>
+    using test_input_range
+      = test_range<T, input_iterator_wrapper>;
+  template<typename T>
+    using test_output_range
+      = test_range<T, output_iterator_wrapper>;
+
   // A type meeting the minimum std::sized_range requirements
   template<typename T, template<typename> class Iter>
     struct test_sized_range : test_range<T, Iter>
@@ -729,6 +748,25 @@ namespace __gnu_test
       std::size_t size() const noexcept
       { return this->bounds.size(); }
     };
+
+  template<typename T>
+    using test_contiguous_sized_range
+      = test_sized_range<T, contiguous_iterator_wrapper>;
+  template<typename T>
+    using test_random_access_sized_range
+      = test_sized_range<T, random_access_iterator_wrapper>;
+  template<typename T>
+    using test_bidirectional_sized_range
+      = test_sized_range<T, bidirectional_iterator_wrapper>;
+  template<typename T>
+    using test_forward_sized_range
+      = test_sized_range<T, forward_iterator_wrapper>;
+  template<typename T>
+    using test_input_sized_range
+      = test_sized_range<T, input_iterator_wrapper>;
+  template<typename T>
+    using test_output_sized_range
+      = test_sized_range<T, output_iterator_wrapper>;
 #endif // C++20
 } // namespace __gnu_test
 #endif // _TESTSUITE_ITERATORS