10        UniquePtr() : ptr(
nullptr), deleteFn() {}
 
   12        explicit UniquePtr(T* ptr, std::function<
void(
void*)> newDeleteFn) : ptr(ptr), deleteFn(newDeleteFn) {}
 
   14        UniquePtr(std::nullptr_t) : ptr(
nullptr), deleteFn() {}
 
   17        UniquePtr(
const UniquePtr<T>& other) = 
delete;
 
   18        UniquePtr& operator=(
const UniquePtr<T>& other) = 
delete;
 
   20        UniquePtr& operator=(std::nullptr_t) {
 
   25        UniquePtr(UniquePtr&& other) noexcept
 
   26            : ptr(other.ptr), deleteFn(std::move(other.deleteFn)) {
 
   28            other.deleteFn = std::function<void(
void*)>{};
 
   32        UniquePtr& operator=(UniquePtr&& other) 
noexcept {
 
   33            UniquePtr tmp(std::move(other));
 
   39            std::enable_if_t<std::is_convertible_v<U*, T*>, 
int> = 0>
 
   40        UniquePtr(UniquePtr<U>&& other) noexcept
 
   41            : ptr(other.Release()), deleteFn(std::move(other.GetDeleter())) {}
 
   44            std::enable_if_t<std::is_convertible_v<U*, T*>, 
int> = 0>
 
   45        UniquePtr& operator=(UniquePtr<U>&& other) 
noexcept {
 
   46            if (
this != 
reinterpret_cast<UniquePtr<T>*
>(&other)) {
 
   48                ptr = other.Release();
 
   49                deleteFn = std::move(other.GetDeleter());
 
   54        T* Release() 
noexcept {
 
   55            T* emptyPtr = 
nullptr;
 
   56            std::swap(emptyPtr, ptr);
 
   57            deleteFn = std::function<void(
void*)>{};
 
   62        void Reset() 
noexcept {
 
   73            deleteFn = std::function<void(
void*)>{};
 
   76        void Swap(UniquePtr& other) 
noexcept {
 
   77            std::swap(ptr, other.ptr);
 
   78            std::swap(deleteFn, other.deleteFn);
 
   82            return ptr == other.ptr && deleteFn == other.deleteFn;
 
   85        bool operator==(
const T* other) 
const noexcept {
 
   89        bool operator==(std::nullptr_t) 
const noexcept {
 
   90            return ptr == 
nullptr;
 
   93        explicit operator T*() 
const {
 
   97        explicit operator bool()
 const {
 
   98            return ptr != 
nullptr;
 
  105        const T* operator->()
 const {
 
  113        const T& operator*()
 const {
 
  121        const T* Get()
 const {
 
  125        const std::function<void(
void*)>& GetDeleter()
 const {
 
  126            return this->deleteFn;
 
  134        bool operator==(
const UniquePtr<U>& other) 
const noexcept {
 
  135            static_assert(std::is_convertible_v<U*, T*> || std::is_convertible_v<T*, U*>,
 
  136                "UniquePtr comparison requires compatible pointer types.");
 
  137            return ptr == other.ptr && deleteFn == other.deleteFn;
 
  142        std::function<void(
void*)> deleteFn;