From 7e3e49c3bbf59e661c4d06e931348d570b130bab Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Thu, 6 Aug 2026 17:46:32 +0300 Subject: [PATCH] ... --- examples/str_exam.cpp | 7 +- include/snipplib/utils/snplib_keyvalue_expr.h | 235 +++++++++++++++--- 2 files changed, 203 insertions(+), 39 deletions(-) diff --git a/examples/str_exam.cpp b/examples/str_exam.cpp index 0b84659..bdfe12d 100644 --- a/examples/str_exam.cpp +++ b/examples/str_exam.cpp @@ -88,17 +88,20 @@ int main() snplib_keyvalue_expr_t kv1; kv1.setKeyValue("KEY", 7.7); - kv1.appendValue(std::string{"dekjlwe"}); + kv1.appendValue(std::string{"dekjlwe1"}); kv1.appendValue(100); std::println("key = '{}'", kv1.key()); std::println("value = '{}'", kv1.value()); std::println("valueSeq = '{}'\n", kv1.valueSeq()); - si = std::string{"dekjlwe"}; + si = std::string{"dekjlwe2"}; kv1.setValue(7.7, snplib_serialization_params_t{}, si, snplib_serialization_params_t{}, 100, snplib_serialization_params_t{}); + si = std::string{"dekjlwe3"}; + kv1.setValue(snplib_serialization_params_t{}, 7.7, si, 100); + std::println("key = '{}'", kv1.key()); std::println("value = '{}'", kv1.value()); std::println("valueSeq = '{}'\n", kv1.valueSeq()); diff --git a/include/snipplib/utils/snplib_keyvalue_expr.h b/include/snipplib/utils/snplib_keyvalue_expr.h index 1c5b497..5a11833 100644 --- a/include/snipplib/utils/snplib_keyvalue_expr.h +++ b/include/snipplib/utils/snplib_keyvalue_expr.h @@ -253,43 +253,6 @@ public: return {}; } - // value1, ser-pars1, value2, ser-pars2, ..., valueN, ser-parsN - template - requires(mutableContent && sizeof...(ValSerParPairTs) >= 4 && (sizeof...(ValSerParPairTs) % 2 == 0)) - error_t setValue(ValSerParPairTs&&... pairs) - { - constexpr auto f = [](std::index_sequence) { - using args_t = std::tuple; - - return ((snplib_serializable_c> && - snplib_serialization_params_c>) && - ...); - }(std::make_index_sequence{}); - - _valueSeq.clear(); // to trigger the first call to setValue - return [this](this auto&& self, auto&& v1, auto&& sp1, auto&&... prs) -> error_t { - auto err = appendValue(std::forward(v1), std::forward(sp1)); - if (err) { - return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); - } - - if constexpr (sizeof...(prs)) { - return std::forward(self)(std::forward(prs)...); - } - - return {}; - }(std::forward(pairs)...); - } - - template - requires(mutableContent && sizeof...(ArgTs) > 2) - error_t setVal(ArgTs&&... args) - { - static_assert(snplib_serialization_params_c>, ""); - - using args_t = snplib_tuple_except_last_t; - } - template requires mutableContent @@ -327,6 +290,204 @@ public: } + // value1, ser-pars1, value2, ser-pars2, ..., valueN, ser-parsN + template + requires(mutableContent && sizeof...(ValSerParPairTs) >= 4 && (sizeof...(ValSerParPairTs) % 2 == 0) && + !snplib_serialization_params_c>>) + error_t setValue(ValSerParPairTs&&... pairs) + { + constexpr auto f = [](std::index_sequence) { + using args_t = std::tuple; + + return ((snplib_serializable_c> && + snplib_serialization_params_c>) && + ...); + }(std::make_index_sequence{}); + + _valueSeq.clear(); // to trigger the first call to setValue + + return [this](this auto&& self, auto&& v1, auto&& sp1, auto&&... prs) -> error_t { + auto err = appendValue(std::forward(v1), std::forward(sp1)); + if (err) { + return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + } + + if constexpr (sizeof...(prs)) { + return std::forward(self)(std::forward(prs)...); + } + + return {}; + }(std::forward(pairs)...); + } + + + // value1, ser-pars1, value2, ser-pars2, ..., valueN, ser-parsN + // or + // common-ser-pars, value1, value2, ..., valueN + template + requires(mutableContent && sizeof...(ArgTs) > 1) + error_t setValue(ArgT&& arg, ArgTs&&... args) + { + static constexpr size_t NARGS = sizeof...(ArgTs) + 1; + + // "val-spar" pairs + constexpr auto is_val_spar_pairs = + !snplib_serialization_params_c && [](std::index_sequence) { + if constexpr (NARGS % 2) { // NARGS must be an even + return false; + } + + using args_t = std::tuple; + + return ((snplib_serializable_c> && + snplib_serialization_params_c>) && + ...); + }(std::make_index_sequence{}); + + + constexpr auto is_val_seq = + snplib_serialization_params_c && [](std::index_sequence) { + return (snplib_serializable_c>> && ...); + }(std::make_index_sequence{}); + + static_assert(is_val_spar_pairs || is_val_seq, "Unsupported input parameter types!"); + + _valueSeq.clear(); // to trigger the first call to setValue + + if constexpr (is_val_spar_pairs) { + return [this](this auto&& self, auto&& v1, auto&& sp1, auto&&... prs) -> error_t { + auto err = appendValue(std::forward(v1), std::forward(sp1)); + if (err) { + return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + } + + if constexpr (sizeof...(prs)) { + return std::forward(self)(std::forward(prs)...); + } + + return {}; + }(std::forward(arg), std::forward(args)...); + } else { // ser-params and values sequence + return [sp = std::forward(arg), this](this auto&& self, auto&& tp) -> error_t { + using tp_t = std::remove_cvref_t; + + if constexpr (I < std::tuple_size_v) { + auto err = appendValue( + std::forward>(std::get(std::forward(tp))), sp); + if (err) { + return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + } + + return std::forward(self).template operator()( + std::forward(tp)); + } + + return {}; + }(std::forward_as_tuple(std::forward(args)...)); + } + } + + + // // common-ser-pars, value1, value2, ..., valueN + // template + // requires(mutableContent && sizeof...(ValueTs) > 1) + // error_t setValue(SParT sparams, ValueTs&&... values) + // { + // _valueSeq.clear(); // to trigger the first call to setValue + + // return [sp = std::move(sparams), this](this auto&& self, auto&& tp) -> error_t { + // using tp_t = std::remove_cvref_t; + + // if constexpr (I < std::tuple_size_v) { + // auto err = appendValue( + // std::forward>(std::get(std::forward(tp))), + // std::move(sp)); + // if (err) { + // return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + // } + + // return std::forward(self).template operator()(std::forward(tp)); + // } + + // return {}; + // }(std::forward_as_tuple(std::forward(values)...)); + // } + + // value1, ser-pars1, value2, ser-pars2, ..., valueN, ser-parsN + // or + // value1, value2, ..., valueN, common-ser-pars + // template + // requires(mutableContent && sizeof...(ArgTs) > 2) + // error_t setValue(ArgTs&&... args) + // { + // constexpr auto is_val_spar_pairs = [](std::index_sequence) { + // using args_t = std::tuple; + + // return ((snplib_serializable_c> && + // snplib_serialization_params_c>) && + // ...); + // }(std::make_index_sequence{}); + + // using v_args_t = snplib_tuple_except_last_t; + + // constexpr auto is_val_seq = [](std::index_sequence) { + // return (snplib_serializable_c> && ...); + // }(std::make_index_sequence>{}); + + // static_assert(is_val_spar_pairs || is_val_seq, "Unsupported input parameter types!"); + + // _valueSeq.clear(); // to trigger the first call to setValue + + // if constexpr (is_val_spar_pairs) { + // return [this](this auto&& self, auto&& v1, auto&& sp1, auto&&... prs) -> error_t { + // auto err = appendValue(std::forward(v1), std::forward(sp1)); + // if (err) { + // return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + // } + + // if constexpr (sizeof...(prs)) { + // return std::forward(self)(std::forward(prs)...); + // } + + // return {}; + // }(std::forward(args)...); + // } else { // value sequence with trailing common serialization parameters + // static_assert(snplib_serialization_params_c>, + // "The last input parameter must satisfy to 'snplib_serialization_params_c' requirement!"); + + // auto make_vals_tuple = [... args = std::forward(args)]() mutable { + // return [tp = std::forward_as_tuple(std::forward(args)...)]( + // std::index_sequence) mutable { + // return std::forward_as_tuple( + // std::forward>(std::get(tp))...); + // }(std::make_index_sequence{}); + // }; + + + // return [spar = std::forward(args)...))>>( + // std::get(std::forward_as_tuple(std::forward(args)...))), + // this](this auto&& self, auto&& tp) -> error_t { + // using tp_t = std::remove_cvref_t; + + // if constexpr (I < std::tuple_size_v) { + // auto err = appendValue( + // std::forward>(std::get(std::forward(tp))), + // std::forward(spar)); + // if (err) { + // return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); + // } + + // return std::forward(self).template operator()( + // std::forward(tp)); + // } + + // return {}; + // }(make_vals_tuple()); + // } + // } + + template