Commit 328b52d6 by Jonathan Wakely Committed by Jonathan Wakely

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.

From-SVN: r277697
parent d5a9005e
2019-10-31 Jonathan Wakely <jwakely@redhat.com> 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. * testsuite/20_util/add_pointer/value.cc: Check void types.
* include/bits/range_access.h (__sizable): Rename to __sentinel_size. * include/bits/range_access.h (__sizable): Rename to __sentinel_size.
......
...@@ -829,6 +829,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \ ...@@ -829,6 +829,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \
include/ostream \ include/ostream \
include/queue \ include/queue \
include/random \ include/random \
include/ranges \
include/ratio \ include/ratio \
include/regex \ include/regex \
include/scoped_allocator \ include/scoped_allocator \
......
...@@ -64,6 +64,7 @@ std_headers = \ ...@@ -64,6 +64,7 @@ std_headers = \
${std_srcdir}/ostream \ ${std_srcdir}/ostream \
${std_srcdir}/queue \ ${std_srcdir}/queue \
${std_srcdir}/random \ ${std_srcdir}/random \
${std_srcdir}/ranges \
${std_srcdir}/ratio \ ${std_srcdir}/ratio \
${std_srcdir}/regex \ ${std_srcdir}/regex \
${std_srcdir}/scoped_allocator \ ${std_srcdir}/scoped_allocator \
......
...@@ -408,6 +408,7 @@ std_headers = \ ...@@ -408,6 +408,7 @@ std_headers = \
${std_srcdir}/ostream \ ${std_srcdir}/ostream \
${std_srcdir}/queue \ ${std_srcdir}/queue \
${std_srcdir}/random \ ${std_srcdir}/random \
${std_srcdir}/ranges \
${std_srcdir}/ratio \ ${std_srcdir}/ratio \
${std_srcdir}/regex \ ${std_srcdir}/regex \
${std_srcdir}/scoped_allocator \ ${std_srcdir}/scoped_allocator \
......
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
// #include <compare> // #include <compare>
#include <concepts> #include <concepts>
#include <numbers> #include <numbers>
// #include <ranges> #include <ranges>
#include <span> #include <span>
// #include <syncstream> // #include <syncstream>
#include <version> #include <version>
......
// <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 */
...@@ -78,6 +78,9 @@ namespace std ...@@ -78,6 +78,9 @@ namespace std
struct unreachable_sentinel_t; struct unreachable_sentinel_t;
} }
struct I { };
template<> constexpr bool std::disable_sized_sentinel<I, I> = true;
namespace __gnu_test namespace __gnu_test
{ {
// customization points // customization points
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
using std::same_as; using std::same_as;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
void void
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
using std::same_as; using std::same_as;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } } // { dg-do compile { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
extern int unbounded[]; extern int unbounded[];
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
#include <iterator> #include <ranges>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
#include <testsuite_iterators.h> #include <testsuite_iterators.h>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" } // { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } } // { dg-do compile { target c++2a } }
#include <iterator> // N.B. should be <ranges> #include <ranges>
extern int unbounded[]; extern int unbounded[];
......
// 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;
}
// 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>> );
// 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>> );
// 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&> );
...@@ -95,7 +95,7 @@ namespace __gnu_test ...@@ -95,7 +95,7 @@ namespace __gnu_test
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template<class U> template<class U>
typename std::enable_if<std::is_assignable<T&, U>::value>::type 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); ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
SharedInfo->writtento[ptr - SharedInfo->first] = 1; SharedInfo->writtento[ptr - SharedInfo->first] = 1;
...@@ -720,6 +720,25 @@ namespace __gnu_test ...@@ -720,6 +720,25 @@ namespace __gnu_test
typename Iter<T>::ContainerType bounds; 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 // A type meeting the minimum std::sized_range requirements
template<typename T, template<typename> class Iter> template<typename T, template<typename> class Iter>
struct test_sized_range : test_range<T, Iter> struct test_sized_range : test_range<T, Iter>
...@@ -729,6 +748,25 @@ namespace __gnu_test ...@@ -729,6 +748,25 @@ namespace __gnu_test
std::size_t size() const noexcept std::size_t size() const noexcept
{ return this->bounds.size(); } { 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 #endif // C++20
} // namespace __gnu_test } // namespace __gnu_test
#endif // _TESTSUITE_ITERATORS #endif // _TESTSUITE_ITERATORS
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment