This commit is contained in:
2026-08-06 13:27:13 +03:00
parent ee450ca108
commit 5d964cd61c
3 changed files with 124 additions and 10 deletions

View File

@@ -88,8 +88,20 @@ int main()
snplib_keyvalue_expr_t kv1;
kv1.setKeyValue("KEY", 7.7);
kv1.appendValue(std::string{"dekjlwe"});
kv1.appendValue(100);
std::println("key = '{}'", kv1.key());
std::println("value = '{}'", kv1.value());
std::println("valueSeq = '{}'\n", kv1.valueSeq());
si = std::string{"dekjlwe"};
kv1.setValue(7.7, snplib_serialization_params_t{}, si, snplib_serialization_params_t{}, 100,
snplib_serialization_params_t{});
std::println("key = '{}'", kv1.key());
std::println("value = '{}'", kv1.value());
std::println("valueSeq = '{}'\n", kv1.valueSeq());
snplib_random_string_generator_t<> rstr_gen;

View File

@@ -82,4 +82,41 @@ template <typename T>
using snplib_func_arg1_t = typename snplib_func_traits_t<T>::arg1_t;
/* create a std::tuple from the input types except the last one*/
template <typename... Ts>
struct snplib_tuple_except_last_helper_t;
template <typename T>
struct snplib_tuple_except_last_helper_t<T> {
using tuple_t = std::tuple<>;
};
template <typename T, typename... Ts>
struct snplib_tuple_except_last_helper_t<T, Ts...> {
using tuple_t =
decltype(std::tuple_cat(std::declval<std::tuple<T>>(),
std::declval<typename snplib_tuple_except_last_helper_t<Ts...>::tuple_t>()));
};
template <typename... Ts>
using snplib_tuple_except_last_t = typename snplib_tuple_except_last_helper_t<Ts...>::tuple_t;
template <typename... Ts>
struct snplib_last_in_pack_helper_t;
template <typename T>
struct snplib_last_in_pack_helper_t<T> {
using type = T;
};
template <typename T, typename... Ts>
struct snplib_last_in_pack_helper_t<T, Ts...> {
using type = typename snplib_last_in_pack_helper_t<Ts...>::type;
};
template <typename... Ts>
using snplib_last_in_pack_t = typename snplib_last_in_pack_helper_t<Ts...>::type;
} // namespace snplib

View File

@@ -2,6 +2,7 @@
#include "../concepts/snplib_concepts.h"
#include "../serialization/snplib_serialization.h"
#include "snipplib/concepts/snplib_traits.h"
namespace snplib
{
@@ -239,27 +240,91 @@ public:
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
}
// it can be a reallocation of the byte sequence so one needs to reinit _key and _value
// a reallocation of the byte sequence may occur so one needs to reinit _key and _value
auto it = _byteSeq.begin();
std::advance(it, key_sz);
_key = {_byteSeq.begin(), it};
std::advance(it, _config.keyval_delim.size());
_value = {it, _byteSeq.end()};
// _valueSeq = snplib_split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
_valueSeq.resize(1);
_valueSeq[0] = _value;
return {};
}
// template <snplib_serializable_c ValueT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
// requires mutableContent
// error_t appendValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{})
// {
// if (_valueSeq.empty()) {
// return setValue(std::forward<ValueT>(value), std::move(sparams));
// }
// }
// value1, ser-pars1, value2, ser-pars2, ..., valueN, ser-parsN
template <typename... ValSerParPairTs>
requires(mutableContent && sizeof...(ValSerParPairTs) >= 4 && (sizeof...(ValSerParPairTs) % 2 == 0))
error_t setValue(ValSerParPairTs&&... pairs)
{
constexpr auto f = []<size_t... Is>(std::index_sequence<Is...>) {
using args_t = std::tuple<ValSerParPairTs...>;
return ((snplib_serializable_c<std::tuple_element_t<Is * 2, args_t>> &&
snplib_serialization_params_c<std::tuple_element_t<Is * 2 + 1, args_t>>) &&
...);
}(std::make_index_sequence<sizeof...(ValSerParPairTs) / 2>{});
_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<decltype(v1)>(v1), std::forward<decltype(sp1)>(sp1));
if (err) {
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
}
if constexpr (sizeof...(prs)) {
return std::forward<decltype(self)>(self)(std::forward<decltype(prs)>(prs)...);
}
return {};
}(std::forward<ValSerParPairTs>(pairs)...);
}
template <typename... ArgTs>
requires(mutableContent && sizeof...(ArgTs) > 2)
error_t setVal(ArgTs&&... args)
{
static_assert(snplib_serialization_params_c<snplib_last_in_pack_t<ArgTs...>>, "");
using args_t = snplib_tuple_except_last_t<ArgTs...>;
}
template <snplib_serializable_c ValueT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
requires mutableContent
error_t appendValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{})
{
if (_valueSeq.empty()) {
return setValue(std::forward<ValueT>(value), std::move(sparams));
}
size_t key_sz = _key.size();
std::ranges::copy(_config.keyval_delim, std::back_inserter(_byteSeq));
auto it = _byteSeq.begin();
std::advance(it, _key.size() + _config.keyval_delim.size());
auto prev_size = std::ranges::distance(_byteSeq);
auto err = snplib_serializer_t<std::remove_cvref_t<ValueT>>{}(_byteSeq, std::forward<ValueT>(value), sparams);
if (err) {
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
}
// a reallocation of the byte sequence may occur so one needs to reinit _key and _value
it = _byteSeq.begin();
std::advance(it, key_sz);
_key = {_byteSeq.begin(), it};
std::advance(it, _config.keyval_delim.size());
_value = {it, _byteSeq.end()};
_valueSeq = snplib_split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
return {};
}
template <snplib_serializable_c KeyT,