// // YaPB - Counter-Strike Bot based on PODBot by Markus Klinge. // Copyright © 2004-2020 YaPB Project . // // SPDX-License-Identifier: MIT // #pragma once #include #include #include CR_NAMESPACE_BEGIN // simple unique ptr template class UniquePtr final : public DenyCopying { private: T *ptr_ {}; public: UniquePtr () = default; explicit UniquePtr (T *ptr) : ptr_ (ptr) { } UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) { } template UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) { } ~UniquePtr () { destroy (); } public: T *get () const { return ptr_; } T *release () { auto ret = ptr_; ptr_ = nullptr; return ret; } void reset (T *ptr = nullptr) { destroy (); ptr_ = ptr; } private: void destroy () { delete ptr_; ptr_ = nullptr; } public: UniquePtr &operator = (UniquePtr &&rhs) noexcept { if (this != &rhs) { reset (rhs.release ()); } return *this; } template UniquePtr &operator = (UniquePtr &&rhs) noexcept { if (this != &rhs) { reset (rhs.release ()); } return *this; } UniquePtr &operator = (decltype (nullptr)) { destroy (); return *this; } T &operator * () const { return *ptr_; } T *operator -> () const { return ptr_; } explicit operator bool () const { return ptr_ != nullptr; } }; template class UniquePtr final : public DenyCopying { private: T *ptr_ { }; public: UniquePtr () = default; explicit UniquePtr (T *ptr) : ptr_ (ptr) { } UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) { } template UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ()) { } ~UniquePtr () { destroy (); } public: T *get () const { return ptr_; } T *release () { auto ret = ptr_; ptr_ = nullptr; return ret; } void reset (T *ptr = nullptr) { destroy (); ptr_ = ptr; } private: void destroy () { delete[] ptr_; ptr_ = nullptr; } public: UniquePtr &operator = (UniquePtr &&rhs) noexcept { if (this != &rhs) { reset (rhs.release ()); } return *this; } template UniquePtr &operator = (UniquePtr &&rhs) noexcept { if (this != &rhs) { reset (rhs.release ()); } return *this; } UniquePtr &operator = (decltype (nullptr)) { destroy (); return *this; } T &operator [] (size_t index) { return ptr_[index]; } const T &operator [] (size_t index) const { return ptr_[index]; } explicit operator bool () const { return ptr_ != nullptr; } }; namespace detail { template struct ClearExtent { using Type = T; }; template struct ClearExtent { using Type = T; }; template struct ClearExtent { using Type = T; }; template struct UniqueIf { using SingleObject = UniquePtr ; }; template struct UniqueIf { using UnknownBound = UniquePtr ; }; template struct UniqueIf { using KnownBound = void; }; } template typename detail::UniqueIf ::SingleObject makeUnique (Args &&... args) { return UniquePtr (new T (cr::forward (args)...)); } template typename detail::UniqueIf ::UnknownBound makeUnique (size_t size) { using Type = typename detail::ClearExtent ::Type; return UniquePtr (new Type[size] ()); } template typename detail::UniqueIf ::KnownBound makeUnique (Args &&...) = delete; CR_NAMESPACE_END