diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h')
-rw-r--r-- | protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h new file mode 100644 index 0000000000..6e5960553d --- /dev/null +++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h @@ -0,0 +1,129 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// 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/common.h" +#include "td/utils/HashTableUtils.h" + +#include <type_traits> +#include <utility> + +namespace td { + +template <class KeyT, class Enable = void> +struct SetNode { + using public_key_type = KeyT; + using public_type = const KeyT; + using second_type = KeyT; // TODO: remove second_type? + + KeyT first; + + const KeyT &key() const { + return first; + } + + const KeyT &get_public() { + return first; + } + + SetNode() : first() { + } + explicit SetNode(KeyT key) : first(std::move(key)) { + } + SetNode(const SetNode &other) = delete; + SetNode &operator=(const SetNode &other) = delete; + SetNode(SetNode &&other) noexcept { + *this = std::move(other); + } + void operator=(SetNode &&other) noexcept { + DCHECK(empty()); + DCHECK(!other.empty()); + first = std::move(other.first); + other.first = KeyT(); + } + ~SetNode() = default; + + void copy_from(const SetNode &other) { + DCHECK(empty()); + first = other.first; + DCHECK(!empty()); + } + + bool empty() const { + return is_hash_table_key_empty(first); + } + + void clear() { + first = KeyT(); + DCHECK(empty()); + } + + void emplace(KeyT key) { + first = std::move(key); + } +}; + +template <class KeyT> +struct SetNode<KeyT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void *))>> { + struct Impl { + using second_type = KeyT; + + KeyT first; + + template <class InputKeyT> + explicit Impl(InputKeyT &&key) : first(std::forward<InputKeyT>(key)) { + DCHECK(!is_hash_table_key_empty(first)); + } + Impl(const Impl &other) = delete; + Impl &operator=(const Impl &other) = delete; + Impl(Impl &&other) = delete; + void operator=(Impl &&other) = delete; + }; + + using public_key_type = KeyT; + using public_type = const KeyT; + using second_type = KeyT; // TODO: remove second_type? + + unique_ptr<Impl> impl_; + + const KeyT &key() const { + DCHECK(!empty()); + return impl_->first; + } + + const KeyT &get_public() { + DCHECK(!empty()); + return impl_->first; + } + + SetNode() : impl_() { + } + explicit SetNode(KeyT key) : impl_(td::make_unique<Impl>(std::move(key))) { + } + + void copy_from(const SetNode &other) { + DCHECK(empty()); + impl_ = td::make_unique<Impl>(other.impl_->first); + DCHECK(!empty()); + } + + bool empty() const { + return impl_ == nullptr; + } + + void clear() { + DCHECK(!empty()); + impl_ = nullptr; + } + + void emplace(KeyT key) { + DCHECK(empty()); + impl_ = td::make_unique<Impl>(std::move(key)); + } +}; + +} // namespace td |