From 5bba9b0470291643393f67a4178a321a82e93eec Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Fri, 18 Jan 2019 19:39:19 +0300 Subject: [PATCH] SetWithPosition: fixes and tests GitOrigin-RevId: 7b74a05c72261222a4f43b86eecad668ffd40403 --- CMakeLists.txt | 1 + td/telegram/FileReferenceManager.h | 52 +-------- td/telegram/SetWithPosition.h | 62 +++++++++++ test/CMakeLists.txt | 5 + test/set_with_position.cpp | 167 +++++++++++++++++++++++++++++ 5 files changed, 236 insertions(+), 51 deletions(-) create mode 100644 td/telegram/SetWithPosition.h create mode 100644 test/set_with_position.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f6c42bb2..fd3a7993f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -569,6 +569,7 @@ set(TDLIB_SOURCE td/telegram/SecureStorage.h td/telegram/SecureValue.h td/telegram/SequenceDispatcher.h + td/telegram/SetWithPosition.h td/telegram/StateManager.h td/telegram/StickersManager.h td/telegram/StorageManager.h diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 6936aa58f..f8c2534fc 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -13,6 +13,7 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/MessageId.h" +#include "td/telegram/SetWithPosition.h" #include "td/telegram/UserId.h" #include "td/utils/Variant.h" @@ -22,57 +23,6 @@ namespace td { extern int VERBOSITY_NAME(file_references); -template -class SetWithPosition { - public: - void add(T value) { - auto it = std::find(values_.begin(), values_.end(), value); - if (it != end(values_)) { - return; - } - values_.push_back(value); - } - void remove(T value) { - auto it = std::find(values_.begin(), values_.end(), value); - if (it == end(values_)) { - return; - } - size_t i = it - values_.begin(); - values_.erase(it); - if (pos_ > i) { - pos_--; - } - } - void reset_position() { - pos_ = 0; - } - T next() { - return values_[pos_++]; - } - bool has_next() { - return pos_ < values_.size(); - } - void merge(SetWithPosition &&other) { - std::vector new_values_; - for (size_t i = 0; i < pos_; i++) { - new_values_.push_back(values_[i]); - } - for (size_t i = 0; i < other.pos_; i++) { - new_values_.push_back(other.values_[i]); - } - for (size_t i = pos_; i < values_.size(); i++) { - new_values_.push_back(values_[i]); - } - for (size_t i = other.pos_; i < other.values_.size(); i++) { - new_values_.push_back(other.values_[i]); - } - pos_ += other.pos_; - } - - private: - std::vector values_; - size_t pos_{0}; -}; class FileReferenceManager : public Actor { struct Node; diff --git a/td/telegram/SetWithPosition.h b/td/telegram/SetWithPosition.h new file mode 100644 index 000000000..ab0f75d6a --- /dev/null +++ b/td/telegram/SetWithPosition.h @@ -0,0 +1,62 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// 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 + +namespace td { +template +class SetWithPosition { + public: + void add(T value) { + auto it = std::find(values_.begin(), values_.end(), value); + if (it != end(values_)) { + return; + } + values_.push_back(value); + } + void remove(T value) { + auto it = std::find(values_.begin(), values_.end(), value); + if (it == end(values_)) { + return; + } + size_t i = it - values_.begin(); + values_.erase(it); + if (pos_ > i) { + pos_--; + } + } + void reset_position() { + pos_ = 0; + } + T next() { + return values_[pos_++]; + } + bool has_next() { + return pos_ < values_.size(); + } + void merge(SetWithPosition &&other) { + SetWithPosition res; + for (size_t i = 0; i < pos_; i++) { + res.add(values_[i]); + } + for (size_t i = 0; i < other.pos_; i++) { + res.add(other.values_[i]); + } + res.pos_ = res.values_.size(); + for (size_t i = pos_; i < values_.size(); i++) { + res.add(values_[i]); + } + for (size_t i = other.pos_; i < other.values_.size(); i++) { + res.add(other.values_[i]); + } + *this = std::move(res); + } + + private: + std::vector values_; + size_t pos_{0}; +}; +} // namespace td diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e127fdb06..5ec9742aa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,7 @@ set(TD_TEST_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/message_entities.cpp ${CMAKE_CURRENT_SOURCE_DIR}/secret.cpp ${CMAKE_CURRENT_SOURCE_DIR}/secure_storage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/set_with_position.cpp ${CMAKE_CURRENT_SOURCE_DIR}/string_cleaning.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tdclient.cpp @@ -29,6 +30,10 @@ target_link_libraries(all_tests PRIVATE tdactor tddb tdcore tdnet tdutils) if (NOT CMAKE_CROSSCOMPILING OR EMSCRIPTEN) #Tests + add_executable(set_with_position ${TESTS_MAIN} set_with_position.cpp) + target_link_libraries(set_with_position PRIVATE tdutils) + target_include_directories(set_with_position PUBLIC $) + add_executable(run_all_tests ${TESTS_MAIN} ${TD_TEST_SOURCE}) if (CLANG AND NOT CYGWIN AND NOT EMSCRIPTEN) target_compile_options(run_all_tests PUBLIC -fsanitize=undefined -fno-sanitize=vptr) diff --git a/test/set_with_position.cpp b/test/set_with_position.cpp new file mode 100644 index 000000000..211cc5b2f --- /dev/null +++ b/test/set_with_position.cpp @@ -0,0 +1,167 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// 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/utils/tests.h" +#include "td/utils/Random.h" + +#include "td/telegram/SetWithPosition.h" + +#include + +using namespace td; + +template class Set = 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() { + 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) { + 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_)); + } + + private: + std::set checked_; + std::set not_checked_; + Set s_; +}; + +template