aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2020-02-20 13:20:44 +0000
committerJonathan Wakely <jwakely@redhat.com>2020-02-20 13:22:29 +0000
commite817c23f6806a6b9201a0a1f77b51cb863af51e9 (patch)
treea1ae7cf999a4a9cd604d98d347412df661b24aac /libstdc++-v3/include
parent4be779f59b04947324889b7e1488fb9a68c81d53 (diff)
downloadgcc-e817c23f6806a6b9201a0a1f77b51cb863af51e9.zip
gcc-e817c23f6806a6b9201a0a1f77b51cb863af51e9.tar.gz
gcc-e817c23f6806a6b9201a0a1f77b51cb863af51e9.tar.bz2
libstdc++: Issues with range access CPOs (P2091R0)
This changes how arrays of unknown bound and/or incomplete element type are handled. * include/bits/range_access.h (ranges::begin): Reject array of incomplete type. (ranges::end, ranges::size): Require arrays to be bounded. (ranges::data): Require lvalue or borrowed_range. (ranges::iterator_t): Remove constraint. * testsuite/std/ranges/access/begin.cc: Do not check array of incomplete type. * testsuite/std/ranges/access/begin_neg.cc: New test. * testsuite/std/ranges/access/end_neg.cc: Adjust expected error. * testsuite/std/ranges/access/size_neg.cc: Adjust expected error. * testsuite/std/ranges/access/ssize.cc: Do not check array of incomplete type.
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/bits/range_access.h42
1 files changed, 23 insertions, 19 deletions
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index e7a1930..eb91ade 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -382,8 +382,8 @@ namespace ranges
{ __decay_copy(__t.begin()) } -> input_or_output_iterator;
};
- template<typename _Tp> void begin(_Tp&&) = delete;
- template<typename _Tp> void begin(initializer_list<_Tp>&&) = delete;
+ void begin(auto&) = delete;
+ void begin(const auto&) = delete;
template<typename _Tp>
concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
@@ -417,7 +417,9 @@ namespace ranges
if constexpr (is_array_v<remove_reference_t<_Tp>>)
{
static_assert(is_lvalue_reference_v<_Tp>);
- return __t;
+ using _Up = remove_all_extents_t<remove_reference_t<_Tp>>;
+ static_assert(sizeof(_Up) != 0, "not array of incomplete type");
+ return __t + 0;
}
else if constexpr (__member_begin<_Tp>)
return __t.begin();
@@ -433,8 +435,8 @@ namespace ranges
-> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
};
- template<typename _Tp> void end(_Tp&&) = delete;
- template<typename _Tp> void end(initializer_list<_Tp>&&) = delete;
+ void end(auto&) = delete;
+ void end(const auto&) = delete;
template<typename _Tp>
concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
@@ -451,7 +453,7 @@ namespace ranges
static constexpr bool
_S_noexcept()
{
- if constexpr (is_array_v<remove_reference_t<_Tp>>)
+ if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
return true;
else if constexpr (__member_end<_Tp>)
return noexcept(__decay_copy(std::declval<_Tp&>().end()));
@@ -461,15 +463,14 @@ namespace ranges
public:
template<__maybe_borrowed_range _Tp>
- requires is_array_v<remove_reference_t<_Tp>> || __member_end<_Tp>
+ requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_end<_Tp>
|| __adl_end<_Tp>
constexpr auto
operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
{
- if constexpr (is_array_v<remove_reference_t<_Tp>>)
+ if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
{
static_assert(is_lvalue_reference_v<_Tp>);
- static_assert(is_bounded_array_v<remove_reference_t<_Tp>>);
return __t + extent_v<remove_reference_t<_Tp>>;
}
else if constexpr (__member_end<_Tp>)
@@ -519,7 +520,8 @@ namespace ranges
{ __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
};
- template<typename _Tp> void rbegin(_Tp&&) = delete;
+ void rbegin(auto&) = delete;
+ void rbegin(const auto&) = delete;
template<typename _Tp>
concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
@@ -582,7 +584,8 @@ namespace ranges
-> sentinel_for<decltype(_RBegin{}(__t))>;
};
- template<typename _Tp> void rend(_Tp&&) = delete;
+ void rend(auto&) = delete;
+ void rend(const auto&) = delete;
template<typename _Tp>
concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
@@ -664,7 +667,8 @@ namespace ranges
-> __detail::__is_integer_like;
};
- template<typename _Tp> void size(_Tp&&) = delete;
+ void size(auto&) = delete;
+ void size(const auto&) = delete;
template<typename _Tp>
concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
@@ -691,7 +695,7 @@ namespace ranges
static constexpr bool
_S_noexcept()
{
- if constexpr (is_array_v<remove_reference_t<_Tp>>)
+ if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
return true;
else if constexpr (__member_size<_Tp>)
return noexcept(__decay_copy(std::declval<_Tp>().size()));
@@ -704,14 +708,13 @@ namespace ranges
public:
template<typename _Tp>
- requires is_array_v<remove_reference_t<_Tp>>
+ requires is_bounded_array_v<remove_reference_t<_Tp>>
|| __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
constexpr auto
operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
{
- if constexpr (is_array_v<remove_reference_t<_Tp>>)
+ if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
{
- static_assert(is_bounded_array_v<remove_reference_t<_Tp>>);
return extent_v<remove_reference_t<_Tp>>;
}
else if constexpr (__member_size<_Tp>)
@@ -826,7 +829,8 @@ namespace ranges
}
public:
- template<typename _Tp> requires __member_data<_Tp> || __begin_data<_Tp>
+ template<__maybe_borrowed_range _Tp>
+ requires __member_data<_Tp> || __begin_data<_Tp>
constexpr auto
operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
{
@@ -881,8 +885,8 @@ namespace ranges
concept borrowed_range
= range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
- template<range _Range>
- using iterator_t = decltype(ranges::begin(std::declval<_Range&>()));
+ template<typename _Tp>
+ using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));
template<range _Range>
using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));