From 6faafa7b47b9e2bba173983bb827f1179aa4f4aa Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Tue, 23 Jun 2026 19:14:19 +0300 Subject: [PATCH] ... --- include/snipplib/utils/snplib_keyvalue.h | 94 ++++++++++++++++++++++++ include/snipplib/utils/snplib_string.h | 45 ++++++++++++ 2 files changed, 139 insertions(+) diff --git a/include/snipplib/utils/snplib_keyvalue.h b/include/snipplib/utils/snplib_keyvalue.h index 2936390..7295a76 100644 --- a/include/snipplib/utils/snplib_keyvalue.h +++ b/include/snipplib/utils/snplib_keyvalue.h @@ -126,6 +126,73 @@ public: } + template + requires(std::ranges::output_range> && + snplib_char_range_c>) + OR valueSeq(size_t start = 0, size_t N = std::numeric_limits::max()) const + { + using el_t = std::ranges::range_value_t; + + OR res; + + if (N == 0 || _valueSeq.empty() || start >= _valueSeq.size()) { + return res; + } + + auto elems = _valueSeq | std::views::drop(start) | std::views::take(N); + + if constexpr (std::same_as) { + std::ranges::copy(elems, std::back_inserter(res)); + } else { + std::ranges::for_each(elems, [&res](auto const& e) { + if constexpr (std::constructible_from) { + std::back_inserter(el_t{e.cbegin(), e.cend()}, std::back_inserter(res)); + } else if constexpr (std::constructible_from) { + std::back_inserter(el_t{e}, std::back_inserter(res)); + } else { + static_assert(false, "Incompatible types: cannot create output element!"); + } + }); + } + + return res; + } + + std::vector valueSeq(size_t start = 0, size_t N = std::numeric_limits::max()) const + { + return valueSeq>(start, N); + } + + + template + OR valueJoinSeq(size_t start = 0, size_t N = std::numeric_limits::max()) const + { + if (N == 0 || _valueSeq.empty() || start >= _valueSeq.size()) { + return OR(); + } + + auto last_idx = start + N; + if (last_idx >= _valueSeq.size()) { + last_idx = _valueSeq.size() - 1; + } + + + if constexpr (std::constructible_from) { + return OR{_valueSeq[start].cbegin(), _valueSeq[last_idx].cend()}; + } else if constexpr (std::constructible_from) { + return OR{std::string_view{_valueSeq[start].begin(), _valueSeq[last_idx].end()}}; + } else if constexpr (snplib_output_char_range_c) { + OR res; + + std::copy(_valueSeq[start].begin(), _valueSeq[last_idx].end(), std::back_inserter(res)); + + return res; + } else { + static_assert(false, "Incompatible types: cannot create output range!"); + } + } + template requires mutableContent error_t setKey(KeyT&& key, SParT const& sparams = snplib_serialization_params_t{}) @@ -138,6 +205,33 @@ public: return {}; } + template + requires mutableContent + error_t setValue(ValueT&& value, SParT const& sparams = snplib_serialization_params_t{}) + { + auto err = snplib_serializer_t>(_key, std::forward(value), sparams); + if (err) { + return snplib_deduced_error(err, std::errc::invalid_argument); + } + + return {}; + } + + + template + requires mutableContent + error_t setKeyValue(KeyT&& key, ValueT&& value, SParT const& sparams = snplib_serialization_params_t{}) + { + auto err = setKey(std::forward(key), sparams); + if (err) { + return err; + } + + return setValue(std::forward(value), sparams); + } + protected: std:: conditional_t> diff --git a/include/snipplib/utils/snplib_string.h b/include/snipplib/utils/snplib_string.h index d5909cd..296bc90 100644 --- a/include/snipplib/utils/snplib_string.h +++ b/include/snipplib/utils/snplib_string.h @@ -194,6 +194,51 @@ static constexpr OR snplib_split_char_range(IR&& input, } +template +OR snplib_join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N = std::numeric_limits::max()) + requires(snplib_char_range_c>) +{ + using el_t = std::ranges::range_value_t; + + if constexpr (std::is_pointer_v>) { // char*, const char*, char[] + if constexpr (std::constructible_from) { + return snplib_join_char_ranges(std::forward(input), el_t(std::begin(delim), std::end(delim)), start, + N); + } else { + return snplib_join_char_ranges(std::forward(input), std::string_view(delim), start, N); + } + } else { + OR res; + + using d_t = std::remove_cvref_t; + + if constexpr (std::same_as) { + std::ranges::copy(std::forward(input) | std::views::join_with(std::forward(delim)), + std::back_inserter(res)); + } else if constexpr (snplib_char_view_c && std::ranges::viewable_range) { + el_t d{delim.begin(), delim.end()}; + + std::ranges::copy(std::forward(input) | std::views::join_with(d), std::back_inserter(res)); + } else if constexpr (snplib_output_char_range_c) { + el_t d; + std::ranges::copy(delim, std::back_inserter(d)); + + std::ranges::copy(std::forward(input) | std::views::join_with(d), std::back_inserter(res)); + } else { // generic case + for (auto const& el : std::forward(input) | std::views::take(std::ranges::size(input) - 1)) { + std::ranges::copy(el, std::back_inserter(res)); + std::ranges::copy(delim, std::back_inserter(res)); + } + // add the last elements + std::ranges::copy(std::forward(input) | std::views::reverse | std::views::take(1), + std::back_inserter(res)); + } + + return res; + } +} + + template static std::optional snplib_num_from_range(R&& r) requires((std::integral || std::floating_point) && std::ranges::contiguous_range)