#ifndef OPENMW_COMPONENTS_MISC_GUARDED_H #define OPENMW_COMPONENTS_MISC_GUARDED_H #include #include namespace Misc { template class Locked { public: Locked(std::mutex& mutex, T& value) : mLock(mutex), mValue(value) {} T& get() const { return mValue.get(); } T* operator ->() const { return std::addressof(get()); } T& operator *() const { return get(); } private: std::unique_lock mLock; std::reference_wrapper mValue; }; template class ScopeGuarded { public: ScopeGuarded() = default; ScopeGuarded(const T& value) : mValue(value) {} ScopeGuarded(T&& value) : mValue(std::move(value)) {} template ScopeGuarded(Args&& ... args) : mValue(std::forward(args) ...) {} ScopeGuarded(const ScopeGuarded& other) : mMutex() , mValue(other.lock().get()) {} ScopeGuarded(ScopeGuarded&& other) : mMutex() , mValue(std::move(other.lock().get())) {} Locked lock() { return Locked(mMutex, mValue); } Locked lockConst() { return Locked(mMutex, mValue); } private: std::mutex mMutex; T mValue; }; template class SharedGuarded { public: SharedGuarded() : mMutex(std::make_shared()) {} SharedGuarded(std::shared_ptr value) : mMutex(std::make_shared()), mValue(std::move(value)) {} Locked lock() const { return Locked(*mMutex, *mValue); } Locked lockConst() const { return Locked(*mMutex, *mValue); } private: std::shared_ptr mMutex; std::shared_ptr mValue; }; } #endif