...
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user