From 97ad939095ac97688136f7745f5b6bec8b03acb6 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Tue, 23 Jun 2026 12:44:12 +0300 Subject: [PATCH] ... --- examples/str_exam.cpp | 20 +++++- include/snipplib/utils/snplib_keyvalue.h | 86 ++++++++++++++++++++++-- include/snipplib/utils/snplib_string.h | 72 ++++++++++++++++++++ 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/examples/str_exam.cpp b/examples/str_exam.cpp index e1b73d1..4aa1bca 100644 --- a/examples/str_exam.cpp +++ b/examples/str_exam.cpp @@ -24,6 +24,24 @@ int main() std::println("sv(TrimType::TRIM_BOTH) = '{}'", sv); - + + si = "123; we; d34534; "; + + std::vector rv; + rv = snplib_split_char_range(si, "; "); + + std::println("\n\nstr = '{}'", si); + + std::println("all elems: "); + for (auto& el : rv) { + std::println("el = '{}'", el); + } + + rv = snplib_split_char_range(si, "; ", 1, 2); + std::println("2 elems starting from 1: "); + for (auto& el : rv) { + std::println("el = '{}'", el); + } + return 0; } \ No newline at end of file diff --git a/include/snipplib/utils/snplib_keyvalue.h b/include/snipplib/utils/snplib_keyvalue.h index fed9b8c..2936390 100644 --- a/include/snipplib/utils/snplib_keyvalue.h +++ b/include/snipplib/utils/snplib_keyvalue.h @@ -15,6 +15,8 @@ class snplib_keyvalue_t { public: static constexpr bool mutableContent = snplib_output_char_range_c; + static constexpr bool stringViewContent = + std::ranges::viewable_range && std::ranges::contiguous_range; typedef std::error_code error_t; @@ -32,8 +34,73 @@ public: template requires mutableContent - error_t fromByteSequence(R&& r) + error_t fromByteSequence(R&& bytes) { + // key and value + + if constexpr (stringViewContent) { + auto bs = snplib_trim_spaces_as_view(bytes, TrimType::TRIM_LEFT); + auto found = std::ranges::search(bs, _config.keyval_delim); + + if (found.empty()) { // no value + _key = snplib_trim_spaces_as_view(bs, TrimType::TRIM_RIGHT); + + _value = std::string_view(); + } else { + _key = snplib_trim_spaces_as_view(std::string_view(bs.begin(), found.begin()), TrimType::TRIM_RIGHT); + + // do not delete space at the end of value-string! + _value = std::string_view(found.end(), bs.end()); + } + + } else if constexpr (std::ranges::viewable_range) { + auto bs = bytes | std::views::drop_while(snplib_is_space); + auto found = std::ranges::search(bs, _config.keyval_delim); + + _value.clear(); + + if (found.empty()) { // no value + _key = snplib_trim_spaces(bs, TrimType::TRIM_RIGHT); + } else { + _key.clear(); + auto N = std::ranges::distance(bs.begin(), found.begin()); + std::ranges::copy(std::views::all(bs) | std::views::take(N) | std::views::reverse | + std::views::drop_while(snplib_is_space), + std::back_inserter(_key)); + + std::ranges::copy(found.end(), bs.end(), std::back_inserter(_value)); + } + } else { // always coping + auto bs = snplib_trim_spaces(bytes, TrimType::TRIM_LEFT); + auto found = std::ranges::search(bs, _config.keyval_delim); + + _value.clear(); + + if (found.empty()) { // no value + _key = snplib_trim_spaces(bs, TrimType::TRIM_RIGHT); + } else { + _key.clear; + auto N = std::ranges::distance(bs.begin(), found.begin()); + // std::ranges::copy_n(bs.begin(), N, std::back_inserter(_key)); + + size_t i = 0; + for (auto it = bs.begin(); it != found.begin(); ++it, ++i) { + if (i < N) { + if (!snplib_is_space(*it)) { + std::back_inserter(_key) = *it; + } + } + } + } + + std::ranges::copy(found.end(), bs.end(), std::back_inserter(_value)); + } + + // split value to elements + + if (_value.size()) { + _valueSeq = snplib_split_char_range(_value, _config.valseq_delim); + } } template @@ -72,9 +139,20 @@ public: } protected: - std::conditional_t _key; - std::conditional_t _value; - std::conditional_t, std::vector> _valueSeq; + std:: + conditional_t> + _key; + std:: + conditional_t> + _value; + std::vector _valueSeq; + // std::conditional_t, + // std::conditional_t, + // std::vector>> + // _valueSeq; + + config_t _config; }; } // namespace snplib \ No newline at end of file diff --git a/include/snipplib/utils/snplib_string.h b/include/snipplib/utils/snplib_string.h index 4063878..d5909cd 100644 --- a/include/snipplib/utils/snplib_string.h +++ b/include/snipplib/utils/snplib_string.h @@ -105,6 +105,9 @@ static constexpr bool snplib_char_ranges_compare(R1&& what, R2&& where, bool cas } +// +// or_ctor_args - to use with non-default-constructible classes (or just for non-default constructors) +// template static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args) { @@ -122,6 +125,75 @@ static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args } } + +template +static constexpr OR snplib_split_char_range(IR&& input, + DR&& delim, + size_t start = 0, + size_t N = std::numeric_limits::max()) + requires(std::ranges::output_range> && !std::ranges::borrowed_range && + snplib_view_or_output_char_range_c>) +{ + static_assert( + snplib_char_view_c> && std::ranges::viewable_range>, + "Incompatible input and output types!"); + + + if constexpr (std::is_pointer_v>) { // char*, const char*, char[] + return snplib_split_char_range(std::forward(input), std::string_view(delim), start, N); + } else { + OR res; + + if (!N) { + return res; + } + + auto dlim_sz = std::ranges::size(delim); + + size_t curr_idx = 0, last_idx = start + N - 1; + + using el_t = std::ranges::range_value_t; + using it_t = std::ranges::iterator_t; + static_assert(std::constructible_from, + "Incompatible input and output types: cannot create element!"); + + auto it = input.begin(); + + std::vector delim_it; + + do { + it = std::search(it, input.end(), delim.begin(), delim.end()); + delim_it.emplace_back(it); + if (it == input.end()) { + break; + } + + std::advance(it, dlim_sz); + + if (++curr_idx > last_idx) { + break; + } + + } while (true); + + it = input.begin(); + + curr_idx = 0; + for (auto const& iter : delim_it) { + if (curr_idx >= start) { + std::back_inserter(res) = el_t(it, iter); + } + + std::advance(it = iter, dlim_sz); + + ++curr_idx; + } + + return res; + } +} + + template static std::optional snplib_num_from_range(R&& r) requires((std::integral || std::floating_point) && std::ranges::contiguous_range)