From 52ae5f4c5a8ceb1af9edcee40ba79a324f703126 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Tue, 28 Jul 2026 12:16:52 +0300 Subject: [PATCH] ... --- examples/str_exam.cpp | 6 +++ include/snipplib/concepts/snplib_concepts.h | 5 +- include/snipplib/utils/snplib_keyvalue_expr.h | 52 +++++++++++++++++-- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/examples/str_exam.cpp b/examples/str_exam.cpp index 1ed05a7..5ab3f3b 100644 --- a/examples/str_exam.cpp +++ b/examples/str_exam.cpp @@ -83,6 +83,12 @@ int main() std::println("valueSeq(4,2) = '{}'", kvl.valueSeq(4, 2)); std::println("valueSeq = '{}'", kvl.valueSeq>()); + std::println("\nOwning 'key-value'"); + snplib_keyvalue_expr_t> kv1; + + kv1.setKeyValue("KEY", 7.7); + std::println("key = '{}'", kv1.key()); + std::println("value = '{}'", kv1.value()); snplib_random_string_generator_t<> rstr_gen; diff --git a/include/snipplib/concepts/snplib_concepts.h b/include/snipplib/concepts/snplib_concepts.h index 7d70c20..9f0a12d 100644 --- a/include/snipplib/concepts/snplib_concepts.h +++ b/include/snipplib/concepts/snplib_concepts.h @@ -128,7 +128,10 @@ concept snplib_fixed_size_range_c = template concept snplib_non_resizable_range_c = std::ranges::range && !requires(T r, std::size_t n) { r.resize(n); }; - +// a range with its own data life-time management +template +concept snplib_owning_range_c = std::ranges::range && !std::is_reference_v && + !std::ranges::enable_view> && std::is_move_constructible_v; /* an concept for error-type */ diff --git a/include/snipplib/utils/snplib_keyvalue_expr.h b/include/snipplib/utils/snplib_keyvalue_expr.h index 2ea57e7..8f732ea 100644 --- a/include/snipplib/utils/snplib_keyvalue_expr.h +++ b/include/snipplib/utils/snplib_keyvalue_expr.h @@ -32,7 +32,16 @@ public: std::string_view valseq_delim{DEFAULT_VALSEQ_DELIM_SEQ}; }; - constexpr snplib_keyvalue_expr_t(CharRangeT& bytes, config_t cfg = config_t{}) : _byteSeq(bytes), _config(cfg) + // inner char-sequence storage + constexpr snplib_keyvalue_expr_t(config_t cfg = config_t{}) + requires snplib_owning_range_c + : _ownByteSeq(), _byteSeq(_ownByteSeq), _config(cfg), _isValid(false) + { + } + + // outter char-sequence storage + constexpr snplib_keyvalue_expr_t(CharRangeT& bytes, config_t cfg = config_t{}) + : _ownByteSeq(), _byteSeq(bytes), _config(cfg) { fromCharRange(bytes, cfg); } @@ -181,12 +190,18 @@ public: requires mutableContent error_t setKey(KeyT&& key, SParT const& sparams = snplib_serialization_params_t{}) { - _byteSeq.clear(); + // _byteSeq.clear(); + _byteSeq = CharRangeT(); + auto err = snplib_serializer_t>{}(_byteSeq, std::forward(key), sparams); if (err) { return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument)); } + _key = {_byteSeq.begin(), _byteSeq.end()}; + _value = {}; + _valueSeq = {}; + return {}; } @@ -194,14 +209,43 @@ public: requires mutableContent error_t setValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{}) { + size_t key_sz = _key.size(); + size_t keyval_delim_pos = _key.size() + _config.keyval_delim.size(); + if constexpr (requires(CharRangeT t) { t.resize(std::declval()); }) { + _byteSeq.resize(keyval_delim_pos); + } else { + auto it = _byteSeq.begin(); + std::advance(it, keyval_delim_pos); + _byteSeq = {_byteSeq.begin(), it}; + } + auto err = snplib_serializer_t>{}(_byteSeq, std::forward(value), sparams); if (err) { 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 + 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(_value, _config.valseq_delim); + _valueSeq.resize(1); + _valueSeq[0] = _value; + return {}; } + template + requires mutableContent + error_t appendValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{}) + { + if (_valueSeq.empty()) { + return setValue(std::forward(value), std::move(sparams)); + } + } + template (value), sparams); + return setValue(std::forward(value), std::move(sparams)); } protected: + CharRangeT _ownByteSeq{}; + CharRangeT& _byteSeq; std::conditional_t>