// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // 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) // #include "td/telegram/SetWithPosition.h" #include "td/utils/algorithm.h" #include "td/utils/common.h" #include "td/utils/misc.h" #include "td/utils/Random.h" #include "td/utils/tests.h" #include #include #include #include template class OldSetWithPosition { public: void add(T value) { if (td::contains(values_, value)) { return; } values_.push_back(value); } void remove(T value) { auto it = std::find(values_.begin(), values_.end(), value); if (it == values_.end()) { return; } std::size_t i = it - values_.begin(); values_.erase(it); if (pos_ > i) { pos_--; } } void reset_position() { pos_ = 0; } T next() { CHECK(has_next()); return values_[pos_++]; } bool has_next() const { return pos_ < values_.size(); } void merge(OldSetWithPosition &&other) { OldSetWithPosition res; for (std::size_t i = 0; i < pos_; i++) { res.add(values_[i]); } for (std::size_t i = 0; i < other.pos_; i++) { res.add(other.values_[i]); } res.pos_ = res.values_.size(); for (std::size_t i = pos_; i < values_.size(); i++) { res.add(values_[i]); } for (std::size_t i = other.pos_; i < other.values_.size(); i++) { res.add(other.values_[i]); } *this = std::move(res); } private: td::vector values_; std::size_t pos_{0}; }; template class SetWithPosition> class CheckedSetWithPosition { public: void add(int x) { s_.add(x); if (checked_.count(x) != 0) { return; } not_checked_.insert(x); } void remove(int x) { s_.remove(x); checked_.erase(x); not_checked_.erase(x); } bool has_next() const { auto res = !not_checked_.empty(); //LOG(ERROR) << res; ASSERT_EQ(res, s_.has_next()); return res; } void reset_position() { s_.reset_position(); not_checked_.insert(checked_.begin(), checked_.end()); checked_ = {}; } T next() { CHECK(has_next()); auto next = s_.next(); //LOG(ERROR) << next; ASSERT_TRUE(not_checked_.count(next) != 0); not_checked_.erase(next); checked_.insert(next); return next; } void merge(CheckedSetWithPosition &&other) { if (size() < other.size()) { std::swap(*this, other); std::swap(this->s_, other.s_); } for (auto x : other.checked_) { not_checked_.erase(x); checked_.insert(x); } for (auto x : other.not_checked_) { if (checked_.count(x) != 0) { continue; } not_checked_.insert(x); } s_.merge(std::move(other.s_)); } std::size_t size() const { return checked_.size() + not_checked_.size(); } private: std::set checked_; std::set not_checked_; td::SetWithPosition s_; }; template