// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include #include #include namespace td { // const-correct and compiler-friendly (g++ RAM and CPU usage 10 times less than for std::unique_ptr) // replacement for std::unique_ptr template class unique_ptr final { public: using pointer = T *; using element_type = T; unique_ptr() noexcept = default; unique_ptr(const unique_ptr &) = delete; unique_ptr &operator=(const unique_ptr &) = delete; unique_ptr(unique_ptr &&other) noexcept : ptr_(other.release()) { } unique_ptr &operator=(unique_ptr &&other) noexcept { reset(other.release()); return *this; } ~unique_ptr() { reset(); } unique_ptr(std::nullptr_t) noexcept { } explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) { } template ::value>> unique_ptr(unique_ptr &&other) noexcept : ptr_(static_cast(other.release())) { } template ::value>> unique_ptr &operator=(unique_ptr &&other) noexcept { reset(static_cast(other.release())); return *this; } void reset(T *new_ptr = nullptr) noexcept { static_assert(sizeof(T) > 0, "Can't destroy unique_ptr with incomplete type"); delete ptr_; ptr_ = new_ptr; } T *release() noexcept { auto res = ptr_; ptr_ = nullptr; return res; } T *get() noexcept { return ptr_; } const T *get() const noexcept { return ptr_; } T *operator->() noexcept { return ptr_; } const T *operator->() const noexcept { return ptr_; } T &operator*() noexcept { return *ptr_; } const T &operator*() const noexcept { return *ptr_; } explicit operator bool() const noexcept { return ptr_ != nullptr; } private: T *ptr_{nullptr}; }; template bool operator==(std::nullptr_t, const unique_ptr &p) { return !p; } template bool operator==(const unique_ptr &p, std::nullptr_t) { return !p; } template bool operator!=(std::nullptr_t, const unique_ptr &p) { return static_cast(p); } template bool operator!=(const unique_ptr &p, std::nullptr_t) { return static_cast(p); } template unique_ptr make_unique(Args &&...args) { return unique_ptr(new Type(std::forward(args)...)); } } // namespace td