diff --git a/CHANGELOG.md b/CHANGELOG.md index 639c49ec1..840f0c502 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ - Dev: Added benchmark for parsing and building recent messages. (#5071) - Dev: Boost is depended on as a header-only library when using conan. (#5107) - Dev: Added signal to invalidate paint buffers of channel views without forcing a relayout. (#5123) +- Dev: Specialize `Atomic>` if underlying standard library supports it. (#5133) ## 2.4.6 diff --git a/src/common/Atomic.hpp b/src/common/Atomic.hpp index 30943e239..cb6686c5f 100644 --- a/src/common/Atomic.hpp +++ b/src/common/Atomic.hpp @@ -1,5 +1,7 @@ #pragma once +#include +#include #include namespace chatterino { @@ -9,9 +11,10 @@ class Atomic { public: Atomic() = default; + ~Atomic() = default; Atomic(T &&val) - : value_(val) + : value_(std::move(val)) { } @@ -47,4 +50,67 @@ private: T value_; }; +#if defined(__cpp_lib_atomic_shared_ptr) && defined(__cpp_concepts) + +template +class Atomic> +{ + // Atomic> must be instantated with a const T +}; + +template + requires std::is_const_v +class Atomic> +{ +public: + Atomic() = default; + ~Atomic() = default; + + Atomic(T &&val) + : value_(std::make_shared(std::move(val))) + { + } + + Atomic(std::shared_ptr &&val) + : value_(std::move(val)) + { + } + + Atomic(const Atomic &) = delete; + Atomic &operator=(const Atomic &) = delete; + + Atomic(Atomic &&) = delete; + Atomic &operator=(Atomic &&) = delete; + + std::shared_ptr get() const + { + return this->value_.load(); + } + + void set(const T &val) + { + this->value_.store(std::make_shared(val)); + } + + void set(T &&val) + { + this->value_.store(std::make_shared(std::move(val))); + } + + void set(const std::shared_ptr &val) + { + this->value_.store(val); + } + + void set(std::shared_ptr &&val) + { + this->value_.store(std::move(val)); + } + +private: + std::atomic> value_; +}; + +#endif + } // namespace chatterino