1#ifndef DITTO_SYNCHRONIZEDVALUE_H
2#define DITTO_SYNCHRONIZEDVALUE_H
29template <
class T,
class Mutex = std::mutex>
class SynchronizedValue {
34 template <
class R_,
class F_,
class T_,
class M_>
35 friend R_ apply(F_ &&f, SynchronizedValue<T_, M_> &sv);
37 template <
class R_,
class F_,
class T_,
class M_>
38 friend R_ apply(F_ &&f,
const SynchronizedValue<T_, M_> &sv);
40 template <
class F_,
class T_,
class M_>
41 friend void apply(F_ &&f, SynchronizedValue<T_, M_> &sv);
43 template <
class F_,
class T_,
class M_>
44 friend void apply(F_ &&f,
const SynchronizedValue<T_, M_> &sv);
46 template <
class F_,
class T_,
class U_,
class M_,
class N_>
47 friend void apply(F_ &&f, SynchronizedValue<T_, M_> &lhs,
48 SynchronizedValue<U_, N_> &rhs);
51 using mutex_type = Mutex;
55 template <
class U = T,
56 typename std::enable_if<std::is_default_constructible<U>::value,
58 SynchronizedValue() : value() {}
62 SynchronizedValue(
const T &desired) : value(desired) {}
66 SynchronizedValue(T &&desired)
noexcept(
67 std::is_nothrow_move_constructible<T>::value)
68 : value(std::move(desired)) {}
70 ~SynchronizedValue() =
default;
72 SynchronizedValue(
const SynchronizedValue &) =
delete;
73 SynchronizedValue &operator=(
const SynchronizedValue &) =
delete;
74 SynchronizedValue(SynchronizedValue &&) =
delete;
75 SynchronizedValue &operator=(SynchronizedValue &&) =
delete;
79 void apply(std::function<
void(T &)> f) {
80 std::lock_guard<Mutex> lock(mtx);
86 void apply(std::function<
void(
const T &)> f)
const {
87 std::lock_guard<Mutex> lock(mtx);
94 std::lock_guard<Mutex> lock(mtx);
101 T exchange(T new_value) {
102 std::lock_guard<Mutex> lock(mtx);
103 T old_value = std::move(value);
104 value = std::move(new_value);
110 void operator=(
const T &desired) {
111 std::lock_guard<Mutex> lock(mtx);
117 void operator=(T &&desired) {
118 std::lock_guard<Mutex> lock(mtx);
119 value = std::move(desired);
127template <
class R,
class F,
class T,
class M>
128R
apply(F &&f, SynchronizedValue<T, M> &sv) {
129 std::lock_guard<M> lock(sv.mtx);
137template <
class R,
class F,
class T,
class M>
138R
apply(F &&f,
const SynchronizedValue<T, M> &sv) {
139 std::lock_guard<M> lock(sv.mtx);
147template <
class F,
class T,
class M>
148void apply(F &&f, SynchronizedValue<T, M> &sv) {
149 std::lock_guard<M> lock(sv.mtx);
157template <
class F,
class T,
class M>
158void apply(F &&f,
const SynchronizedValue<T, M> &sv) {
159 std::lock_guard<M> lock(sv.mtx);
172template <
class F,
class T,
class U,
class M,
class N>
173void apply(F &&f, SynchronizedValue<T, M> &lhs, SynchronizedValue<U, N> &rhs) {
174 if ((
void *)&lhs == (
void *)&rhs) {
176 std::lock_guard<M> lock(lhs.mtx);
177 f(lhs.value, rhs.value);
179 std::lock(lhs.mtx, rhs.mtx);
180 std::lock_guard<M> lock_lhs(lhs.mtx, std::adopt_lock);
181 std::lock_guard<N> lock_rhs(rhs.mtx, std::adopt_lock);
182 f(lhs.value, rhs.value);
195template <
class T,
class M,
class N>
196void swap(SynchronizedValue<T, M> &lhs, SynchronizedValue<T, N> &rhs) {
197 if ((
void *)&lhs == (
void *)&rhs) {
200 apply([](T &a, T &b) { std::swap(a, b); }, lhs, rhs);
Namespace for internal Ditto SDK functionality.
Definition Ditto.hpp:29
R apply(F &&f, SynchronizedValue< T, M > &sv)
Applies a function to the wrapped value of a SynchronizedValue.
Definition SynchronizedValue.hpp:128
void swap(SynchronizedValue< T, M > &lhs, SynchronizedValue< T, N > &rhs)
Swaps the values of two SynchronizedValue objects.
Definition SynchronizedValue.hpp:196
Namespace for the Ditto C++ SDK types and functions.
Definition AbstractDocumentPath.hpp:19