Skip to content

Commit

Permalink
STL extension: Add a template argument to Prevent_deref for the value…
Browse files Browse the repository at this point in the history
… type (#7410)

## Summary of Changes

Fix issue #7400

## Release Management

* Affected package(s):  Triangulation_2, Triangulation_3, STL_extension
* Issue(s) solved (if any): fix #7400 

* License and copyright ownership: unchanged
  • Loading branch information
sloriot authored May 26, 2024
2 parents ab8848f + ce16436 commit 1c172bb
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 64 deletions.
16 changes: 8 additions & 8 deletions Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a range over handles of the arrangement vertices .
returns a range over handles of the arrangement vertices.
*/
Iterator_range<Prevent_deref<Vertex_iterator> >
vertex_handles()
Expand All @@ -1068,7 +1068,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a const range (model of `ConstRange`) over handles of the arrangement vertices .
returns a const range (model of `ConstRange`) over handles of the arrangement vertices.
*/
Iterator_range<Prevent_deref<Vertex_const_iterator> >
vertex_handles() const
Expand Down Expand Up @@ -1098,7 +1098,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a range over handles of the arrangement halfedges .
returns a range over handles of the arrangement halfedges.
*/
Iterator_range<Prevent_deref<Halfedge_iterator> >
halfedge_handles()
Expand All @@ -1122,7 +1122,7 @@ class Arrangement_on_surface_2 {
_Is_valid_halfedge(&m_topol_traits)));
}
/*!
returns a const range (model of `ConstRange`) over handles of the arrangement halfedges .
returns a const range (model of `ConstRange`) over handles of the arrangement halfedges.
*/
Iterator_range<Prevent_deref<Halfedge_const_iterator> >
halfedge_handles() const
Expand All @@ -1149,7 +1149,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a range over handles of the arrangement edges .
returns a range over handles of the arrangement edges.
*/
Iterator_range<Prevent_deref<Edge_iterator> >
edge_handles()
Expand All @@ -1172,7 +1172,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a const range (model of `ConstRange`) over handles of the arrangement edges .
returns a const range (model of `ConstRange`) over handles of the arrangement edges.
*/
Iterator_range<Prevent_deref<Edge_const_iterator> >
edge_handles() const
Expand All @@ -1199,7 +1199,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a range over handles of the arrangement faces .
returns a range over handles of the arrangement faces.
*/
Iterator_range<Prevent_deref<Face_iterator> >
face_handles()
Expand All @@ -1221,7 +1221,7 @@ class Arrangement_on_surface_2 {
}

/*!
returns a const range (model of `ConstRange`) over handles of the arrangement faces .
returns a const range (model of `ConstRange`) over handles of the arrangement faces.
*/
Iterator_range<Prevent_deref<Face_const_iterator> >
face_handles() const
Expand Down
20 changes: 9 additions & 11 deletions SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ class Mesh_complex_3_in_triangulation_3
*/
void remove_from_complex(const Vertex_handle& v)
{
corners_.erase(v);
v->set_dimension(-1);
corners_.erase(v);
}

/** sets the index of vertex \p vertex to \p index
Expand Down Expand Up @@ -983,7 +983,7 @@ class Mesh_complex_3_in_triangulation_3
pointer operator->() const { return *(this->base()); }
reference operator*() const { return **(this->base()); }

operator Vertex_handle() { return Vertex_handle(*(this->base())); }
operator const Vertex_handle&() const { return *(this->base()); }
};

public:
Expand Down Expand Up @@ -1048,13 +1048,13 @@ class Mesh_complex_3_in_triangulation_3
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }

operator Cell_handle() const { return Cell_handle(this->base()); }
operator const Cell_handle&() const { return this->base(); }
}; // end class Cells_in_complex_iterator

typedef Iterator_range<Prevent_deref<Vertices_in_complex_iterator> > Vertices_in_complex;
typedef Iterator_range<Edges_in_complex_iterator> Edges_in_complex;
typedef Iterator_range<Facets_in_complex_iterator> Facets_in_complex;
typedef Iterator_range<Prevent_deref<Cells_in_complex_iterator> > Cells_in_complex;
typedef Iterator_range<Prevent_deref<Vertices_in_complex_iterator, const Vertex_handle&>> Vertices_in_complex;
typedef Iterator_range<Edges_in_complex_iterator> Edges_in_complex;
typedef Iterator_range<Facets_in_complex_iterator> Facets_in_complex;
typedef Iterator_range<Prevent_deref<Cells_in_complex_iterator, const Cell_handle&>> Cells_in_complex;

#endif

Expand Down Expand Up @@ -1162,8 +1162,7 @@ class Mesh_complex_3_in_triangulation_3
*/
Vertices_in_complex vertices_in_complex() const
{
return make_prevent_deref_range(vertices_in_complex_begin(),
vertices_in_complex_end());
return { vertices_in_complex_begin(), vertices_in_complex_end() };
}
/*!
returns a range of iterators over the edges of the 1D complex,
Expand Down Expand Up @@ -1193,8 +1192,7 @@ class Mesh_complex_3_in_triangulation_3
*/
Cells_in_complex cells_in_complex() const
{
return make_prevent_deref_range(cells_in_complex_begin(),
cells_in_complex_end());
return { cells_in_complex_begin(), cells_in_complex_end() };
}
/// @}

Expand Down
12 changes: 12 additions & 0 deletions SMDS_3/test/SMDS_3/test_c3t3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ struct Tester
typedef typename C3t3::Facets_in_complex_iterator Facet_iterator;
typedef typename C3t3::Vertex_handle Vertex_handle;

typedef typename C3t3::Vertices_in_complex Vertices_in_complex;
typedef typename C3t3::Cells_in_complex Cells_in_complex;

typedef typename C3t3::Subdomain_index Subdomain_index;
typedef typename C3t3::Surface_patch_index Surface_patch_index;
typedef typename C3t3::Index Index;
Expand Down Expand Up @@ -120,6 +123,15 @@ struct Tester
assert(c3t3.is_in_complex(ch));
assert(c3t3.subdomain_index(ch) == subdomain_index);

// Test iterator range
{
Cell_handle ch = *c3t3.cells_in_complex().begin();
for (auto c : c3t3.cells_in_complex()) {
assert(c == ch);
break;
}
}

//-------------------------------------------------------
// Test move construction
//-------------------------------------------------------
Expand Down
19 changes: 18 additions & 1 deletion SMDS_3/test/SMDS_3/test_c3t3_with_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,18 @@ struct Tester
|| ( v == vp4 && tr.point(vit) == p4 ) );

assert ( tv1.in_dimension() == tv2.in_dimension() );


// Test iterator range
{
Vertex_handle vh = *c3t3.vertices_in_complex().begin();
for (auto v : c3t3.vertices_in_complex()) {
assert(v == vh);
break;
}
}


//-------------------------------------------------------
// Check adjacencies
//-------------------------------------------------------
Expand Down Expand Up @@ -335,8 +347,13 @@ struct Tester
//-------------------------------------------------------
std::cout << "Test vertex iterators\n";
const Vertex_handle& vertex_to_modify = c3t3.vertices_in_complex_begin();
Vertex_handle vertex_to_modify_copy = vertex_to_modify;

c3t3.remove_from_complex(vertex_to_modify);
c3t3.add_to_complex(vertex_to_modify,corner_index_bis);
// now `vertex_to_modify` is a dangling ref to a `Vertex_handle`

// use a copy of it: `vertex_to_modify_copy`
c3t3.add_to_complex(vertex_to_modify_copy,corner_index_bis);

typename C3t3::Vertices_in_complex_iterator corner_vit =
c3t3.vertices_in_complex_begin(corner_index);
Expand Down
29 changes: 18 additions & 11 deletions STL_Extension/include/CGAL/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <CGAL/circulator.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/tuple.h>
#include <CGAL/type_traits.h>
#include <CGAL/use.h>

#include <variant>
Expand All @@ -37,28 +38,34 @@

namespace CGAL {

template<typename I>
template<typename I, typename Reference_type = const I&>
class Prevent_deref
: public boost::iterator_adaptor<
Prevent_deref<I>
Prevent_deref<I, Reference_type>
, I // base
, I // value
, CGAL::cpp20::remove_cvref_t<Reference_type> // value
, boost::use_default // category
, Reference_type // ref
>
{
public:
typedef boost::iterator_adaptor<
Prevent_deref<I>
using Value_type = CGAL::cpp20::remove_cvref_t<Reference_type>;
using Base = boost::iterator_adaptor<
Prevent_deref<I, Reference_type>
, I // base
, I // value
> Base;
typedef typename Base::reference reference;
, Value_type // value
, boost::use_default // category
, Reference_type // ref
>;
typedef typename std::pair<I, I> range;

Prevent_deref() : Base() {}
Prevent_deref() = default;
Prevent_deref(const I& i) : Base(i) {}
private:
friend class boost::iterator_core_access;
reference dereference() const { return const_cast<std::remove_reference_t<reference>&>(this->base_reference()); }
Reference_type dereference() const {
return this->base_reference();
}
};

template<typename I>
Expand Down Expand Up @@ -608,7 +615,7 @@ struct Filter_iterator {
reference operator*() const { return *c_; }
pointer operator->() const { return &*c_; }
const Predicate& predicate() const { return p_; }
Iterator base() const { return c_; }
const Iterator& base() const { return c_; }

Iterator end() const { return e_; }
bool is_end() const { return (c_ == e_); }
Expand Down
1 change: 1 addition & 0 deletions STL_Extension/test/STL_Extension/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ if(NOT TARGET CGAL::TBB_support)
message(STATUS "NOTICE: Tests are not using TBB.")
endif()

create_single_source_cgal_program("issue_7400.cpp")
create_single_source_cgal_program("test_Boolean_tag.cpp")
create_single_source_cgal_program("test_Cache.cpp")
create_single_source_cgal_program("test_Compact_container.cpp")
Expand Down
54 changes: 54 additions & 0 deletions STL_Extension/test/STL_Extension/issue_7400.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <type_traits>
#include <iterator>
#include <CGAL/type_traits.h>

// Add C++20 utilities to C++14
template <class Iterator>
using iter_value_t = std::remove_reference_t<decltype(*std::declval<Iterator>())>;

template<class Range>
using range_value_t = iter_value_t<CGAL::cpp20::remove_cvref_t<decltype(std::begin(std::declval<Range>()))>>;

template< class T, class U >
constexpr bool is_same_v = std::is_same<T, U>::value;

template< class T, class U >
constexpr bool is_convertible_v = std::is_convertible<T, U>::value;


#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_3.h>

using Triangulation = CGAL::Triangulation_3<CGAL::Exact_predicates_inexact_constructions_kernel>;

using Vertex_handle = Triangulation::Vertex_handle;

Triangulation t;

// Tds::vertex_handles() -> Vertex_handle
static_assert(is_same_v<range_value_t<decltype(t.tds().vertex_handles())>, const Vertex_handle>);

// Triangulation::all_vertex_handles() -> Vertex_handle
static_assert(is_same_v<range_value_t<decltype(t.all_vertex_handles())>, const Vertex_handle>);

// Triangulation::finite_vertex_handles() -> convertible to Vertex_handle
static_assert(is_convertible_v<decltype(*std::begin(t.finite_vertex_handles())), Vertex_handle>);

// But is it equal to Vertex_handle
static_assert(is_same_v<range_value_t<decltype(t.finite_vertex_handles())>, const Vertex_handle>);

int main()
{
Vertex_handle v_inf = t.infinite_vertex();
for(auto v: t.finite_vertex_handles()) {
Vertex_handle v2 = v;
CGAL_USE(v2);
if(v == v_inf) return 1;
}
for (auto v : t.all_vertex_handles()) {
Vertex_handle v2 = v;
CGAL_USE(v2);
if (v == v_inf) std::cout << "found inf" << std::endl;
}
return 0;
}
2 changes: 1 addition & 1 deletion Stream_support/include/CGAL/IO/PLY/PLY_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <CGAL/Kernel_traits.h>
#include <CGAL/property_map.h>

#include <boost/cstdint.hpp>
#include <cstdint>
#include <boost/range/value_type.hpp>

#include <iostream>
Expand Down
4 changes: 2 additions & 2 deletions TDS_2/include/CGAL/Triangulation_data_structure_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class Triangulation_data_structure_2
}

Face_handles face_handles() const {
return make_prevent_deref_range(faces_begin(),faces_end());
return { faces_begin(), faces_end() };
}

Vertex_iterator vertices_begin() const {
Expand All @@ -195,7 +195,7 @@ class Triangulation_data_structure_2
}

Vertex_handles vertex_handles() const {
return make_prevent_deref_range(vertices_begin(),vertices_end());
return { vertices_begin(), vertices_end() };
}

Edge_iterator edges_begin() const {
Expand Down
4 changes: 2 additions & 2 deletions TDS_3/include/CGAL/Triangulation_data_structure_3.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ class Triangulation_data_structure_3

Cell_handles cell_handles() const
{
return make_prevent_deref_range(cells_begin(), cells_end());
return { cells_begin(), cells_end() };
}

Cell_iterator raw_cells_begin() const
Expand Down Expand Up @@ -720,7 +720,7 @@ class Triangulation_data_structure_3

Vertex_handles vertex_handles() const
{
return make_prevent_deref_range(vertices_begin(), vertices_end());
return { vertices_begin(), vertices_end() };
}

// CIRCULATOR METHODS
Expand Down
Loading

0 comments on commit 1c172bb

Please sign in to comment.