Traversal is now done by index (internally)

This commit is contained in:
JacksonCampolattaro 2023-04-11 12:17:32 +02:00
parent 1a1ca5cf28
commit a5a92ad795
2 changed files with 33 additions and 17 deletions

View File

@ -123,7 +123,7 @@ public:
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
typedef unspecified_type Node_range; typedef unspecified_type Node_range;
#else #else
typedef boost::iterator_range<Traversal_iterator<const Node>> Node_range; typedef boost::iterator_range<Traversal_iterator<Self>> Node_range;
#endif #endif
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
@ -449,6 +449,12 @@ public:
return std::distance(m_nodes.data(), &node); return std::distance(m_nodes.data(), &node);
} }
boost::optional<std::size_t> index(const Node* node) const {
if (node == nullptr) return {};
return index(*node);
}
const Node& operator[](std::size_t index) const { const Node& operator[](std::size_t index) const {
return m_nodes[index]; return m_nodes[index];
} }
@ -480,12 +486,14 @@ public:
const Node* first = traversal.first(); const Node* first = traversal.first();
Node_traversal_method_const next = [=](const Node* n) -> const Node* { auto next = [=](const Self& tree, std::size_t index) -> boost::optional<std::size_t> {
return traversal.next(n); auto n = traversal.next(&tree[index]);
if (n == nullptr) return {};
return tree.index(*n);
}; };
return boost::make_iterator_range(Traversal_iterator<const Node>(first, next), return boost::make_iterator_range(Traversal_iterator<Self>(*this, first, next),
Traversal_iterator<const Node>()); Traversal_iterator<Self>());
} }
// todo: document this convenience function // todo: document this convenience function

View File

@ -15,6 +15,7 @@
#include <CGAL/license/Orthtree.h> #include <CGAL/license/Orthtree.h>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
@ -30,9 +31,9 @@ namespace CGAL {
* *
* \tparam Value * \tparam Value
*/ */
template <class Value> template <class Tree>
class Traversal_iterator class Traversal_iterator
: public boost::iterator_facade<Traversal_iterator<Value>, Value, boost::forward_traversal_tag> { : public boost::iterator_facade<Traversal_iterator<Tree>, const typename Tree::Node, boost::forward_traversal_tag> {
public: public:
/// \name Types /// \name Types
@ -43,7 +44,7 @@ public:
* *
* \todo * \todo
*/ */
typedef std::function<Value*(Value*)> Traversal_function; typedef std::function<boost::optional<std::size_t>(const Tree&, std::size_t)> Traversal_function;
/// @} /// @}
@ -53,43 +54,50 @@ public:
/// @{ /// @{
/*! /*!
* \brief * \brief Default constructor, creates an end sentinel
* *
* \todo * \todo
*/ */
Traversal_iterator() : m_value(nullptr), m_next() {} Traversal_iterator() : m_next() {}
/*! /*!
* \brief * \brief
* *
* \todo * \todo
* *
* \param tree
* \param first * \param first
* \param next * \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: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
bool equal(Traversal_iterator<Value> const& other) const { bool equal(Traversal_iterator<Tree> const& other) const {
return m_value == other.m_value; return m_index == other.m_index;
} }
void increment() { 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 { const typename Tree::Node& dereference() const {
return *m_value; return (*m_tree)[m_index.get()];
} }
private: private:
Value* m_value;
Traversal_function m_next; Traversal_function m_next;
boost::optional<std::size_t> m_index = {};
const Tree* m_tree = nullptr;
}; };
} }