24 DoubleBuffer()
noexcept
26 static_assert(std::is_default_constructible_v<T>,
27 "T must be default constructible for DoubleBuffer default ctor");
30 m_CurrentRead.store(&m_Buffers[0], std::memory_order_release);
31 m_CurrentWrite = &m_Buffers[1];
34 template <
typename... Args,
typename = std::enable_if_t<std::is_constructible_v<T, Args...>>>
35 explicit DoubleBuffer(Args&&... args)
37 m_Buffers = std::array<T, 2>{T(std::forward<Args>(args)...), T(std::forward<Args>(args)...)};
38 m_CurrentRead.store(&m_Buffers[0], std::memory_order_release);
39 m_CurrentWrite = &m_Buffers[1];
43 DoubleBuffer(
const DoubleBuffer&) =
delete;
44 DoubleBuffer& operator=(
const DoubleBuffer&) =
delete;
47 DoubleBuffer(DoubleBuffer&& other)
noexcept
49 m_Buffers = std::move(other.m_Buffers);
51 T* other_read = other.m_CurrentRead.load(std::memory_order_acquire);
53 if (other_read == &other.m_Buffers[0]) idx = 0;
54 else if (other_read == &other.m_Buffers[1]) idx = 1;
57 m_CurrentRead.store(&m_Buffers[idx], std::memory_order_release);
58 m_CurrentWrite = &m_Buffers[1 - idx];
61 other.m_CurrentRead.store(&other.m_Buffers[0], std::memory_order_release);
62 other.m_CurrentWrite = &other.m_Buffers[1];
65 DoubleBuffer& operator=(DoubleBuffer&& other)
noexcept
67 if (
this == &other)
return *
this;
69 m_Buffers = std::move(other.m_Buffers);
71 T* other_read = other.m_CurrentRead.load(std::memory_order_acquire);
73 if (other_read == &other.m_Buffers[0]) idx = 0;
74 else if (other_read == &other.m_Buffers[1]) idx = 1;
77 m_CurrentRead.store(&m_Buffers[idx], std::memory_order_release);
78 m_CurrentWrite = &m_Buffers[1 - idx];
80 other.m_CurrentRead.store(&other.m_Buffers[0], std::memory_order_release);
81 other.m_CurrentWrite = &other.m_Buffers[1];
86 const T& readView()
noexcept
88 return *m_CurrentRead.load(std::memory_order_acquire);
93 return *m_CurrentRead.load(std::memory_order_acquire);
98 return *m_CurrentWrite;
103 T* old_read = m_CurrentRead.exchange(m_CurrentWrite, std::memory_order_acq_rel);
104 m_CurrentWrite = old_read;
107 void push(
const T& frame)
noexcept
109 std::memcpy(m_CurrentWrite, &frame,
sizeof(T));
114 std::array<T, 2> m_Buffers;
116 std::atomic<T*> m_CurrentRead{
nullptr};
117 T* m_CurrentWrite{
nullptr};