diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 9cef7004..754c1c91 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -202,6 +202,7 @@ set(TDUTILS_SOURCE td/utils/translit.h td/utils/type_traits.h td/utils/unicode.h + td/utils/unique_ptr.h td/utils/utf8.h td/utils/Variant.h td/utils/VectorQueue.h diff --git a/tdutils/td/utils/common.h b/tdutils/td/utils/common.h index d1217016..6c12a7dc 100644 --- a/tdutils/td/utils/common.h +++ b/tdutils/td/utils/common.h @@ -43,10 +43,9 @@ // clang-format on #include "td/utils/int_types.h" +#include "td/utils/unique_ptr.h" -#include #include -#include #include #define TD_DEBUG @@ -99,11 +98,6 @@ using string = std::string; template using vector = std::vector; -template -using unique_ptr = std::unique_ptr; - -using std::make_unique; - struct Unit {}; struct Auto { diff --git a/tdutils/td/utils/unique_ptr.h b/tdutils/td/utils/unique_ptr.h new file mode 100644 index 00000000..ee6e25e3 --- /dev/null +++ b/tdutils/td/utils/unique_ptr.h @@ -0,0 +1,94 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// 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 { + +template +class unique_ptr { + public: + using pointer = T *; + using element_type = T; + + unique_ptr() noexcept = default; + unique_ptr(const unique_ptr &other) = delete; + unique_ptr &operator=(const unique_ptr &other) = 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 { + delete ptr_; + ptr_ = new_ptr; + } + T *release() noexcept { + auto res = ptr_; + ptr_ = nullptr; + return res; + } + T *get() const noexcept { + return ptr_; + } + T *operator->() const noexcept { + return ptr_; + } + 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