...
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
41
include/snipplib/containers/snplib_hvec.h
Normal file
41
include/snipplib/containers/snplib_hvec.h
Normal 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
|
||||||
Reference in New Issue
Block a user