diff options
Diffstat (limited to 'include/cru/base')
| -rw-r--r-- | include/cru/base/ClonablePtr.h | 216 | ||||
| -rw-r--r-- | include/cru/base/ClonePtr.h | 119 |
2 files changed, 119 insertions, 216 deletions
diff --git a/include/cru/base/ClonablePtr.h b/include/cru/base/ClonablePtr.h deleted file mode 100644 index 1198315f..00000000 --- a/include/cru/base/ClonablePtr.h +++ /dev/null @@ -1,216 +0,0 @@ -#pragma once - -#include <cstddef> -#include <functional> -#include <memory> -#include <type_traits> - -namespace cru { -template <typename TClonable> -class ClonablePtr { - template <typename T> - friend class ClonablePtr; - - public: - using element_type = typename std::unique_ptr<TClonable>::element_type; - using pointer = typename std::unique_ptr<TClonable>::pointer; - - ClonablePtr() = default; - ClonablePtr(std::nullptr_t) noexcept : ptr_(nullptr) {} - explicit ClonablePtr(pointer p) noexcept : ptr_(p) {} - ClonablePtr(std::unique_ptr<element_type>&& p) noexcept - : ptr_(std::move(p)) {} - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr(std::unique_ptr<O>&& p) : ptr_(std::move(p)) {} - ClonablePtr(const ClonablePtr& other) : ptr_(other.ptr_->Clone()) {} - ClonablePtr(ClonablePtr&& other) = default; - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr(const ClonablePtr<O>& other) : ptr_(other.ptr_->Clone()) {} - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr(ClonablePtr<O>&& other) noexcept : ptr_(std::move(other.ptr_)) {} - ClonablePtr& operator=(std::nullptr_t) noexcept { - ptr_ = nullptr; - return *this; - } - ClonablePtr& operator=(std::unique_ptr<element_type>&& other) noexcept { - ptr_ = std::move(other); - return *this; - } - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr& operator=(std::unique_ptr<O>&& p) noexcept { - ptr_ = std::move(p); - return *this; - } - ClonablePtr& operator=(const ClonablePtr& other) { - if (this != &other) { - ptr_ = std::unique_ptr<element_type>(other.ptr_->Clone()); - } - return *this; - } - ClonablePtr& operator=(ClonablePtr&& other) = default; - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr& operator=(const ClonablePtr<O>& other) noexcept { - if (this != &other) { - ptr_ = std::unique_ptr<element_type>(other.ptr_->Clone()); - } - return *this; - } - template <typename O, - std::enable_if_t<std::is_convertible_v< - typename ClonablePtr<O>::pointer, pointer>, - int> = 0> - ClonablePtr& operator=(ClonablePtr<O>&& other) noexcept { - ptr_ = std::move(other.ptr_); - } - - ~ClonablePtr() = default; - - public: - pointer release() noexcept { return ptr_.release(); } - void reset(pointer p = pointer()) noexcept { ptr_.reset(p); } - void swap(ClonablePtr& other) noexcept { ptr_.swap(other.ptr_); } - - public: - pointer get() const noexcept { return ptr_.get(); } - - operator bool() const noexcept { return ptr_ != nullptr; } - - element_type& operator*() const noexcept { return *ptr_; } - pointer operator->() const noexcept { return ptr_.get(); } - - int Compare(const ClonablePtr& other) const noexcept { - if (ptr_ == other.ptr_) { - return 0; - } else if (ptr_ < other.ptr_) { - return -1; - } else { - return 1; - } - } - - int Compare(std::nullptr_t) const noexcept { return ptr_ ? 1 : 0; } - - private: - std::unique_ptr<element_type> ptr_; -}; - -template <typename T> -void swap(ClonablePtr<T>& left, ClonablePtr<T>& right) noexcept { - left.swap(right); -} - -template <typename T> -bool operator==(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) == 0; -} - -template <typename T> -bool operator!=(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) != 0; -} - -template <typename T> -bool operator<(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) < 0; -} - -template <typename T> -bool operator<=(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) <= 0; -} - -template <typename T> -bool operator>(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) > 0; -} - -template <typename T> -bool operator>=(const ClonablePtr<T>& left, const ClonablePtr<T>& right) { - return left.Compare(right) >= 0; -} - -template <typename T> -bool operator==(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) == 0; -} - -template <typename T> -bool operator!=(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) != 0; -} - -template <typename T> -bool operator<(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) < 0; -} - -template <typename T> -bool operator<=(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) <= 0; -} - -template <typename T> -bool operator>(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) > 0; -} - -template <typename T> -bool operator>=(const ClonablePtr<T>& left, std::nullptr_t) { - return left.Compare(nullptr) >= 0; -} - -template <typename T> -bool operator==(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) == 0; -} - -template <typename T> -bool operator!=(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) != 0; -} - -template <typename T> -bool operator<(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) > 0; -} - -template <typename T> -bool operator<=(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) >= 0; -} - -template <typename T> -bool operator>(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) < 0; -} - -template <typename T> -bool operator>=(std::nullptr_t, const ClonablePtr<T>& right) { - return right.Compare(nullptr) <= 0; -} - -} // namespace cru - -namespace std { -template <typename T> -struct hash<cru::ClonablePtr<T>> { - std::size_t operator()(const cru::ClonablePtr<T>& p) const { - return std::hash<typename cru::ClonablePtr<T>::pointer>(p.get()); - } -}; -} // namespace std diff --git a/include/cru/base/ClonePtr.h b/include/cru/base/ClonePtr.h new file mode 100644 index 00000000..452c2cdd --- /dev/null +++ b/include/cru/base/ClonePtr.h @@ -0,0 +1,119 @@ +#pragma once + +#include <cstddef> +#include <functional> +#include <memory> +#include <type_traits> + +namespace cru { +template <typename T> +class ClonePtr { + template <typename O> + friend class ClonePtr; + + public: + using element_type = typename std::unique_ptr<T>::element_type; + using pointer = typename std::unique_ptr<T>::pointer; + + ClonePtr() = default; + ClonePtr(std::nullptr_t) noexcept : ptr_(nullptr) {} + explicit ClonePtr(pointer p) noexcept : ptr_(p) {} + ClonePtr(std::unique_ptr<element_type>&& p) noexcept : ptr_(std::move(p)) {} + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr(std::unique_ptr<O>&& p) : ptr_(std::move(p)) {} + ClonePtr(const ClonePtr& other) : ptr_(other.ptr_->Clone()) {} + ClonePtr(ClonePtr&& other) = default; + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr(const ClonePtr<O>& other) : ptr_(other.ptr_->Clone()) {} + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr(ClonePtr<O>&& other) noexcept : ptr_(std::move(other.ptr_)) {} + ClonePtr& operator=(std::nullptr_t) noexcept { + ptr_ = nullptr; + return *this; + } + ClonePtr& operator=(std::unique_ptr<element_type>&& other) noexcept { + ptr_ = std::move(other); + return *this; + } + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr& operator=(std::unique_ptr<O>&& p) noexcept { + ptr_ = std::move(p); + return *this; + } + ClonePtr& operator=(const ClonePtr& other) { + if (this != &other) { + ptr_ = std::unique_ptr<element_type>(other.ptr_->Clone()); + } + return *this; + } + ClonePtr& operator=(ClonePtr&& other) = default; + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr& operator=(const ClonePtr<O>& other) noexcept { + if (this != &other) { + ptr_ = std::unique_ptr<element_type>(other.ptr_->Clone()); + } + return *this; + } + template <typename O, + std::enable_if_t< + std::is_convertible_v<typename ClonePtr<O>::pointer, pointer>, + int> = 0> + ClonePtr& operator=(ClonePtr<O>&& other) noexcept { + ptr_ = std::move(other.ptr_); + } + + ~ClonePtr() = default; + + public: + pointer release() noexcept { return ptr_.release(); } + void reset(pointer p = pointer()) noexcept { ptr_.reset(p); } + void swap(ClonePtr& other) noexcept { ptr_.swap(other.ptr_); } + + public: + pointer get() const noexcept { return ptr_.get(); } + + operator bool() const noexcept { return ptr_ != nullptr; } + + element_type& operator*() const noexcept { return *ptr_; } + pointer operator->() const noexcept { return ptr_.get(); } + + auto operator<=>(std::nullptr_t) const { return ptr_.operator<=>(nullptr); } + + auto operator<=>(const ClonePtr& other) const { + return ptr_.operator<=>(other.ptr_); + } + + private: + std::unique_ptr<element_type> ptr_; +}; + +template <typename T> +void swap(ClonePtr<T>& left, ClonePtr<T>& right) noexcept { + left.swap(right); +} + +} // namespace cru + +namespace std { +template <typename T> +struct hash<cru::ClonePtr<T>> { + std::size_t operator()(const cru::ClonePtr<T>& p) const { + return std::hash<typename cru::ClonePtr<T>::pointer>(p.get()); + } +}; +} // namespace std |
