aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-10-31 13:17:48 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-10-31 13:17:48 +0000
commitb3ffa117e5cc0e0451ab1fb2aafd6ca56258912b (patch)
tree290c2c9e5ea352b33b0f217bb8a5022ea4230a62
parentbeaecb2d6b2f3c48740b7b8749ee2d2468c8dc14 (diff)
downloadgcc-b3ffa117e5cc0e0451ab1fb2aafd6ca56258912b.zip
gcc-b3ffa117e5cc0e0451ab1fb2aafd6ca56258912b.tar.gz
gcc-b3ffa117e5cc0e0451ab1fb2aafd6ca56258912b.tar.bz2
Remove PR 92268 workaround and fix new test failures
With the compiler bug fixed we can simplify the __sizable concept to use a return-type-requirement again. I also realised it was redundantly re-checking a subset of the sized_sentinel_for requirements. The compiler fix also revealed bugs in two tests which started to fail and are fixed by this patch. * include/bits/range_access.h (__sizable): Rename to __sentinel_size. Remove workaround for PR c++/92268 and remove redundant requirements that are already checked by sized_sentinel_for. * testsuite/std/ranges/access/cend.cc: Fix failures. * testsuite/std/ranges/access/end.cc: Likewise. From-SVN: r277667
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/include/bits/range_access.h22
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/cend.cc11
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/end.cc20
4 files changed, 34 insertions, 25 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 542a350..d51a7d4 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
2019-10-31 Jonathan Wakely <jwakely@redhat.com>
+ * include/bits/range_access.h (__sizable): Rename to __sentinel_size.
+ Remove workaround for PR c++/92268 and remove redundant requirements
+ that are already checked by sized_sentinel_for.
+ * testsuite/std/ranges/access/cend.cc: Fix failures.
+ * testsuite/std/ranges/access/end.cc: Likewise.
+
* include/bits/range_access.h (ranges::begin): Combine array and
non-array overloads into one function template. Only use ADL for
classes and enums.
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index f0a3392..de07446 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -689,19 +689,13 @@ namespace ranges
-> __detail::__is_integer_like;
};
- // FIXME: needed due to PR c++/92268
- template<forward_iterator _It, sized_sentinel_for<_It> _End>
- requires requires (_It __it, _End __end)
- { { __end - __it } -> __detail::__is_integer_like; }
- void
- __subtractable_fwd_iter(_It, _End)
- { }
-
template<typename _Tp>
- concept __sizable = requires(_Tp&& __t)
+ concept __sentinel_size = requires(_Tp&& __t)
{
- __subtractable_fwd_iter(_Begin{}(std::forward<_Tp>(__t)),
- _End{}(std::forward<_Tp>(__t)));
+ { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
+
+ { _End{}(std::forward<_Tp>(__t)) }
+ -> sized_sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
};
struct _Size
@@ -717,7 +711,7 @@ namespace ranges
return noexcept(__decay_copy(std::declval<_Tp>().size()));
else if constexpr (__adl_size<_Tp>)
return noexcept(__decay_copy(size(std::declval<_Tp>())));
- else if constexpr (__sizable<_Tp>)
+ else if constexpr (__sentinel_size<_Tp>)
return noexcept(_End{}(std::declval<_Tp>())
- _Begin{}(std::declval<_Tp>()));
}
@@ -725,7 +719,7 @@ namespace ranges
public:
template<typename _Tp>
requires is_array_v<remove_reference_t<_Tp>>
- || __member_size<_Tp> || __adl_size<_Tp> || __sizable<_Tp>
+ || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
constexpr auto
operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
{
@@ -738,7 +732,7 @@ namespace ranges
return std::forward<_Tp>(__e).size();
else if constexpr (__adl_size<_Tp>)
return size(std::forward<_Tp>(__e));
- else if constexpr (__sizable<_Tp>)
+ else if constexpr (__sentinel_size<_Tp>)
return __detail::__to_unsigned_like(
_End{}(std::forward<_Tp>(__e))
- _Begin{}(std::forward<_Tp>(__e)));
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
index 789c6ca..94349c3 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
@@ -66,15 +66,18 @@ struct RR
long l = 0;
int a[4] = { 0, 1, 2, 3 };
- const void* begin() const { return nullptr; }
- friend const void* begin(const RR&&) noexcept { return nullptr; }
+ const void* begin() const; // return type not an iterator
+ friend int* end(RR&) { throw 1; }
short* end() noexcept { return &s; }
+
+ friend const long* begin(const RR&) noexcept;
const long* end() const { return &l; }
- friend int* end(RR&) { throw 1; }
+ friend int* begin(RR&&) noexcept;
friend int* end(RR&& r) { return r.a + 1; }
- friend const int* end(const RR&) { throw 1; }
+
+ friend const int* begin(const RR&&) noexcept;
friend const int* end(const RR&& r) noexcept { return r.a + 3; }
};
diff --git a/libstdc++-v3/testsuite/std/ranges/access/end.cc b/libstdc++-v3/testsuite/std/ranges/access/end.cc
index 7f09cc2..6638bb3 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/end.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/end.cc
@@ -61,11 +61,12 @@ struct R
{
int a[4] = { 0, 1, 2, 3 };
- const int* begin() const { return nullptr; }
- friend const int* begin(const R&& r) noexcept { return nullptr; }
+ const int* begin() const;
+ friend int* begin(R&&) noexcept;
+ friend const int* begin(const R&&) noexcept;
// Should be ignored because it doesn't return a sentinel for int*
- const long* end() const { return nullptr; }
+ const long* end() const;
friend int* end(R& r) { return r.a + 0; }
friend int* end(R&& r) { return r.a + 1; }
@@ -105,15 +106,20 @@ struct RR
long l = 0;
int a[4] = { 0, 1, 2, 3 };
- const void* begin() const { return nullptr; }
- friend const void* begin(const RR&&) noexcept { return nullptr; }
+ const void* begin() const; // return type not an iterator
+ friend const short* begin(RR&) noexcept;
short* end() noexcept { return &s; }
+
+ friend const long* begin(const RR&) noexcept;
const long* end() const { return &l; }
- friend int* end(RR&) { throw 1; }
+ friend const int* begin(RR&&) noexcept;
+ friend int* end(RR&) { throw 1; } // not valid for rvalues
friend int* end(RR&& r) { return r.a + 1; }
- friend const int* end(const RR&) { throw 1; }
+
+ friend const int* begin(const RR&&) noexcept;
+ friend const int* end(const RR&) { throw 1; } // not valid for rvalues
friend const int* end(const RR&& r) noexcept { return r.a + 3; }
};