14#ifdef __cpp_impl_three_way_comparison
22#include <libcopp/utils/config/libcopp_build_features.h>
24LIBCOPP_COPP_NAMESPACE_BEGIN
50 if (
px !=
nullptr && add_ref) {
51 intrusive_ptr_add_ref(
px);
57 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
nullptr)
60 intrusive_ptr_add_ref(
px);
66 intrusive_ptr_add_ref(
px);
72 intrusive_ptr_release(
px);
95 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
nullptr) noexcept
100 template <
typename U,
typename Deleter>
136 inline operator bool() const noexcept {
return px !=
nullptr; }
150template <
typename T,
typename U>
152 return a.get() == b.get();
155template <
typename T,
typename U>
160template <
typename T,
typename U>
165#ifdef __cpp_impl_three_way_comparison
166template <
typename T,
typename U>
167inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &a, intrusive_ptr<U>
const &b)
noexcept {
168 return a.get() <=> b.get();
171template <
typename T,
typename U>
172inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &a, U *b)
noexcept {
173 return a.get() <=> b;
176template <
typename T,
typename U>
177inline std::strong_ordering operator<=>(T *a, intrusive_ptr<U>
const &b)
noexcept {
178 return a <=> b.get();
181template <
typename T,
typename U>
183 return a.get() != b.get();
186template <
typename T,
typename U>
191template <
typename T,
typename U>
196template <
typename T,
typename U>
198 return a.get() < b.get();
201template <
typename T,
typename U>
206template <
typename T,
typename U>
211template <
typename T,
typename U>
213 return a.get() <= b.get();
216template <
typename T,
typename U>
221template <
typename T,
typename U>
226template <
typename T,
typename U>
228 return a.get() > b.get();
231template <
typename T,
typename U>
236template <
typename T,
typename U>
241template <
typename T,
typename U>
243 return a.get() >= b.get();
246template <
typename T,
typename U>
251template <
typename T,
typename U>
260 return p.get() ==
nullptr;
265 return p.get() ==
nullptr;
268#ifdef __cpp_impl_three_way_comparison
270inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &p, std::nullptr_t)
noexcept {
271 return p.get() <=>
nullptr;
275inline std::strong_ordering operator<=>(std::nullptr_t, intrusive_ptr<T>
const &p)
noexcept {
276 return p.get() <=>
nullptr;
281 return p.get() !=
nullptr;
286 return p.get() !=
nullptr;
291 return p.get() <
nullptr;
296 return p.get() <
nullptr;
301 return p.get() <=
nullptr;
306 return p.get() <=
nullptr;
311 return p.get() >
nullptr;
316 return p.get() >
nullptr;
321 return p.get() >=
nullptr;
326 return p.get() >=
nullptr;
342template <
typename T,
typename U>
344 return static_cast<T *
>(p.
get());
347template <
typename T,
typename U>
349 return const_cast<T *
>(p.
get());
352#if defined(LIBCOPP_MACRO_ENABLE_RTTI) && LIBCOPP_MACRO_ENABLE_RTTI
353template <
typename T,
typename U>
354intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U>
const &p) {
355 return dynamic_cast<T *
>(p.get());
360template <
typename E,
typename T,
typename Y>
361std::basic_ostream<E, T> &
operator<<(std::basic_ostream<E, T> &os, intrusive_ptr<Y>
const &p) {
366LIBCOPP_COPP_NAMESPACE_END
368#if LIBCOPP_MACRO_ENABLE_MULTI_THREAD
369# define LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type<size_t>
371# define LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE \
372 LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< \
373 LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type<size_t> >
371# define LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE \ …
376#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_MEMBER_DECL(T) \
379 LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE intrusive_ref_counter_; \
380 friend void intrusive_ptr_add_ref(T *p); \
381 friend void intrusive_ptr_release(T *p); \
384 const size_t use_count() const { return intrusive_ref_counter_.load(); }
376#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_MEMBER_DECL(T) \ …
386#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DECL(T) \
387 void intrusive_ptr_add_ref(T *p); \
388 void intrusive_ptr_release(T *p);
386#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DECL(T) \ …
390#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_MEMBER_INIT() this->intrusive_ref_counter_.store(0)
392#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DEFI(T) \
393 void intrusive_ptr_add_ref(T *p) { \
394 if (nullptr != p) { \
395 ++p->intrusive_ref_counter_; \
398 void intrusive_ptr_release(T *p) { \
399 if (nullptr == p) { \
402 assert(p->intrusive_ref_counter_.load() > 0); \
403 size_t ref = --p->intrusive_ref_counter_; \
392#define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DEFI(T) \ …
constexpr intrusive_ptr() noexcept
intrusive_ptr(self_type const &rhs)
intrusive_ptr & operator=(intrusive_ptr< U > const &rhs)
element_type * get() const noexcept
bool operator!() const noexcept
self_type & operator=(self_type &&rhs) noexcept
intrusive_ptr(T *p, bool add_ref=true)
element_type * operator->() const
intrusive_ptr< T > self_type
intrusive_ptr(intrusive_ptr< U > &&rhs, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr) noexcept
element_type & operator*() const
void swap(intrusive_ptr &rhs) noexcept
self_type & operator=(std::unique_ptr< U, Deleter > &&rhs)
intrusive_ptr(intrusive_ptr< U > const &rhs, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
void reset(element_type *rhs, bool add_ref)
intrusive_ptr(self_type &&rhs) noexcept
element_type * detach() noexcept
self_type & operator=(self_type const &rhs)
void reset(element_type *rhs)
T * get_pointer(intrusive_ptr< T > const &p)
intrusive_ptr< T > const_pointer_cast(intrusive_ptr< U > const &p)
bool operator==(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept
bool operator<(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept
std::basic_ostream< E, T > & operator<<(std::basic_ostream< E, T > &os, intrusive_ptr< Y > const &p)
bool operator>(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept
intrusive_ptr< T > static_pointer_cast(intrusive_ptr< U > const &p)
bool operator<=(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept
void swap(intrusive_ptr< T > &lhs, intrusive_ptr< T > &rhs)
bool operator!=(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept
bool operator>=(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) noexcept