mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[libc++][memory] Applied [[nodiscard]] to smart pointers (#168483)
Applied `[[nodiscard]]` where relevant to smart pointers and related functions. - [x] - `std::unique_ptr` - [x] - `std::shared_ptr` - [x] - `std::weak_ptr` See guidelines: - https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant - `[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. For example a locking constructor in unique_lock. --------- Co-authored-by: Hristo Hristov <zingam@outlook.com>
This commit is contained in:
@@ -568,37 +568,43 @@ public:
|
||||
shared_ptr(__p, __d, __a).swap(*this);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT {
|
||||
return *__ptr_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {
|
||||
static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
|
||||
return __ptr_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
|
||||
return __cntrl_ ? __cntrl_->use_count() : 0;
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
|
||||
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }
|
||||
[[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT {
|
||||
return use_count() == 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
|
||||
return __cntrl_ < __p.__cntrl_;
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
|
||||
return __cntrl_ < __p.__cntrl_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
_LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
|
||||
static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
|
||||
return __ptr_[__i];
|
||||
}
|
||||
@@ -669,7 +675,7 @@ shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
|
||||
// std::allocate_shared and std::make_shared
|
||||
//
|
||||
template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
|
||||
using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
|
||||
using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
|
||||
__allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
|
||||
@@ -680,21 +686,21 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&
|
||||
}
|
||||
|
||||
template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
|
||||
return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
|
||||
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
|
||||
_ForOverwriteAllocator __alloc(__a);
|
||||
return std::allocate_shared<_Tp>(__alloc);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
|
||||
return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>());
|
||||
}
|
||||
|
||||
@@ -886,67 +892,69 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _
|
||||
|
||||
// bounded array variants
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
|
||||
return std::__allocate_shared_bounded_array<_Tp>(__a);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
|
||||
allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
|
||||
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
|
||||
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
|
||||
_ForOverwriteAllocator __alloc(__a);
|
||||
return std::__allocate_shared_bounded_array<_Tp>(__alloc);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
|
||||
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
|
||||
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
|
||||
return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
|
||||
}
|
||||
|
||||
// unbounded array variants
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
|
||||
allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
|
||||
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
|
||||
_ForOverwriteAllocator __alloc(__a);
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
|
||||
}
|
||||
|
||||
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
|
||||
return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
|
||||
}
|
||||
|
||||
@@ -1075,7 +1083,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __
|
||||
}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
|
||||
static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
|
||||
}
|
||||
|
||||
@@ -1083,13 +1092,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_pt
|
||||
// We don't backport because it is an evolutionary change.
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
[[__nodiscard__]] inline
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
typedef typename shared_ptr<_Tp>::element_type _ET;
|
||||
_ET* __p = dynamic_cast<_ET*>(__r.get());
|
||||
return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
|
||||
@@ -1099,14 +1109,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_p
|
||||
// We don't backport because it is an evolutionary change.
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
|
||||
return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
typedef typename shared_ptr<_Tp>::element_type _RTp;
|
||||
return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
|
||||
}
|
||||
@@ -1115,13 +1125,13 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>&
|
||||
// We don't backport because it is an evolutionary change.
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
|
||||
return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
|
||||
}
|
||||
|
||||
@@ -1129,7 +1139,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<
|
||||
// We don't backport because it is an evolutionary change.
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
|
||||
return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
|
||||
}
|
||||
#endif
|
||||
@@ -1137,7 +1147,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&&
|
||||
#if _LIBCPP_HAS_RTTI
|
||||
|
||||
template <class _Dp, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
|
||||
return __p.template __get_deleter<_Dp>();
|
||||
}
|
||||
|
||||
@@ -1192,15 +1202,19 @@ public:
|
||||
_LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT;
|
||||
_LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
|
||||
_LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; }
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
|
||||
return __cntrl_ ? __cntrl_->use_count() : 0;
|
||||
}
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT {
|
||||
return __cntrl_ == nullptr || __cntrl_->use_count() == 0;
|
||||
}
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
|
||||
return __cntrl_ < __r.__cntrl_;
|
||||
}
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
|
||||
return __cntrl_ < __r.__cntrl_;
|
||||
}
|
||||
|
||||
@@ -1384,13 +1398,15 @@ protected:
|
||||
_LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const {
|
||||
return shared_ptr<const _Tp>(__weak_this_);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
_LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
|
||||
#endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
template <class _Up>
|
||||
|
||||
@@ -258,14 +258,17 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
|
||||
_NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
|
||||
return *__ptr_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
|
||||
return __deleter_;
|
||||
}
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type&
|
||||
get_deleter() const _NOEXCEPT {
|
||||
return __deleter_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
|
||||
@@ -748,12 +751,13 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
|
||||
template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
|
||||
return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
|
||||
}
|
||||
|
||||
template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
|
||||
typedef __remove_extent_t<_Tp> _Up;
|
||||
return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
|
||||
}
|
||||
@@ -766,12 +770,13 @@ void make_unique(_Args&&...) = delete;
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
|
||||
return unique_ptr<_Tp>(new _Tp);
|
||||
}
|
||||
|
||||
template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp>
|
||||
make_unique_for_overwrite(size_t __n) {
|
||||
return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,19 +6,144 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// REQUIRES: std-at-least-c++23
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
// <memory>
|
||||
|
||||
// Check that functions are marked [[nodiscard]]
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
void test() {
|
||||
{ // [unique.ptr]
|
||||
std::unique_ptr<int> uPtr;
|
||||
|
||||
*uPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
uPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
uPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
const std::unique_ptr<int> cuPtr;
|
||||
cuPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
|
||||
#if TEST_STD_VER >= 14
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_unique<int>(94);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_unique<int[]>(82);
|
||||
#endif
|
||||
#if TEST_STD_VER >= 20
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_unique_for_overwrite<int>();
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_unique_for_overwrite<int[]>(5);
|
||||
#endif
|
||||
}
|
||||
{ // [util.sharedptr]
|
||||
std::shared_ptr<int[]> sPtr;
|
||||
|
||||
sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
*sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
sPtr.owner_before(std::shared_ptr<int>());
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
sPtr.owner_before(std::weak_ptr<int>());
|
||||
#if TEST_STD_VER >= 17
|
||||
sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
#endif
|
||||
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared<int>(std::allocator<int>(), 5);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared<int>();
|
||||
#if TEST_STD_VER >= 20
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared_for_overwrite<int>(std::allocator<int>());
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared_for_overwrite<int>();
|
||||
|
||||
// Bounded array variants
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared<int[5]>(std::allocator<int>());
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared<int[5]>(std::allocator<int>(), 5);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared_for_overwrite<int[5]>(std::allocator<int>());
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared<int[5]>();
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared<int[5]>(94);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared_for_overwrite<int[5]>();
|
||||
|
||||
// Unbounded array variants
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared<int[]>(std::allocator<int>(), 5);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared<int[]>(std::allocator<int>(), 5, 94);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::allocate_shared_for_overwrite<int[]>(std::allocator<int>(), 5);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared<int[]>(5);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared<int[]>(5, 82);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::make_shared_for_overwrite<int[]>(5);
|
||||
#endif
|
||||
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::static_pointer_cast<int[]>(sPtr);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::static_pointer_cast<int[]>(std::move(sPtr));
|
||||
class Empty {};
|
||||
std::shared_ptr<Empty> dsPtr;
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::dynamic_pointer_cast<Empty>(dsPtr);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::dynamic_pointer_cast<Empty>(std::move(dsPtr));
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::const_pointer_cast<int[]>(sPtr);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::const_pointer_cast<int[]>(std::move(sPtr));
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::reinterpret_pointer_cast<int[]>(sPtr);
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::reinterpret_pointer_cast<int[]>(std::move(sPtr));
|
||||
#if !defined(TEST_HAS_NO_RTTI)
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
std::get_deleter<int[]>(sPtr);
|
||||
#endif
|
||||
}
|
||||
{ // [util.smartptr.weak]
|
||||
std::weak_ptr<int> wPtr;
|
||||
|
||||
wPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
wPtr.expired(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
wPtr.lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
wPtr.owner_before(std::weak_ptr<int>());
|
||||
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
wPtr.owner_before(std::shared_ptr<int>());
|
||||
}
|
||||
{ // [util.smartptr.enab]
|
||||
class EnableShared : public std::enable_shared_from_this<EnableShared> {};
|
||||
EnableShared es;
|
||||
const EnableShared ces;
|
||||
|
||||
es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
#if TEST_STD_VER >= 17
|
||||
es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
#endif
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
{ // [smartptr.adapt]
|
||||
std::unique_ptr<int> uPtr;
|
||||
// [inout.ptr]
|
||||
std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
|
||||
void f() {
|
||||
const std::shared_ptr<int> p;
|
||||
p.unique(); // expected-warning {{'unique' is deprecated}}
|
||||
(void)p.unique(); // expected-warning {{'unique' is deprecated}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user