Fix tl::unique_ptr.

GitOrigin-RevId: 1a8cf83048e27435ce44adef8ee2123724d4fc23
This commit is contained in:
levlam 2018-09-21 20:13:32 +03:00
parent dd9964ae3a
commit eba99a8957

View File

@ -11,9 +11,11 @@
* Contains the declarations of a base class for all TL-objects and some helper methods * Contains the declarations of a base class for all TL-objects and some helper methods
*/ */
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <type_traits>
#include <utility> #include <utility>
namespace td { namespace td {
@ -90,46 +92,54 @@ class TlObject {
* A smart wrapper to store a pointer to a TL-object. * A smart wrapper to store a pointer to a TL-object.
*/ */
namespace tl { namespace tl {
template <class T> template <class T>
class unique_ptr { class unique_ptr {
public: public:
unique_ptr() = default; 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() { ~unique_ptr() {
reset(); reset();
} }
unique_ptr(std::nullptr_t) {
unique_ptr(std::nullptr_t) noexcept {
} }
explicit unique_ptr(T *ptr) : ptr_(ptr) { explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) {
} }
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>> template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
unique_ptr(unique_ptr<S> &&other) : ptr_(static_cast<S *>(other.release())) { unique_ptr(unique_ptr<S> &&other) noexcept : ptr_(static_cast<S *>(other.release())) {
} }
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>> template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
unique_ptr &operator=(unique_ptr<S> &&other) { unique_ptr &operator=(unique_ptr<S> &&other) noexcept {
auto other_ptr = static_cast<T *>(other.release()); reset(static_cast<T *>(other.release()));
reset();
ptr_ = other_ptr;
return *this; return *this;
} }
void reset() { void reset(T *new_ptr = nullptr) noexcept {
delete ptr_; delete ptr_;
ptr_ = nullptr; ptr_ = new_ptr;
} }
T *release() { T *release() noexcept {
auto res = ptr_; auto res = ptr_;
ptr_ = nullptr; ptr_ = nullptr;
return res; return res;
} }
T *get() const { T *get() const noexcept {
return ptr_; return ptr_;
} }
T *operator->() const { T *operator->() const noexcept {
return ptr_; return ptr_;
} }
T &operator*() const { T &operator*() const noexcept {
return *ptr_; return *ptr_;
} }
operator bool() const { explicit operator bool() const noexcept {
return ptr_ != nullptr; return ptr_ != nullptr;
} }