Make Node a const range and fix encapsulation

This commit is contained in:
Simon Giraudot 2021-01-20 10:14:35 +01:00
parent e8e3cbda72
commit b7057e1785
2 changed files with 65 additions and 50 deletions

View File

@ -25,15 +25,38 @@
namespace CGAL { namespace CGAL {
/// \cond SKIP_IN_MANUAL
namespace Orthtrees
{
// Non-documented, or testing purpose only
struct Node_access
{
template <typename Node, typename LC>
static Node create_node (Node parent, LC local_coordinates)
{
return Node(parent, local_coordinates);
}
template <typename Node>
static typename Node::Point_range& points(Node node) { return node.points(); }
template <typename Node>
static void split(Node node) { return node.split(); }
};
} // namespace Orthtrees
/// \endcond
/*! /*!
\brief represents a single node of the tree. Alternatively referred \brief represents a single node of the tree. Alternatively referred
to as a cell, orthant, or subtree. to as a cell, orthant, or subtree.
A `Node` is a lightweight object and thus generally passed by A `Node` is a lightweight object and thus generally passed by
copy. It is also a `Range` whose value type is `Traits::Point_d`. copy. It is also a `ConstRange` whose value type is `Traits::Point_d`.
\cgalModels Range \cgalModels ConstRange
*/ */
template<typename Traits, typename PointRange, typename PointMap> template<typename Traits, typename PointRange, typename PointMap>
class Orthtree<Traits, PointRange, PointMap>::Node class Orthtree<Traits, PointRange, PointMap>::Node
@ -81,16 +104,8 @@ public:
typedef std::array<std::uint32_t, Dimension::value> Global_coordinates; typedef std::array<std::uint32_t, Dimension::value> Global_coordinates;
typedef typename PointRange::iterator iterator; ///< iterator type.
typedef typename PointRange::const_iterator const_iterator; ///< constant iterator type. typedef typename PointRange::const_iterator const_iterator; ///< constant iterator type.
/// \cond SKIP_IN_MANUAL
/*!
\brief point range type.
*/
typedef boost::iterator_range<iterator> Point_range;
/// \endcond
/*! /*!
\brief easy access to adjacency directions. \brief easy access to adjacency directions.
*/ */
@ -100,6 +115,14 @@ public:
private: private:
/// \cond SKIP_IN_MANUAL
/*!
\brief point range type.
*/
typedef typename PointRange::iterator iterator; ///< constant iterator type.
typedef boost::iterator_range<iterator> Point_range;
/// \endcond
// make Node trivially copiabled // make Node trivially copiabled
struct Data struct Data
{ {
@ -115,16 +138,26 @@ private:
std::shared_ptr<Data> m_data; std::shared_ptr<Data> m_data;
public:
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
// Only the Orthtree class has access to the non-default
// constructor, mutators, etc.
friend Enclosing;
// Hidden class to access methods for testing purposes
friend Orthtrees::Node_access;
/*!
* \brief access to the content held by this node
* \return a reference to the collection of point indices
*/
Point_range &points() { return m_data->points; }
const Point_range &points() const { return m_data->points; }
/// \name Construction /// \name Construction
/// @{ /// @{
// Default creates null node
Node() { }
/*! /*!
\brief creates a new node, optionally as the child of a parent \brief creates a new node, optionally as the child of a parent
@ -195,6 +228,14 @@ public:
/// \endcond /// \endcond
public:
/// \cond SKIP_IN_MANUAL
// Default creates null node
Node() { }
/// \endcond
/// \name Type & Location /// \name Type & Location
/// @{ /// @{
@ -450,20 +491,6 @@ public:
/// \name Point Range /// \name Point Range
/// @{ /// @{
/// \cond SKIP_IN_MANUAL
/*!
* \brief access to the content held by this node
* \return a reference to the collection of point indices
*/
Point_range &points() { return m_data->points; }
/*!
* \brief read-only access to the content held by this node
* \return a read-only reference to the collection of point indices
*/
const Point_range &points() const { return m_data->points; }
/// \endcond
/*! /*!
\brief returns the number of points of this node. \brief returns the number of points of this node.
*/ */
@ -478,18 +505,6 @@ public:
return std::distance(m_data->points.begin(), m_data->points.end()); return std::distance(m_data->points.begin(), m_data->points.end());
} }
/*!
\brief returns the iterator at the start of the collection of
points held by this node.
*/
iterator begin() { return m_data->points.begin(); }
/*!
\brief returns the iterator at the end of the collection of
points held by this node.
*/
iterator end() { return m_data->points.end(); }
/*! /*!
\brief returns the iterator at the start of the collection of \brief returns the iterator at the start of the collection of
points held by this node. points held by this node.

View File

@ -11,8 +11,7 @@
typedef CGAL::Simple_cartesian<double> Kernel; typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point; typedef Kernel::Point_3 Point;
typedef CGAL::Point_set_3<Point> Point_set; typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> Octree;
Octree;
typedef Octree::Node Node; typedef Octree::Node Node;
void test_1_point() { void test_1_point() {
@ -26,8 +25,9 @@ void test_1_point() {
octree.refine(10, 1); octree.refine(10, 1);
// Check that the topology matches // Check that the topology matches
Node single_node(Node(), 0); Node single_node = CGAL::Orthtrees::Node_access::create_node(Node(), 0);
single_node.points() = octree.root().points(); CGAL::Orthtrees::Node_access::points(single_node)
= CGAL::Orthtrees::Node_access::points(octree.root());
assert(Node::is_topology_equal(single_node, octree.root())); assert(Node::is_topology_equal(single_node, octree.root()));
assert(0 == octree.depth()); assert(0 == octree.depth());
@ -45,8 +45,8 @@ void test_2_points() {
octree.refine(10, 1); octree.refine(10, 1);
// The octree should have been split once // The octree should have been split once
Node other(Node(), 0); Node other = CGAL::Orthtrees::Node_access::create_node(Node(), 0);
other.split(); CGAL::Orthtrees::Node_access::split(other);
assert(Node::is_topology_equal(other, octree.root())); assert(Node::is_topology_equal(other, octree.root()));
assert(1 == octree.depth()); assert(1 == octree.depth());
@ -65,10 +65,10 @@ void test_4_points() {
octree.refine(10, 1); octree.refine(10, 1);
// The octree should have been split once on the first level, and twice on the second // The octree should have been split once on the first level, and twice on the second
Node other(Node(), 0); Node other = CGAL::Orthtrees::Node_access::create_node(Node(), 0);
other.split(); CGAL::Orthtrees::Node_access::split(other);
other[3].split(); CGAL::Orthtrees::Node_access::split(other[3]);
other[7].split(); CGAL::Orthtrees::Node_access::split(other[7]);
assert(Node::is_topology_equal(other, octree.root())); assert(Node::is_topology_equal(other, octree.root()));
assert(2 == octree.depth()); assert(2 == octree.depth());
} }