#include <vector>
#include <list>
#include <span>
#include <iterator>
template<typename T>
class concat_view {
public:
using value_type = T;
using const_pointer = const value_type*;
using const_reference = const value_type&;
concat_view(std::initializer_list<std::span<const T>> spans) : spans_(spans) {}
class iterator {
public:
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = const T*;
using reference = const T&;
using iterator_category = std::input_iterator_tag;
iterator(std::vector<std::span<const T>> const& spans, size_t outer, size_t inner)
: spans_(spans), outer_(outer), inner_(inner) {
advance_past_empty_spans();
}
reference operator*() const {
return spans_[outer_][inner_];
}
iterator& operator++() {
++inner_;
advance_past_empty_spans();
return *this;
}
bool operator==(const iterator& other) const {
return outer_ == other.outer_ && inner_ == other.inner_;
}
bool operator!=(const iterator& other) const {
return !(*this == other);
}
private:
std::vector<std::span<const T>> spans_;
size_t outer_ = 0;
size_t inner_ = 0;
void advance_past_empty_spans() {
while (outer_ < spans_.size() && inner_ == spans_[outer_].size()) {
++outer_;
inner_ = 0;
}
}
};
iterator begin() const {
return iterator(spans_, 0, 0);
}
iterator end() const {
return iterator(spans_, spans_.size(), 0);
}
private:
std::vector<std::span<const T>> spans_;
};
Comments
0 B
|👍
/👎
0 B
|👍
/👎