25 ptr_->owners.fetch_add(1, std::memory_order::relaxed);
34 if (ptr_->owners.fetch_sub(1, std::memory_order_acq_rel) == 1) {
53 std::swap(a.ptr_, b.ptr_);
67 if (ptr_->owners.load(std::memory_order_acquire) == 1) {
68 return static_cast<T*
>(ptr_->data);
72 return static_cast<T*
>(ptr_->data);
75 long use_count() const noexcept {
return ptr_->owners; }
80 template<
typename U,
typename... Args>
83 struct ControlBlock final {
84 explicit ControlBlock(
void (*deleter)(ControlBlock*)
noexcept,
void* data) noexcept :
89 std::atomic<long> owners = 1;
90 void (*deleter)(ControlBlock*)
noexcept;
96 template<
typename... Args>
97 requires std::constructible_from<
T, Args&&...>
98 static ControlBlock* allocate_representation(Args&&... args)
101 constexpr size_t data_offset = (
sizeof(ControlBlock) + (
alignof(
T) - 1)) & ~(
alignof(
T) - 1);
102 constexpr size_t allocation_size = data_offset +
sizeof(
T);
103 constexpr std::align_val_t allocation_alignment{std::max(
alignof(ControlBlock),
alignof(
T))};
106 auto deleter = [](ControlBlock* cb)
noexcept ->
void
108 std::destroy_at(
static_cast<T*
>(cb->data));
110 ::operator
delete(
static_cast<void*
>(cb), allocation_alignment);
114 std::unique_ptr<void, void(*)(
void*)> allocation{
115 ::operator
new(allocation_size, allocation_alignment),
116 [](
void* p) { ::operator
delete(p, allocation_alignment); },
120 std::byte* data_ptr =
static_cast<std::byte*
>(allocation.get()) + data_offset;
121 new (data_ptr)
T(std::forward<Args>(args)...);
122 static_assert(std::is_nothrow_constructible_v<ControlBlock,
decltype(deleter),
decltype(data_ptr)>);
123 new (allocation.get()) ControlBlock(deleter, data_ptr);
125 return static_cast<ControlBlock*
>(allocation.release());
131 template<
typename U,
typename... Args>
Definition copy_on_upd_shared_value.h:16
CopyOnUpdSharedValue & operator=(const CopyOnUpdSharedValue &rhs) noexcept
Definition copy_on_upd_shared_value.h:39
CopyOnUpdSharedValue(const CopyOnUpdSharedValue &other) noexcept
Definition copy_on_upd_shared_value.h:22
friend CopyOnUpdSharedValue< U > make_cowv(Args &&...)
const_reference operator*() const
Definition copy_on_upd_shared_value.h:63
~CopyOnUpdSharedValue() noexcept
Definition copy_on_upd_shared_value.h:32
pointer upd()
Definition copy_on_upd_shared_value.h:65
const_pointer operator->() const noexcept
Definition copy_on_upd_shared_value.h:62
const T * const_pointer
Definition copy_on_upd_shared_value.h:19
const_pointer get() const noexcept
Definition copy_on_upd_shared_value.h:61
long use_count() const noexcept
Definition copy_on_upd_shared_value.h:75
friend void swap(CopyOnUpdSharedValue &a, CopyOnUpdSharedValue &b) noexcept
Definition copy_on_upd_shared_value.h:51
CopyOnUpdSharedValue & operator=(CopyOnUpdSharedValue &&rhs) noexcept
Definition copy_on_upd_shared_value.h:46
CopyOnUpdSharedValue(CopyOnUpdSharedValue &&tmp) noexcept
Definition copy_on_upd_shared_value.h:28
friend auto operator<=>(const CopyOnUpdSharedValue &lhs, const CopyOnUpdSharedValue< U > &rhs)
Definition copy_on_upd_shared_value.h:59
T * pointer
Definition copy_on_upd_shared_value.h:18
const T & const_reference
Definition copy_on_upd_shared_value.h:20
friend bool operator==(const CopyOnUpdSharedValue &lhs, const CopyOnUpdSharedValue< U > &rhs)
Definition copy_on_upd_shared_value.h:57
Definition custom_decoration_generator.h:5
CopyOnUpdSharedValue< U > make_cowv(Args &&... args)
Definition copy_on_upd_shared_value.h:132