diff --git a/HalfedgeDS/doc/HalfedgeDS/Concepts/HalfedgeDS.h b/HalfedgeDS/doc/HalfedgeDS/Concepts/HalfedgeDS.h index 0c54a22ec76..cb405146e2f 100644 --- a/HalfedgeDS/doc/HalfedgeDS/Concepts/HalfedgeDS.h +++ b/HalfedgeDS/doc/HalfedgeDS/Concepts/HalfedgeDS.h @@ -177,6 +177,24 @@ iterator over all faces. */ typedef unspecified_type Face_iterator; +/*! + range type for iterating over the vertices, with a nested + type `iterator` that has as value type `Vertex_handle` +*/ +typedef Iterator_range Vertex_handles; + +/*! + range type for iterating over the halfedges, with a nested + type `iterator` that has as value type `Halfedge_handle` +*/ +typedef Iterator_range Halfedge_handles; + +/*! + range type for iterating over the faces, with a nested + type `iterator` that has as value type `Face_handle` +*/ +typedef Iterator_range Face_handles; + /// @} /* \name Types for Tagging Optional Features @@ -397,6 +415,12 @@ Vertex_iterator vertices_begin(); */ Vertex_iterator vertices_end(); +/*! +returns a range of handles over the vertices. +\note The value type of `Vertex_handles::iterator` is `Vertex_handle`. +*/ +Vertex_handles vertex_handles(); + /*! iterator over all halfedges */ @@ -407,6 +431,12 @@ Halfedge_iterator halfedges_begin(); */ Halfedge_iterator halfedges_end(); +/*! +returns a range of handles over the halfedges. +\note The value type of `Halfedge_handles::iterator` is `Halfedge_handle`. +*/ +Halfedge_handles halfedge_handles(); + /*! iterator over all faces. */ @@ -417,6 +447,12 @@ Face_iterator faces_begin(); */ Face_iterator faces_end(); +/*! +returns a range of handles over the faces. +\note The value type of `Face_handles::iterator` is `Face_handle`. +*/ +Face_handles face_handles(); + /// @} /*! \name Insertion diff --git a/HalfedgeDS/include/CGAL/HalfedgeDS_list.h b/HalfedgeDS/include/CGAL/HalfedgeDS_list.h index 46fdd1c9b81..aecf7b7e29b 100644 --- a/HalfedgeDS/include/CGAL/HalfedgeDS_list.h +++ b/HalfedgeDS/include/CGAL/HalfedgeDS_list.h @@ -22,6 +22,7 @@ #include #include #include +#include #include namespace CGAL { @@ -209,6 +210,9 @@ public: typedef typename Types::Vertex_iterator Vertex_iterator; typedef typename Types::Vertex_const_iterator Vertex_const_iterator; + typedef Iterator_range< Prevent_deref > Vertex_handles; + typedef Iterator_range< Prevent_deref > Vertex_const_handles; + typedef typename Types::Halfedge_allocator Halfedge_allocator; typedef typename Types::Halfedge_list Halfedge_list; typedef typename Types::Halfedge_handle Halfedge_handle; @@ -216,6 +220,9 @@ public: typedef typename Types::Halfedge_iterator Halfedge_iterator; typedef typename Types::Halfedge_const_iterator Halfedge_const_iterator; + typedef Iterator_range< Prevent_deref > Halfedge_handles; + typedef Iterator_range< Prevent_deref > Halfedge_const_handles; + typedef typename Types::Face_allocator Face_allocator; typedef typename Types::Face_list Face_list; typedef typename Types::Face_handle Face_handle; @@ -223,6 +230,9 @@ public: typedef typename Types::Face_iterator Face_iterator; typedef typename Types::Face_const_iterator Face_const_iterator; + typedef Iterator_range< Prevent_deref > Face_handles; + typedef Iterator_range< Prevent_deref > Face_const_handles; + typedef typename Types::size_type size_type; typedef typename Types::difference_type difference_type; typedef typename Types::iterator_category iterator_category; @@ -453,19 +463,25 @@ public: Vertex_iterator vertices_begin() { return vertices.begin();} Vertex_iterator vertices_end() { return vertices.end();} + Vertex_handles vertex_handles() { return make_prevent_deref_range(vertices_begin(), vertices_end());} Halfedge_iterator halfedges_begin() { return halfedges.begin();} Halfedge_iterator halfedges_end() { return halfedges.end();} + Halfedge_handles halfedge_handles() { return make_prevent_deref_range(halfedges_begin(), halfedges_end());} Face_iterator faces_begin() { return faces.begin();} Face_iterator faces_end() { return faces.end();} + Face_handles face_handles() { return make_prevent_deref_range(faces_begin(), faces_end());} // The constant iterators and circulators. - Vertex_const_iterator vertices_begin() const{ return vertices.begin();} - Vertex_const_iterator vertices_end() const{ return vertices.end();} - Halfedge_const_iterator halfedges_begin() const{ return halfedges.begin();} - Halfedge_const_iterator halfedges_end() const{ return halfedges.end();} - Face_const_iterator faces_begin() const{ return faces.begin();} - Face_const_iterator faces_end() const{ return faces.end();} + Vertex_const_iterator vertices_begin() const{ return vertices.begin();} + Vertex_const_iterator vertices_end() const{ return vertices.end();} + Vertex_const_handles vertex_handles() const{ return make_prevent_deref_range(vertices_begin(), vertices_end());} + Halfedge_const_iterator halfedges_begin() const{ return halfedges.begin();} + Halfedge_const_iterator halfedges_end() const{ return halfedges.end();} + Halfedge_const_handles halfedge_handles() const{ return make_prevent_deref_range(halfedges_begin(), halfedges_end());} + Face_const_iterator faces_begin() const{ return faces.begin();} + Face_const_iterator faces_end() const{ return faces.end();} + Face_const_handles face_handles() const{ return make_prevent_deref_range(faces_begin(), faces_end());} // Insertion // diff --git a/HalfedgeDS/include/CGAL/HalfedgeDS_vector.h b/HalfedgeDS/include/CGAL/HalfedgeDS_vector.h index 46aa588a168..5df62e4138c 100644 --- a/HalfedgeDS/include/CGAL/HalfedgeDS_vector.h +++ b/HalfedgeDS/include/CGAL/HalfedgeDS_vector.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,9 @@ public: typedef typename Types::Vertex_I Vertex_I; typedef typename Types::Vertex_CI Vertex_CI; + typedef Iterator_range< Prevent_deref > Vertex_handles; + typedef Iterator_range< Prevent_deref > Vertex_const_handles; + typedef typename Types::Halfedge_vector Halfedge_vector; typedef typename Types::Halfedge_handle Halfedge_handle; typedef typename Types::Halfedge_const_handle Halfedge_const_handle; @@ -169,6 +173,9 @@ public: typedef typename Types::Halfedge_I Halfedge_I; typedef typename Types::Halfedge_CI Halfedge_CI; + typedef Iterator_range< Prevent_deref > Halfedge_handles; + typedef Iterator_range< Prevent_deref > Halfedge_const_handles; + typedef typename Types::Face_vector Face_vector; typedef typename Types::Face_handle Face_handle; typedef typename Types::Face_const_handle Face_const_handle; @@ -177,6 +184,9 @@ public: typedef typename Types::Face_I Face_I; typedef typename Types::Face_CI Face_CI; + typedef Iterator_range< Prevent_deref > Face_handles; + typedef Iterator_range< Prevent_deref > Face_const_handles; + typedef typename Types::size_type size_type; typedef typename Types::difference_type difference_type; typedef typename Types::iterator_category iterator_category; @@ -371,19 +381,25 @@ public: Vertex_iterator vertices_begin() { return vertices.begin();} Vertex_iterator vertices_end() { return vertices.end();} + Vertex_handles vertex_handles() { return make_prevent_deref_range(vertices_begin(), vertices_end());} Halfedge_iterator halfedges_begin() { return halfedges.begin();} Halfedge_iterator halfedges_end() { return halfedges.end();} + Halfedge_handles halfedge_handles() { return make_prevent_deref_range(halfedges_begin(), halfedges_end());} Face_iterator faces_begin() { return faces.begin();} Face_iterator faces_end() { return faces.end();} + Face_handles face_handles() { return make_prevent_deref_range(faces_begin(), faces_end());} // The constant iterators and circulators. - Vertex_const_iterator vertices_begin() const{ return vertices.begin();} - Vertex_const_iterator vertices_end() const{ return vertices.end();} - Halfedge_const_iterator halfedges_begin() const{ return halfedges.begin();} - Halfedge_const_iterator halfedges_end() const{ return halfedges.end();} - Face_const_iterator faces_begin() const{ return faces.begin();} - Face_const_iterator faces_end() const{ return faces.end();} + Vertex_const_iterator vertices_begin() const{ return vertices.begin();} + Vertex_const_iterator vertices_end() const{ return vertices.end();} + Vertex_const_handles vertex_handles() const{ return make_prevent_deref_range(vertices_begin(), vertices_end());} + Halfedge_const_iterator halfedges_begin() const{ return halfedges.begin();} + Halfedge_const_iterator halfedges_end() const{ return halfedges.end();} + Halfedge_const_handles halfedge_handles() const{ return make_prevent_deref_range(halfedges_begin(), halfedges_end());} + Face_const_iterator faces_begin() const{ return faces.begin();} + Face_const_iterator faces_end() const{ return faces.end();} + Face_const_handles face_handles() const{ return make_prevent_deref_range(faces_begin(), faces_end());} // Insertion // diff --git a/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp b/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp new file mode 100644 index 00000000000..19adc023f29 --- /dev/null +++ b/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include + +using Kernel = CGAL::Simple_cartesian; +using HDS_list = CGAL::HalfedgeDS_list; +using HDS_vector = CGAL::HalfedgeDS_vector; + +// void test_vertex_handles_and_points( +// Polyhedron& polyhedron) { + +// auto pit = polyhedron.points_begin(); +// auto vit = polyhedron.vertices_begin(); +// for (auto vh : polyhedron.vertex_handles()) { +// assert(vh == vit); +// assert(vh->point() == vit->point()); +// assert(vh->point() == *pit); +// ++vit; ++pit; +// } +// assert(pit == polyhedron.points_end()); +// assert(vit == polyhedron.vertices_end()); + +// pit = polyhedron.points_begin(); +// vit = polyhedron.vertices_begin(); +// for (auto& point : polyhedron.points()) { +// assert(*pit == point); +// assert(vit->point() == point); +// ++vit; ++pit; +// } +// assert(pit == polyhedron.points_end()); +// assert(vit == polyhedron.vertices_end()); +// } + +// void test_const_vertex_handles_and_points( +// const Polyhedron& polyhedron) { + +// auto pit = polyhedron.points_begin(); +// auto vit = polyhedron.vertices_begin(); +// for (const auto vh : polyhedron.vertex_handles()) { +// assert(vh == vit); +// assert(vh->point() == vit->point()); +// assert(vh->point() == *pit); +// ++vit; ++pit; +// } +// assert(pit == polyhedron.points_end()); +// assert(vit == polyhedron.vertices_end()); + +// pit = polyhedron.points_begin(); +// vit = polyhedron.vertices_begin(); +// for (const auto& point : polyhedron.points()) { +// assert(*pit == point); +// assert(vit->point() == point); +// ++vit; ++pit; +// } +// assert(pit == polyhedron.points_end()); +// assert(vit == polyhedron.vertices_end()); +// } + +// void test_facet_handles_and_planes( +// Polyhedron& polyhedron) { + +// auto pit = polyhedron.planes_begin(); +// auto fit = polyhedron.facets_begin(); +// for (auto fh : polyhedron.facet_handles()) { +// assert(fh == fit); +// assert(fh->plane() == fit->plane()); +// assert(fh->plane() == *pit); +// ++fit; ++pit; +// } +// assert(pit == polyhedron.planes_end()); +// assert(fit == polyhedron.facets_end()); + +// pit = polyhedron.planes_begin(); +// fit = polyhedron.facets_begin(); +// for (auto& plane : polyhedron.planes()) { +// assert(*pit == plane); +// assert(fit->plane() == plane); +// ++fit; ++pit; +// } +// assert(pit == polyhedron.planes_end()); +// assert(fit == polyhedron.facets_end()); +// } + +// void test_const_facet_handles_and_planes( +// const Polyhedron& polyhedron) { + +// auto pit = polyhedron.planes_begin(); +// auto fit = polyhedron.facets_begin(); +// for (const auto fh : polyhedron.facet_handles()) { +// assert(fh == fit); +// assert(fh->plane() == fit->plane()); +// assert(fh->plane() == *pit); +// ++fit; ++pit; +// } +// assert(pit == polyhedron.planes_end()); +// assert(fit == polyhedron.facets_end()); + +// pit = polyhedron.planes_begin(); +// fit = polyhedron.facets_begin(); +// for (const auto& plane : polyhedron.planes()) { +// assert(*pit == plane); +// assert(fit->plane() == plane); +// ++fit; ++pit; +// } +// assert(pit == polyhedron.planes_end()); +// assert(fit == polyhedron.facets_end()); +// } + +// void test_halfedge_handles_and_edges( +// Polyhedron& polyhedron) { + +// auto hit = polyhedron.halfedges_begin(); +// for (auto hh : polyhedron.halfedge_handles()) { +// assert(hh == hit); +// assert(hh->facet() == hit->facet()); +// assert(hh->vertex() == hit->vertex()); +// ++hit; +// } +// assert(hit == polyhedron.halfedges_end()); + +// auto eit = polyhedron.edges_begin(); +// for (auto& edge : polyhedron.edges()) { +// assert((*eit).facet() == edge.facet()); +// assert((*eit).vertex() == edge.vertex()); +// ++eit; +// } +// assert(eit == polyhedron.edges_end()); +// } + +// void test_const_halfedge_handles_and_edges( +// const Polyhedron& polyhedron) { + +// auto hit = polyhedron.halfedges_begin(); +// for (const auto hh : polyhedron.halfedge_handles()) { +// assert(hh == hit); +// assert(hh->facet() == hit->facet()); +// assert(hh->vertex() == hit->vertex()); +// ++hit; +// } +// assert(hit == polyhedron.halfedges_end()); + +// auto eit = polyhedron.edges_begin(); +// for (const auto& edge : polyhedron.edges()) { +// assert((*eit).facet() == edge.facet()); +// assert((*eit).vertex() == edge.vertex()); +// ++eit; +// } +// assert(eit == polyhedron.edges_end()); +// } + +int main() { + + HDS_list hds_list(1, 2, 2); + HDS_vector hds_vector(1, 2, 2); + + // test_vertex_handles_and_points(polyhedron); + // test_const_vertex_handles_and_points(polyhedron); + // test_facet_handles_and_planes(polyhedron); + // test_const_facet_handles_and_planes(polyhedron); + // test_halfedge_handles_and_edges(polyhedron); + // test_const_halfedge_handles_and_edges(polyhedron); + + std::cout << "test_hds_range_based_loops: SUCCESS" << std::endl; + return EXIT_SUCCESS; +}