This commit is contained in:
2026-06-23 19:14:19 +03:00
parent 97ad939095
commit 6faafa7b47
2 changed files with 139 additions and 0 deletions

View File

@@ -126,6 +126,73 @@ public:
} }
template <std::ranges::range OR>
requires(std::ranges::output_range<OR, std::ranges::range_value_t<OR>> &&
snplib_char_range_c<std::ranges::range_value_t<OR>>)
OR valueSeq(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
using el_t = std::ranges::range_value_t<OR>;
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<OR, decltype(_valueSeq)>) {
std::ranges::copy(elems, std::back_inserter(res));
} else {
std::ranges::for_each(elems, [&res](auto const& e) {
if constexpr (std::constructible_from<el_t, std::string_view::const_iterator,
std::string_view::const_iterator>) {
std::back_inserter(el_t{e.cbegin(), e.cend()}, std::back_inserter(res));
} else if constexpr (std::constructible_from<el_t, std::string_view>) {
std::back_inserter(el_t{e}, std::back_inserter(res));
} else {
static_assert(false, "Incompatible types: cannot create output element!");
}
});
}
return res;
}
std::vector<std::string_view> valueSeq(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
return valueSeq<std::vector<std::string_view>>(start, N);
}
template <snplib_char_range_c OR>
OR valueJoinSeq(size_t start = 0, size_t N = std::numeric_limits<size_t>::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<OR, std::string_view::const_iterator, std::string_view::const_iterator>) {
return OR{_valueSeq[start].cbegin(), _valueSeq[last_idx].cend()};
} else if constexpr (std::constructible_from<OR, std::string_view>) {
return OR{std::string_view{_valueSeq[start].begin(), _valueSeq[last_idx].end()}};
} else if constexpr (snplib_output_char_range_c<OR>) {
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 <snplib_serializable_c KeyT, snplib_serialization_params_c SParT = snplib_serialization_params_t> template <snplib_serializable_c KeyT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
requires mutableContent requires mutableContent
error_t setKey(KeyT&& key, SParT const& sparams = snplib_serialization_params_t{}) error_t setKey(KeyT&& key, SParT const& sparams = snplib_serialization_params_t{})
@@ -138,6 +205,33 @@ public:
return {}; return {};
} }
template <snplib_serializable_c ValueT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
requires mutableContent
error_t setValue(ValueT&& value, SParT const& sparams = snplib_serialization_params_t{})
{
auto err = snplib_serializer_t<std::remove_cvref_t<ValueT>>(_key, std::forward<ValueT>(value), sparams);
if (err) {
return snplib_deduced_error(err, std::errc::invalid_argument);
}
return {};
}
template <snplib_serializable_c KeyT,
snplib_serializable_c ValueT,
snplib_serialization_params_c SParT = snplib_serialization_params_t>
requires mutableContent
error_t setKeyValue(KeyT&& key, ValueT&& value, SParT const& sparams = snplib_serialization_params_t{})
{
auto err = setKey(std::forward<KeyT>(key), sparams);
if (err) {
return err;
}
return setValue(std::forward<KeyT>(value), sparams);
}
protected: protected:
std:: std::
conditional_t<mutableContent, std::string, std::conditional_t<stringViewContent, std::string_view, std::string>> conditional_t<mutableContent, std::string, std::conditional_t<stringViewContent, std::string_view, std::string>>

View File

@@ -194,6 +194,51 @@ static constexpr OR snplib_split_char_range(IR&& input,
} }
template <snplib_output_char_range_c OR, std::ranges::input_range IR, snplib_input_char_range_c DR>
OR snplib_join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
requires(snplib_char_range_c<std::ranges::range_value_t<IR>>)
{
using el_t = std::ranges::range_value_t<IR>;
if constexpr (std::is_pointer_v<std::decay_t<DR>>) { // char*, const char*, char[]
if constexpr (std::constructible_from<el_t, decltype(std::begin(delim)), decltype(std::end(delim))>) {
return snplib_join_char_ranges<OR>(std::forward<IR>(input), el_t(std::begin(delim), std::end(delim)), start,
N);
} else {
return snplib_join_char_ranges<OR>(std::forward<IR>(input), std::string_view(delim), start, N);
}
} else {
OR res;
using d_t = std::remove_cvref_t<DR>;
if constexpr (std::same_as<el_t, d_t>) {
std::ranges::copy(std::forward<IR>(input) | std::views::join_with(std::forward<DR>(delim)),
std::back_inserter(res));
} else if constexpr (snplib_char_view_c<el_t> && std::ranges::viewable_range<d_t>) {
el_t d{delim.begin(), delim.end()};
std::ranges::copy(std::forward<IR>(input) | std::views::join_with(d), std::back_inserter(res));
} else if constexpr (snplib_output_char_range_c<el_t>) {
el_t d;
std::ranges::copy(delim, std::back_inserter(d));
std::ranges::copy(std::forward<IR>(input) | std::views::join_with(d), std::back_inserter(res));
} else { // generic case
for (auto const& el : std::forward<IR>(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<IR>(input) | std::views::reverse | std::views::take(1),
std::back_inserter(res));
}
return res;
}
}
template <typename T, snplib_input_char_range_c R> template <typename T, snplib_input_char_range_c R>
static std::optional<T> snplib_num_from_range(R&& r) static std::optional<T> snplib_num_from_range(R&& r)
requires((std::integral<T> || std::floating_point<T>) && std::ranges::contiguous_range<R>) requires((std::integral<T> || std::floating_point<T>) && std::ranges::contiguous_range<R>)