diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-10-31 21:42:18 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-10-31 21:42:18 +0000 |
commit | 328b52d6751733f6e0f2d31feca44e1d8f2abfc6 (patch) | |
tree | df343cd7a1cd3846feea7c59d9679cfb0e96c126 | |
parent | d5a9005e641f25c0363c3998ed2fa9abc826a289 (diff) | |
download | gcc-328b52d6751733f6e0f2d31feca44e1d8f2abfc6.zip gcc-328b52d6751733f6e0f2d31feca44e1d8f2abfc6.tar.gz gcc-328b52d6751733f6e0f2d31feca44e1d8f2abfc6.tar.bz2 |
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
26 files changed, 488 insertions, 16 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2a47289..1004d76 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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. diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in index 3c0295d..4200101 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 401c87a..3e526dc 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/Makefile.in b/libstdc++-v3/include/Makefile.in index e0a7496..d9eb306 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -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 \ diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index fefd6e7..57c3e2e 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 0000000..884fa1d1 --- /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 2dbfb76..824b0b4 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 100dcf6..e4c245a 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 34dd7fec..54db365 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 9a1ab5b..b16c996 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 94349c3..3b57b3d 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 24939ac..d9e5b0c 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 ef0fb0e..e564919 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 d9129d0..4932164 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 64b1e1b..9d6aa28 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 6638bb3..ed269c5 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 a2a8fb0..0b40d27 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 6cfc1a3..067ddd7 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 2192825..17caa9f 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 b0a27ca..6e9af79 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 0ba8d81..65fce10 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 0000000..d4596cc --- /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 0000000..44869de --- /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 0000000..0b31539 --- /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 0000000..dd685c7 --- /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 c5ae5b1..d20257c 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 |