This commit is contained in:
2026-09-02 18:52:56 +03:00
parent d15928eb68
commit a49e7b5d5f
2 changed files with 98 additions and 65 deletions

View File

@@ -162,5 +162,66 @@ int main()
}
}
std::println("\n\n\n\n");
snplib::hmap<std::string> hm;
std::string k1{"k_int"}, k2{"k_str"}, k3("k_dbl");
int i1 = 10;
double f1 = 7.7;
std::string s1 = "test-str";
std::print("push element with key '{}' and value {}\t...", k1, i1);
ok = hm.push(k1, i1, std::tuple<long, double, float, long long>{});
if (!ok) {
std::println("cannot insert the value {}", i1);
} else {
std::println("OK");
}
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());
// }
});
if (!ok) {
std::println("cannot insert the value {}", s1);
} else {
std::println("OK");
}
std::print("push element with key '{}' and value {}\t...", k3, f1);
ok = hm.push(k3, f1, std::tuple<long, int, float, long long>{});
if (!ok) {
std::println("cannot insert the value {}", f1);
} else {
std::println("OK");
}
std::println("\n");
std::print("get '{}'-element as double: ", k1);
auto f2 = hm.get<double>(k1);
if (f2) {
std::println("{}", f2.value());
} else {
std::println("FAIL");
}
return 0;
}

View File

@@ -454,64 +454,34 @@ protected:
inline static std::vector<std::function<bool(KeyT const&, const hmap*)>> _containsFunc{};
// trivial conversional functors
struct trivial_conv_from_t {
hmap const* obj;
KeyT const& key;
template <typename VT, typename UT>
hmap_expected_t<UT> operator()(hmap_expected_t<VT> const&)
{
auto v = obj->get<VT>(key);
if (v) {
return static_cast<UT>(v.value());
}
return hmap_error_e::ERROR_USER_CONV;
}
};
struct trivial_conv_to_t {
hmap const* obj;
KeyT const& key;
template <typename VT, typename UT>
hmap_expected_t<VT> operator()(hmap_expected_t<UT> const& uval)
{
if (uval) {
auto err = obj->set(key, uval.value());
if (err) {
return std::unexpected(err);
}
// return
}
return hmap_error_e::ERROR_USER_CONV;
}
};
// trivial conversional functions
template <typename VT, typename UT>
requires requires(VT v, UT u) { v = u; }
inline static std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)> trivial_conv_from =
[](hmap_expected_t<VT> const& val) -> hmap_expected_t<UT> {
if (val) {
return static_cast<UT>(val.value());
} else {
return val.error();
}
inline static std::function<hmap_expected_t<UT>(VT const&)> trivial_conv_from =
[](VT const& val) -> hmap_expected_t<UT> {
// inline static std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)> trivial_conv_from =
// [](hmap_expected_t<VT> const& val) -> hmap_expected_t<UT> {
return static_cast<UT>(val);
// if (val) {
// return static_cast<UT>(val.value());
// } else {
// return val.error();
// }
};
template <typename VT, typename UT>
requires requires(VT v, UT u) { u = v; }
inline static std::function<hmap_expected_t<VT>(hmap_expected_t<UT> const&)> trivial_conv_to =
[](hmap_expected_t<UT> const& uval) -> hmap_expected_t<VT> {
if (uval) {
return static_cast<VT>(uval.value());
} else {
return uval.error();
}
inline static std::function<hmap_expected_t<VT>(UT const&)> trivial_conv_to =
[](UT const& uval) -> hmap_expected_t<VT> {
// inline static std::function<hmap_expected_t<VT>(hmap_expected_t<UT> const&)> trivial_conv_to =
// [](hmap_expected_t<UT> const& uval) -> hmap_expected_t<VT> {
return static_cast<VT>(uval);
// if (uval) {
// return static_cast<VT>(uval.value());
// } else {
// return uval.error();
// }
};
public:
@@ -692,7 +662,7 @@ public:
}
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>;
using u_t = std::invoke_result_t<decltype(from_cnv_func), v_t>::value_type;
// user type must differ from inserted one
static_assert(!std::same_as<v_t, u_t>, "INVALID CONVERSIONAL 'FROM-FUNCTION' SIGNATURE!");
@@ -704,16 +674,17 @@ public:
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 {
auto val = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
if (val) {
_values<v_t>[obj][kk] = val;
return hmap_error_e::ERROR_OK;
} else {
return val.error();
}
});
_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 {
auto val = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
if (val) {
_values<v_t>[obj][kk] = val.value();
return hmap_error_e::ERROR_OK;
} else {
return val.error();
}
});
_clearFunc.emplace_back([](hmap* obj) {
_getter<u_t>[obj].clear();
@@ -741,14 +712,15 @@ public:
requires(sizeof...(Ts) > 0)
auto push(KeyT const& key, VT&& value, std::tuple<Ts...>)
{
using v_t = std::decay_t<VT>;
using tp_t = std::tuple<Ts...>;
return [&key, val = std::forward<VT>(value), this]<size_t... Is>(std::index_sequence<Is...>) {
return [&key, val = std::forward<VT>(value), this]<size_t... Is>(std::index_sequence<Is...>) mutable {
return std::apply([this](auto&&... args) { return push(std::forward<decltype(args)>(args)...); },
std::tuple_cat(std::forward_as_tuple(key, std::forward<VT>(val)),
std::tuple_cat(std::forward_as_tuple(
hmap::trivial_conv_from<VT, std::tuple_element_t<Is, tp_t>>,
hmap::trivial_conv_to<VT, std::tuple_element_t<Is, tp_t>>)...)));
hmap::trivial_conv_from<v_t, std::tuple_element_t<Is, tp_t>>,
hmap::trivial_conv_to<v_t, std::tuple_element_t<Is, tp_t>>)...)));
}(std::make_index_sequence<sizeof...(Ts)>{});
}