#pragma once #include #include namespace chatterino { template class AccessGuard { public: AccessGuard(T &element, std::mutex &mutex) : element_(element) , mutex_(mutex) { this->mutex_.lock(); } ~AccessGuard() { this->mutex_.unlock(); } const T *operator->() const { return &this->element_; } T *operator->() { return &this->element_; } const T &operator*() const { return this->element_; } T &operator*() { return this->element_; } T clone() const { return T(this->element_); } private: T &element_; std::mutex &mutex_; }; template class UniqueAccess { public: template UniqueAccess() : element_(T()) { } UniqueAccess(const T &element) : element_(element) { } UniqueAccess(T &&element) : element_(element) { } UniqueAccess &operator=(const T &element) { this->element_ = element; return *this; } UniqueAccess &operator=(T &&element) { this->element_ = element; return *this; } AccessGuard access() { return AccessGuard(this->element_, this->mutex_); } const AccessGuard access() const { return AccessGuard(this->element_, this->mutex_); } private: mutable T element_; mutable std::mutex mutex_; }; } // namespace chatterino