|
|
@@ -16,8 +16,7 @@
|
|
|
#include <iterator/iterator_fwd.hpp>
|
|
|
|
|
|
namespace iterator::joining {
|
|
|
-template <typename Iter, typename = void>
|
|
|
-class iterator {
|
|
|
+template <typename Iter, typename = void> class iterator {
|
|
|
protected:
|
|
|
using inner_t = decltype(*std::declval<Iter>());
|
|
|
|
|
|
@@ -33,7 +32,7 @@ protected:
|
|
|
: iterator(end_aware_iterator(std::forward<C>(container))) {}
|
|
|
|
|
|
iterator(end_aware_iterator<Iter> join) : iterator(join, {}, true) {}
|
|
|
-
|
|
|
+
|
|
|
iterator(end_aware_iterator<Iter> join,
|
|
|
end_aware_iterator<iter<inner_t>> elem, bool update = false)
|
|
|
: joiner_(join), element_(elem) {
|
|
|
@@ -64,16 +63,14 @@ protected:
|
|
|
update_iterator();
|
|
|
}
|
|
|
|
|
|
- iterator(end_aware_iterator<Iter> join) : joiner_(join) {
|
|
|
- update_iterator();
|
|
|
- }
|
|
|
-
|
|
|
+ iterator(end_aware_iterator<Iter> join) : joiner_(join) { update_iterator(); }
|
|
|
+
|
|
|
void update_iterator() {
|
|
|
while (!joiner_.at_end() && sync().at_end()) {
|
|
|
++joiner_;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private:
|
|
|
end_aware_iterator<iter<inner_t>> const & sync() {
|
|
|
if (joiner_.at_end()) { return element_ = {}; }
|
|
|
@@ -91,18 +88,21 @@ protected:
|
|
|
|
|
|
namespace iterator {
|
|
|
template <typename Iter>
|
|
|
-class joining_iterator : public facade<joining_iterator<Iter>>, public joining::iterator<Iter> {
|
|
|
+class joining_iterator : public facade<joining_iterator<Iter>>,
|
|
|
+ public joining::iterator<Iter> {
|
|
|
public:
|
|
|
using super_t = joining::iterator<Iter>;
|
|
|
-
|
|
|
+ struct sentinal_type {};
|
|
|
+ static constexpr sentinal_type sentinal;
|
|
|
+
|
|
|
public:
|
|
|
using super_t::super_t;
|
|
|
-
|
|
|
+
|
|
|
template <typename C, typename = std::enable_if_t<detail::is_container_v<C>>>
|
|
|
joining_iterator(C && container) : super_t(std::forward<C>(container)) {}
|
|
|
|
|
|
joining_iterator(end_aware_iterator<Iter> join) : super_t(join) {}
|
|
|
-
|
|
|
+
|
|
|
void increment() {
|
|
|
if ((++super_t::element_).at_end()) {
|
|
|
++super_t::joiner_;
|
|
|
@@ -112,13 +112,14 @@ public:
|
|
|
|
|
|
decltype(auto) dereference() const { return *super_t::element_; }
|
|
|
|
|
|
+ bool at_end() const { return join_iterator().at_end(); }
|
|
|
bool equal_to(joining_iterator const & other) const {
|
|
|
return join_iterator() == other.join_iterator() &&
|
|
|
- element_iterator() == other.element_iterator();
|
|
|
+ element_iterator() == other.element_iterator();
|
|
|
}
|
|
|
-
|
|
|
- auto const &join_iterator() const { return super_t::joiner_; }
|
|
|
- auto const &element_iterator() const { return super_t::element_; }
|
|
|
+
|
|
|
+ auto const & join_iterator() const { return super_t::joiner_; }
|
|
|
+ auto const & element_iterator() const { return super_t::element_; }
|
|
|
};
|
|
|
|
|
|
template <typename C> joining_iterator(C &&) -> joining_iterator<iter<C>>;
|