...
This commit is contained in:
@@ -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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -454,64 +454,34 @@ protected:
|
|||||||
inline static std::vector<std::function<bool(KeyT const&, const hmap*)>> _containsFunc{};
|
inline static std::vector<std::function<bool(KeyT const&, const hmap*)>> _containsFunc{};
|
||||||
|
|
||||||
|
|
||||||
// trivial conversional functors
|
// trivial conversional functions
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename VT, typename UT>
|
template <typename VT, typename UT>
|
||||||
requires requires(VT v, UT u) { v = u; }
|
requires requires(VT v, UT u) { v = u; }
|
||||||
inline static std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)> trivial_conv_from =
|
inline static std::function<hmap_expected_t<UT>(VT const&)> trivial_conv_from =
|
||||||
[](hmap_expected_t<VT> const& val) -> hmap_expected_t<UT> {
|
[](VT const& val) -> hmap_expected_t<UT> {
|
||||||
if (val) {
|
// inline static std::function<hmap_expected_t<UT>(hmap_expected_t<VT> const&)> trivial_conv_from =
|
||||||
return static_cast<UT>(val.value());
|
// [](hmap_expected_t<VT> const& val) -> hmap_expected_t<UT> {
|
||||||
} else {
|
return static_cast<UT>(val);
|
||||||
return val.error();
|
// if (val) {
|
||||||
}
|
// return static_cast<UT>(val.value());
|
||||||
|
// } else {
|
||||||
|
// return val.error();
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename VT, typename UT>
|
template <typename VT, typename UT>
|
||||||
requires requires(VT v, UT u) { u = v; }
|
requires requires(VT v, UT u) { u = v; }
|
||||||
inline static std::function<hmap_expected_t<VT>(hmap_expected_t<UT> const&)> trivial_conv_to =
|
inline static std::function<hmap_expected_t<VT>(UT const&)> trivial_conv_to =
|
||||||
[](hmap_expected_t<UT> const& uval) -> hmap_expected_t<VT> {
|
[](UT const& uval) -> hmap_expected_t<VT> {
|
||||||
if (uval) {
|
// inline static std::function<hmap_expected_t<VT>(hmap_expected_t<UT> const&)> trivial_conv_to =
|
||||||
return static_cast<VT>(uval.value());
|
// [](hmap_expected_t<UT> const& uval) -> hmap_expected_t<VT> {
|
||||||
} else {
|
return static_cast<VT>(uval);
|
||||||
return uval.error();
|
// if (uval) {
|
||||||
}
|
// return static_cast<VT>(uval.value());
|
||||||
|
// } else {
|
||||||
|
// return uval.error();
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -692,7 +662,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto add_cnv_func = [this](KeyT const& kk, auto&& from_cnv_func, auto&& to_cnv_func) {
|
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
|
// user type must differ from inserted one
|
||||||
static_assert(!std::same_as<v_t, u_t>, "INVALID CONVERSIONAL 'FROM-FUNCTION' SIGNATURE!");
|
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]);
|
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)](
|
_setter<u_t>[this].emplace(kk,
|
||||||
const u_t& v, const hmap* obj) mutable {
|
[kk, to_cnv_func_arg = std::forward<decltype(to_cnv_func)>(to_cnv_func)](
|
||||||
auto val = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
|
const u_t& v, const hmap* obj) mutable -> hmap::error_t {
|
||||||
if (val) {
|
auto val = std::forward<decltype(to_cnv_func_arg)>(to_cnv_func_arg)(v);
|
||||||
_values<v_t>[obj][kk] = val;
|
if (val) {
|
||||||
return hmap_error_e::ERROR_OK;
|
_values<v_t>[obj][kk] = val.value();
|
||||||
} else {
|
return hmap_error_e::ERROR_OK;
|
||||||
return val.error();
|
} else {
|
||||||
}
|
return val.error();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
_clearFunc.emplace_back([](hmap* obj) {
|
_clearFunc.emplace_back([](hmap* obj) {
|
||||||
_getter<u_t>[obj].clear();
|
_getter<u_t>[obj].clear();
|
||||||
@@ -741,14 +712,15 @@ public:
|
|||||||
requires(sizeof...(Ts) > 0)
|
requires(sizeof...(Ts) > 0)
|
||||||
auto push(KeyT const& key, VT&& value, std::tuple<Ts...>)
|
auto push(KeyT const& key, VT&& value, std::tuple<Ts...>)
|
||||||
{
|
{
|
||||||
|
using v_t = std::decay_t<VT>;
|
||||||
using tp_t = std::tuple<Ts...>;
|
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)...); },
|
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(key, std::forward<VT>(val)),
|
||||||
std::tuple_cat(std::forward_as_tuple(
|
std::tuple_cat(std::forward_as_tuple(
|
||||||
hmap::trivial_conv_from<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<VT, 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)>{});
|
}(std::make_index_sequence<sizeof...(Ts)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user