#pragma once #include class Spinlock { public: void lock(); void unlock(); bool is_locked() const { return m_lock.load() != -1; } // Call this before use if the Spinlock is a global variable. void init() { m_lock = -1; } private: Atomic m_lock{-1}; }; template class LockedValue { struct LockedValueGuard { LockedValueGuard(LockedValue& value_ref) : m_value_ref(value_ref) { } ~LockedValueGuard() { m_value_ref.m_lock.unlock(); } T& ref() { return m_value_ref.m_value; } void set(const T& other) { ref() = other; } T* operator->() { return &ref(); } T& operator*() { return ref(); } private: LockedValue& m_value_ref; }; public: LockedValue() : m_value() { } LockedValue(T value) : m_value(value) { } // Call this before use if the LockedValue is a global variable. void init() { m_lock.init(); } LockedValueGuard lock() { m_lock.lock(); return {*this}; } private: T m_value; Spinlock m_lock; };