From a5a92ad7959b232ff30421ed1e395e56a069897d Mon Sep 17 00:00:00 2001 From: JacksonCampolattaro Date: Tue, 11 Apr 2023 12:17:32 +0200 Subject: [PATCH] Traversal is now done by index (internally) --- Orthtree/include/CGAL/Orthtree.h | 18 ++++++++--- .../CGAL/Orthtree/Traversal_iterator.h | 32 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index 8ccb5155a63..77423037461 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -123,7 +123,7 @@ public: #ifdef DOXYGEN_RUNNING typedef unspecified_type Node_range; #else - typedef boost::iterator_range> Node_range; + typedef boost::iterator_range> Node_range; #endif /// \cond SKIP_IN_MANUAL @@ -449,6 +449,12 @@ public: return std::distance(m_nodes.data(), &node); } + boost::optional index(const Node* node) const { + if (node == nullptr) return {}; + return index(*node); + } + + const Node& operator[](std::size_t index) const { return m_nodes[index]; } @@ -480,12 +486,14 @@ public: const Node* first = traversal.first(); - Node_traversal_method_const next = [=](const Node* n) -> const Node* { - return traversal.next(n); + auto next = [=](const Self& tree, std::size_t index) -> boost::optional { + auto n = traversal.next(&tree[index]); + if (n == nullptr) return {}; + return tree.index(*n); }; - return boost::make_iterator_range(Traversal_iterator(first, next), - Traversal_iterator()); + return boost::make_iterator_range(Traversal_iterator(*this, first, next), + Traversal_iterator()); } // todo: document this convenience function diff --git a/Orthtree/include/CGAL/Orthtree/Traversal_iterator.h b/Orthtree/include/CGAL/Orthtree/Traversal_iterator.h index d69783260b7..ba0e0f78f0a 100644 --- a/Orthtree/include/CGAL/Orthtree/Traversal_iterator.h +++ b/Orthtree/include/CGAL/Orthtree/Traversal_iterator.h @@ -15,6 +15,7 @@ #include #include +#include #include /// \cond SKIP_IN_MANUAL @@ -30,9 +31,9 @@ namespace CGAL { * * \tparam Value */ -template +template class Traversal_iterator - : public boost::iterator_facade, Value, boost::forward_traversal_tag> { + : public boost::iterator_facade, const typename Tree::Node, boost::forward_traversal_tag> { public: /// \name Types @@ -43,7 +44,7 @@ public: * * \todo */ - typedef std::function Traversal_function; + typedef std::function(const Tree&, std::size_t)> Traversal_function; /// @} @@ -53,43 +54,50 @@ public: /// @{ /*! - * \brief + * \brief Default constructor, creates an end sentinel * * \todo */ - Traversal_iterator() : m_value(nullptr), m_next() {} + Traversal_iterator() : m_next() {} /*! * \brief * * \todo * + * \param tree * \param first * \param next */ - Traversal_iterator(Value* first, const Traversal_function& next) : m_value(first), m_next(next) {} + Traversal_iterator(const Tree& tree, const typename Tree::Node* first, const Traversal_function& next) : + m_tree(&tree), m_index(tree.index(first)), m_next(next) {} /// @} private: + friend class boost::iterator_core_access; - bool equal(Traversal_iterator const& other) const { - return m_value == other.m_value; + bool equal(Traversal_iterator const& other) const { + return m_index == other.m_index; } void increment() { - m_value = m_next(m_value); + // invoking increment on the sentinel is undefined behavior + m_index = m_next(*m_tree, m_index.get()); } - Value& dereference() const { - return *m_value; + const typename Tree::Node& dereference() const { + return (*m_tree)[m_index.get()]; } private: - Value* m_value; Traversal_function m_next; + + boost::optional m_index = {}; + const Tree* m_tree = nullptr; + }; }