12#include <promeki/config.h>
13#if PROMEKI_ENABLE_CORE
20PROMEKI_NAMESPACE_BEGIN
62template <
typename T>
class UniquePtr {
67 template <
typename U>
friend class UniquePtr;
70 UniquePtr() =
default;
73 UniquePtr(std::nullptr_t)
noexcept {}
76 UniquePtr(
const UniquePtr &) =
delete;
79 UniquePtr &operator=(
const UniquePtr &) =
delete;
82 UniquePtr(UniquePtr &&o) noexcept : _ptr(o._ptr) { o._ptr =
nullptr; }
92 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<T, U> && !std::is_same_v<T, U>>>
93 UniquePtr(UniquePtr<U> &&o) noexcept : _ptr(o._ptr) {
97 ~UniquePtr() { clear(); }
100 UniquePtr &operator=(UniquePtr &&o)
noexcept {
101 if (&o ==
this)
return *
this;
114 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<T, U> && !std::is_same_v<T, U>>>
115 UniquePtr &operator=(UniquePtr<U> &&o)
noexcept {
126 template <
typename... Args>
static UniquePtr create(Args &&...args) {
128 up._ptr =
new T(std::forward<Args>(args)...);
140 static UniquePtr takeOwnership(T *obj) {
148 if (_ptr ==
nullptr)
return;
180 void reset(T *obj =
nullptr) {
187 void swap(UniquePtr &other)
noexcept { std::swap(_ptr, other._ptr); }
190 bool isNull()
const {
return _ptr ==
nullptr; }
193 bool isValid()
const {
return _ptr !=
nullptr; }
196 explicit operator bool()
const {
return _ptr !=
nullptr; }
198 bool operator==(
const UniquePtr &other)
const {
return _ptr == other._ptr; }
199 bool operator!=(
const UniquePtr &other)
const {
return _ptr != other._ptr; }
200 bool operator==(std::nullptr_t)
const {
return _ptr ==
nullptr; }
201 bool operator!=(std::nullptr_t)
const {
return _ptr !=
nullptr; }
211 assert(_ptr !=
nullptr);
222 T *get()
const {
return _ptr; }
224 T *operator->()
const {
return ptr(); }
225 T &operator*()
const {
return *ptr(); }
232template <
typename T>
void swap(UniquePtr<T> &a, UniquePtr<T> &b)
noexcept {
265template <
typename T>
class UniquePtr<T[]> {
268 UniquePtr() =
default;
271 UniquePtr(std::nullptr_t)
noexcept {}
274 UniquePtr(
const UniquePtr &) =
delete;
277 UniquePtr &operator=(
const UniquePtr &) =
delete;
280 UniquePtr(UniquePtr &&o) noexcept : _ptr(o._ptr) { o._ptr =
nullptr; }
282 ~UniquePtr() { clear(); }
285 UniquePtr &operator=(UniquePtr &&o)
noexcept {
286 if (&o ==
this)
return *
this;
302 static UniquePtr createArray(
size_t n) {
321 static UniquePtr createArrayValueInit(
size_t n) {
323 up._ptr =
new T[n]();
335 static UniquePtr takeOwnership(T *obj) {
343 if (_ptr ==
nullptr)
return;
370 void reset(T *obj =
nullptr) {
377 void swap(UniquePtr &other)
noexcept { std::swap(_ptr, other._ptr); }
380 bool isNull()
const {
return _ptr ==
nullptr; }
383 bool isValid()
const {
return _ptr !=
nullptr; }
386 explicit operator bool()
const {
return _ptr !=
nullptr; }
388 bool operator==(
const UniquePtr &other)
const {
return _ptr == other._ptr; }
389 bool operator!=(
const UniquePtr &other)
const {
return _ptr != other._ptr; }
390 bool operator==(std::nullptr_t)
const {
return _ptr ==
nullptr; }
391 bool operator!=(std::nullptr_t)
const {
return _ptr !=
nullptr; }
401 assert(_ptr !=
nullptr);
408 T *get()
const {
return _ptr; }
417 T &operator[](
size_t i)
const {
418 assert(_ptr !=
nullptr);
427template <
typename T>
void swap(UniquePtr<T[]> &a, UniquePtr<T[]> &b)
noexcept {
451template <
typename Derived,
typename Base> UniquePtr<Derived> uniquePointerCast(UniquePtr<Base> &&up) {
452 static_assert(std::is_base_of_v<Base, Derived>,
"Derived must publicly derive from Base");
453 if (up.isNull())
return UniquePtr<Derived>();
454 Derived *d =
dynamic_cast<Derived *
>(up.ptr());
455 if (d ==
nullptr)
return UniquePtr<Derived>();
457 return UniquePtr<Derived>::takeOwnership(d);