From 16cec9c2fb991e3fbcea7acb11968fbabafbe2db Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 1 Oct 2023 20:59:29 +0300 Subject: [PATCH] Add td::add_to_top. --- tdutils/td/utils/algorithm.h | 48 ++++++++++++++++++++++++++++++++++++ tdutils/test/misc.cpp | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/tdutils/td/utils/algorithm.h b/tdutils/td/utils/algorithm.h index 00aae8f64..28fb9708c 100644 --- a/tdutils/td/utils/algorithm.h +++ b/tdutils/td/utils/algorithm.h @@ -86,6 +86,54 @@ bool remove(V &v, const T &value) { return true; } +template +void add_to_top(V &v, size_t max_size, T value) { + size_t size = v.size(); + size_t i; + for (i = 0; i < size; i++) { + if (v[i] == value) { + value = std::move(v[i]); + break; + } + } + if (i == size) { + if (size < max_size || i == 0) { + v.emplace_back(); + } else { + i--; + } + } + while (i > 0) { + v[i] = std::move(v[i - 1]); + i--; + } + v[0] = std::move(value); +} + +template +void add_to_top_if(V &v, size_t max_size, T value, const F &is_equal_to_value) { + size_t size = v.size(); + size_t i; + for (i = 0; i < size; i++) { + if (is_equal_to_value(v[i])) { + value = std::move(v[i]); + break; + } + } + if (i == size) { + if (size < max_size || i == 0) { + v.emplace_back(); + } else { + i--; + } + } + while (i > 0) { + v[i] = std::move(v[i - 1]); + i--; + } + v[0] = std::move(value); +} + template void unique(V &v) { if (v.empty()) { diff --git a/tdutils/test/misc.cpp b/tdutils/test/misc.cpp index aaea9fa7c..92e632333 100644 --- a/tdutils/test/misc.cpp +++ b/tdutils/test/misc.cpp @@ -409,6 +409,49 @@ TEST(Misc, remove) { test_remove(v, 1, v); } +static void test_add_to_top(td::vector v, size_t max_size, int new_value, const td::vector &expected) { + auto u = v; + td::add_to_top(v, max_size, new_value); + ASSERT_EQ(expected, v); + + td::add_to_top_if(u, max_size, new_value, [new_value](int value) { return value == new_value; }); + ASSERT_EQ(expected, u); +} + +static void test_add_to_top_if(td::vector v, int max_size, int new_value, const td::vector &expected) { + td::add_to_top_if(v, max_size, new_value, [new_value](int value) { return value % 10 == new_value % 10; }); + ASSERT_EQ(expected, v); +} + +TEST(Misc, add_to_top) { + test_add_to_top({}, 0, 1, {1}); + test_add_to_top({}, 1, 1, {1}); + test_add_to_top({}, 6, 1, {1}); + + test_add_to_top({1, 2, 3, 4, 5, 6}, 3, 2, {2, 1, 3, 4, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 1, {1, 2, 3, 4, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 1, {1, 2, 3, 4, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 2, {2, 1, 3, 4, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 2, {2, 1, 3, 4, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 4, {4, 1, 2, 3, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 4, {4, 1, 2, 3, 5, 6}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 6, {6, 1, 2, 3, 4, 5}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 6, {6, 1, 2, 3, 4, 5}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 7, {7, 1, 2, 3, 4, 5}); + test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 7, {7, 1, 2, 3, 4, 5, 6}); + + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 11, {1, 2, 3, 4, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 21, {1, 2, 3, 4, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 32, {2, 1, 3, 4, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 42, {2, 1, 3, 4, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 54, {4, 1, 2, 3, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 64, {4, 1, 2, 3, 5, 6}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 76, {6, 1, 2, 3, 4, 5}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 86, {6, 1, 2, 3, 4, 5}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 97, {97, 1, 2, 3, 4, 5}); + test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 87, {87, 1, 2, 3, 4, 5, 6}); +} + static void test_unique(td::vector v, const td::vector &expected) { auto v_str = td::transform(v, &td::to_string); auto expected_str = td::transform(expected, &td::to_string);