LWG-2762 `unique_ptr` `operator*()` should be `noexcept` (#2376)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Omar 2021-12-09 05:44:47 +02:00 коммит произвёл GitHub
Родитель c33d3fd112
Коммит 524cab2959
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 13 добавлений и 55 удалений

Просмотреть файл

@ -3242,7 +3242,7 @@ public:
return _Mypair._Get_first();
}
_NODISCARD add_lvalue_reference_t<_Ty> operator*() const noexcept /* strengthened */ {
_NODISCARD add_lvalue_reference_t<_Ty> operator*() const noexcept(noexcept(*_STD declval<pointer>())) {
return *_Mypair._Myval2;
}

Просмотреть файл

@ -342,38 +342,38 @@ public:
}
}
_NODISCARD constexpr const _Ty* operator->() const {
_NODISCARD constexpr const _Ty* operator->() const noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _STD addressof(this->_Value);
}
_NODISCARD constexpr _Ty* operator->() {
_NODISCARD constexpr _Ty* operator->() noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _STD addressof(this->_Value);
}
_NODISCARD constexpr const _Ty& operator*() const& {
_NODISCARD constexpr const _Ty& operator*() const& noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return this->_Value;
}
_NODISCARD constexpr _Ty& operator*() & {
_NODISCARD constexpr _Ty& operator*() & noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return this->_Value;
}
_NODISCARD constexpr _Ty&& operator*() && {
_NODISCARD constexpr _Ty&& operator*() && noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _STD move(this->_Value);
}
_NODISCARD constexpr const _Ty&& operator*() const&& {
_NODISCARD constexpr const _Ty&& operator*() const&& noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(this->_Has_value, "Cannot access value of empty optional");
#endif // _CONTAINER_DEBUG_LEVEL > 0

Просмотреть файл

@ -4776,14 +4776,7 @@ int run_test()
{
optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(*opt), X&);
// ASSERT_NOT_NOEXCEPT(*opt);
// TODO: This assertion fails with GCC because it can see that
// (A) operator*() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(*opt));
}
{
optional<X> opt(X{});
@ -4847,14 +4840,7 @@ int run_test()
{
const optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(*opt), X const&);
// ASSERT_NOT_NOEXCEPT(*opt);
// TODO: This assertion fails with GCC because it can see that
// (A) operator*() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(*opt));
}
{
constexpr optional<X> opt(X{});
@ -4921,14 +4907,7 @@ int run_test()
{
const optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(*std::move(opt)), X const &&);
// ASSERT_NOT_NOEXCEPT(*std::move(opt));
// TODO: This assertion fails with GCC because it can see that
// (A) operator*() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(*std::move(opt)));
}
{
constexpr optional<X> opt(X{});
@ -5002,14 +4981,7 @@ int run_test()
{
optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(*std::move(opt)), X&&);
// ASSERT_NOT_NOEXCEPT(*std::move(opt));
// TODO: This assertion fails with GCC because it can see that
// (A) operator*() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(*std::move(opt)));
}
{
optional<X> opt(X{});
@ -5119,14 +5091,7 @@ int run_test()
{
std::optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
// ASSERT_NOT_NOEXCEPT(opt.operator->());
// TODO: This assertion fails with GCC because it can see that
// (A) operator->() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(opt.operator->()));
}
{
optional<X> opt(X{});
@ -5195,14 +5160,7 @@ int run_test()
{
const std::optional<X> opt; ((void)opt);
ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*);
// ASSERT_NOT_NOEXCEPT(opt.operator->());
// TODO: This assertion fails with GCC because it can see that
// (A) operator->() is constexpr, and
// (B) there is no path through the function that throws.
// It's arguable if this is the correct behavior for the noexcept
// operator.
// Regardless this function should still be noexcept(false) because
// it has a narrow contract.
STATIC_ASSERT(noexcept(opt.operator->()));
}
{
constexpr optional<X> opt(X{});