From a95a3a5d1b522c1d651fba789fba78c4d32ebf86 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Thu, 18 Jun 2026 00:31:08 +0300 Subject: [PATCH] ... --- examples/hmap_example.cpp | 19 ++++++++++ include/snipplib/concepts/snplib_concepts.h | 31 ++++++++++++++++ include/snipplib/containers/snplib_hmap.h | 34 +++++++++++++++-- include/snipplib/containers/snplib_hvec.h | 41 +++++++++++++++++++++ 4 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 include/snipplib/containers/snplib_hvec.h diff --git a/examples/hmap_example.cpp b/examples/hmap_example.cpp index 293ae49..4906bc2 100644 --- a/examples/hmap_example.cpp +++ b/examples/hmap_example.cpp @@ -96,5 +96,24 @@ int main() } } + std::println("\n{:*^80}", " delete key "); + + std::println("erase node with key 'int_key'"); + if (hmap_move.erase("int_key")) { + auto ri = hmap_move.get("int_key"); + if (ri) { // should not be + std::println("hmap_move['int_key'] = {}", ri.value()); + } else { + std::println("cannot get value of hmap_move['int_key']"); + } + + ri = hmap_copy.get("int_key"); + if (ri) { + std::println("hmap_copy['int_key'] = {}", ri.value()); + } else { + std::println("cannot get value of hmap_copy['int_key']"); + } + } + return 0; } \ No newline at end of file diff --git a/include/snipplib/concepts/snplib_concepts.h b/include/snipplib/concepts/snplib_concepts.h index e66af12..2f477c0 100644 --- a/include/snipplib/concepts/snplib_concepts.h +++ b/include/snipplib/concepts/snplib_concepts.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -12,6 +13,7 @@ concept snplib_hashable_c = requires(T t) { { std::hash{}(t) } -> std::convertible_to; }; +// some concepts for various types of char sequence template concept snplib_char_range_c = std::ranges::range && std::same_as, CharT>; @@ -25,5 +27,34 @@ template concept snplib_char_view_c = std::ranges::view && std::same_as, CharT>; +// std::chrono related concepts + +template +concept snplib_time_duration_c = requires(T t) { + [](std::type_identity>) { + + }(std::type_identity>()); +}; + +template +concept snplib_time_point_c = requires(T t) { + [](std::type_identity>) { + + }(std::type_identity>()); +}; + +template +concept snplib_systime_point_c = snplib_time_point_c; + + +template +concept snplib_utctime_point_c = snplib_time_point_c; + + +// callables (does not working for templated functions/methods and generic lambdas!) + +template +concept snplib_callable_c = std::is_function_v || (std::is_object_v && requires(T) { &T::operator(); }); + } // namespace snplib \ No newline at end of file diff --git a/include/snipplib/containers/snplib_hmap.h b/include/snipplib/containers/snplib_hmap.h index 99c30da..46588ea 100644 --- a/include/snipplib/containers/snplib_hmap.h +++ b/include/snipplib/containers/snplib_hmap.h @@ -36,6 +36,7 @@ protected: inline static std::vector> _copyFunc{}; inline static std::vector> _clearFunc{}; + inline static std::vector> _eraseFunc{}; inline static std::vector> _containsFunc{}; public: @@ -43,7 +44,7 @@ public: HeterogenMap() = default; - ~HeterogenMap() + virtual ~HeterogenMap() { clear(); } @@ -154,6 +155,16 @@ public: _getter[obj].clear(); _setter[obj].clear(); }); + + _eraseFunc.emplace_back([](KeyT const& k, const HeterogenMap* obj) { + bool do_delete = _values[obj].erase(k) != 0; + if (do_delete) { + _getter[obj].erase(k); + _setter[obj].erase(k); + } + + return do_delete; + }); } _values[this].emplace(key, std::forward(value)); @@ -164,7 +175,6 @@ public: _getter[this].emplace(key, [key](const HeterogenMap* obj) { return _values[obj][key]; }); _setter[this].emplace(key, [key](const v_t& v, const HeterogenMap* obj) { _values[obj][key] = v; }); - return true; } @@ -198,6 +208,13 @@ public: _getter[obj].clear(); _setter[obj].clear(); }); + + _eraseFunc.emplace_back([](KeyT const& k, const HeterogenMap* obj) { + _getter[obj].erase(k); + _setter[obj].erase(k); + + return true; + }); } }; @@ -209,11 +226,22 @@ public: } template - size_t emplace(KeyT const& key, CtorArgTs&&... args) + bool emplace(KeyT const& key, CtorArgTs&&... args) { return push(key, VT(std::forward(args)...)); } + + bool erase(KeyT const& key) + { + bool ok = false; + for (auto& func : _eraseFunc) { + ok |= func(key, this); + } + + return ok; + } + template std::expected get(KeyT const& key) const { diff --git a/include/snipplib/containers/snplib_hvec.h b/include/snipplib/containers/snplib_hvec.h new file mode 100644 index 0000000..b134c28 --- /dev/null +++ b/include/snipplib/containers/snplib_hvec.h @@ -0,0 +1,41 @@ +#pragma once + + +#include +#include + + +namespace snplib +{ + +class HeterogenVec +{ +protected: + template + inline static std::unordered_map> _values{}; + + inline static std::vector> _clearFunc{}; + +public: + void clear() + { + for (auto& func : _clearFunc) { + func(this); + } + } + + + template + void insert(VT&& value) + { + using v_t = std::decay_t; + + if (_values.empty()) { + _clearFunc.emplace_back([](const HeterogenVec* obj) { _values[obj].clear(); }); + } + + _values[this].push_back(std::forward(value)); + } +}; + +} // end of namespace snplib \ No newline at end of file