forked from OSchip/llvm-project
[libc++] Remove conditional noexcepts from view_interface.
As suggested in D117966. These conditional noexcepts are *permitted* by the Standard (as long as there were no mistakes in them, I guess); but not *mandated*. The Standard doesn't put any noexcept-specifications on these member functions. The same logic would apply to `transform_view::iterator::operator*` and `transform_view::iterator::operator[]`, but the Standard mandates conditional noexcept on `iter_move(transform_view::iterator)`, and I think it doesn't make much sense to say "moving from this iterator is conditionally noexcept but not-moving from it is noexcept(false)," so I'm leaving transform_view alone for now. Differential Revision: https://reviews.llvm.org/D119374
This commit is contained in:
parent
c9c9307301
commit
7bdf41653c
|
@ -9,6 +9,8 @@
|
|||
#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
|
||||
#define _LIBCPP___RANGES_VIEW_INTERFACE_H
|
||||
|
||||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__config>
|
||||
#include <__debug>
|
||||
#include <__iterator/concepts.h>
|
||||
|
@ -18,7 +20,6 @@
|
|||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/empty.h>
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -31,12 +32,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
template<class _Tp>
|
||||
concept __can_empty = requires(_Tp __t) { ranges::empty(__t); };
|
||||
|
||||
template<class _Tp>
|
||||
void __implicitly_convert_to(type_identity_t<_Tp>) noexcept;
|
||||
|
||||
template<class _Derived>
|
||||
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
|
||||
class view_interface {
|
||||
|
@ -55,7 +50,6 @@ class view_interface {
|
|||
public:
|
||||
template<class _D2 = _Derived>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
|
||||
noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
|
||||
requires forward_range<_D2>
|
||||
{
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
|
@ -63,7 +57,6 @@ public:
|
|||
|
||||
template<class _D2 = _Derived>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
|
||||
noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
|
||||
requires forward_range<const _D2>
|
||||
{
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
|
@ -72,8 +65,7 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit operator bool()
|
||||
noexcept(noexcept(ranges::empty(declval<_D2>())))
|
||||
requires __can_empty<_D2>
|
||||
requires requires (_D2& __t) { ranges::empty(__t); }
|
||||
{
|
||||
return !ranges::empty(__derived());
|
||||
}
|
||||
|
@ -81,8 +73,7 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit operator bool() const
|
||||
noexcept(noexcept(ranges::empty(declval<const _D2>())))
|
||||
requires __can_empty<const _D2>
|
||||
requires requires (const _D2& __t) { ranges::empty(__t); }
|
||||
{
|
||||
return !ranges::empty(__derived());
|
||||
}
|
||||
|
@ -90,7 +81,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto data()
|
||||
noexcept(noexcept(std::to_address(ranges::begin(__derived()))))
|
||||
requires contiguous_iterator<iterator_t<_D2>>
|
||||
{
|
||||
return std::to_address(ranges::begin(__derived()));
|
||||
|
@ -99,7 +89,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto data() const
|
||||
noexcept(noexcept(std::to_address(ranges::begin(__derived()))))
|
||||
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
|
||||
{
|
||||
return std::to_address(ranges::begin(__derived()));
|
||||
|
@ -108,9 +97,7 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size()
|
||||
noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
|
||||
requires forward_range<_D2>
|
||||
&& sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
|
||||
requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
|
||||
{
|
||||
return ranges::end(__derived()) - ranges::begin(__derived());
|
||||
}
|
||||
|
@ -118,9 +105,7 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const
|
||||
noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
|
||||
requires forward_range<const _D2>
|
||||
&& sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
|
||||
requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
|
||||
{
|
||||
return ranges::end(__derived()) - ranges::begin(__derived());
|
||||
}
|
||||
|
@ -128,7 +113,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) front()
|
||||
noexcept(noexcept(*ranges::begin(__derived())))
|
||||
requires forward_range<_D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
|
@ -139,7 +123,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) front() const
|
||||
noexcept(noexcept(*ranges::begin(__derived())))
|
||||
requires forward_range<const _D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
|
@ -150,7 +133,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) back()
|
||||
noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
|
||||
requires bidirectional_range<_D2> && common_range<_D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
|
@ -161,7 +143,6 @@ public:
|
|||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) back() const
|
||||
noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
|
||||
requires bidirectional_range<const _D2> && common_range<const _D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
|
@ -172,7 +153,6 @@ public:
|
|||
template<random_access_range _RARange = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
|
||||
noexcept(noexcept(ranges::begin(__derived())[__index]))
|
||||
{
|
||||
return ranges::begin(__derived())[__index];
|
||||
}
|
||||
|
@ -180,7 +160,6 @@ public:
|
|||
template<random_access_range _RARange = const _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
|
||||
noexcept(noexcept(ranges::begin(__derived())[__index]))
|
||||
{
|
||||
return ranges::begin(__derived())[__index];
|
||||
}
|
||||
|
|
|
@ -126,17 +126,16 @@ struct DataIsNull : std::ranges::view_interface<DataIsNull> {
|
|||
};
|
||||
static_assert(std::ranges::view<DataIsNull>);
|
||||
|
||||
template<bool IsNoexcept>
|
||||
struct BoolConvertibleComparison : std::ranges::view_interface<BoolConvertibleComparison<IsNoexcept>> {
|
||||
struct BoolConvertibleComparison : std::ranges::view_interface<BoolConvertibleComparison> {
|
||||
struct ResultType {
|
||||
bool value;
|
||||
constexpr operator bool() const noexcept(IsNoexcept) { return value; }
|
||||
constexpr operator bool() const { return value; }
|
||||
};
|
||||
|
||||
struct SentinelType {
|
||||
int *base_;
|
||||
SentinelType() = default;
|
||||
explicit constexpr SentinelType(int *base) : base_(base) {}
|
||||
explicit SentinelType() = default;
|
||||
constexpr explicit SentinelType(int *base) : base_(base) {}
|
||||
friend constexpr ResultType operator==(ForwardIter const& iter, SentinelType const& sent) noexcept { return {iter.base() == sent.base_}; }
|
||||
friend constexpr ResultType operator==(SentinelType const& sent, ForwardIter const& iter) noexcept { return {iter.base() == sent.base_}; }
|
||||
friend constexpr ResultType operator!=(ForwardIter const& iter, SentinelType const& sent) noexcept { return {iter.base() != sent.base_}; }
|
||||
|
@ -144,11 +143,10 @@ struct BoolConvertibleComparison : std::ranges::view_interface<BoolConvertibleCo
|
|||
};
|
||||
|
||||
int buff[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
constexpr ForwardIter begin() const noexcept { return ForwardIter(const_cast<int*>(buff)); }
|
||||
constexpr SentinelType end() const noexcept { return SentinelType(const_cast<int*>(buff) + 8); }
|
||||
constexpr ForwardIter begin() const { return ForwardIter(const_cast<int*>(buff)); }
|
||||
constexpr SentinelType end() const { return SentinelType(const_cast<int*>(buff) + 8); }
|
||||
};
|
||||
static_assert(std::ranges::view<BoolConvertibleComparison<true>>);
|
||||
static_assert(std::ranges::view<BoolConvertibleComparison<false>>);
|
||||
static_assert(std::ranges::view<BoolConvertibleComparison>);
|
||||
|
||||
template<class T>
|
||||
concept EmptyInvocable = requires (T const& obj) { obj.empty(); };
|
||||
|
@ -189,19 +187,17 @@ constexpr bool testEmpty() {
|
|||
MoveOnlyForwardRange moveOnly;
|
||||
assert(!std::move(moveOnly).empty());
|
||||
|
||||
BoolConvertibleComparison<true> boolConv;
|
||||
BoolConvertibleComparison<false> boolConv2;
|
||||
LIBCPP_ASSERT_NOEXCEPT(boolConv.empty());
|
||||
ASSERT_NOT_NOEXCEPT(boolConv2.empty());
|
||||
BoolConvertibleComparison boolConv;
|
||||
ASSERT_NOT_NOEXCEPT(boolConv.empty());
|
||||
|
||||
assert(!boolConv.empty());
|
||||
assert(!static_cast<BoolConvertibleComparison<true> const&>(boolConv).empty());
|
||||
assert(!static_cast<const BoolConvertibleComparison&>(boolConv).empty());
|
||||
|
||||
assert(boolConv);
|
||||
assert(static_cast<BoolConvertibleComparison<true> const&>(boolConv));
|
||||
assert(static_cast<const BoolConvertibleComparison&>(boolConv));
|
||||
|
||||
assert(!std::ranges::empty(boolConv));
|
||||
assert(!std::ranges::empty(static_cast<BoolConvertibleComparison<true> const&>(boolConv)));
|
||||
assert(!std::ranges::empty(static_cast<const BoolConvertibleComparison&>(boolConv)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue