diff options
| author | levlam <levlam@telegram.org> | 2023-01-22 23:36:30 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2023-01-22 23:36:30 +0300 |
| commit | 201af22ef28348b837ab061c106e25abbb4e5a65 (patch) | |
| tree | c28c69dbf61a6422c3e2d0a41002f008eed5c9eb /tdutils | |
| parent | d6502824b3f64c69190c2ba36adb7b75b505f00f (diff) | |
Add unique_value_ptr.
Diffstat (limited to 'tdutils')
| -rw-r--r-- | tdutils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tdutils/td/utils/unique_value_ptr.h | 93 | ||||
| -rw-r--r-- | tdutils/test/misc.cpp | 30 |
3 files changed, 124 insertions, 0 deletions
diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 08d8029cc..e7b4b788a 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -292,6 +292,7 @@ set(TDUTILS_SOURCE td/utils/uint128.h td/utils/unicode.h td/utils/unique_ptr.h + td/utils/unique_value_ptr.h td/utils/utf8.h td/utils/Variant.h td/utils/VectorQueue.h diff --git a/tdutils/td/utils/unique_value_ptr.h b/tdutils/td/utils/unique_value_ptr.h new file mode 100644 index 000000000..1b8abf732 --- /dev/null +++ b/tdutils/td/utils/unique_value_ptr.h @@ -0,0 +1,93 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// 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 "td/utils/unique_ptr.h" + +#include <cstddef> +#include <utility> + +namespace td { + +// copyable by value td::unique_ptr +template <class T> +class unique_value_ptr final { + public: + unique_value_ptr() noexcept = default; + unique_value_ptr(const unique_value_ptr &other) { + if (other != nullptr) { + ptr_ = make_unique<T>(*other); + } + } + unique_value_ptr &operator=(const unique_value_ptr &other) { + if (other == nullptr) { + ptr_ = nullptr; + } else { + ptr_ = make_unique<T>(*other); + } + return *this; + } + unique_value_ptr(unique_value_ptr &&other) noexcept = default; + unique_value_ptr &operator=(unique_value_ptr &&other) = default; + unique_value_ptr(std::nullptr_t) noexcept { + } + unique_value_ptr(unique_ptr<T> &&ptr) noexcept : ptr_(std::move(ptr)) { + } + T *get() noexcept { + return ptr_.get(); + } + const T *get() const noexcept { + return ptr_.get(); + } + T *operator->() noexcept { + return ptr_.get(); + } + const T *operator->() const noexcept { + return ptr_.get(); + } + T &operator*() noexcept { + return *ptr_; + } + const T &operator*() const noexcept { + return *ptr_; + } + explicit operator bool() const noexcept { + return ptr_ != nullptr; + } + + private: + unique_ptr<T> ptr_; +}; + +template <class T> +bool operator==(const unique_value_ptr<T> &p, std::nullptr_t) { + return !p; +} +template <class T> +bool operator!=(const unique_value_ptr<T> &p, std::nullptr_t) { + return static_cast<bool>(p); +} + +template <class T> +bool operator==(const unique_value_ptr<T> &lhs, const unique_value_ptr<T> &rhs) { + if (lhs == nullptr) { + return rhs == nullptr; + } + return rhs != nullptr && *lhs == *rhs; +} + +template <class T> +bool operator!=(const unique_value_ptr<T> &lhs, const unique_value_ptr<T> &rhs) { + return !(lhs == rhs); +} + +template <class Type, class... Args> +unique_value_ptr<Type> make_unique_value(Args &&...args) { + return unique_value_ptr<Type>(make_unique<Type>(std::forward<Args>(args)...)); +} + +} // namespace td diff --git a/tdutils/test/misc.cpp b/tdutils/test/misc.cpp index 2e58cd356..05f9b16d9 100644 --- a/tdutils/test/misc.cpp +++ b/tdutils/test/misc.cpp @@ -40,6 +40,7 @@ #include "td/utils/translit.h" #include "td/utils/uint128.h" #include "td/utils/unicode.h" +#include "td/utils/unique_value_ptr.h" #include "td/utils/utf8.h" #include <algorithm> @@ -1260,3 +1261,32 @@ TEST(FloodControl, Fast) { LOG(INFO) << ++count << ": " << now; } } + +TEST(UniqueValuePtr, Basic) { + auto a = td::make_unique_value<int>(5); + td::unique_value_ptr<int> b; + ASSERT_TRUE(b == nullptr); + ASSERT_TRUE(a != nullptr); + ASSERT_TRUE(a != b); + b = a; + ASSERT_TRUE(a != nullptr); + ASSERT_TRUE(b != nullptr); + ASSERT_TRUE(a == b); + *a = 6; + ASSERT_TRUE(a != nullptr); + ASSERT_TRUE(b != nullptr); + ASSERT_TRUE(a != b); + b = std::move(a); + ASSERT_TRUE(a == nullptr); + ASSERT_TRUE(b != nullptr); + ASSERT_TRUE(a != b); + auto c = td::make_unique_value<td::unique_value_ptr<int>>(a); + ASSERT_TRUE(*c == a); + ASSERT_TRUE(*c == nullptr); + c = td::make_unique_value<td::unique_value_ptr<int>>(b); + ASSERT_TRUE(*c == b); + ASSERT_TRUE(**c == 6); + auto d = c; + ASSERT_TRUE(c == d); + ASSERT_TRUE(6 == **d); +} |
