Commit 37f33df7 by Jonathan Wakely Committed by Jonathan Wakely

libstdc++: Define C++20 range utilities and range factories

This adds another chunk of the <ranges> header.

The changes from P1456R1 (Move-only views) and P1862R1 (Range adaptors
for non-copyable iterators) are included, but not the changes from
P1870R1 (forwarding-range<T> is too subtle).

The tests for subrange and iota_view are poor and should be improved.

	* include/bits/regex.h (match_results): Specialize __enable_view_impl.
	* include/bits/stl_set.h (set): Likewise.
	* include/bits/unordered_set.h (unordered_set, unordered_multiset):
	Likewise.
	* include/debug/multiset.h (__debug::multiset): Likewise.
	* include/debug/set.h (__debug::set): Likewise.
	* include/debug/unordered_set (__debug::unordered_set)
	(__debug::unordered_multiset): Likewise.
	* include/std/ranges (ranges::view, ranges::enable_view)
	(ranges::view_interface, ranges::subrange, ranges::empty_view)
	(ranges::single_view, ranges::views::single, ranges::iota_view)
	(ranges::views::iota): Define for C++20.
	* testsuite/std/ranges/empty_view.cc: New test.
	* testsuite/std/ranges/iota_view.cc: New test.
	* testsuite/std/ranges/single_view.cc: New test.
	* testsuite/std/ranges/view.cc: New test.

From-SVN: r278370
parent efbd2539
2019-11-17 Jonathan Wakely <jwakely@redhat.com>
* include/bits/regex.h (match_results): Specialize __enable_view_impl.
* include/bits/stl_set.h (set): Likewise.
* include/bits/unordered_set.h (unordered_set, unordered_multiset):
Likewise.
* include/debug/multiset.h (__debug::multiset): Likewise.
* include/debug/set.h (__debug::set): Likewise.
* include/debug/unordered_set (__debug::unordered_set)
(__debug::unordered_multiset): Likewise.
* include/std/ranges (ranges::view, ranges::enable_view)
(ranges::view_interface, ranges::subrange, ranges::empty_view)
(ranges::single_view, ranges::views::single, ranges::iota_view)
(ranges::views::iota): Define for C++20.
* testsuite/std/ranges/empty_view.cc: New test.
* testsuite/std/ranges/iota_view.cc: New test.
* testsuite/std/ranges/single_view.cc: New test.
* testsuite/std/ranges/view.cc: New test.
2019-11-16 Jonathan Wakely <jwakely@redhat.com>
* include/std/ranges: Revert accidentally committed changes.
......
......@@ -2056,9 +2056,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
match_results<_Bi_iter, _Alloc>& __rhs) noexcept
{ __lhs.swap(__rhs); }
_GLIBCXX_END_NAMESPACE_CXX11
#if __cplusplus > 201703L
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Bi_iter, typename _Alloc>
inline constexpr bool __enable_view_impl<match_results<_Bi_iter, _Alloc>>
= false;
} // namespace ranges::__detail
#endif // C++20
// [28.11.2] Function template regex_match
/**
* @name Matching, Searching, and Replacing
......
......@@ -1039,6 +1039,16 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
{ return __set._M_t; }
};
#if __cplusplus > 201703L
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Key, typename _Compare, typename _Alloc>
inline constexpr bool
__enable_view_impl<_GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>>
= false;
} // namespace ranges::__detail
#endif // C++20
#endif // C++17
_GLIBCXX_END_NAMESPACE_VERSION
......
......@@ -1051,6 +1051,15 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set)
{ return __set._M_t; }
};
#if __cplusplus > 201703L
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Key, typename _Compare, typename _Alloc>
inline constexpr bool
__enable_view_impl<_GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>> = false;
} // namespace ranges::__detail
#endif // C++20
#endif // C++17
_GLIBCXX_END_NAMESPACE_VERSION
......
......@@ -1771,6 +1771,21 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
{ return __set._M_h; }
};
#if __cplusplus > 201703L
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
inline constexpr bool
__enable_view_impl<_GLIBCXX_STD_C::unordered_set<_Val, _Hash, _Eq,
_Alloc>> = false;
template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
inline constexpr bool
__enable_view_impl<_GLIBCXX_STD_C::unordered_multiset<_Val, _Hash, _Eq,
_Alloc>> = false;
} // namespace ranges::__detail
#endif // C++20
#endif // C++17
_GLIBCXX_END_NAMESPACE_VERSION
......
......@@ -630,6 +630,19 @@ namespace __debug
{ return __x.swap(__y); }
} // namespace __debug
#if __cplusplus > 201703L
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Key, typename _Compare, typename _Alloc>
inline constexpr bool
__enable_view_impl<std::__debug::multiset<_Key, _Compare, _Alloc>>
= false;
} // namespace ranges::__detail
_GLIBCXX_END_NAMESPACE_VERSION
#endif // C++20
} // namespace std
#endif
......@@ -641,6 +641,18 @@ namespace __debug
{ return __x.swap(__y); }
} // namespace __debug
#if __cplusplus > 201703L
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Key, typename _Compare, typename _Alloc>
inline constexpr bool
__enable_view_impl<std::__debug::set<_Key, _Compare, _Alloc>> = false;
} // namespace ranges::__detail
_GLIBCXX_END_NAMESPACE_VERSION
#endif // C++20
} // namespace std
#endif
......@@ -1183,6 +1183,22 @@ namespace __debug
{ return !(__x == __y); }
} // namespace __debug
#if __cplusplus > 201703L
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges::__detail
{
template<typename _Tp> inline constexpr bool __enable_view_impl;
template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
inline constexpr bool
__enable_view_impl<std::__debug::unordered_set<_Val, _Hash, _Eq, _Alloc>>
= false;
template<typename _Val, typename _Hash, typename _Eq, typename _Alloc>
inline constexpr bool
__enable_view_impl<std::__debug::unordered_multiset<_Val, _Hash, _Eq,
_Alloc>> = false;
} // namespace ranges::__detail
_GLIBCXX_END_NAMESPACE_VERSION
#endif // C++20
} // namespace std
#endif // C++11
......
// 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>
static_assert(std::ranges::view<std::ranges::empty_view<int>>);
std::ranges::empty_view<int> e;
static_assert(std::ranges::empty(e));
static_assert(0 == e.size());
static_assert(e.begin() == nullptr);
static_assert(e.end() == nullptr);
static_assert(e.data() == nullptr);
static_assert(e.empty());
static_assert(begin(e) == nullptr);
static_assert(end(e) == nullptr);
// 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 run { target c++2a } }
#include <ranges>
#include <testsuite_hooks.h>
void
test01()
{
int vals[5] = { };
int* out = vals;
for (int i : std::ranges::iota_view{1, 4})
*out++ = i;
VERIFY(out == vals + 3);
VERIFY(vals[0] == 1);
VERIFY(vals[1] == 2);
VERIFY(vals[2] == 3);
VERIFY(vals[3] == 0);
}
void
test02()
{
auto v = std::ranges::views::iota(4);
auto it = v.begin();
VERIFY( *it == 4 );
++it;
VERIFY( *it == 5 );
it++;
VERIFY( *it == 6 );
}
void
test03()
{
auto v = std::ranges::views::iota(10, 15);
auto it = v.begin();
VERIFY( *it == 10 );
it += 2;
VERIFY( *it == 12 );
it += 2;
VERIFY( *it == 14 );
++it;
VERIFY( it == v.end() );
}
int
main()
{
test01();
test02();
test03();
}
// 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 run { target c++2a } }
#include <ranges>
#include <testsuite_hooks.h>
void
test01()
{
std::ranges::single_view s{4};
static_assert(std::same_as<std::ranges::range_value_t<decltype(s)>, int>);
static_assert(std::ranges::size(s) == 1);
int count = 0;
for (auto i : s)
++count;
VERIFY(count == 1);
VERIFY(*std::ranges::begin(s) == 4);
}
void
test02()
{
std::ranges::single_view<long> s2;
static_assert(std::same_as<std::ranges::range_value_t<decltype(s2)>, long>);
static_assert(std::ranges::size(s2) == 1);
int count = 0;
for (auto l : s2)
++count;
VERIFY(count == 1);
VERIFY(*std::ranges::begin(s2) == 0L);
}
void
test03()
{
auto s3 = std::ranges::views::single('a');
static_assert(std::same_as<std::ranges::range_value_t<decltype(s3)>, char>);
static_assert(std::ranges::size(s3) == 1);
VERIFY(*std::ranges::begin(s3) == 'a');
}
int main()
{
test01();
test02();
test03();
}
// 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 <vector>
#include <set>
#include <unordered_set>
#include <regex>
#include <testsuite_iterators.h>
static_assert(std::ranges::view<std::vector<int>>);
static_assert(!std::ranges::view<const std::vector<int>>);
static_assert(!std::ranges::view<std::initializer_list<int>>);
static_assert(!std::ranges::view<const std::initializer_list<int>>);
static_assert(!std::ranges::view<std::set<int>>);
static_assert(!std::ranges::view<const std::set<int>>);
static_assert(!std::ranges::view<std::multiset<int>>);
static_assert(!std::ranges::view<std::unordered_set<int>>);
static_assert(!std::ranges::view<std::unordered_multiset<int>>);
static_assert(!std::ranges::view<std::cmatch>);
// const test_random_access_range<T> is not a range:
static_assert(!std::ranges::view<__gnu_test::test_random_access_range<int>>);
template<typename T>
struct test_view
: __gnu_test::test_random_access_range<T>, std::ranges::view_base
{
// views must be default-initializable:
test_view() : __gnu_test::test_random_access_range<T>(nullptr, nullptr) { }
};
static_assert(std::ranges::view<test_view<int>>);
template<>
constexpr bool std::ranges::enable_view<test_view<long>> = false;
static_assert(!std::ranges::view<test_view<long>>);
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