working hmap class
This commit is contained in:
@@ -182,23 +182,8 @@ int main()
|
||||
|
||||
std::print("push element with key '{}' and value {}\t...", k2, s1);
|
||||
ok = hm.push(
|
||||
k2, s1,
|
||||
[](auto const& v) -> decltype(hm)::hmap_expected_t<const char*> {
|
||||
return v.c_str();
|
||||
// if (v) {
|
||||
// return v.c_str();
|
||||
// } else {
|
||||
// return std::unexpected(v.error());
|
||||
// }
|
||||
},
|
||||
[](auto const& v) -> decltype(hm)::hmap_expected_t<std::string> {
|
||||
return std::string(v.value());
|
||||
// if (v) {
|
||||
// return std::string(v.value());
|
||||
// } else {
|
||||
// return std::unexpected(v.error());
|
||||
// }
|
||||
});
|
||||
k2, s1, [](auto const& v) -> hmap_expected_t<const char*> { return v.c_str(); },
|
||||
[](auto const& v) -> hmap_expected_t<std::string> { return std::string(v); });
|
||||
if (!ok) {
|
||||
std::println("cannot insert the value {}", s1);
|
||||
} else {
|
||||
@@ -213,6 +198,8 @@ int main()
|
||||
std::println("OK");
|
||||
}
|
||||
|
||||
std::println("in total {} elelents were pushed", hm.size());
|
||||
|
||||
std::println("\n");
|
||||
|
||||
std::print("get '{}'-element as double: ", k1);
|
||||
@@ -223,5 +210,15 @@ int main()
|
||||
std::println("FAIL");
|
||||
}
|
||||
|
||||
std::println("\n");
|
||||
|
||||
std::print("get '{}'-element as const char*: ", k2);
|
||||
auto sp2 = hm.get<const char*>(k2);
|
||||
if (sp2) {
|
||||
std::println("{}", sp2.value());
|
||||
} else {
|
||||
std::println("FAIL");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -116,6 +116,7 @@ public:
|
||||
return does_contain;
|
||||
}
|
||||
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (auto& func : _clearFunc) {
|
||||
@@ -413,15 +414,17 @@ inline std::error_code make_error_code(hmap_error_e ec)
|
||||
}
|
||||
|
||||
|
||||
typedef std::error_code hmap_error_t;
|
||||
|
||||
template <typename VT>
|
||||
using hmap_expected_t = std::expected<VT, hmap_error_t>;
|
||||
|
||||
|
||||
|
||||
template <snplib_hashable_c KeyT>
|
||||
class hmap
|
||||
{
|
||||
public:
|
||||
typedef std::error_code error_t;
|
||||
|
||||
template <typename VT>
|
||||
using hmap_expected_t = std::expected<VT, hmap::error_t>;
|
||||
|
||||
template <typename VT, typename UT>
|
||||
using hmap_user_conv_from_t = std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)>;
|
||||
|
||||
@@ -439,7 +442,7 @@ protected:
|
||||
|
||||
template <typename UT>
|
||||
inline static std::unordered_map<const hmap*,
|
||||
std::unordered_map<KeyT, std::function<hmap::error_t(UT const&, const hmap*)>>>
|
||||
std::unordered_map<KeyT, std::function<hmap_error_t(UT const&, const hmap*)>>>
|
||||
_setter{};
|
||||
|
||||
|
||||
@@ -555,6 +558,16 @@ public:
|
||||
return does_contain;
|
||||
}
|
||||
|
||||
bool erase(KeyT const& key)
|
||||
{
|
||||
bool ok = false;
|
||||
for (auto& func : _eraseFunc) {
|
||||
ok |= func(key, this);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (auto& func : _clearFunc) {
|
||||
@@ -574,6 +587,7 @@ public:
|
||||
return N;
|
||||
}
|
||||
|
||||
|
||||
template <typename VT>
|
||||
bool push(KeyT const& key, VT&& value)
|
||||
{
|
||||
@@ -632,7 +646,9 @@ public:
|
||||
// NOTE: do not use here iterator since after insertion
|
||||
// an rehashing may occur and all iterators will be invalidated!
|
||||
|
||||
_getter<v_t>[this].emplace(key, [key](const hmap* obj) { return _values<v_t>[obj][key]; });
|
||||
_getter<v_t>[this].emplace(key,
|
||||
[key](const hmap* obj) -> hmap_expected_t<v_t> { return _values<v_t>[obj][key]; });
|
||||
|
||||
_setter<v_t>[this].emplace(key, [key](const v_t& v, const hmap* obj) {
|
||||
_values<v_t>[obj][key] = v;
|
||||
return hmap_error_e::ERROR_OK;
|
||||
@@ -643,8 +659,8 @@ public:
|
||||
|
||||
|
||||
// FTs - conversional functions:
|
||||
// convert-from: std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)> (from inner type to user)
|
||||
// convert-to: std::function<hmap_expected_t<VT>(hmap_expected_t<UT> const&)> (from user type to inner)
|
||||
// convert-from: std::function<hmap_expected_t<UT>(VT const&)> (from inner type to user)
|
||||
// convert-to: std::function<hmap_expected_t<VT>(UT const&)> (from user type to inner)
|
||||
//
|
||||
template <typename VT, typename... FTs>
|
||||
requires(sizeof...(FTs) > 1)
|
||||
@@ -669,14 +685,14 @@ public:
|
||||
|
||||
_getter<u_t>[this].emplace(
|
||||
kk,
|
||||
[kk, from_cnv_func_arg =
|
||||
std::forward<decltype(from_cnv_func)>(from_cnv_func)](const hmap* obj) mutable -> u_t {
|
||||
[kk, from_cnv_func_arg = std::forward<decltype(from_cnv_func)>(from_cnv_func)](
|
||||
const hmap* obj) mutable -> hmap_expected_t<u_t> {
|
||||
return std::forward<decltype(from_cnv_func_arg)>(from_cnv_func_arg)(_values<v_t>[obj][kk]);
|
||||
});
|
||||
|
||||
_setter<u_t>[this].emplace(kk,
|
||||
[kk, to_cnv_func_arg = std::forward<decltype(to_cnv_func)>(to_cnv_func)](
|
||||
const u_t& v, const hmap* obj) mutable -> hmap::error_t {
|
||||
const u_t& v, const hmap* obj) mutable -> hmap_error_t {
|
||||
auto val = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
|
||||
if (val) {
|
||||
_values<v_t>[obj][kk] = val.value();
|
||||
@@ -708,6 +724,9 @@ public:
|
||||
return ok;
|
||||
}
|
||||
|
||||
//
|
||||
// overloaded method with trivial conversion functions constructed from
|
||||
// element types of the input std::tuple
|
||||
template <typename VT, typename... Ts>
|
||||
requires(sizeof...(Ts) > 0)
|
||||
auto push(KeyT const& key, VT&& value, std::tuple<Ts...>)
|
||||
@@ -735,7 +754,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename UT>
|
||||
hmap::error_t set(KeyT const& key, UT&& value)
|
||||
hmap_error_t set(KeyT const& key, UT&& value)
|
||||
{
|
||||
using u_t = std::decay_t<UT>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user