This commit is contained in:
Timur A. Fatkhullin
2025-10-07 23:51:58 +03:00
parent 8b16ac79b8
commit 27dccfe7c0
3 changed files with 260 additions and 8 deletions

View File

@@ -401,6 +401,94 @@ static constexpr size_t FNV1aHash(std::forward_iterator auto begin, std::sentine
}
class MccSimpleDeserializer
{
public:
static constexpr std::string RANGE_DELIM_SEQ = ",";
template <traits::mcc_input_char_range R>
MccSimpleDeserializer& setRangeDelim(R&& r)
{
if (std::ranges::size(std::forward<R>(r))) {
_rangeDelim.clear();
std::ranges::copy(std::forward<R>(r), std::back_inserter(_rangeDelim));
}
return *this;
}
template <traits::mcc_output_char_range R>
R getRangeDelim() const
{
R r;
std::ranges::copy(_rangeDelim, std::back_inserter(r));
return r;
}
std::string getRangeDelim() const
{
return getRangeDelim<std::string>();
}
template <traits::mcc_input_char_range IR, typename VT>
std::error_code operator()(IR&& bytes, VT& value)
{
std::error_code ret{};
if constexpr (std::is_arithmetic_v<VT>) {
auto v = mcc::utils::numFromStr<VT>(trimSpaces(bytes));
if (!v.has_value()) {
return std::make_error_code(std::errc::invalid_argument);
}
value = v.value();
} else if constexpr (mcc::traits::mcc_output_char_range<VT>) {
VT r;
std::ranges::copy(bytes, std::back_inserter(r));
value = r;
} else if constexpr (std::ranges::range<VT>) {
using el_t = std::ranges::range_value_t<VT>;
if constexpr (std::is_reference_v<el_t> || std::is_const_v<el_t>) { // no reference or constants allowed
return std::make_error_code(std::errc::invalid_argument);
}
VT r;
el_t elem;
auto els = std::views::split(bytes, _rangeDelim);
for (auto const& el : els) {
ret = (*this)(std::string_view(el), elem);
if (!ret) {
std::back_inserter(r) = elem;
} else {
return std::make_error_code(std::errc::invalid_argument);
}
}
value = r;
} else if constexpr (mcc::traits::mcc_time_duration_c<VT>) {
typename VT::rep vd;
ret = (*this)(trimSpaces(bytes), vd);
if (!ret) {
value = VT{vd};
}
} else {
ret = std::make_error_code(std::errc::invalid_argument);
}
return ret;
}
protected:
std::string _rangeDelim{RANGE_DELIM_SEQ};
};
/* key-value pair holder */
// to follow std::variant requirements (not references, not array, not void)
@@ -521,7 +609,8 @@ public:
template <std::ranges::contiguous_range R, std::ranges::input_range RecDelimT = std::string_view>
std::error_code fromCharRange(const R& buffer, RecDelimT rec_delim = std::string_view("\n"))
{
return fromCharRange(buffer, KeyValueHolder::defaultDeserializeFunc, std::move(rec_delim));
// return fromCharRange(buffer, KeyValueHolder::defaultDeserializeFunc, std::move(rec_delim));
return fromCharRange(buffer, MccSimpleDeserializer{}.setRangeDelim(VALUE_ARRAY_DELIM), std::move(rec_delim));
}
template <std::ranges::contiguous_range R,