diff --git a/include/ifaces/IIterator.h b/include/ifaces/IIterator.h index ea21be5..473a69a 100644 --- a/include/ifaces/IIterator.h +++ b/include/ifaces/IIterator.h @@ -11,6 +11,4 @@ public: virtual bool operator!=(const IIterator& other) const = 0; virtual IIterator& operator++() = 0; - - virtual size_t level() const = 0; }; diff --git a/include/iterators/BFSIterator.h b/include/iterators/BFSIterator.h index 908e0c4..1491f75 100644 --- a/include/iterators/BFSIterator.h +++ b/include/iterators/BFSIterator.h @@ -7,11 +7,11 @@ template class BFSIterator : public BaseIterator { public: explicit BFSIterator(T* ptr) : BaseIterator(ptr) { - if (!this->current) + if (!this->current()) return; - for (auto& it : BaseIterator::current->children()) - q.push(it.get()); + for (auto& it : this->current()->children()) + q.push({it.get(), 1}); } IIterator& operator++() override { @@ -19,24 +19,22 @@ public: return *this; } - virtual size_t level() const { - return level_; - } - protected: - std::queue q; - size_t level_; + std::queue> q; void advance() { if (q.empty()) { - this->current = nullptr; + this->set_current(nullptr); return; } - this->current = q.front(); + auto& [node, lvl] = q.front(); q.pop(); - for (auto& it : this->current->children()) - q.push(it.get()); + this->set_current(node); + this->set_level(lvl); + + for (auto& it : this->current()->children()) + q.push({it.get(), lvl + 1}); } }; diff --git a/include/iterators/BaseIterator.h b/include/iterators/BaseIterator.h index c9e1321..59cd8d2 100644 --- a/include/iterators/BaseIterator.h +++ b/include/iterators/BaseIterator.h @@ -11,7 +11,7 @@ template class BaseIterator : public IIterator { public: - explicit BaseIterator(T* ptr) : current(ptr) {} + explicit BaseIterator(T* ptr) : proxy{ptr, 0} {} struct Proxy { T* e; @@ -20,24 +20,24 @@ public: T& operator*() const { return *e; } T* operator->() const { return e; } }; + Proxy& operator*() { return proxy; } - Proxy& operator*() { - proxy = Proxy{ current, this->level() }; - return proxy; - } - - T* operator->() const override { return current; } - operator const T*() const { return current; } - operator T&() const { return *current; } - operator T*() const { return current; } + T* operator->() const override { return current(); } + operator const T*() const { return current(); } + operator T&() const { return *current(); } + operator T*() const { return current(); } bool operator!=(const IIterator& other) const override { const T* other_current = other; - return current != other_current; + return current() != other_current; } protected: - T* current; + T* current() const { return proxy.e; } + void set_current(T* e) { proxy.e = e; } + + size_t level() const { return proxy.level; } + void set_level(size_t level) { proxy.level = level; } private: Proxy proxy; }; diff --git a/include/iterators/DFSIterator.h b/include/iterators/DFSIterator.h index 06ae01a..0d863cd 100644 --- a/include/iterators/DFSIterator.h +++ b/include/iterators/DFSIterator.h @@ -7,11 +7,12 @@ template class DFSIterator : public BaseIterator { public: - explicit DFSIterator(T* ptr) : BaseIterator(ptr), level_(0) { - if (!this->current) + explicit DFSIterator(T* ptr) : BaseIterator(ptr) { + if (!this->current()) return; - for (auto it = BaseIterator::current->children().rbegin(); it != BaseIterator::current->children().rend(); ++it) + for (auto it = this->current()->children().rbegin(); + it != this->current()->children().rend(); ++it) s.push({it->get(), 1}); } @@ -20,28 +21,23 @@ public: return *this; } - virtual size_t level() const { - return level_; - } - protected: std::stack> s; - size_t level_; void advance() { if (s.empty()) { - this->current = nullptr; + this->set_current(nullptr); return; } auto [node, lvl] = s.top(); s.pop(); - this->current = node; - level_ = lvl; + this->set_current(node); + this->set_level(lvl); - for (auto it = this->current->children().rbegin(); - it != this->current->children().rend(); ++it) + for (auto it = this->current()->children().rbegin(); + it != this->current()->children().rend(); ++it) s.push({it->get(), lvl + 1}); } };