#pragma once template class MutexGuard { public: MutexGuard(): inner(*(T*)nullptr), mutex() {} MutexGuard(HANDLE mutex, T& inner): inner(inner), mutex(mutex){} ~MutexGuard() { ReleaseMutex(mutex); } T* operator->() { return &inner; } T& operator* () { return inner; } private: HANDLE mutex; T& inner; }; template class Mutex { public: Mutex(T&& value); MutexGuard lock(); private: HANDLE mutex; T inner; }; template Mutex::Mutex(T&& value): inner(value) { mutex = CreateMutex(nullptr, false, nullptr); } template MutexGuard Mutex::lock() { auto result = WaitForSingleObject(mutex, INFINITE); switch (result) { case WAIT_OBJECT_0: return MutexGuard(mutex, inner); default: return MutexGuard(); } }