2022-03-09 14:29:47 +01:00
|
|
|
//
|
2024-01-01 01:07:21 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
|
2022-03-09 14:29:47 +01:00
|
|
|
//
|
|
|
|
// 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"
|
|
|
|
|
2022-06-02 15:19:16 +02:00
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
|
|
|
|
2022-03-09 14:29:47 +01:00
|
|
|
namespace td {
|
|
|
|
|
2024-03-21 16:43:47 +01:00
|
|
|
template <class KeyT, class EqT, class Enable = void>
|
2022-03-09 14:29:47 +01:00
|
|
|
struct SetNode {
|
|
|
|
using public_key_type = KeyT;
|
2022-03-12 13:27:14 +01:00
|
|
|
using public_type = const KeyT;
|
2022-03-09 14:29:47 +01:00
|
|
|
using second_type = KeyT; // TODO: remove second_type?
|
|
|
|
|
2022-07-23 13:53:32 +02:00
|
|
|
KeyT first;
|
2022-03-09 14:29:47 +01:00
|
|
|
|
|
|
|
const KeyT &key() const {
|
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
2022-03-12 13:27:14 +01:00
|
|
|
const KeyT &get_public() {
|
2022-03-09 14:29:47 +01:00
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
2022-10-03 13:39:20 +02:00
|
|
|
SetNode() : first() {
|
2022-07-23 13:53:32 +02:00
|
|
|
}
|
2022-03-09 14:29:47 +01:00
|
|
|
explicit SetNode(KeyT key) : first(std::move(key)) {
|
|
|
|
}
|
2023-05-05 12:51:19 +02:00
|
|
|
SetNode(const SetNode &) = delete;
|
|
|
|
SetNode &operator=(const SetNode &) = delete;
|
2022-03-09 14:29:47 +01:00
|
|
|
SetNode(SetNode &&other) noexcept {
|
|
|
|
*this = std::move(other);
|
|
|
|
}
|
|
|
|
void operator=(SetNode &&other) noexcept {
|
|
|
|
DCHECK(empty());
|
|
|
|
DCHECK(!other.empty());
|
|
|
|
first = std::move(other.first);
|
2022-07-23 13:53:32 +02:00
|
|
|
other.first = KeyT();
|
2022-03-09 14:29:47 +01:00
|
|
|
}
|
|
|
|
~SetNode() = default;
|
|
|
|
|
|
|
|
void copy_from(const SetNode &other) {
|
|
|
|
DCHECK(empty());
|
|
|
|
first = other.first;
|
2022-03-11 19:38:48 +01:00
|
|
|
DCHECK(!empty());
|
2022-03-09 14:29:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool empty() const {
|
2024-03-21 16:43:47 +01:00
|
|
|
return is_hash_table_key_empty<EqT>(first);
|
2022-03-09 14:29:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
|
|
|
first = KeyT();
|
|
|
|
DCHECK(empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
void emplace(KeyT key) {
|
|
|
|
first = std::move(key);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-03-21 16:43:47 +01:00
|
|
|
template <class KeyT, class EqT>
|
|
|
|
struct SetNode<KeyT, EqT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void *))>> {
|
2022-04-19 01:33:12 +02:00
|
|
|
struct Impl {
|
|
|
|
using second_type = KeyT;
|
|
|
|
|
2022-07-23 13:53:32 +02:00
|
|
|
KeyT first;
|
2022-04-19 01:33:12 +02:00
|
|
|
|
|
|
|
template <class InputKeyT>
|
2022-06-02 15:19:16 +02:00
|
|
|
explicit Impl(InputKeyT &&key) : first(std::forward<InputKeyT>(key)) {
|
2024-03-21 16:43:47 +01:00
|
|
|
DCHECK(!is_hash_table_key_empty<EqT>(first));
|
2022-04-19 01:33:12 +02:00
|
|
|
}
|
2023-05-05 12:51:19 +02:00
|
|
|
Impl(const Impl &) = delete;
|
|
|
|
Impl &operator=(const Impl &) = delete;
|
|
|
|
Impl(Impl &&) = delete;
|
2023-05-05 13:31:55 +02:00
|
|
|
Impl &operator=(Impl &&) = delete;
|
2022-04-19 01:33:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-10-03 13:39:20 +02:00
|
|
|
SetNode() : impl_() {
|
2022-04-19 01:33:12 +02:00
|
|
|
}
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-03-09 14:29:47 +01:00
|
|
|
} // namespace td
|