Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
rcu_value.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
7#include <atomic>
8#include <memory>
9#include <type_traits>
10
11namespace kcenon::container
12{
39 template<typename T>
41 {
42 public:
43 static_assert(std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>,
44 "T must be copy or move constructible");
45
49 rcu_value() requires std::is_default_constructible_v<T>
50 : current_(std::make_shared<const T>()) {}
51
56 explicit rcu_value(T initial)
57 : current_(std::make_shared<const T>(std::move(initial))) {}
58
63 rcu_value(const rcu_value& other)
64 : current_(std::atomic_load_explicit(&other.current_, std::memory_order_acquire)) {}
65
70 rcu_value(rcu_value&& other) noexcept
71 : current_(std::atomic_load_explicit(&other.current_, std::memory_order_acquire)) {}
72
78 rcu_value& operator=(const rcu_value& other) {
79 if (this != &other) {
80 auto new_ptr = std::atomic_load_explicit(&other.current_, std::memory_order_acquire);
81 std::atomic_store_explicit(&current_, new_ptr, std::memory_order_release);
82 }
83 return *this;
84 }
85
91 rcu_value& operator=(rcu_value&& other) noexcept {
92 if (this != &other) {
93 auto new_ptr = std::atomic_load_explicit(&other.current_, std::memory_order_acquire);
94 std::atomic_store_explicit(&current_, new_ptr, std::memory_order_release);
95 }
96 return *this;
97 }
98
102 ~rcu_value() = default;
103
115 [[nodiscard]] std::shared_ptr<const T> read() const noexcept {
116 return std::atomic_load_explicit(&current_, std::memory_order_acquire);
117 }
118
129 void update(T new_value) {
130 auto new_ptr = std::make_shared<const T>(std::move(new_value));
131 std::atomic_store_explicit(&current_, new_ptr, std::memory_order_release);
132 update_count_.fetch_add(1, std::memory_order_relaxed);
133 }
134
148 bool compare_and_update(const std::shared_ptr<const T>& expected, T new_value) {
149 auto new_ptr = std::make_shared<const T>(std::move(new_value));
150 auto expected_copy = expected;
151 bool success = std::atomic_compare_exchange_strong_explicit(
152 &current_,
153 &expected_copy,
154 new_ptr,
155 std::memory_order_acq_rel,
156 std::memory_order_acquire
157 );
158 if (success) {
159 update_count_.fetch_add(1, std::memory_order_relaxed);
160 }
161 return success;
162 }
163
168 [[nodiscard]] size_t update_count() const noexcept {
169 return update_count_.load(std::memory_order_relaxed);
170 }
171
176 [[nodiscard]] bool has_value() const noexcept {
177 return std::atomic_load_explicit(&current_, std::memory_order_acquire) != nullptr;
178 }
179
180 private:
181 std::shared_ptr<const T> current_;
182 std::atomic<size_t> update_count_{0};
183 };
184
185} // namespace kcenon::container
Lock-free value wrapper using Read-Copy-Update (RCU) pattern.
Definition rcu_value.h:41
bool has_value() const noexcept
Check if the value has been initialized.
Definition rcu_value.h:176
rcu_value()
Default constructor - initializes with default-constructed T.
Definition rcu_value.h:49
size_t update_count() const noexcept
Get the number of updates performed.
Definition rcu_value.h:168
~rcu_value()=default
Destructor.
std::shared_ptr< const T > current_
Definition rcu_value.h:181
rcu_value(T initial)
Construct with initial value.
Definition rcu_value.h:56
std::shared_ptr< const T > read() const noexcept
Lock-free read - returns current snapshot.
Definition rcu_value.h:115
void update(T new_value)
Update the value atomically.
Definition rcu_value.h:129
bool compare_and_update(const std::shared_ptr< const T > &expected, T new_value)
Compare-and-swap update.
Definition rcu_value.h:148
rcu_value & operator=(rcu_value &&other) noexcept
Move assignment operator.
Definition rcu_value.h:91
rcu_value & operator=(const rcu_value &other)
Copy assignment operator.
Definition rcu_value.h:78
rcu_value(const rcu_value &other)
Copy constructor.
Definition rcu_value.h:63
rcu_value(rcu_value &&other) noexcept
Move constructor.
Definition rcu_value.h:70
std::atomic< size_t > update_count_
Definition rcu_value.h:182