...
This commit is contained in:
@@ -24,6 +24,24 @@ int main()
|
|||||||
|
|
||||||
std::println("sv(TrimType::TRIM_BOTH) = '{}'", sv);
|
std::println("sv(TrimType::TRIM_BOTH) = '{}'", sv);
|
||||||
|
|
||||||
|
|
||||||
|
si = "123; we; d34534; ";
|
||||||
|
|
||||||
|
std::vector<std::string_view> rv;
|
||||||
|
rv = snplib_split_char_range<decltype(rv)>(si, "; ");
|
||||||
|
|
||||||
|
std::println("\n\nstr = '{}'", si);
|
||||||
|
|
||||||
|
std::println("all elems: ");
|
||||||
|
for (auto& el : rv) {
|
||||||
|
std::println("el = '{}'", el);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = snplib_split_char_range<decltype(rv)>(si, "; ", 1, 2);
|
||||||
|
std::println("2 elems starting from 1: ");
|
||||||
|
for (auto& el : rv) {
|
||||||
|
std::println("el = '{}'", el);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@ class snplib_keyvalue_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr bool mutableContent = snplib_output_char_range_c<ByteSeqT>;
|
static constexpr bool mutableContent = snplib_output_char_range_c<ByteSeqT>;
|
||||||
|
static constexpr bool stringViewContent =
|
||||||
|
std::ranges::viewable_range<ByteSeqT> && std::ranges::contiguous_range<ByteSeqT>;
|
||||||
|
|
||||||
typedef std::error_code error_t;
|
typedef std::error_code error_t;
|
||||||
|
|
||||||
@@ -32,8 +34,73 @@ public:
|
|||||||
|
|
||||||
template <snplib_char_range_c R>
|
template <snplib_char_range_c R>
|
||||||
requires mutableContent
|
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<R>) {
|
||||||
|
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<decltype(_valueSeq)>(_value, _config.valseq_delim);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <snplib_char_range_c R>
|
template <snplib_char_range_c R>
|
||||||
@@ -72,9 +139,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::conditional_t<mutableContent, std::string, std::string_view> _key;
|
std::
|
||||||
std::conditional_t<mutableContent, std::string, std::string_view> _value;
|
conditional_t<mutableContent, std::string, std::conditional_t<stringViewContent, std::string_view, std::string>>
|
||||||
std::conditional_t<mutableContent, std::vector<std::string>, std::vector<std::string_view>> _valueSeq;
|
_key;
|
||||||
|
std::
|
||||||
|
conditional_t<mutableContent, std::string, std::conditional_t<stringViewContent, std::string_view, std::string>>
|
||||||
|
_value;
|
||||||
|
std::vector<std::string_view> _valueSeq;
|
||||||
|
// std::conditional_t<mutableContent,
|
||||||
|
// std::vector<std::string>,
|
||||||
|
// std::conditional_t<stringViewContent, std::vector<std::string_view>,
|
||||||
|
// std::vector<std::string>>>
|
||||||
|
// _valueSeq;
|
||||||
|
|
||||||
|
config_t _config;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace snplib
|
} // namespace snplib
|
||||||
@@ -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 <snplib_char_range_c OR, snplib_char_range_c IR, typename... CTorTs>
|
template <snplib_char_range_c OR, snplib_char_range_c IR, typename... CTorTs>
|
||||||
static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args)
|
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 <std::ranges::range OR, snplib_input_char_range_c IR, snplib_input_char_range_c DR>
|
||||||
|
static constexpr OR snplib_split_char_range(IR&& input,
|
||||||
|
DR&& delim,
|
||||||
|
size_t start = 0,
|
||||||
|
size_t N = std::numeric_limits<size_t>::max())
|
||||||
|
requires(std::ranges::output_range<OR, std::ranges::range_value_t<OR>> && !std::ranges::borrowed_range<OR> &&
|
||||||
|
snplib_view_or_output_char_range_c<std::ranges::range_value_t<OR>>)
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
snplib_char_view_c<std::ranges::range_value_t<OR>> && std::ranges::viewable_range<std::remove_cvref_t<IR>>,
|
||||||
|
"Incompatible input and output types!");
|
||||||
|
|
||||||
|
|
||||||
|
if constexpr (std::is_pointer_v<std::decay_t<DR>>) { // char*, const char*, char[]
|
||||||
|
return snplib_split_char_range<OR>(std::forward<IR>(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<OR>;
|
||||||
|
using it_t = std::ranges::iterator_t<IR>;
|
||||||
|
static_assert(std::constructible_from<el_t, it_t, it_t>,
|
||||||
|
"Incompatible input and output types: cannot create element!");
|
||||||
|
|
||||||
|
auto it = input.begin();
|
||||||
|
|
||||||
|
std::vector<it_t> 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 <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>)
|
||||||
|
|||||||
Reference in New Issue
Block a user