// shared_ptr and weak_ptr implementation -*- C++ -*-
-// Copyright (C) 2007-2020 Free Software Foundation, Inc.
+// Copyright (C) 2007-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
#ifndef _SHARED_PTR_H
#define _SHARED_PTR_H 1
+#include <iosfwd> // std::basic_ostream
#include <bits/shared_ptr_base.h>
namespace std _GLIBCXX_VISIBILITY(default)
/**
* @brief A smart pointer with reference-counted copy semantics.
+ * @headerfile memory
+ * @since C++11
*
* A `shared_ptr` object is either empty or _owns_ a pointer passed
* to the constructor. Copies of a `shared_ptr` share ownership of
#if __cplusplus >= 201703L
# define __cpp_lib_shared_ptr_weak_type 201606
/// The corresponding weak_ptr type for this shared_ptr
+ /// @since C++17
using weak_type = weak_ptr<_Tp>;
#endif
/**
* @param __r A `shared_ptr`.
* @param __p A pointer that will remain valid while `*__r` is valid.
* @post `get() == __p && !__r.use_count() && !__r.get()`
+ * @since C++17
*
* This can be used to construct a `shared_ptr` to a sub-object
* of an object managed by an existing `shared_ptr`. The complete
allocate_shared(const _Alloc& __a, _Args&&... __args);
// This constructor is non-standard, it is used by weak_ptr::lock().
- shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
+ shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
: __shared_ptr<_Tp>(__r, std::nothrow) { }
friend class weak_ptr<_Tp>;
operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !__a; }
+#ifdef __cpp_lib_three_way_comparison
+ template<typename _Tp, typename _Up>
+ inline strong_ordering
+ operator<=>(const shared_ptr<_Tp>& __a,
+ const shared_ptr<_Up>& __b) noexcept
+ { return compare_three_way()(__a.get(), __b.get()); }
+
+ template<typename _Tp>
+ inline strong_ordering
+ operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
+ {
+ using pointer = typename shared_ptr<_Tp>::element_type*;
+ return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
+ }
+#else
/// shared_ptr comparison with nullptr
template<typename _Tp>
_GLIBCXX_NODISCARD inline bool
_GLIBCXX_NODISCARD inline bool
operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(nullptr < __a); }
+#endif
// 20.7.2.2.8 shared_ptr specialized algorithms.
#if __cplusplus >= 201703L
/// Convert type of `shared_ptr`, via `reinterpret_cast`
+ /// @since C++17
template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
// 2996. Missing rvalue overloads for shared_ptr operations
/// Convert type of `shared_ptr` rvalue, via `static_cast`
+ /// @since C++20
template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
}
/// Convert type of `shared_ptr` rvalue, via `const_cast`
+ /// @since C++20
template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
}
/// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
+ /// @since C++20
template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
}
/// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
+ /// @since C++20
template<typename _Tp, typename _Up>
inline shared_ptr<_Tp>
reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
#endif // C++20
#endif // C++17
- // @}
+ /// @}
/**
* @brief A non-owning observer for a pointer owned by a shared_ptr
+ * @headerfile memory
+ * @since C++11
*
* A weak_ptr provides a safe alternative to a raw pointer when you want
* a non-owning reference to an object that is managed by a shared_ptr.
{ };
/**
- * @brief Base class allowing use of member function shared_from_this.
+ * @brief Base class allowing use of the member function `shared_from_this`.
+ * @headerfile memory
+ * @since C++11
*/
template<typename _Tp>
class enable_shared_from_this
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
#define __cpp_lib_enable_shared_from_this 201603
+ /** @{
+ * Get a `weak_ptr` referring to the object that has `*this` as its base.
+ * @since C++17
+ */
weak_ptr<_Tp>
weak_from_this() noexcept
{ return this->_M_weak_this; }
weak_ptr<const _Tp>
weak_from_this() const noexcept
{ return this->_M_weak_this; }
+ /// @}
#endif
private:
inline shared_ptr<_Tp>
allocate_shared(const _Alloc& __a, _Args&&... __args)
{
+ static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
+
return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
std::forward<_Args>(__args)...);
}
}
};
- // @} relates shared_ptr
- // @} group pointer_abstractions
+ /// @} relates shared_ptr
+ /// @} group pointer_abstractions
#if __cplusplus >= 201703L
namespace __detail::__variant