#pragma once #include #include "../../common/specialized.hpp" namespace sprawl { template class TreeIterator : public std::iterator { public: typedef AccessorType* accessor_type; TreeIterator(AccessorType* item) : m_currentItem(item) { // } AccessorType& operator*() { return *m_currentItem; } AccessorType* operator->() { return m_currentItem; } AccessorType const& operator*() const { return *m_currentItem; } AccessorType const* operator->() const { return m_currentItem; } template auto Key() const -> decltype(accessor_type(nullptr)->Accessor(Specialized()).Key()) { return m_currentItem->Accessor(Specialized()).Key(); } auto Key() const -> decltype(accessor_type(nullptr)->Accessor(Specialized<0>()).Key()) { return m_currentItem->Accessor(Specialized<0>()).Key(); } ValueType& Value() { return m_currentItem->m_value; } ValueType const& Value() const { return m_currentItem->m_value; } TreeIterator& operator++() { m_currentItem = nextItem_(m_currentItem); return *this; } TreeIterator operator++(int) { TreeIterator tmp(*this); ++(*this); return tmp; } TreeIterator const& operator++() const { m_currentItem = nextItem_(m_currentItem); return *this; } TreeIterator const operator++(int) const { TreeIterator tmp(*this); ++(*this); return tmp; } TreeIterator operator+(int steps) { AccessorType* item = m_currentItem; for(int i = 0; i < steps; ++i) { if(!item) { break; } item = nextItem_(m_currentItem); } return TreeIterator(item); } TreeIterator const operator+(int steps) const { AccessorType* item = m_currentItem; for(int i = 0; i < steps; ++i) { if(!item) { break; } item = nextItem_(m_currentItem); } return TreeIterator(item); } TreeIterator& operator--() { m_currentItem = previousItem_(m_currentItem); return *this; } TreeIterator operator--(int) { TreeIterator tmp(*this); --(*this); return tmp; } TreeIterator const& operator--() const { m_currentItem = previousItem_(m_currentItem); return *this; } TreeIterator const operator--(int) const { TreeIterator tmp(*this); --(*this); return tmp; } TreeIterator operator-(int steps) { AccessorType* item = m_currentItem; for(int i = 0; i < steps; ++i) { if(!item) { break; } item = previousItem_(m_currentItem); } return TreeIterator(item); } TreeIterator const operator-(int steps) const { AccessorType* item = m_currentItem; for(int i = 0; i < steps; ++i) { if(!item) { break; } item = previousItem_(m_currentItem); } return TreeIterator(item); } bool operator==(TreeIterator const& rhs) const { return m_currentItem == rhs.m_currentItem; } bool operator!=(TreeIterator const& rhs) const { return !this->operator==(rhs); } operator bool() const { return m_currentItem != nullptr; } bool operator!() const { return m_currentItem != nullptr; } bool Valid() const { return m_currentItem != nullptr; } bool More() const { return m_currentItem != nullptr && nextItem_(m_currentItem) != nullptr; } TreeIterator Next() { return TreeIterator(nextItem_(m_currentItem)); } TreeIterator const Next() const { return TreeIterator(nextItem_(m_currentItem)); } operator bool() { return m_currentItem != nullptr; } protected: AccessorType* previousItem_(AccessorType* item) const { AccessorType* left = item->Left(spec); if(left != nullptr) { while(left->Right(spec) != nullptr) { left = left->Right(spec); } return left; } AccessorType* parent = item->Parent(spec); if(parent == nullptr || item == parent->Right(spec)) { return parent; } AccessorType* child = item; while(parent != nullptr && child == parent->Left(spec)) { child = parent; parent = parent->Parent(spec); } return parent; } AccessorType* nextItem_(AccessorType* item) const { AccessorType* right = item->Right(spec); if(right != nullptr) { while(right->Left(spec) != nullptr) { right = right->Left(spec); } return right; } AccessorType* parent = item->Parent(spec); if(parent == nullptr || item == parent->Left(spec)) { return parent; } AccessorType* child = item; while(parent != nullptr && child == parent->Right(spec)) { child = parent; parent = parent->Parent(spec); } return parent; } mutable AccessorType* m_currentItem; Specialized spec; }; }