diff --git a/include/duckhandy/ScapegoatMap.inl b/include/duckhandy/implem/scapegoat_map.inl similarity index 100% rename from include/duckhandy/ScapegoatMap.inl rename to include/duckhandy/implem/scapegoat_map.inl diff --git a/include/duckhandy/ScapegoatTree.inl b/include/duckhandy/implem/scapegoat_tree.inl similarity index 100% rename from include/duckhandy/ScapegoatTree.inl rename to include/duckhandy/implem/scapegoat_tree.inl diff --git a/include/duckhandy/implem/tree_iterator.inl b/include/duckhandy/implem/tree_iterator.inl new file mode 100644 index 0000000..09a296a --- /dev/null +++ b/include/duckhandy/implem/tree_iterator.inl @@ -0,0 +1,235 @@ +namespace duckmem { + namespace Implem { + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + bool TreeIterator_base

::Exhausted() const { + return m_stack.empty(); + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + TreeIterator_base

::TreeIterator_base (const TreeIterator_base& parOther) : + m_stack(parOther.m_stack) + { + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + template + TreeIterator_base

::TreeIterator_base (const TreeIterator_base& parOther) { + typename TreeIterator_base::StackType otherStackCopy(parOther.m_stack); + std::vector

localCopy; + localCopy.reserve(parOther.m_stack.size()); + while (not otherStackCopy.empty()) { + P convertedItem = otherStackCopy.top(); + localCopy.push_back(convertedItem); + otherStackCopy.pop(); + } + m_stack.reserve(parOther.m_stack.capacity()); + for (typename std::vector

::reverse_iterator itRev = localCopy.rbegin(), itRevEnd = localCopy.rend(); itRev != itRevEnd; ++itRev) { + Assert(m_stack.capacity() > m_stack.size()); + m_stack.push(*itRev); + } + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::reference TreeIterator_const_layer::operator* () { + AssertRelease(not this->Exhausted()); + return this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::const_reference TreeIterator_const_layer::operator* () const { + AssertRelease(not this->Exhausted()); + return this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::pointer TreeIterator_const_layer::operator-> () { + AssertRelease(not this->Exhausted()); + return &this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::const_pointer TreeIterator_const_layer::operator-> () const { + AssertRelease(not this->Exhausted()); + return &this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + N* TreeIterator_const_layer::GetPointer() { + AssertRelease(not this->Exhausted()); + return this->m_stack.top(); + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + const N* TreeIterator_const_layer::GetPointer() const { + AssertRelease(not this->Exhausted()); + return this->m_stack.top(); + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::const_reference TreeIterator_const_layer::operator* () const { + AssertRelease(not this->Exhausted()); + return this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + typename TreeIterator_const_layer::const_pointer TreeIterator_const_layer::operator-> () const { + AssertRelease(not this->Exhausted()); + return &this->m_stack.top()->content; + } + + ///--------------------------------------------------------------------- + ///--------------------------------------------------------------------- + template + const N* TreeIterator_const_layer::GetPointer() const { + AssertRelease(not this->Exhausted()); + return this->m_stack.top(); + } + } //namespace Implem + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + TreeIterator::TreeIterator() { + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + TreeIterator::TreeIterator (const TreeIterator& parOther) : + parent_type(parOther) + { + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + template + TreeIterator::TreeIterator (const TreeIterator& parOther) : + parent_type(parOther) + { + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + template + TreeIterator::TreeIterator (S parCopyStackBottomUp, size_type parStackLen, size_type parMaxDepthHint) { + AssertRelease(parStackLen > 0); + this->m_stack.reserve(std::max(parStackLen, parMaxDepthHint)); + typename StackType::value_type prevNode = *parCopyStackBottomUp; + ++parCopyStackBottomUp; + this->m_stack.push(prevNode); + + for (size_type z = 1; z < parStackLen; ++z) { + typename StackType::value_type currNode = *parCopyStackBottomUp; + if (prevNode->left == currNode) { + Assert(this->m_stack.capacity() > this->m_stack.size()); + this->m_stack.push(currNode); + } + else { + //If you get this assertion make sure the iterator you are + //passing in is reversed (ie: from leaf to root) + AssertRelease(currNode == prevNode->right); + } + + prevNode = currNode; + ++parCopyStackBottomUp; + } + Assert(not this->Exhausted()); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + TreeIterator::TreeIterator (NodeTypePointer parRoot, size_type parMaxDepthHint) { + if (parMaxDepthHint > 0) + this->m_stack.reserve(parMaxDepthHint); + RecurseLeft(parRoot); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + TreeIterator::~TreeIterator() { + } + + ///------------------------------------------------------------------------- + ///Post-increment + ///------------------------------------------------------------------------- + template + TreeIterator TreeIterator::operator++ (int) { + AssertRelease(not this->Exhausted()); + TreeIterator retVal = *this; + ++(*this); + return retVal; + } + + ///------------------------------------------------------------------------- + ///Pre-increment + ///------------------------------------------------------------------------- + template + TreeIterator& TreeIterator::operator++() { + AssertRelease(not this->Exhausted()); + NodeTypePointer currNode = this->m_stack.top(); +#if defined(ASSERTIONSENABLED) + const size_type stackCapacity = this->m_stack.capacity(); +#endif + this->m_stack.pop(); +#if defined(ASSERTIONSENABLED) + //It shouldn't normally happen, but it's just to make sure + Assert(stackCapacity == this->m_stack.capacity()); +#endif + RecurseLeft(currNode->right); + return *this; + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + const TreeIterator& TreeIterator::operator= (const TreeIterator& parOther) { + this->m_stack = parOther.m_stack; + Assert(this->m_stack.capacity() >= parOther.m_stack.capacity()); + return *this; + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + bool TreeIterator::operator== (const TreeIterator& parOther) const { + return this->m_stack.size() == parOther.m_stack.size() and (this->m_stack.empty() or parOther.m_stack.top() == this->m_stack.top()); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + void TreeIterator::RecurseLeft (NodeTypePointer parFrom) { + NodeTypePointer currNode = parFrom; + while (NULL != currNode) { + Assert(this->m_stack.capacity() > this->m_stack.size()); + this->m_stack.push(currNode); + currNode = currNode->left; + } + } +} //namespace duckmem diff --git a/include/duckhandy/ScapegoatMap.hpp b/include/duckhandy/scapegoat_map.hpp similarity index 92% rename from include/duckhandy/ScapegoatMap.hpp rename to include/duckhandy/scapegoat_map.hpp index dba3586..e0010fa 100644 --- a/include/duckhandy/ScapegoatMap.hpp +++ b/include/duckhandy/scapegoat_map.hpp @@ -1,7 +1,7 @@ #ifndef idDD2D1A57ABEB4BEEA0F7E46C347D1637 #define idDD2D1A57ABEB4BEEA0F7E46C347D1637 -#include "ScapegoatTree.hpp" +#include "scapegoat_tree.hpp" namespace duckmem { template @@ -29,6 +29,6 @@ namespace duckmem { }; } //namespace duckmem -#include "ScapegoatMap.inl" +#include "implem/scapegoat_map.inl" #endif diff --git a/include/duckhandy/ScapegoatTree.hpp b/include/duckhandy/scapegoat_tree.hpp similarity index 98% rename from include/duckhandy/ScapegoatTree.hpp rename to include/duckhandy/scapegoat_tree.hpp index 6fb085e..51247b7 100644 --- a/include/duckhandy/ScapegoatTree.hpp +++ b/include/duckhandy/scapegoat_tree.hpp @@ -1,7 +1,7 @@ #ifndef id79CEDB2530B54204A6BEDCBE0B767EA1 #define id79CEDB2530B54204A6BEDCBE0B767EA1 -#include "TreeIterator.hpp" +#include "tree_iterator.hpp" #include "IteratorOnPtr.hpp" #include "SmallObject.hpp" #include "DuckMaths/Functions.hpp" @@ -126,6 +126,6 @@ namespace duckmem { }; } //namespace duckmem -#include "ScapegoatTree.inl" +#include "implem/scapegoat_tree.inl" #endif diff --git a/include/duckhandy/tree_iterator.hpp b/include/duckhandy/tree_iterator.hpp new file mode 100644 index 0000000..c910396 --- /dev/null +++ b/include/duckhandy/tree_iterator.hpp @@ -0,0 +1,121 @@ +#ifndef id6109D5EDE99D43C4909F084A231BF2C2 +#define id6109D5EDE99D43C4909F084A231BF2C2 + +#include "DuckCore/Stack.hpp" +#include "DuckCore/Helpers.hpp" +#include +#include + +namespace duckmem { + namespace Implem { + template + class TreeIterator_base { + template friend class TreeIterator_base; + public: + explicit TreeIterator_base ( void ) {} + TreeIterator_base ( const TreeIterator_base& parOther ); + template + explicit TreeIterator_base ( const TreeIterator_base& parOther ); + ~TreeIterator_base ( void ) {} + protected: + typedef duckcore::Stack > StackType; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + bool Exhausted ( void ) const; + StackType m_stack; + }; + + template + class TreeIterator_const_layer; + template + class TreeIterator_const_layer : protected TreeIterator_base { + template friend class TreeIterator_const_layer; + typedef TreeIterator_base parent_type; + public: + typedef const T* pointer; + typedef const T* const_pointer; + typedef const T& reference; + typedef const T& const_reference; + typedef typename parent_type::size_type size_type; + typedef typename parent_type::difference_type difference_type; + typedef N NodeType; + typedef const N* NodeTypePointer; + enum { IS_CONST = 1 }; + TreeIterator_const_layer ( void ) {} + TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} + template + explicit TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} + const_reference operator* ( void ) const; + const_pointer operator-> ( void ) const; + const N* GetPointer ( void ) const; + protected: + typedef typename parent_type::StackType StackType; + }; + template + class TreeIterator_const_layer : protected TreeIterator_base { + template friend class TreeIterator_const_layer; + typedef TreeIterator_base parent_type; + public: + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef typename parent_type::size_type size_type; + typedef typename parent_type::difference_type difference_type; + typedef N NodeType; + typedef N* NodeTypePointer; + enum { IS_CONST = 0 }; + TreeIterator_const_layer ( void ) {} + TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} + template + explicit TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} + reference operator* ( void ); + const_reference operator* ( void ) const; + pointer operator-> ( void ); + const_pointer operator-> ( void ) const; + const N* GetPointer ( void ) const; + N* GetPointer ( void ); + protected: + typedef typename parent_type::StackType StackType; + }; + } //namespace Implem + + template + class TreeIterator : public Implem::TreeIterator_const_layer::isConst> { + typedef Implem::TreeIterator_const_layer::isConst> parent_type; + typedef typename parent_type::NodeTypePointer NodeTypePointer; + typedef typename parent_type::NodeType NodeType; + typedef typename parent_type::StackType StackType; + public: + typedef T value_type; + typedef std::forward_iterator_tag iterator_category; + typedef typename parent_type::difference_type difference_type; + typedef typename parent_type::size_type size_type; + typedef typename parent_type::pointer pointer; + typedef typename parent_type::const_pointer const_pointer; + typedef typename parent_type::reference reference; + typedef typename parent_type::const_reference const_reference; + + TreeIterator ( void ); + TreeIterator ( const TreeIterator& parOther ); + TreeIterator ( NodeTypePointer parRoot, size_type parMaxDepthHint ); + template + TreeIterator ( S parCopyStackBottomUp, size_type parStackLen, size_type parMaxDepthHint ); + template + TreeIterator ( const TreeIterator& parOther ); + ~TreeIterator ( void ); + + const TreeIterator& operator= ( const TreeIterator& parOther ); + bool operator== ( const TreeIterator& parOther ) const; + bool operator!= ( const TreeIterator& parOther ) const { return not (*this == parOther); } + TreeIterator& operator++ ( void ); //pre + TreeIterator operator++ ( int ); //post + + private: + void RecurseLeft ( NodeTypePointer parFrom ); + }; +} //namespace duckmem + +#include "implem/tree_iterator.inl" + +#endif