23 #ifdef __cpp_impl_three_way_comparison
30 #include <libcopp/utils/config/libcopp_build_features.h>
32 LIBCOPP_COPP_NAMESPACE_BEGIN
58 if (
px !=
nullptr && add_ref) {
59 intrusive_ptr_add_ref(
px);
65 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
nullptr)
68 intrusive_ptr_add_ref(
px);
74 intrusive_ptr_add_ref(
px);
80 intrusive_ptr_release(
px);
101 template <
typename U>
103 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
nullptr) LIBCOPP_MACRO_NOEXCEPT
108 template <
typename U,
typename Deleter>
144 inline operator bool()
const LIBCOPP_MACRO_NOEXCEPT {
return px !=
nullptr; }
158 template <
typename T,
typename U>
160 return a.get() == b.get();
163 template <
typename T,
typename U>
168 template <
typename T,
typename U>
173 #ifdef __cpp_impl_three_way_comparison
174 template <
typename T,
typename U>
175 inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &a, intrusive_ptr<U>
const &b) LIBCOPP_MACRO_NOEXCEPT {
176 return a.get() <=> b.get();
179 template <
typename T,
typename U>
180 inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &a, U *b) LIBCOPP_MACRO_NOEXCEPT {
181 return a.get() <=> b;
184 template <
typename T,
typename U>
185 inline std::strong_ordering operator<=>(T *a, intrusive_ptr<U>
const &b) LIBCOPP_MACRO_NOEXCEPT {
186 return a <=> b.get();
189 template <
typename T,
typename U>
191 return a.get() != b.get();
194 template <
typename T,
typename U>
199 template <
typename T,
typename U>
204 template <
typename T,
typename U>
206 return a.get() < b.get();
209 template <
typename T,
typename U>
214 template <
typename T,
typename U>
219 template <
typename T,
typename U>
221 return a.get() <= b.get();
224 template <
typename T,
typename U>
229 template <
typename T,
typename U>
234 template <
typename T,
typename U>
236 return a.get() > b.get();
239 template <
typename T,
typename U>
244 template <
typename T,
typename U>
249 template <
typename T,
typename U>
251 return a.get() >= b.get();
254 template <
typename T,
typename U>
259 template <
typename T,
typename U>
266 template <
typename T>
268 return p.get() ==
nullptr;
271 template <
typename T>
273 return p.get() ==
nullptr;
276 #ifdef __cpp_impl_three_way_comparison
277 template <
typename T>
278 inline std::strong_ordering operator<=>(intrusive_ptr<T>
const &p, std::nullptr_t) LIBCOPP_MACRO_NOEXCEPT {
279 return p.get() <=>
nullptr;
282 template <
typename T>
283 inline std::strong_ordering operator<=>(std::nullptr_t, intrusive_ptr<T>
const &p) LIBCOPP_MACRO_NOEXCEPT {
284 return p.get() <=>
nullptr;
287 template <
typename T>
289 return p.get() !=
nullptr;
292 template <
typename T>
294 return p.get() !=
nullptr;
297 template <
typename T>
299 return p.get() <
nullptr;
302 template <
typename T>
304 return p.get() <
nullptr;
307 template <
typename T>
309 return p.get() <=
nullptr;
312 template <
typename T>
314 return p.get() <=
nullptr;
317 template <
typename T>
319 return p.get() >
nullptr;
322 template <
typename T>
324 return p.get() >
nullptr;
327 template <
typename T>
329 return p.get() >=
nullptr;
332 template <
typename T>
334 return p.get() >=
nullptr;
338 template <
typename T>
345 template <
typename T>
350 template <
typename T,
typename U>
352 return static_cast<T *
>(p.
get());
355 template <
typename T,
typename U>
357 return const_cast<T *
>(p.
get());
360 #if defined(LIBCOPP_MACRO_ENABLE_RTTI) && LIBCOPP_MACRO_ENABLE_RTTI
361 template <
typename T,
typename U>
362 intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U>
const &p) {
363 return dynamic_cast<T *
>(p.get());
368 template <
typename E,
typename T,
typename Y>
369 std::basic_ostream<E, T> &
operator<<(std::basic_ostream<E, T> &os, intrusive_ptr<Y>
const &p) {
374 LIBCOPP_COPP_NAMESPACE_END
376 #if defined(LIBCOPP_LOCK_DISABLE_MT) && LIBCOPP_LOCK_DISABLE_MT
377 # define LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE \
378 LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< \
379 LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type<size_t> >
381 # define LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type<size_t>
384 #define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_MEMBER_DECL(T) \
387 LIBCOPP_UTIL_INTRUSIVE_PTR_ATOMIC_TYPE intrusive_ref_counter_; \
388 friend void intrusive_ptr_add_ref(T *p); \
389 friend void intrusive_ptr_release(T *p); \
392 const size_t use_count() const { return intrusive_ref_counter_.load(); }
394 #define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DECL(T) \
395 void intrusive_ptr_add_ref(T *p); \
396 void intrusive_ptr_release(T *p);
398 #define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_MEMBER_INIT() this->intrusive_ref_counter_.store(0)
400 #define LIBCOPP_UTIL_INTRUSIVE_PTR_REF_FN_DEFI(T) \
401 void intrusive_ptr_add_ref(T *p) { \
402 if (nullptr != p) { \
403 ++p->intrusive_ref_counter_; \
406 void intrusive_ptr_release(T *p) { \
407 if (nullptr == p) { \
410 assert(p->intrusive_ref_counter_.load() > 0); \
411 size_t ref = --p->intrusive_ref_counter_; \
intrusive_ptr & operator=(intrusive_ptr< U > const &rhs)
element_type * detach() LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr(intrusive_ptr< U > const &rhs, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
void swap(intrusive_ptr &rhs) LIBCOPP_MACRO_NOEXCEPT
self_type & operator=(std::unique_ptr< U, Deleter > &&rhs)
element_type & operator*() const
void reset(element_type *rhs, bool add_ref)
constexpr intrusive_ptr() LIBCOPP_MACRO_NOEXCEPT
self_type & operator=(self_type &&rhs) LIBCOPP_MACRO_NOEXCEPT
void reset() LIBCOPP_MACRO_NOEXCEPT
element_type * get() const LIBCOPP_MACRO_NOEXCEPT
void reset(element_type *rhs)
bool operator!() const LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr(self_type const &rhs)
element_type * operator->() const
self_type & operator=(self_type const &rhs)
intrusive_ptr(T *p, bool add_ref=true)
intrusive_ptr(self_type &&rhs) LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr(intrusive_ptr< U > &&rhs, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr) LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr< T > self_type
bool operator>(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) LIBCOPP_MACRO_NOEXCEPT
bool operator<(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr< T > static_pointer_cast(intrusive_ptr< U > const &p)
bool operator==(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) LIBCOPP_MACRO_NOEXCEPT
bool operator>=(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) LIBCOPP_MACRO_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) LIBCOPP_MACRO_NOEXCEPT
T * get_pointer(intrusive_ptr< T > const &p)
bool operator!=(intrusive_ptr< T > const &a, intrusive_ptr< U > const &b) LIBCOPP_MACRO_NOEXCEPT
intrusive_ptr< T > const_pointer_cast(intrusive_ptr< U > const &p)
void swap(intrusive_ptr< T > &lhs, intrusive_ptr< T > &rhs)