add possibility to iterate with the parser, update unit tests, update README

This commit is contained in:
ado
2021-02-28 19:22:54 +01:00
parent e62afbb8a5
commit 1ddc61c62e
5 changed files with 210 additions and 31 deletions

View File

@@ -1,4 +1,7 @@
#pragma once
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <vector>
namespace ss {
@@ -21,7 +24,6 @@ inline ssize_t get_line(char** lineptr, size_t* n, FILE* stream) {
return getline(lineptr, n, stream);
}
#else
#include <cstdint>
using ssize_t = int64_t;
inline ssize_t get_line(char** lineptr, size_t* n, FILE* stream) {
size_t pos;

View File

@@ -85,6 +85,73 @@ public:
return value;
}
////////////////
// iterator
////////////////
template <bool get_object, typename T, typename... Ts>
struct iterable {
struct iterator {
using value =
ss::ternary_t<get_object, T, no_void_validator_tup_t<T, Ts...>>;
iterator() : parser_{nullptr} {}
iterator(parser<Matchers...>* parser) : parser_{parser} {}
value& operator*() { return value_; }
value* operator->() { return &value_; }
iterator& operator++() {
if (parser_->eof()) {
parser_ = nullptr;
} else {
if constexpr (get_object) {
value_ =
std::move(parser_->template get_object<T, Ts...>());
} else {
value_ =
std::move(parser_->template get_next<T, Ts...>());
}
}
return *this;
}
iterator& operator++(int) { return ++*this; }
friend bool operator==(const iterator& lhs, const iterator& rhs) {
return (lhs.parser_ == nullptr && rhs.parser_ == nullptr) ||
(lhs.parser_ == rhs.parser_ &&
&lhs.value_ == &rhs.value_);
}
friend bool operator!=(const iterator& lhs, const iterator& rhs) {
return !(lhs == rhs);
}
private:
value value_;
parser<Matchers...>* parser_;
};
iterable(parser<Matchers...>* parser) : parser_{parser} {}
iterator begin() { return ++iterator{parser_}; }
iterator end() { return iterator{}; }
private:
parser<Matchers...>* parser_;
};
template <typename... Ts>
auto iterate() {
return iterable<false, Ts...>{this};
}
template <typename... Ts>
auto iterate_object() {
return iterable<true, Ts...>{this};
}
////////////////
// composite conversion
////////////////

View File

@@ -388,7 +388,7 @@ T to_object_impl(std::index_sequence<Is...>, U&& data) {
template <class T, class U>
T to_object(U&& data) {
using NoRefU = std::remove_reference_t<U>;
using NoRefU = std::decay_t<U>;
if constexpr (is_instance_of_v<std::tuple, NoRefU>) {
return to_object_impl<
T>(std::make_index_sequence<std::tuple_size<NoRefU>{}>{},