This commit is contained in:
Timur A. Fatkhullin
2026-06-18 00:31:08 +03:00
parent 10703e22d6
commit a95a3a5d1b
4 changed files with 122 additions and 3 deletions

View File

@@ -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>("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>("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; return 0;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <chrono>
#include <concepts> #include <concepts>
#include <ranges> #include <ranges>
@@ -12,6 +13,7 @@ concept snplib_hashable_c = requires(T t) {
{ std::hash<T>{}(t) } -> std::convertible_to<size_t>; { std::hash<T>{}(t) } -> std::convertible_to<size_t>;
}; };
// some concepts for various types of char sequence
template <typename T, typename CharT = char> template <typename T, typename CharT = char>
concept snplib_char_range_c = std::ranges::range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>; concept snplib_char_range_c = std::ranges::range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
@@ -25,5 +27,34 @@ template <typename T, typename CharT = char>
concept snplib_char_view_c = std::ranges::view<T> && std::same_as<std::ranges::range_value_t<T>, CharT>; concept snplib_char_view_c = std::ranges::view<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
// std::chrono related concepts
template <typename T>
concept snplib_time_duration_c = requires(T t) {
[]<typename R, typename P>(std::type_identity<std::chrono::duration<R, P>>) {
}(std::type_identity<std::remove_cvref_t<T>>());
};
template <typename T, typename ClockT>
concept snplib_time_point_c = requires(T t) {
[]<typename DurT>(std::type_identity<std::chrono::time_point<ClockT, DurT>>) {
}(std::type_identity<std::remove_cvref_t<T>>());
};
template <typename T>
concept snplib_systime_point_c = snplib_time_point_c<T, std::chrono::system_clock>;
template <typename T>
concept snplib_utctime_point_c = snplib_time_point_c<T, std::chrono::utc_clock>;
// callables (does not working for templated functions/methods and generic lambdas!)
template <typename T>
concept snplib_callable_c = std::is_function_v<T> || (std::is_object_v<T> && requires(T) { &T::operator(); });
} // namespace snplib } // namespace snplib

View File

@@ -36,6 +36,7 @@ protected:
inline static std::vector<std::function<void(const HeterogenMap*, HeterogenMap*)>> _copyFunc{}; inline static std::vector<std::function<void(const HeterogenMap*, HeterogenMap*)>> _copyFunc{};
inline static std::vector<std::function<void(HeterogenMap*)>> _clearFunc{}; inline static std::vector<std::function<void(HeterogenMap*)>> _clearFunc{};
inline static std::vector<std::function<bool(KeyT const&, const HeterogenMap*)>> _eraseFunc{};
inline static std::vector<std::function<bool(KeyT const&, const HeterogenMap*)>> _containsFunc{}; inline static std::vector<std::function<bool(KeyT const&, const HeterogenMap*)>> _containsFunc{};
public: public:
@@ -43,7 +44,7 @@ public:
HeterogenMap() = default; HeterogenMap() = default;
~HeterogenMap() virtual ~HeterogenMap()
{ {
clear(); clear();
} }
@@ -154,6 +155,16 @@ public:
_getter<v_t>[obj].clear(); _getter<v_t>[obj].clear();
_setter<v_t>[obj].clear(); _setter<v_t>[obj].clear();
}); });
_eraseFunc.emplace_back([](KeyT const& k, const HeterogenMap* obj) {
bool do_delete = _values<v_t>[obj].erase(k) != 0;
if (do_delete) {
_getter<v_t>[obj].erase(k);
_setter<v_t>[obj].erase(k);
}
return do_delete;
});
} }
_values<v_t>[this].emplace(key, std::forward<VT>(value)); _values<v_t>[this].emplace(key, std::forward<VT>(value));
@@ -164,7 +175,6 @@ public:
_getter<v_t>[this].emplace(key, [key](const HeterogenMap* obj) { return _values<v_t>[obj][key]; }); _getter<v_t>[this].emplace(key, [key](const HeterogenMap* obj) { return _values<v_t>[obj][key]; });
_setter<v_t>[this].emplace(key, [key](const v_t& v, const HeterogenMap* obj) { _values<v_t>[obj][key] = v; }); _setter<v_t>[this].emplace(key, [key](const v_t& v, const HeterogenMap* obj) { _values<v_t>[obj][key] = v; });
return true; return true;
} }
@@ -198,6 +208,13 @@ public:
_getter<u_t>[obj].clear(); _getter<u_t>[obj].clear();
_setter<u_t>[obj].clear(); _setter<u_t>[obj].clear();
}); });
_eraseFunc.emplace_back([](KeyT const& k, const HeterogenMap* obj) {
_getter<u_t>[obj].erase(k);
_setter<u_t>[obj].erase(k);
return true;
});
} }
}; };
@@ -209,11 +226,22 @@ public:
} }
template <typename VT, typename... CtorArgTs> template <typename VT, typename... CtorArgTs>
size_t emplace(KeyT const& key, CtorArgTs&&... args) bool emplace(KeyT const& key, CtorArgTs&&... args)
{ {
return push(key, VT(std::forward<CtorArgTs>(args)...)); return push(key, VT(std::forward<CtorArgTs>(args)...));
} }
bool erase(KeyT const& key)
{
bool ok = false;
for (auto& func : _eraseFunc) {
ok |= func(key, this);
}
return ok;
}
template <typename UT> template <typename UT>
std::expected<UT, Error> get(KeyT const& key) const std::expected<UT, Error> get(KeyT const& key) const
{ {

View File

@@ -0,0 +1,41 @@
#pragma once
#include <functional>
#include <unordered_map>
namespace snplib
{
class HeterogenVec
{
protected:
template <typename VT>
inline static std::unordered_map<const HeterogenVec*, std::vector<VT>> _values{};
inline static std::vector<std::function<void(const HeterogenVec*)>> _clearFunc{};
public:
void clear()
{
for (auto& func : _clearFunc) {
func(this);
}
}
template <typename VT>
void insert(VT&& value)
{
using v_t = std::decay_t<VT>;
if (_values<v_t>.empty()) {
_clearFunc.emplace_back([](const HeterogenVec* obj) { _values<v_t>[obj].clear(); });
}
_values<v_t>[this].push_back(std::forward<VT>(value));
}
};
} // end of namespace snplib