1 #ifndef CYCLE_PTR_CYCLE_PTR_H 2 #define CYCLE_PTR_CYCLE_PTR_H 11 #include <cycle_ptr/detail/intrusive_ptr.h> 12 #include <cycle_ptr/detail/control.h> 13 #include <cycle_ptr/detail/vertex.h> 37 template<
typename T,
typename Alloc,
typename... Args>
38 auto allocate_cycle(Alloc alloc, Args&&... args) ->
cycle_gptr<T>;
63 : control_(detail::base_control::publisher_lookup(this, sizeof(*this)))
72 : control_(detail::base_control::unowned_control())
121 assert(control_ !=
nullptr);
127 if (control_->under_construction)
128 throw std::bad_weak_ptr();
131 if (!control_->weak_acquire())
throw std::bad_weak_ptr();
132 result.emplace_(this_ptr, control_);
151 class cycle_member_ptr
152 :
private detail::vertex
155 template<
typename>
friend class cycle_gptr;
156 template<
typename>
friend class cycle_weak_ptr;
276 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
278 : detail::vertex(detail::base_control::unowned_control()),
281 ptr.throw_if_owner_expired();
282 this->detail::vertex::reset(ptr.get_control(),
false,
false);
323 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
365 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
367 : detail::vertex(detail::base_control::unowned_control()),
370 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
411 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
413 : detail::vertex(detail::base_control::unowned_control()),
414 target_(std::
exchange(ptr.target_, nullptr))
416 this->detail::vertex::reset(
417 std::move(ptr.target_ctrl_),
441 : detail::vertex(detail::base_control::unowned_control()),
444 ptr.throw_if_owner_expired();
445 this->detail::vertex::reset(ptr.get_control(),
false,
false);
466 : detail::vertex(detail::base_control::unowned_control()),
469 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
508 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
524 : vertex(owner.control_)
553 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
555 : detail::vertex(owner.control_),
558 ptr.throw_if_owner_expired();
559 this->detail::vertex::reset(ptr.get_control(),
false,
false);
576 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
594 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
596 : detail::vertex(owner.control_),
599 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
616 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
618 : detail::vertex(owner.control_),
619 target_(std::
exchange(ptr.target_, nullptr))
621 this->detail::vertex::reset(
622 std::move(ptr.target_ctrl_),
648 : detail::vertex(owner.control_),
651 ptr.throw_if_owner_expired();
652 this->detail::vertex::reset(ptr.get_control(),
false,
false);
677 : detail::vertex(owner.control_),
680 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
693 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
757 : target_(ptr.target_)
759 ptr.throw_if_owner_expired();
760 this->detail::vertex::reset(ptr.get_control(),
false,
false);
808 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
810 : target_(ptr.target_)
812 ptr.throw_if_owner_expired();
813 this->detail::vertex::reset(ptr.get_control(),
false,
false);
837 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
862 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
864 : target_(ptr.target_)
866 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
890 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
892 : target_(std::
exchange(ptr.target_, nullptr))
894 this->detail::vertex::reset(
895 std::move(ptr.target_ctrl_),
924 ptr.throw_if_owner_expired();
925 this->detail::vertex::reset(ptr.get_control(),
false,
false);
953 this->detail::vertex::reset(ptr.target_ctrl_,
false,
true);
974 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1004 this->detail::vertex::reset(other.get_control(),
false,
false);
1005 target_ = other.target_;
1022 if (
this != &other) [[likely]] {
1037 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1042 this->detail::vertex::reset(other.get_control(),
false,
false);
1043 target_ = other.target_;
1058 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1073 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1076 this->detail::vertex::reset(other.target_ctrl_,
false,
true);
1077 target_ = other.target_;
1091 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1094 this->detail::vertex::reset(
1095 std::move(other.target_ctrl_),
1097 target_ = std::exchange(other.target_,
nullptr);
1110 this->detail::vertex::reset();
1125 std::tie(*
this, other) = std::forward_as_tuple(
1141 std::tie(*
this, other) = std::forward_as_tuple(
1162 template<
bool Enable = !std::is_
void_v<T>>
1164 -> std::enable_if_t<Enable, T>& {
1165 assert(
get() !=
nullptr);
1175 template<
bool Enable = !std::is_
void_v<T>>
1177 -> std::enable_if_t<Enable, T>* {
1178 assert(
get() !=
nullptr);
1187 explicit operator bool()
const {
1188 return get() !=
nullptr;
1192 template<
typename U>
1200 template<
typename U>
1208 template<
typename U>
1217 T* target_ =
nullptr;
1231 template<
typename T>
1233 template<
typename>
friend class cycle_member_ptr;
1235 template<
typename>
friend class cycle_weak_ptr;
1236 friend class cycle_base;
1238 template<
typename Type,
typename Alloc,
typename... Args>
1239 friend auto cycle_ptr::allocate_cycle(Alloc alloc, Args&&... args) -> cycle_gptr<Type>;
1253 constexpr
cycle_gptr([[maybe_unused]] std::nullptr_t nil) noexcept
1263 : target_(other.target_),
1264 target_ctrl_(other.target_ctrl_)
1266 if (target_ctrl_ !=
nullptr) target_ctrl_->acquire_no_red();
1278 : target_(std::exchange(other.target_,
nullptr)),
1279 target_ctrl_(other.target_ctrl_.detach(),
false)
1287 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1289 : target_(other.target_),
1290 target_ctrl_(other.target_ctrl_)
1292 if (target_ctrl_ !=
nullptr) target_ctrl_->acquire_no_red();
1303 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1305 : target_(std::exchange(other.target_,
nullptr)),
1306 target_ctrl_(other.target_ctrl_.detach(),
false)
1316 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1318 : target_(other.target_),
1319 target_ctrl_(other.get_control())
1321 other.throw_if_owner_expired();
1322 if (target_ctrl_ !=
nullptr) target_ctrl_->acquire();
1335 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1350 template<
typename U>
1353 target_ctrl_(other.target_ctrl_)
1355 if (target_ctrl_ !=
nullptr) target_ctrl_->acquire_no_red();
1368 template<
typename U>
1371 target_ctrl_(other.get_control())
1373 other.throw_if_owner_expired();
1374 if (target_ctrl_ !=
nullptr) target_ctrl_->acquire();
1384 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1386 : target_(other.target_),
1387 target_ctrl_(other.target_ctrl_)
1389 if (target_ctrl_ ==
nullptr || !target_ctrl_->weak_acquire())
1390 throw std::bad_weak_ptr();
1402 if (bc !=
nullptr) bc->acquire_no_red();
1404 target_ = other.target_;
1405 bc.swap(target_ctrl_);
1406 if (bc !=
nullptr) bc->release(bc == target_ctrl_);
1422 auto bc = std::move(other.target_ctrl_);
1424 target_ = std::exchange(other.target_,
nullptr);
1425 bc.swap(target_ctrl_);
1426 if (bc !=
nullptr) bc->release(bc == target_ctrl_);
1436 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1441 if (bc !=
nullptr) bc->acquire_no_red();
1443 target_ = other.target_;
1444 bc.swap(target_ctrl_);
1445 if (bc !=
nullptr) bc->release(bc == target_ctrl_);
1458 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1462 auto bc = std::move(other.target_ctrl_);
1464 target_ = std::exchange(other.target_,
nullptr);
1465 bc.swap(target_ctrl_);
1466 if (bc !=
nullptr) bc->release(bc == target_ctrl_);
1478 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1481 other.throw_if_owner_expired();
1484 if (bc !=
nullptr) bc->acquire();
1486 target_ = other.target_;
1487 bc.swap(target_ctrl_);
1488 if (bc !=
nullptr) bc->release(bc == target_ctrl_);
1503 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1512 if (target_ctrl_ !=
nullptr)
1513 target_ctrl_->release();
1524 if (target_ctrl_ !=
nullptr) {
1526 target_ctrl_->release();
1527 target_ctrl_.reset();
1542 std::swap(target_, other.target_);
1543 target_ctrl_.swap(other.target_ctrl_);
1574 template<
bool Enable = !std::is_
void_v<T>>
1576 -> std::enable_if_t<Enable, T>& {
1577 assert(
get() !=
nullptr);
1585 template<
bool Enable = !std::is_
void_v<T>>
1587 -> std::enable_if_t<Enable, T>* {
1588 assert(
get() !=
nullptr);
1596 explicit operator bool() const noexcept {
1597 return get() !=
nullptr;
1601 template<
typename U>
1605 return target_ctrl_ < other.target_ctrl_;
1609 template<
typename U>
1613 return target_ctrl_ < other.target_ctrl_;
1617 template<
typename U>
1621 return target_ctrl_ < other.get_control();
1648 assert(new_target_ctrl ==
nullptr || new_target !=
nullptr);
1649 assert(target_ctrl_ ==
nullptr);
1651 target_ = new_target;
1652 target_ctrl_ = std::move(new_target_ctrl);
1656 T* target_ =
nullptr;
1658 detail::intrusive_ptr<detail::base_control> target_ctrl_ =
nullptr;
1669 template<
typename T>
1670 class cycle_weak_ptr {
1671 template<
typename>
friend class cycle_member_ptr;
1672 template<
typename>
friend class cycle_gptr;
1684 : target_(other.target_),
1685 target_ctrl_(other.target_ctrl_)
1694 : target_(std::exchange(other.target_,
nullptr)),
1695 target_ctrl_(other.target_ctrl_.detach(),
false)
1699 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1701 : target_(other.target_),
1702 target_ctrl_(other.target_ctrl_)
1707 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1709 : target_(std::exchange(other.target_,
nullptr)),
1710 target_ctrl_(other.target_ctrl_.detach(),
false)
1715 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1717 : target_(other.target_),
1718 target_ctrl_(other.target_ctrl_)
1723 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1725 : target_(other.target_),
1726 target_ctrl_(other.get_control())
1733 target_ = other.target_;
1734 target_ctrl_ = other.target_ctrl_;
1743 target_ = std::exchange(other.target_,
nullptr);
1744 target_ctrl_.reset(other.target_ctrl_.detach(),
false);
1749 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1753 target_ = other.target_;
1754 target_ctrl_ = other.target_ctrl_;
1760 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1764 target_ = std::exchange(other.target_,
nullptr);
1765 target_ctrl_.reset(other.target_ctrl_.detach(),
false);
1771 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1775 target_ = other.target_;
1776 target_ctrl_ = other.target_ctrl_;
1782 template<
typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
1786 target_ = other.target_;
1787 target_ctrl_ = other.get_control();
1797 target_ctrl_.reset();
1804 std::swap(target_, other.target_);
1805 target_ctrl_.swap(other.target_ctrl_);
1813 return target_ctrl_ ==
nullptr || target_ctrl_->expired();
1826 if (target_ctrl_ !=
nullptr && target_ctrl_->weak_acquire())
1827 result.emplace_(target_, target_ctrl_);
1832 template<
typename U>
1836 return target_ctrl_ < other.target_ctrl_;
1840 template<
typename U>
1844 return target_ctrl_ < other.target_ctrl_;
1848 template<
typename U>
1852 return target_ctrl_ < other.get_control();
1857 T* target_ =
nullptr;
1865 template<
typename T,
typename U>
1869 return x.get() == y.get();
1874 template<
typename T>
1883 template<
typename U>
1892 template<
typename T,
typename U>
1901 template<
typename T>
1910 template<
typename U>
1919 template<
typename T,
typename U>
1923 return x.get() < y.get();
1928 template<
typename T>
1932 return std::less<typename cycle_member_ptr<T>::element_type*>()(x.get(),
nullptr);
1937 template<
typename U>
1941 return std::less<typename cycle_member_ptr<U>::element_type*>()(
nullptr, y.get());
1946 template<
typename T,
typename U>
1955 template<
typename T>
1964 template<
typename U>
1973 template<
typename T,
typename U>
1982 template<
typename T>
1986 return !(
nullptr < x);
1991 template<
typename U>
1995 return !(y <
nullptr);
2000 template<
typename T,
typename U>
2009 template<
typename T>
2013 return !(x <
nullptr);
2018 template<
typename U>
2022 return !(
nullptr < y);
2027 template<
typename T>
2037 template<
typename T>
2047 template<
typename T,
typename U>
2051 return x.get() == y.get();
2056 template<
typename T>
2065 template<
typename U>
2074 template<
typename T,
typename U>
2083 template<
typename T>
2092 template<
typename U>
2101 template<
typename T,
typename U>
2105 return x.get() < y.get();
2110 template<
typename T>
2114 return std::less<typename cycle_gptr<T>::element_type*>()(x.get(),
nullptr);
2119 template<
typename U>
2123 return std::less<typename cycle_gptr<U>::element_type*>()(
nullptr, y.get());
2128 template<
typename T,
typename U>
2137 template<
typename T>
2146 template<
typename U>
2155 template<
typename T,
typename U>
2164 template<
typename T>
2168 return !(
nullptr < x);
2173 template<
typename U>
2177 return !(y <
nullptr);
2182 template<
typename T,
typename U>
2191 template<
typename T>
2195 return !(x <
nullptr);
2200 template<
typename U>
2204 return !(
nullptr < y);
2209 template<
typename T>
2219 template<
typename T>
2229 template<
typename T>
2240 template<
typename T,
typename U>
2244 return x.get() == y.get();
2250 template<
typename T,
typename U>
2254 return x.get() == y.get();
2260 template<
typename T,
typename U>
2270 template<
typename T,
typename U>
2280 template<
typename T,
typename U>
2284 return x.get() < y.get();
2290 template<
typename T,
typename U>
2294 return x.get() < y.get();
2300 template<
typename T,
typename U>
2310 template<
typename T,
typename U>
2320 template<
typename T,
typename U>
2330 template<
typename T,
typename U>
2340 template<
typename T,
typename U>
2350 template<
typename T,
typename U>
2369 template<
typename T,
typename Alloc,
typename... Args>
2372 using alloc_t =
typename std::allocator_traits<Alloc>::template rebind_alloc<T>;
2374 using alloc_traits =
typename std::allocator_traits<Alloc>::template rebind_traits<control_t>;
2375 using ctrl_alloc_t =
typename std::allocator_traits<Alloc>::template rebind_alloc<control_t>;
2377 ctrl_alloc_t ctrl_alloc = alloc;
2379 control_t* raw_ctrl_ptr = alloc_traits::allocate(ctrl_alloc, 1);
2381 alloc_traits::construct(ctrl_alloc, raw_ctrl_ptr, ctrl_alloc);
2383 alloc_traits::deallocate(ctrl_alloc, raw_ctrl_ptr, 1);
2387 T* elem_ptr = raw_ctrl_ptr->instantiate(std::forward<Args>(args)...);
2390 result.emplace_(elem_ptr, std::move(ctrl_ptr));
2406 template<
typename T,
typename... Args>
2409 return allocate_cycle<T>(std::allocator<T>(), std::forward<Args>(args)...);
2415 template<
typename Char,
typename Traits,
typename T>
2417 -> std::basic_ostream<Char, Traits>& {
2418 return out << ptr.get();
2423 template<
typename Char,
typename Traits,
typename T>
2425 -> std::basic_ostream<Char, Traits>& {
2426 return out << ptr.get();
2445 template<
typename T,
typename U = cycle_ptr::cycle_gptr<T>>
2448 x = std::forward<U>(y);
2459 template<
typename T>
2460 struct hash<cycle_ptr::cycle_member_ptr<T>> {
2479 return std::hash<typename cycle_ptr::cycle_member_ptr<T>::element_type*>()(p.get());
2491 return std::hash<typename cycle_ptr::cycle_gptr<T>::element_type*>()(p.get());
2502 template<
typename T>
2503 struct hash<cycle_ptr::cycle_gptr<T>>
2504 : hash<cycle_ptr::cycle_member_ptr<T>>
2515 template<
typename T,
typename U>
2525 template<
typename T,
typename U>
2535 template<
typename T,
typename U>
2545 template<
typename T,
typename U>
2556 template<
typename T,
typename U>
2566 template<
typename T,
typename U>
2576 template<
typename T,
typename U>
2586 template<
typename T,
typename U>
auto operator<(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:1929
auto operator=(cycle_weak_ptr< U > &&other) noexcept -> cycle_weak_ptr &
Move assignment.
Definition: cycle_ptr.h:1761
cycle_member_ptr(cycle_base &owner, [[maybe_unused]] std::nullptr_t nil) noexcept
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:538
auto operator<(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:2281
auto operator>=([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2019
auto operator()(const cycle_ptr::cycle_gptr< T > &p) const noexcept -> std::size_t
Compute the hashcode of a cycle pointer.
Definition: cycle_ptr.h:2488
cycle_gptr(cycle_gptr< U > &&other) noexcept
Move constructor.
Definition: cycle_ptr.h:1304
constexpr cycle_gptr() noexcept
Default constructor.
Definition: cycle_ptr.h:1249
cycle_member_ptr(cycle_base &owner, const cycle_member_ptr< U > &ptr)
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:554
cycle_base([[maybe_unused]] unowned_cycle_t unowned_tag)
Specialized constructor that signifies *this will not be pointed at by a cycle_ptr.
Definition: cycle_ptr.h:71
auto operator<=(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:2156
auto const_pointer_cast(const cycle_ptr::cycle_gptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform const cast on pointer.
Definition: cycle_ptr.h:2536
auto dynamic_pointer_cast(const cycle_ptr::cycle_gptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform dynamic cast on pointer.
Definition: cycle_ptr.h:2526
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag, const cycle_member_ptr< U > &ptr)
Create an unowned member pointer, pointing at ptr.
Definition: cycle_ptr.h:277
auto operator *() const -> std::enable_if_t< Enable, T > &
Dereference operation.
Definition: cycle_ptr.h:1575
auto operator=(const cycle_weak_ptr &other) noexcept -> cycle_weak_ptr &
Copy assignment.
Definition: cycle_ptr.h:1730
auto static_pointer_cast(const cycle_ptr::cycle_member_ptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform static cast on pointer.
Definition: cycle_ptr.h:2557
auto operator>(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:1947
auto operator!=(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:2084
std::remove_extent_t< T > element_type
Element type of this pointer.
Definition: cycle_ptr.h:1243
Adaptor for collections with member types.
Definition: allocator.h:19
auto lock() const noexcept -> cycle_gptr< T >
Retrieve cycle_gptr from this.
Definition: cycle_ptr.h:1822
cycle_member_ptr(const cycle_member_ptr< U > &ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:809
cycle_member_ptr(cycle_base &owner, const cycle_gptr< U > &ptr, element_type *target)
Aliasing constructor with explicitly specified ownership.
Definition: cycle_ptr.h:676
auto allocate_cycle(Alloc alloc, Args &&... args) -> cycle_gptr< T >
Allocate a new instance of T, using the specificied allocator.
Definition: cycle_ptr.h:2370
cycle_base(const cycle_base &) noexcept
Copy constructor.
Definition: cycle_ptr.h:85
auto operator=(const cycle_base &) noexcept -> cycle_base &
Copy assignment.
Definition: cycle_ptr.h:95
auto operator<<(std::basic_ostream< Char, Traits > &out, const cycle_gptr< T > &ptr) -> std::basic_ostream< Char, Traits > &
Write pointer to output stream.
Definition: cycle_ptr.h:2424
auto throw_if_owner_expired() const -> void
Throw exception if owner is expired.
Definition: vertex.h:57
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag, const cycle_member_ptr< U > &ptr, element_type *target)
Aliasing constructor for unowned member pointer.
Definition: cycle_ptr.h:440
cycle_member_ptr(cycle_member_ptr< U > &&ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:838
auto operator<=(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:2165
auto operator>=([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2201
auto swap(cycle_gptr &other) noexcept -> void
Swap with other.
Definition: cycle_ptr.h:1539
auto dynamic_pointer_cast(const cycle_ptr::cycle_member_ptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform dynamic cast on pointer.
Definition: cycle_ptr.h:2567
auto owner_before(const cycle_weak_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1833
auto operator>(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:2138
cycle_base()
Default constructor acquires its control block from context.
Definition: cycle_ptr.h:62
auto operator=(cycle_weak_ptr &&other) noexcept -> cycle_weak_ptr &
Move assignment.
Definition: cycle_ptr.h:1740
auto reinterpret_pointer_cast(const cycle_ptr::cycle_gptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform reinterpret cast on pointer.
Definition: cycle_ptr.h:2546
cycle_gptr(const cycle_gptr< U > &other, element_type *target) noexcept
Aliasing constructor.
Definition: cycle_ptr.h:1351
auto static_pointer_cast(const cycle_ptr::cycle_gptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform static cast on pointer.
Definition: cycle_ptr.h:2516
auto owner_before(const cycle_member_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1618
auto operator<=(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:2331
auto swap(cycle_gptr< T > &other) -> void
Swap with other pointer.
Definition: cycle_ptr.h:1139
auto operator=(cycle_member_ptr &&other) -> cycle_member_ptr &
Move assignment operator.
Definition: cycle_ptr.h:1020
auto owner_before(const cycle_weak_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1602
auto reinterpret_pointer_cast(const cycle_ptr::cycle_member_ptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform reinterpret cast on pointer.
Definition: cycle_ptr.h:2587
auto swap(cycle_member_ptr< T > &x, cycle_gptr< T > &y) noexcept -> void
Swap two pointers.
Definition: cycle_ptr.h:2038
cycle_member_ptr(cycle_base &owner, const cycle_member_ptr< U > &ptr, element_type *target)
Aliasing constructor with explicitly specified ownership.
Definition: cycle_ptr.h:647
auto reset() -> void
Clear this pointer.
Definition: cycle_ptr.h:1108
auto swap(cycle_member_ptr &other) -> void
Swap with other pointer.
Definition: cycle_ptr.h:1123
auto operator>=(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2001
auto operator>([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:1965
auto swap(cycle_member_ptr< T > &other) -> void
Swap with other.
Definition: cycle_ptr.h:1556
auto operator==(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:1866
Intrusive pointer.
Definition: intrusive_ptr.h:21
auto shared_from_this(T *this_ptr) const -> cycle_gptr< T >
Create a cycle_gptr (equivalent of std::shared_ptr) from this.
Definition: cycle_ptr.h:119
auto operator=(const cycle_member_ptr< U > &other) -> cycle_gptr &
Copy assignment.
Definition: cycle_ptr.h:1479
cycle_gptr(cycle_gptr &&other) noexcept
Move constructor.
Definition: cycle_ptr.h:1277
cycle_gptr(const cycle_gptr< U > &other) noexcept
Copy constructor.
Definition: cycle_ptr.h:1288
auto swap(cycle_weak_ptr &other) noexcept -> void
Swap with another weak pointer.
Definition: cycle_ptr.h:1801
auto owner_before(const cycle_member_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1209
auto operator>=(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2341
auto operator<(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:2291
auto operator=(const cycle_member_ptr< U > &other) -> cycle_member_ptr &
Copy assignment operator.
Definition: cycle_ptr.h:1038
auto operator>(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:1956
auto swap(cycle_member_ptr< T > &x, cycle_member_ptr< T > &y) noexcept -> void
Swap two pointers.
Definition: cycle_ptr.h:2028
cycle_gptr(const cycle_member_ptr< U > &other)
Copy constructor.
Definition: cycle_ptr.h:1317
auto operator<(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:2111
auto operator<<(std::basic_ostream< Char, Traits > &out, const cycle_member_ptr< T > &ptr) -> std::basic_ostream< Char, Traits > &
Write pointer to output stream.
Definition: cycle_ptr.h:2416
std::remove_extent_t< T > element_type
Element type of this pointer.
Definition: cycle_ptr.h:1677
auto operator>(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:2301
auto operator!=([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:2093
cycle_member_ptr(const cycle_member_ptr< U > &ptr, element_type *target)
Aliasing constructor with automatic ownership detection.
Definition: cycle_ptr.h:921
auto operator!=(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:1902
auto operator==([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:1884
auto operator=(const cycle_gptr< U > &other) -> cycle_member_ptr &
Copy assignment operator.
Definition: cycle_ptr.h:1074
cycle_weak_ptr(const cycle_member_ptr< U > &other) noexcept
Create weak pointer from other.
Definition: cycle_ptr.h:1724
cycle_member_ptr()
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:716
cycle_ptr::cycle_member_ptr< T > argument_type
Argument type.
Definition: cycle_ptr.h:2464
cycle_member_ptr(cycle_base &owner, cycle_member_ptr< U > &&ptr)
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:577
auto operator=(const cycle_gptr< U > &other) noexcept -> cycle_weak_ptr &
Assign other. post this->lock() == other.
Definition: cycle_ptr.h:1772
cycle_member_ptr(const cycle_member_ptr &ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:756
cycle_member_ptr(unowned_cycle_t unowned_tag, cycle_member_ptr< U > &&ptr)
Create an unowned member pointer, pointing at ptr.
Definition: cycle_ptr.h:324
cycle_member_ptr(cycle_base &owner, const cycle_gptr< U > &ptr)
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:595
auto operator>=(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2010
auto reset() noexcept -> void
Clear this pointer.
Definition: cycle_ptr.h:1521
auto operator=(cycle_member_ptr< U > &&other) -> cycle_member_ptr &
Move assignment operator.
Definition: cycle_ptr.h:1059
auto owner_before(const cycle_weak_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1193
cycle_member_ptr(unowned_cycle_t unowned_tag, const cycle_weak_ptr< U > &ptr)
Create an unowned member pointer, pointing at ptr.
Definition: cycle_ptr.h:509
auto operator<(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:2102
auto reset() noexcept -> void
Reset this pointer.
Definition: cycle_ptr.h:1793
auto operator<([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:1938
~cycle_base() noexcept=default
Default destructor.
auto operator->() const -> std::enable_if_t< Enable, T > *
Indirection operation.
Definition: cycle_ptr.h:1586
auto operator==(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:2251
auto exchange(cycle_ptr::cycle_member_ptr< T > &x, U &&y)
Specialize std::exchange.
Definition: cycle_ptr.h:2446
auto operator!=([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:1911
auto owner_before(const cycle_member_ptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1849
auto operator=([[maybe_unused]] std::nullptr_t nil) -> cycle_member_ptr &
Assignment operator.
Definition: cycle_ptr.h:986
auto get() const noexcept -> T *
Retrieve address of this pointer.
Definition: cycle_ptr.h:1564
cycle_member_ptr(const cycle_weak_ptr< U > &ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:975
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag) noexcept
Create an unowned member pointer, representing a nullptr.
Definition: cycle_ptr.h:198
cycle_ptr::cycle_gptr< T > argument_type
Argument type.
Definition: cycle_ptr.h:2509
auto swap(cycle_weak_ptr< T > &x, cycle_weak_ptr< T > &y) noexcept -> void
Swap two pointers.
Definition: cycle_ptr.h:2230
auto owner_before(const cycle_gptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1201
auto operator<=([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:2174
auto get_control() const noexcept -> intrusive_ptr< base_control >
Read the target control block.
auto operator<(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:1920
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag, cycle_gptr< U > &&ptr)
Create an unowned member pointer, pointing at ptr.
Definition: cycle_ptr.h:412
Control block implementation for given type and allocator combination.
Definition: control.h:24
cycle_weak_ptr(const cycle_weak_ptr< U > &other) noexcept
Copy constructor.
Definition: cycle_ptr.h:1700
auto operator->() const -> std::enable_if_t< Enable, T > *
Indirection operation.
Definition: cycle_ptr.h:1176
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag, const cycle_gptr< U > &ptr, element_type *target)
Aliasing constructor for unowned member pointer.
Definition: cycle_ptr.h:465
cycle_gptr(const cycle_gptr &other) noexcept
Copy constructor.
Definition: cycle_ptr.h:1262
auto operator<([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Less comparison.
Definition: cycle_ptr.h:2120
Tag indicating an edge without owner.
Definition: cycle_ptr.h:24
cycle_member_ptr([[maybe_unused]] std::nullptr_t nil)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:736
cycle_member_ptr(const cycle_gptr< U > &ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:863
auto make_cycle(Args &&... args) -> cycle_gptr< T >
Allocate a new instance of T, using the default allocator.
Definition: cycle_ptr.h:2407
cycle_gptr(const cycle_member_ptr< U > &other, element_type *target)
Aliasing constructor.
Definition: cycle_ptr.h:1369
auto swap(cycle_gptr< T > &x, cycle_gptr< T > &y) noexcept -> void
Swap two pointers.
Definition: cycle_ptr.h:2210
auto owner_before(const cycle_gptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1610
cycle_weak_ptr(cycle_weak_ptr &&other) noexcept
Move constructor.
Definition: cycle_ptr.h:1693
cycle_member_ptr(cycle_gptr< U > &&ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:891
Weak cycle pointer.
Definition: cycle_ptr.h:34
auto operator!=(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:2271
auto expired() const noexcept -> bool
Test if this weak pointer is expired.
Definition: cycle_ptr.h:1810
auto operator=(cycle_gptr< U > &&other) -> cycle_member_ptr &
Move assignment operator.
Definition: cycle_ptr.h:1092
auto swap(cycle_gptr< T > &x, cycle_member_ptr< T > &y) noexcept -> void
Swap two pointers.
Definition: cycle_ptr.h:2220
auto operator==(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:2048
cycle_gptr(const cycle_weak_ptr< U > &other)
Construct from cycle_weak_ptr.
Definition: cycle_ptr.h:1385
auto operator=(cycle_gptr &&other) noexcept -> cycle_gptr &
Move assignment.
Definition: cycle_ptr.h:1419
auto operator=(cycle_gptr< U > &&other) noexcept -> cycle_gptr &
Move assignment.
Definition: cycle_ptr.h:1459
auto operator<=(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:1983
auto operator!=(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:1893
An optional base for classes which need to supply ownership to cycle_member_ptr.
Definition: cycle_ptr.h:49
auto operator=(const cycle_gptr< U > &other) noexcept -> cycle_gptr &
Copy assignment.
Definition: cycle_ptr.h:1437
cycle_weak_ptr(const cycle_weak_ptr &other) noexcept
Copy constructor.
Definition: cycle_ptr.h:1683
auto operator=(cycle_member_ptr< U > &&other) -> cycle_gptr &
Move assignment.
Definition: cycle_ptr.h:1504
auto operator>=(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2192
static auto unowned_control() -> intrusive_ptr< base_control >
Create a control block that represents no ownership.
auto operator=(const cycle_member_ptr &other) -> cycle_member_ptr &
Copy assignment operator.
Definition: cycle_ptr.h:1000
auto operator==(const cycle_gptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:2057
auto operator!=(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:2261
Global (or automatic) scope smart pointer.
Definition: cycle_ptr.h:33
auto operator=(const cycle_gptr &other) noexcept -> cycle_gptr &
Copy assignment.
Definition: cycle_ptr.h:1398
cycle_weak_ptr(const cycle_gptr< U > &other) noexcept
Create weak pointer from other.
Definition: cycle_ptr.h:1716
auto operator<=(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:2321
auto get() const -> T *
Returns the raw pointer of this.
Definition: cycle_ptr.h:1150
cycle_member_ptr(cycle_base &owner, const cycle_weak_ptr< U > &ptr)
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:694
cycle_member_ptr(unowned_cycle_t unowned_tag, [[maybe_unused]] std::nullptr_t nil) noexcept
Create an unowned member pointer, representing a nullptr.
Definition: cycle_ptr.h:237
auto operator>(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:2311
std::remove_extent_t< T > element_type
Element type of this pointer.
Definition: cycle_ptr.h:160
auto operator==([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:2066
auto operator<=([[maybe_unused]] std::nullptr_t x, const cycle_member_ptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:1992
cycle_gptr(cycle_member_ptr< U > &&other)
Move constructor.
Definition: cycle_ptr.h:1336
auto operator()(const cycle_ptr::cycle_member_ptr< T > &p) const noexcept -> std::size_t
Compute the hashcode of a cycle pointer.
Definition: cycle_ptr.h:2476
constexpr cycle_gptr([[maybe_unused]] std::nullptr_t nil) noexcept
Nullptr constructor.
Definition: cycle_ptr.h:1253
cycle_member_ptr([[maybe_unused]] unowned_cycle_t unowned_tag, const cycle_gptr< U > &ptr)
Create an unowned member pointer, pointing at ptr.
Definition: cycle_ptr.h:366
auto operator>=(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2183
auto operator<=(const cycle_member_ptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Less or equal comparison.
Definition: cycle_ptr.h:1974
auto operator>(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:2129
auto operator>([[maybe_unused]] std::nullptr_t x, const cycle_gptr< U > &y) noexcept -> bool
Greater comparison.
Definition: cycle_ptr.h:2147
auto operator!=(const cycle_gptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Inequality comparison.
Definition: cycle_ptr.h:2075
std::size_t result_type
Argument type.
Definition: cycle_ptr.h:2468
auto operator==(const cycle_gptr< T > &x, const cycle_member_ptr< U > &y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:2241
cycle_weak_ptr(cycle_weak_ptr< U > &&other) noexcept
Move constructor.
Definition: cycle_ptr.h:1708
cycle_member_ptr(cycle_base &owner) noexcept
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:523
constexpr cycle_weak_ptr() noexcept
Default constructor.
Definition: cycle_ptr.h:1680
auto operator=(const cycle_member_ptr< U > &other) noexcept -> cycle_weak_ptr &
Assign other. post this->lock() == other.
Definition: cycle_ptr.h:1783
auto const_pointer_cast(const cycle_ptr::cycle_member_ptr< U > &r) -> cycle_ptr::cycle_gptr< T >
Perform const cast on pointer.
Definition: cycle_ptr.h:2577
cycle_member_ptr(cycle_member_ptr &&ptr)
Constructor with automatic ownership detection.
Definition: cycle_ptr.h:784
cycle_member_ptr(const cycle_gptr< U > &ptr, element_type *target)
Aliasing constructor with automatic ownership detection.
Definition: cycle_ptr.h:950
auto owner_before(const cycle_gptr< U > &other) const noexcept -> bool
Ownership ordering.
Definition: cycle_ptr.h:1841
auto operator *() const -> std::enable_if_t< Enable, T > &
Dereference operation.
Definition: cycle_ptr.h:1163
cycle_member_ptr(cycle_base &owner, cycle_gptr< U > &&ptr)
Constructor with explicitly specified ownership.
Definition: cycle_ptr.h:617
Pointer between objects participating in the cycle_ptr graph.
Definition: cycle_ptr.h:32
auto operator==(const cycle_member_ptr< T > &x, [[maybe_unused]] std::nullptr_t y) noexcept -> bool
Equality comparison.
Definition: cycle_ptr.h:1875
auto operator=(const cycle_weak_ptr< U > &other) noexcept -> cycle_weak_ptr &
Copy assignment.
Definition: cycle_ptr.h:1750
auto operator>=(const cycle_member_ptr< T > &x, const cycle_gptr< U > &y) noexcept -> bool
Greater or equal comparison.
Definition: cycle_ptr.h:2351