From 7f5fce13ef08a02ad3af409f7ca96c5f8942984c Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Thu, 19 Oct 2023 11:23:55 -0300 Subject: [PATCH] feat: vector-sort (#1690) vector_sort is a container that contains sorted objects. --- src/pch.hpp | 1 + src/utils/vectorsort.hpp | 178 +++++++++++++++++++++++++++++++++++++++ vcproj/canary.vcxproj | 1 + 3 files changed, 180 insertions(+) create mode 100644 src/utils/vectorsort.hpp diff --git a/src/pch.hpp b/src/pch.hpp index c2308989b8f..84d07897ba1 100644 --- a/src/pch.hpp +++ b/src/pch.hpp @@ -18,6 +18,7 @@ #include "utils/definitions.hpp" #include "utils/simd.hpp" #include "utils/vectorset.hpp" +#include "utils/vectorsort.hpp" // -------------------- // STL Includes diff --git a/src/utils/vectorsort.hpp b/src/utils/vectorsort.hpp new file mode 100644 index 00000000000..7069e5463c8 --- /dev/null +++ b/src/utils/vectorsort.hpp @@ -0,0 +1,178 @@ +/** + * Canary - A free and open-source MMORPG server emulator + * Copyright (©) 2019-2022 OpenTibiaBR + * Repository: https://github.com/opentibiabr/canary + * License: https://github.com/opentibiabr/canary/blob/main/LICENSE + * Contributors: https://github.com/opentibiabr/canary/graphs/contributors + * Website: https://docs.opentibiabr.com/ + */ + +#pragma once + +#include +#include + +// # Mehah +// vector_sort is a container that contains sorted objects. + +namespace stdext { + template + class vector_sort { + public: + bool contains(const T &v) { + update(); + return std::ranges::binary_search(container, v); + } + + bool erase(const T &v) { + update(); + + const auto &it = std::ranges::lower_bound(container, v); + if (it == container.end()) { + return false; + } + container.erase(it); + + return true; + } + + bool erase(const size_t begin, const size_t end) { + update(); + + if (begin > size() || end > size()) { + return false; + } + + container.erase(container.begin() + begin, container.begin() + end); + return true; + } + + template + bool erase_if(F fnc) { + update(); + return std::erase_if(container, std::move(fnc)) > 0; + } + + auto &front() { + update(); + return container.front(); + } + + void pop_back() { + update(); + container.pop_back(); + } + + auto &back() { + update(); + return container.back(); + } + + void push_back(const T &v) { + needUpdate = true; + container.push_back(v); + } + + void push_back(T &&_Val) { + needUpdate = true; + container.push_back(std::move(_Val)); + } + + // Copy all content list to this + auto insert_all(const vector_sort &list) { + needUpdate = true; + return container.insert(container.end(), list.begin(), list.end()); + } + + // Copy all content list to this + auto insert_all(const std::vector &list) { + needUpdate = true; + return container.insert(container.end(), list.begin(), list.end()); + } + + // Move all content list to this + auto join(vector_sort &list) { + needUpdate = true; + auto res = container.insert(container.end(), make_move_iterator(list.begin()), make_move_iterator(list.end())); + list.clear(); + return res; + } + + // Move all content list to this + auto join(std::vector &list) { + needUpdate = true; + auto res = container.insert(container.end(), make_move_iterator(list.begin()), make_move_iterator(list.end())); + list.clear(); + return res; + } + + template + decltype(auto) emplace_back(_Valty &&... v) { + needUpdate = true; + return container.emplace_back(std::forward<_Valty>(v)...); + } + + void partial_sort(size_t begin, size_t end = 0) { + partial_begin = begin; + if (end > begin) { + partial_end = size() - end; + } + } + + void notify_sort() { + needUpdate = true; + } + + bool empty() const noexcept { + return container.empty(); + } + + size_t size() const noexcept { + return container.size(); + } + + auto begin() noexcept { + update(); + return container.begin(); + } + + auto end() noexcept { + return container.end(); + } + + void clear() noexcept { + partial_begin = partial_end = 0; + return container.clear(); + } + + void reserve(size_t newCap) noexcept { + container.reserve(newCap); + } + + const auto &data() noexcept { + update(); + return container.data(); + } + + T &operator[](const size_t i) { + update(); + return container[i]; + } + + private: + inline void update() noexcept { + if (!needUpdate) { + return; + } + + needUpdate = false; + std::ranges::sort(container.begin() + partial_begin, container.end() - partial_end, std::less()); + } + + std::vector container; + + bool needUpdate = false; + size_t partial_begin { 0 }; + size_t partial_end { 0 }; + }; +} diff --git a/vcproj/canary.vcxproj b/vcproj/canary.vcxproj index e7fa84338e0..67268dff0f7 100644 --- a/vcproj/canary.vcxproj +++ b/vcproj/canary.vcxproj @@ -220,6 +220,7 @@ +