normalize members of iterator

iters
Sergey Marinkevich 6 months ago
parent 038cbb73f4
commit 08f7b59aa7

@ -11,6 +11,4 @@ public:
virtual bool operator!=(const IIterator& other) const = 0; virtual bool operator!=(const IIterator& other) const = 0;
virtual IIterator& operator++() = 0; virtual IIterator& operator++() = 0;
virtual size_t level() const = 0;
}; };

@ -7,11 +7,11 @@ template <typename T>
class BFSIterator : public BaseIterator<T> { class BFSIterator : public BaseIterator<T> {
public: public:
explicit BFSIterator(T* ptr) : BaseIterator<T>(ptr) { explicit BFSIterator(T* ptr) : BaseIterator<T>(ptr) {
if (!this->current) if (!this->current())
return; return;
for (auto& it : BaseIterator<T>::current->children()) for (auto& it : this->current()->children())
q.push(it.get()); q.push({it.get(), 1});
} }
IIterator<T>& operator++() override { IIterator<T>& operator++() override {
@ -19,24 +19,22 @@ public:
return *this; return *this;
} }
virtual size_t level() const {
return level_;
}
protected: protected:
std::queue<T*> q; std::queue<std::pair<T*, size_t>> q;
size_t level_;
void advance() { void advance() {
if (q.empty()) { if (q.empty()) {
this->current = nullptr; this->set_current(nullptr);
return; return;
} }
this->current = q.front(); auto& [node, lvl] = q.front();
q.pop(); q.pop();
for (auto& it : this->current->children()) this->set_current(node);
q.push(it.get()); this->set_level(lvl);
for (auto& it : this->current()->children())
q.push({it.get(), lvl + 1});
} }
}; };

@ -11,7 +11,7 @@
template <typename T> template <typename T>
class BaseIterator : public IIterator<T> { class BaseIterator : public IIterator<T> {
public: public:
explicit BaseIterator(T* ptr) : current(ptr) {} explicit BaseIterator(T* ptr) : proxy{ptr, 0} {}
struct Proxy { struct Proxy {
T* e; T* e;
@ -20,24 +20,24 @@ public:
T& operator*() const { return *e; } T& operator*() const { return *e; }
T* operator->() const { return e; } T* operator->() const { return e; }
}; };
Proxy& operator*() { return proxy; }
Proxy& operator*() { T* operator->() const override { return current(); }
proxy = Proxy{ current, this->level() }; operator const T*() const { return current(); }
return proxy; 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<T>& other) const override { bool operator!=(const IIterator<T>& other) const override {
const T* other_current = other; const T* other_current = other;
return current != other_current; return current() != other_current;
} }
protected: 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: private:
Proxy proxy; Proxy proxy;
}; };

@ -7,11 +7,12 @@
template <typename T> template <typename T>
class DFSIterator : public BaseIterator<T> { class DFSIterator : public BaseIterator<T> {
public: public:
explicit DFSIterator(T* ptr) : BaseIterator<T>(ptr), level_(0) { explicit DFSIterator(T* ptr) : BaseIterator<T>(ptr) {
if (!this->current) if (!this->current())
return; return;
for (auto it = BaseIterator<T>::current->children().rbegin(); it != BaseIterator<T>::current->children().rend(); ++it) for (auto it = this->current()->children().rbegin();
it != this->current()->children().rend(); ++it)
s.push({it->get(), 1}); s.push({it->get(), 1});
} }
@ -20,28 +21,23 @@ public:
return *this; return *this;
} }
virtual size_t level() const {
return level_;
}
protected: protected:
std::stack<std::pair<T*, size_t>> s; std::stack<std::pair<T*, size_t>> s;
size_t level_;
void advance() { void advance() {
if (s.empty()) { if (s.empty()) {
this->current = nullptr; this->set_current(nullptr);
return; return;
} }
auto [node, lvl] = s.top(); auto [node, lvl] = s.top();
s.pop(); s.pop();
this->current = node; this->set_current(node);
level_ = lvl; this->set_level(lvl);
for (auto it = this->current->children().rbegin(); for (auto it = this->current()->children().rbegin();
it != this->current->children().rend(); ++it) it != this->current()->children().rend(); ++it)
s.push({it->get(), lvl + 1}); s.push({it->get(), lvl + 1});
} }
}; };

Loading…
Cancel
Save