12#include <promeki/config.h>
13#if PROMEKI_ENABLE_CORE
19PROMEKI_NAMESPACE_BEGIN
61template <
typename T>
class UniquePtr {
66 template <
typename U>
friend class UniquePtr;
69 UniquePtr() =
default;
72 UniquePtr(std::nullptr_t)
noexcept {}
75 UniquePtr(
const UniquePtr &) =
delete;
78 UniquePtr &operator=(
const UniquePtr &) =
delete;
81 UniquePtr(UniquePtr &&o) noexcept : _ptr(o._ptr) { o._ptr =
nullptr; }
91 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<T, U> && !std::is_same_v<T, U>>>
92 UniquePtr(UniquePtr<U> &&o) noexcept : _ptr(o._ptr) {
96 ~UniquePtr() { clear(); }
99 UniquePtr &operator=(UniquePtr &&o)
noexcept {
100 if (&o ==
this)
return *
this;
113 template <
typename U,
typename = std::enable_if_t<std::is_base_of_v<T, U> && !std::is_same_v<T, U>>>
114 UniquePtr &operator=(UniquePtr<U> &&o)
noexcept {
125 template <
typename... Args>
static UniquePtr create(Args &&...args) {
127 up._ptr =
new T(std::forward<Args>(args)...);
139 static UniquePtr takeOwnership(T *obj) {
147 if (_ptr ==
nullptr)
return;
179 void reset(T *obj =
nullptr) {
186 void swap(UniquePtr &other)
noexcept { std::swap(_ptr, other._ptr); }
189 bool isNull()
const {
return _ptr ==
nullptr; }
192 bool isValid()
const {
return _ptr !=
nullptr; }
195 explicit operator bool()
const {
return _ptr !=
nullptr; }
197 bool operator==(
const UniquePtr &other)
const {
return _ptr == other._ptr; }
198 bool operator!=(
const UniquePtr &other)
const {
return _ptr != other._ptr; }
199 bool operator==(std::nullptr_t)
const {
return _ptr ==
nullptr; }
200 bool operator!=(std::nullptr_t)
const {
return _ptr !=
nullptr; }
210 assert(_ptr !=
nullptr);
221 T *get()
const {
return _ptr; }
223 T *operator->()
const {
return ptr(); }
224 T &operator*()
const {
return *ptr(); }
231template <
typename T>
void swap(UniquePtr<T> &a, UniquePtr<T> &b)
noexcept {
264template <
typename T>
class UniquePtr<T[]> {
267 UniquePtr() =
default;
270 UniquePtr(std::nullptr_t)
noexcept {}
273 UniquePtr(
const UniquePtr &) =
delete;
276 UniquePtr &operator=(
const UniquePtr &) =
delete;
279 UniquePtr(UniquePtr &&o) noexcept : _ptr(o._ptr) { o._ptr =
nullptr; }
281 ~UniquePtr() { clear(); }
284 UniquePtr &operator=(UniquePtr &&o)
noexcept {
285 if (&o ==
this)
return *
this;
301 static UniquePtr createArray(
size_t n) {
320 static UniquePtr createArrayValueInit(
size_t n) {
322 up._ptr =
new T[n]();
334 static UniquePtr takeOwnership(T *obj) {
342 if (_ptr ==
nullptr)
return;
369 void reset(T *obj =
nullptr) {
376 void swap(UniquePtr &other)
noexcept { std::swap(_ptr, other._ptr); }
379 bool isNull()
const {
return _ptr ==
nullptr; }
382 bool isValid()
const {
return _ptr !=
nullptr; }
385 explicit operator bool()
const {
return _ptr !=
nullptr; }
387 bool operator==(
const UniquePtr &other)
const {
return _ptr == other._ptr; }
388 bool operator!=(
const UniquePtr &other)
const {
return _ptr != other._ptr; }
389 bool operator==(std::nullptr_t)
const {
return _ptr ==
nullptr; }
390 bool operator!=(std::nullptr_t)
const {
return _ptr !=
nullptr; }
400 assert(_ptr !=
nullptr);
407 T *get()
const {
return _ptr; }
416 T &operator[](
size_t i)
const {
417 assert(_ptr !=
nullptr);
426template <
typename T>
void swap(UniquePtr<T[]> &a, UniquePtr<T[]> &b)
noexcept {
450template <
typename Derived,
typename Base> UniquePtr<Derived> uniquePointerCast(UniquePtr<Base> &&up) {
451 static_assert(std::is_base_of_v<Base, Derived>,
"Derived must publicly derive from Base");
452 if (up.isNull())
return UniquePtr<Derived>();
453 Derived *d =
dynamic_cast<Derived *
>(up.ptr());
454 if (d ==
nullptr)
return UniquePtr<Derived>();
456 return UniquePtr<Derived>::takeOwnership(d);