[PATCH] Partial implementation of C++20 of <ranges> header
Jonathan Wakely
jwakely@redhat.com
Thu Oct 31 21:57:00 GMT 2019
* 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.
I have lots more of this header written, but I need to finish writing
the tests. This is a start.
Tested powerpc64le-linux, committed to trunk.
-------------- next part --------------
commit 30d052cfd06792c8c317b69129b5ca9031b90391
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Oct 31 19:42:03 2019 +0000
Partial implementation of C++20 of <ranges> header
* 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.
diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 3c0295d99a5..42001016721 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -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 \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 401c87ad103..3e526dc14b7 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -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 \
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index fefd6e76845..57c3e2e32ee 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -138,7 +138,7 @@
// #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
index 00000000000..884fa1d1408
--- /dev/null
+++ b/libstdc++-v3/include/std/ranges
@@ -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 */
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
index 2dbfb767fdb..824b0b4f38c 100644
--- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/std/ranges/access/begin.cc b/libstdc++-v3/testsuite/std/ranges/access/begin.cc
index 100dcf69c6e..e4c245a76bb 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/begin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/begin.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
index 34dd7fec3c6..54db3658896 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
@@ -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;
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
index 9a1ab5b9607..b16c99607a5 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
-#include <iterator>
+#include <ranges>
#include <testsuite_hooks.h>
void
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
index 94349c35d51..3b57b3dbcaf 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
@@ -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;
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
index 24939ac658e..d9e5b0cbef7 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crend.cc b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
index ef0fb0e6b09..e56491973b2 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/data.cc b/libstdc++-v3/testsuite/std/ranges/access/data.cc
index d9129d055fc..49321640182 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/data.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/data.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/empty.cc b/libstdc++-v3/testsuite/std/ranges/access/empty.cc
index 64b1e1b5e1b..9d6aa282142 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/empty.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/empty.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/end.cc b/libstdc++-v3/testsuite/std/ranges/access/end.cc
index 6638bb35721..ed269c5433f 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/end.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/end.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc b/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc
index a2a8fb05f92..0b40d274567 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/end_neg.cc
@@ -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/access/rbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
index 6cfc1a38122..067ddd7ced6 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/rend.cc b/libstdc++-v3/testsuite/std/ranges/access/rend.cc
index 2192825708a..17caa9fb31a 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/rend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/rend.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/size.cc b/libstdc++-v3/testsuite/std/ranges/access/size.cc
index b0a27ca2a87..6e9af7942ec 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/size.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/size.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc b/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc
index 0ba8d81874f..65fce104ff6 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/size_neg.cc
@@ -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
index 00000000000..d4596cc8db5
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/headers/ranges/synopsis.cc
@@ -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
index 00000000000..44869de3ffb
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/range.cc
@@ -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
index 00000000000..0b315397944
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/refinements.cc
@@ -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
index 00000000000..dd685c7a674
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/sized.cc
@@ -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&> );
diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h
index c5ae5b123fe..d20257c1b31 100644
--- a/libstdc++-v3/testsuite/util/testsuite_iterators.h
+++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h
@@ -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
More information about the Gcc-patches
mailing list