* 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.
commit 30d052cfd06792c8c317b69129b5ca9031b90391 Author: Jonathan Wakely <jwak...@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