add the pushWithCnv method to the HeterogenMap class

This commit is contained in:
2026-07-15 18:33:42 +03:00
parent 21f3ff9a4c
commit 117765ddd7
2 changed files with 84 additions and 0 deletions

View File

@@ -128,5 +128,31 @@ int main()
std::println("hmap_move.size() = {}", hmap_move.size());
std::println("hmap_copy.size() = {}", hmap_copy.size());
std::println("\n{:*^80}", " hmap with custom conv funcs ");
hmap.pushWithCnv(
"str_cst", std::string{"ABC"}, [&s](std::string const& v) { return s.c_str(); },
[&s](const char* p) {
s = p;
return s;
});
auto ptr = hmap.get<const char*>("str_cst");
if (ptr) {
std::println("ptr = {}", ptr.value());
} else {
std::println("cannot get PTR");
}
// std::string pp = "EEEE";
// auto err = hmap.set("str_cst", pp.c_str());
const char* pp = "EEEE";
auto err = hmap.set("str_cst", pp);
if (err) {
std::println("cannot set 'str_cst'");
} else {
std::println("s = {}", s);
}
return 0;
}

View File

@@ -247,6 +247,64 @@ public:
return ok;
}
// FTs - conversional functions:
// convert-from: std::function<UT(VT const&)> (from inner type to user)
// convert-to: std::function<VT(UT const&)> (from user type to inner)
//
template <typename VT, typename... FTs>
requires(sizeof...(FTs) > 1)
auto pushWithCnv(KeyT const& key, VT&& value, FTs&&... cnv_funcs)
{
static_assert(sizeof...(FTs) % 2 == 0,
"IT MUST BE EVEN NUMBER OF THE INPUT CALLABLES!"); // must be even number ("convert-from" and
// "convert-to")!
using v_t = std::decay_t<VT>;
bool ok = push(key, std::forward<VT>(value));
if (!ok) { // element with given 'key' is already in the map
return ok;
}
auto add_cnv_func = [this](KeyT const& kk, auto&& from_cnv_func, auto&& to_cnv_func) {
using u_t = std::invoke_result_t<decltype(from_cnv_func), v_t>;
// user type must differ from inserted one
static_assert(!std::same_as<v_t, u_t>, "INVALID CONVERSIONAL 'FROM-FUNCTION' SIGNATURE!");
_getter<u_t>[this].emplace(
kk,
[kk, from_cnv_func_arg =
std::forward<decltype(from_cnv_func)>(from_cnv_func)](const HeterogenMap* obj) mutable -> 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 HeterogenMap* obj) mutable {
_values<v_t>[obj][kk] = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
});
_clearFunc.emplace_back([](HeterogenMap* obj) {
_getter<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;
});
};
[&add_cnv_func, key,
tp = std::forward_as_tuple(std::forward<FTs>(cnv_funcs)...)]<size_t... Is>(std::index_sequence<Is...>) {
(add_cnv_func(key, std::get<Is * 2>(tp), std::get<Is * 2 + 1>(tp)), ...);
}(std::make_index_sequence<sizeof...(FTs) / 2>());
return ok;
}
template <typename VT, typename... CtorArgTs>
bool emplace(KeyT const& key, CtorArgTs&&... args)
{