1#ifndef LIBSBX_SIGNAL_COPY_ON_WRITE_HPP_
2#define LIBSBX_SIGNAL_COPY_ON_WRITE_HPP_
7namespace sbx::signals {
14 template<
typename... Args>
15 explicit payload(Args&&... args)
17 value{std::forward<Args>(args)...} { }
21 std::atomic<std::size_t> count;
26 template<
typename Other>
31 using value_type = Type;
34 : _payload{
new payload{}} { }
36 template<
typename Other>
37 requires (!std::is_same_v<std::decay_t<Other>,
copy_on_write>)
39 : _payload{
new payload{std::forward<Other>(other)}} { }
42 : _payload{other._payload} {
44 _payload->count.fetch_add(1, std::memory_order_relaxed);
49 : _payload{std::exchange(other._payload,
nullptr)} {}
58 _payload = other._payload;
61 _payload->count.fetch_add(1, std::memory_order_relaxed);
71 _payload = std::exchange(other._payload,
nullptr);
77 auto read()
const noexcept ->
const value_type& {
78 return _payload->value;
81 auto write() -> value_type& {
86 return _payload->value;
91 auto _release() ->
void {
92 if (_payload && _payload->count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
99 auto _is_unique()
const ->
bool {
100 return _payload->count == 1;
107template<
typename Type>
110 swap(lhs._payload, rhs._payload);
113template<
typename Type>
114auto cow_read(
const Type& value) ->
const Type& {
118template<
typename Type>
119auto cow_read(copy_on_write<Type>& value) ->
const Type& {
123template<
typename Type>
124auto cow_write(Type& value) -> Type& {
128template<
typename Type>
129auto cow_write(copy_on_write<Type>& value) -> Type& {
130 return value.write();
Definition: copy_on_write.hpp:10