#pragma once #include #include #include namespace chatterino { template > class AccessGuard { public: AccessGuard(T &element, std::shared_mutex &mutex) : element_(&element) , lock_(mutex) { } AccessGuard(AccessGuard &&other) : element_(other.element_) , lock_(std::move(other.lock_)) { } AccessGuard &operator=(AccessGuard &&other) { this->element_ = other.element_; this->lock_ = std::move(other.lock_); return *this; } T *operator->() const { return this->element_; } T &operator*() const { return *this->element_; } private: T *element_{}; LockType lock_; }; template using SharedAccessGuard = AccessGuard>; template class UniqueAccess { public: 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() const { return AccessGuard(this->element_, this->mutex_); } template ::value>> SharedAccessGuard accessConst() const { return SharedAccessGuard(this->element_, this->mutex_); } private: mutable T element_; mutable std::shared_mutex mutex_; }; } // namespace chatterino