Merge pull request #4496 from lrineau/CGAL-move_semantic_for_triangulations-GF

Add move-semantic to Compact_container and Triangulations
This commit is contained in:
Laurent Rineau 2020-06-03 16:23:22 +02:00
commit 871c97273a
69 changed files with 647 additions and 430 deletions

View File

@ -142,7 +142,7 @@ public:
private: private:
Trpz_parameter_space* ptr() const { return (Trpz_parameter_space*)(PTR.p); } Trpz_parameter_space* ptr() const { return (Trpz_parameter_space*)(PTR); }
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
@ -323,7 +323,7 @@ public:
{ {
//define the initial trapezoid: left, right, btm, top are at infinity. //define the initial trapezoid: left, right, btm, top are at infinity.
// its type is TD_TRAPEZOID ,it is on all boundaries, and has no neighbours // its type is TD_TRAPEZOID ,it is on all boundaries, and has no neighbours
PTR.p = new Trpz_parameter_space PTR = new Trpz_parameter_space
(Traits::vtx_at_left_infinity(), (Traits::vtx_at_left_infinity(),
Traits::vtx_at_right_infinity(), Traits::vtx_at_right_infinity(),
Traits::he_at_bottom_infinity(), Traits::he_at_bottom_infinity(),
@ -353,7 +353,7 @@ public:
else //tp == TD_VERTEX else //tp == TD_VERTEX
type_flag |= CGAL_TD_VERTEX; type_flag |= CGAL_TD_VERTEX;
PTR.p = new Trpz_parameter_space PTR = new Trpz_parameter_space
(l, r, b, t, type_flag | boundness_flag, lb, lt, rb, rt); (l, r, b, t, type_flag | boundness_flag, lb, lt, rb, rt);
m_dag_node = node; m_dag_node = node;
} }
@ -370,7 +370,7 @@ public:
Self* rb = 0, Self* rt = 0, Self* rb = 0, Self* rt = 0,
Dag_node* node = 0) Dag_node* node = 0)
{ {
PTR.p = new Trpz_parameter_space PTR = new Trpz_parameter_space
(l ? *l : Traits::vtx_at_left_infinity(), (l ? *l : Traits::vtx_at_left_infinity(),
r ? *r : Traits::vtx_at_right_infinity(), r ? *r : Traits::vtx_at_right_infinity(),
b ? *b : Traits::he_at_bottom_infinity(), b ? *b : Traits::he_at_bottom_infinity(),
@ -436,7 +436,7 @@ public:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
CGAL_TD_INLINE unsigned long id() const CGAL_TD_INLINE unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }
/*! Access trapezoid left. */ /*! Access trapezoid left. */

View File

@ -135,7 +135,7 @@ public:
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
@ -194,7 +194,7 @@ public:
Td_active_edge () Td_active_edge ()
{ {
PTR.p = new Data PTR = new Data
(Traits::empty_he_handle(), Td_map_item(0), nullptr); (Traits::empty_he_handle(), Td_map_item(0), nullptr);
//m_dag_node = nullptr; //m_dag_node = nullptr;
} }
@ -204,7 +204,7 @@ public:
boost::optional<Td_map_item&> next = boost::none) boost::optional<Td_map_item&> next = boost::none)
{ {
PTR.p = new Data(he, (next) ? *next : Td_map_item(0), node); PTR = new Data(he, (next) ? *next : Td_map_item(0), node);
//m_dag_node = node; //m_dag_node = node;
} }
@ -261,7 +261,7 @@ public:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
CGAL_TD_INLINE unsigned long id() const CGAL_TD_INLINE unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }

View File

@ -129,7 +129,7 @@ public:
}; };
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const Curve_end vtx_to_ce(Vertex_const_handle v) const
{ {
@ -180,14 +180,14 @@ public:
Td_active_fictitious_vertex() Td_active_fictitious_vertex()
{ {
PTR.p = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr); PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
} }
/*! Constructor given Vertex & Halfedge handles. */ /*! Constructor given Vertex & Halfedge handles. */
Td_active_fictitious_vertex(Vertex_const_handle v, Td_active_fictitious_vertex(Vertex_const_handle v,
Halfedge_const_handle cw_he, Halfedge_const_handle cw_he,
Dag_node* node = 0) Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); } { PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */ /*! Copy constructor. */
@ -224,7 +224,7 @@ public:
inline const Self& self() const { return *this; } inline const Self& self() const { return *this; }
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const { return (unsigned long) PTR.p; } inline unsigned long id() const { return (unsigned long) PTR; }
/*! Access trapezoid left. /*! Access trapezoid left.
* filters out the infinite case which returns predefined dummy values * filters out the infinite case which returns predefined dummy values

View File

@ -144,7 +144,7 @@ public:
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
public: public:
@ -255,7 +255,7 @@ private:
{ {
//define the initial trapezoid: left, right, btm, top are at infinity. //define the initial trapezoid: left, right, btm, top are at infinity.
// has no neighbours // has no neighbours
PTR.p = new Data PTR = new Data
(Traits::empty_vtx_handle(), (Traits::empty_vtx_handle(),
Traits::empty_vtx_handle(), Traits::empty_vtx_handle(),
Traits::empty_he_handle(), Traits::empty_he_handle(),
@ -274,7 +274,7 @@ private:
boost::optional<Td_map_item&> rt = boost::none, boost::optional<Td_map_item&> rt = boost::none,
Dag_node* node = 0) Dag_node* node = 0)
{ {
PTR.p = new Data (l, r, b, t, (lb) ? *lb : Td_map_item(0), (lt) ? *lt : Td_map_item(0), PTR = new Data (l, r, b, t, (lb) ? *lb : Td_map_item(0), (lt) ? *lt : Td_map_item(0),
(rb) ? *rb : Td_map_item(0), (rt) ? *rt : Td_map_item(0), node); (rb) ? *rb : Td_map_item(0), (rt) ? *rt : Td_map_item(0), node);
//m_dag_node = node; //m_dag_node = node;
} }
@ -332,7 +332,7 @@ private:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const inline unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }
/*! Access trapezoid left. /*! Access trapezoid left.

View File

@ -134,7 +134,7 @@ public:
}; };
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const Curve_end vtx_to_ce(Vertex_const_handle v) const
{ {
@ -184,14 +184,14 @@ public:
Td_active_vertex() Td_active_vertex()
{ {
PTR.p = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr); PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
} }
/*! Constructor given Vertex & Halfedge handles. */ /*! Constructor given Vertex & Halfedge handles. */
Td_active_vertex(Vertex_const_handle v, Halfedge_const_handle cw_he, Td_active_vertex(Vertex_const_handle v, Halfedge_const_handle cw_he,
Dag_node* node = 0) Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); } { PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */ /*! Copy constructor. */
@ -228,7 +228,7 @@ public:
inline const Self& self() const { return *this; } inline const Self& self() const { return *this; }
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const { return (unsigned long) PTR.p; } inline unsigned long id() const { return (unsigned long) PTR; }
inline Vertex_const_handle vertex() const { return ptr()->v; } inline Vertex_const_handle vertex() const { return ptr()->v; }

View File

@ -41,14 +41,14 @@ public: //iddo (for CC-7.2) maybe protected?
typedef const T & const_reference; typedef const T & const_reference;
protected: protected:
void init() { PTR.p = 0; } void init() { PTR = 0; }
public: public:
Td_dag_base() {init();} Td_dag_base() {init();}
Td_dag_base(const Td_dag_base<T> & x) : Handle(x) {} Td_dag_base(const Td_dag_base<T> & x) : Handle(x) {}
Td_dag_base & operator=(const Td_dag_base<T> & x) Td_dag_base & operator=(const Td_dag_base<T> & x)
{Handle::operator=(x); return *this; } {Handle::operator=(x); return *this; }
bool operator!() const { return PTR.p == 0; } bool operator!() const { return PTR == 0; }
}; };
template<class T> template<class T>
@ -96,9 +96,9 @@ public:
Td_dag(){} Td_dag(){}
Td_dag(const Td_dag_handle& dag):Td_dag_handle(dag){} Td_dag(const Td_dag_handle& dag):Td_dag_handle(dag){}
Td_dag(const Self& dag):Td_dag_handle(dag){} Td_dag(const Self& dag):Td_dag_handle(dag){}
Td_dag(const T& rootValue){PTR.p = new node(rootValue);} Td_dag(const T& rootValue){PTR = new node(rootValue);}
Td_dag(const T& rootValue, const Self& left, const Self& right) Td_dag(const T& rootValue, const Self& left, const Self& right)
{PTR.p = new node(rootValue, left, right); rebalance_depth();} {PTR = new node(rootValue, left, right); rebalance_depth();}
~Td_dag(){} ~Td_dag(){}
/* --------information retrieval -------*/ /* --------information retrieval -------*/
@ -145,7 +145,7 @@ public:
} }
bool operator==(const Self& b) const bool operator==(const Self& b) const
{ {
return PTR.p==b.PTR.p; return PTR==b.PTR;
} }
bool operator!=(const Self& b) const bool operator!=(const Self& b) const
{ {
@ -189,7 +189,7 @@ public:
// detach left son,redirect to dummy // detach left son,redirect to dummy
set_left(dummy); set_left(dummy);
// set left son pointer to 0 // set left son pointer to 0
ptr()->leftPtr.PTR.p=0; ptr()->leftPtr.PTR=0;
// delete dummy Td_dag // delete dummy Td_dag
delete dummy.ptr(); delete dummy.ptr();
} }
@ -204,7 +204,7 @@ public:
// detach right son,redirect to dummy // detach right son,redirect to dummy
set_right(dummy); set_right(dummy);
// set right son pointer to 0 // set right son pointer to 0
ptr()->rightPtr.PTR.p=0; ptr()->rightPtr.PTR=0;
// delete dummy Td_dag // delete dummy Td_dag
delete dummy.ptr(); delete dummy.ptr();
} }
@ -371,7 +371,7 @@ protected:
} }
#endif #endif
private: private:
node* ptr() const {return (node*)PTR.p;} node* ptr() const {return (node*)PTR;}
}; };
template<class T,class Traits> template<class T,class Traits>
@ -441,7 +441,7 @@ template<class T> std::ostream& operator<<(std::ostream& out,
tech notes: tech notes:
The code is Handle designed. The code is Handle designed.
left(),right() are designed to cope with Handle(Handle& x) left(),right() are designed to cope with Handle(Handle& x)
precondition x.PTR.p!=0 precondition x.PTR!=0
operator=() performs shallow copy operator=() performs shallow copy
operator*() returns data type operator*() returns data type
output is done as a binary tree. output is done as a binary tree.

View File

@ -39,7 +39,7 @@ template<class Traits>
class Td_dag_node_base : public Handle class Td_dag_node_base : public Handle
{ {
protected: protected:
void init() { PTR.p = 0; } //MICHAL: I think it is not used - so need to be removed void init() { PTR = 0; } //MICHAL: I think it is not used - so need to be removed
public: public:
//c'tors //c'tors
@ -57,12 +57,12 @@ public:
return *this; return *this;
} }
//bool operator!() const { return PTR.p == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar //bool operator!() const { return PTR == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar
bool is_null() const { return PTR.p == 0; } bool is_null() const { return PTR == 0; }
Rep * ptr() const { return (Rep*) PTR.p; } Rep * ptr() const { return (Rep*) PTR; }
protected: protected:
//Rep *& ptr() { return (Rep*) PTR.p; } //Rep *& ptr() { return (Rep*) PTR; }
void set_ptr(Rep* rep) { PTR.p = rep; } void set_ptr(Rep* rep) { PTR = rep; }
}; };
@ -94,7 +94,7 @@ public:
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
public: public:
//using Td_dag_node_handle::PTR.p; //using Td_dag_node_handle::PTR;
//using Td_dag_node_handle::operator!; //using Td_dag_node_handle::operator!;
#endif //CGAL_CFG_USING_BASE_MEMBER_BUG_2 #endif //CGAL_CFG_USING_BASE_MEMBER_BUG_2
@ -549,7 +549,7 @@ protected:
private: private:
Node* node() const { return (Node*)Base::PTR.p; } Node* node() const { return (Node*)Base::PTR; }
}; };
@ -629,7 +629,7 @@ std::ostream& operator<< (std::ostream& out,
tech notes: tech notes:
The code is Handle designed. The code is Handle designed.
left_child(),right_child() are designed to cope with Handle(Handle& x) left_child(),right_child() are designed to cope with Handle(Handle& x)
precondition x.PTR.p!=0 precondition x.PTR!=0
operator=() performs shallow copy operator=() performs shallow copy
operator*() returns data type operator*() returns data type
output is done as a binary tree. output is done as a binary tree.

View File

@ -128,7 +128,7 @@ public:
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
@ -161,7 +161,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */ /*! Constructor given Vertex & Halfedge handles. */
Td_inactive_edge (boost::shared_ptr<X_monotone_curve_2>& cv, Dag_node* node = nullptr) Td_inactive_edge (boost::shared_ptr<X_monotone_curve_2>& cv, Dag_node* node = nullptr)
{ {
PTR.p = new Data(cv,node); PTR = new Data(cv,node);
} }
/*! Copy constructor. */ /*! Copy constructor. */
@ -215,7 +215,7 @@ public:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const inline unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }
inline X_monotone_curve_2& curve() const inline X_monotone_curve_2& curve() const

View File

@ -133,7 +133,7 @@ public:
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const Curve_end vtx_to_ce(Vertex_const_handle v) const
{ {
@ -185,7 +185,7 @@ public:
{ {
Curve_end v_ce(vtx_to_ce(v_before_rem)); Curve_end v_ce(vtx_to_ce(v_before_rem));
PTR.p = new Data( v_ce.cv(), v_ce.ce(), node); PTR = new Data( v_ce.cv(), v_ce.ce(), node);
} }
@ -241,7 +241,7 @@ public:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const inline unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }

View File

@ -127,7 +127,7 @@ public:
private: private:
Data* ptr() const { return (Data*)(PTR.p); } Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
@ -162,7 +162,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */ /*! Constructor given Vertex & Halfedge handles. */
Td_inactive_vertex (Vertex_const_handle v_before_rem, Dag_node* node = nullptr) Td_inactive_vertex (Vertex_const_handle v_before_rem, Dag_node* node = nullptr)
{ {
PTR.p = new Data(v_before_rem->point(), node); PTR = new Data(v_before_rem->point(), node);
} }
@ -217,7 +217,7 @@ public:
/*! Access the trapezoid id (PTR). */ /*! Access the trapezoid id (PTR). */
inline unsigned long id() const inline unsigned long id() const
{ {
return (unsigned long) PTR.p; return (unsigned long) PTR;
} }
inline Point& point() const inline Point& point() const

View File

@ -197,8 +197,8 @@ namespace CGAL {
void * for_compact_container() const void * for_compact_container() const
{ return vp; } { return vp; }
void * & for_compact_container() void for_compact_container(void *p)
{ return vp; } { vp = p; }
private: private:
/// Reference counting: the number of darts linked to this cell. /// Reference counting: the number of darts linked to this cell.
@ -310,8 +310,8 @@ namespace CGAL {
void * for_compact_container() const void * for_compact_container() const
{ return mdart.for_compact_container(); } { return mdart.for_compact_container(); }
void * & for_compact_container() void for_compact_container(void *p)
{ return mdart.for_compact_container(); } { mdart.for_compact_container(p); }
private: private:
/// The dart handle associated with the cell. /// The dart handle associated with the cell.

View File

@ -105,8 +105,8 @@ namespace CGAL {
void * for_compact_container() const void * for_compact_container() const
{ return mf[0].for_compact_container(); } { return mf[0].for_compact_container(); }
void * & for_compact_container() void for_compact_container(void *p)
{ return mf[0].for_compact_container(); } { mf[0].for_compact_container(p); }
Dart_handle get_f(unsigned int i) const Dart_handle get_f(unsigned int i) const
{ {

View File

@ -39,7 +39,7 @@ class Tee_for_output_iterator
public: public:
Tee_for_output_iterator(const OutputIterator& o) : o_it(o) Tee_for_output_iterator(const OutputIterator& o) : o_it(o)
{ PTR.p = (Rep*) new _Tee_for_output_iterator_rep<T>(); } { PTR = (Rep*) new _Tee_for_output_iterator_rep<T>(); }
Tee_for_output_iterator<OutputIterator,T>& Tee_for_output_iterator<OutputIterator,T>&
operator=(const T& value) operator=(const T& value)
@ -82,7 +82,7 @@ public:
_Tee_for_output_iterator_rep<T>* _Tee_for_output_iterator_rep<T>*
ptr() ptr()
{ return (_Tee_for_output_iterator_rep<T>*)(PTR.p); } { return (_Tee_for_output_iterator_rep<T>*)PTR; }
protected: protected:
OutputIterator o_it; OutputIterator o_it;

View File

@ -87,7 +87,7 @@ public:
void* pp; void* pp;
void* for_compact_container() const { return pp; } void* for_compact_container() const { return pp; }
void* & for_compact_container() { return pp; } void for_compact_container(void *p) { pp = p; }
#ifdef CGAL_USE_LEDA #ifdef CGAL_USE_LEDA
LEDA_MEMORY(RC_vertex_d) LEDA_MEMORY(RC_vertex_d)
@ -153,7 +153,7 @@ public:
void* pp; void* pp;
void* for_compact_container() const { return pp; } void* for_compact_container() const { return pp; }
void* & for_compact_container() { return pp; } void for_compact_container(void *p) { pp = p; }
#if 0 #if 0
struct Point_const_iterator { struct Point_const_iterator {

View File

@ -718,17 +718,17 @@ public :
Lazy(Self_rep *r) Lazy(Self_rep *r)
{ {
PTR.p = r; PTR = r;
} }
Lazy(const ET& e) Lazy(const ET& e)
{ {
PTR.p = new Lazy_rep_0<AT,ET,E2A>(e); PTR = new Lazy_rep_0<AT,ET,E2A>(e);
} }
Lazy(ET&& e) Lazy(ET&& e)
{ {
PTR.p = new Lazy_rep_0<AT,ET,E2A>(std::move(e)); PTR = new Lazy_rep_0<AT,ET,E2A>(std::move(e));
} }
friend void swap(Lazy& a, Lazy& b) noexcept friend void swap(Lazy& a, Lazy& b) noexcept
@ -768,7 +768,7 @@ public :
return z; return z;
} }
Self_rep * ptr() const { return (Self_rep*) PTR.p; } Self_rep * ptr() const { return (Self_rep*) PTR; }
}; };
// The magic functor for Construct_bbox_[2,3], as there is no Lazy<Bbox> // The magic functor for Construct_bbox_[2,3], as there is no Lazy<Bbox>

View File

@ -115,7 +115,7 @@ class Interval_for_container : public Interval_
{} {}
void * for_compact_container() const { return p; } void * for_compact_container() const { return p; }
void * & for_compact_container() { return p; } void for_compact_container(void *ptr) { p = ptr; }
}; };
@ -457,7 +457,7 @@ class Interval_for_container : public Interval_
public: public:
#ifdef CGAL_ISL_USE_CCC #ifdef CGAL_ISL_USE_CCC
void * for_compact_container() const { return p; } void * for_compact_container() const { return p; }
void * & for_compact_container() { return p; } void for_compact_container(void *ptr) { p = ptr; }
#endif #endif
bool operator==(const IntervalListElt& e) bool operator==(const IntervalListElt& e)

View File

@ -491,7 +491,7 @@ public:
// For use by Compact_container. // For use by Compact_container.
void * for_compact_container() const { return N[0].for_compact_container(); } void * for_compact_container() const { return N[0].for_compact_container(); }
void * & for_compact_container() { return N[0].for_compact_container(); } void for_compact_container(void *p) { N[0].for_compact_container(p); }
// TDS internal data access functions. // TDS internal data access functions.
TDS_data& tds_data() { return _tds_data; } TDS_data& tds_data() { return _tds_data; }

View File

@ -233,7 +233,7 @@ public:
// For use by Compact_container. // For use by Compact_container.
void * for_compact_container() const { return N[0].for_compact_container(); } void * for_compact_container() const { return N[0].for_compact_container(); }
void * & for_compact_container() { return N[0].for_compact_container(); } void for_compact_container(void *p) { N[0].for_compact_container(p); }
// TDS internal data access functions. // TDS internal data access functions.
TDS_data& tds_data() { return _tds_data; } TDS_data& tds_data() { return _tds_data; }

View File

@ -80,8 +80,8 @@ public:
// For use by the Compact_container. // For use by the Compact_container.
void * for_compact_container() const void * for_compact_container() const
{ return _c.for_compact_container(); } { return _c.for_compact_container(); }
void * & for_compact_container() void for_compact_container(void *p)
{ return _c.for_compact_container(); } { _c.for_compact_container(p); }
private: private:
Cell_handle _c; Cell_handle _c;

View File

@ -26,7 +26,7 @@ struct Truc
{ {
Truc(int v = 0) : value(v), /*value2(v), */p(NULL) {} Truc(int v = 0) : value(v), /*value2(v), */p(NULL) {}
void * for_compact_container() const { return p; } void * for_compact_container() const { return p; }
void * & for_compact_container() { return p; } void for_compact_container(void *ptr) { p = ptr; }
int value; int value;
int value2; int value2;

View File

@ -30,10 +30,9 @@ Returns the pointer necessary for `Compact_container_traits<T>`.
void * for_compact_container() const; void * for_compact_container() const;
/*! /*!
Returns a reference to the pointer necessary for Sets the pointer necessary for `Compact_container_traits<T>` to `p`.
`Compact_container_traits<T>`.
*/ */
void * & for_compact_container(); void for_compact_container(void* p);
/// @} /// @}
@ -796,7 +795,7 @@ types `T` to make them usable with the default `Compact_container_traits`.
`void * t.for_compact_container() const;` `void * t.for_compact_container() const;`
`void *& t.for_compact_container();`. `void t.for_compact_container(void *);`.
*/ */
@ -820,11 +819,11 @@ static void * pointer(const T &t);
/// \name Operations /// \name Operations
/// @{ /// @{
/*! /*!
Returns a reference to the pointer held by `t`. Sets the pointer held by `t` to `p`.
The template version defines this function as: `return t.for_compact_container();` The template version defines this function as: `t.for_compact_container(p);`
*/ */
static void * & pointer(T &t); static void set_pointer(T &t, void* p);

View File

@ -22,7 +22,7 @@ types `T` to make them usable with the default `Concurrent_compact_container`.
`T` is any type providing the following member functions: `T` is any type providing the following member functions:
`void * t.for_compact_container() const;` `void * t.for_compact_container() const;`
`void *& t.for_compact_container();`. `void t.for_compact_container(void *);`.
*/ */
template< typename T > template< typename T >
struct Concurrent_compact_container_traits { struct Concurrent_compact_container_traits {
@ -40,11 +40,11 @@ struct Concurrent_compact_container_traits {
/// \name Operations /// \name Operations
/// @{ /// @{
/*! /*!
Returns a reference to the pointer held by `t`. Sets the pointer held by `t` to `p`.
The template version defines this function as: `return t.for_compact_container();` The template version defines this function as: `t.for_compact_container(p);`
*/ */
static void * & pointer(T &t); static void set_pointer(T &t, void* p);
/// @} /// @}

View File

@ -25,6 +25,7 @@
#include <vector> #include <vector>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <atomic>
#include <CGAL/memory.h> #include <CGAL/memory.h>
#include <CGAL/iterator.h> #include <CGAL/iterator.h>
@ -148,7 +149,7 @@ public:
Compact_container_base() Compact_container_base()
: p(nullptr) {} : p(nullptr) {}
void * for_compact_container() const { return p; } void * for_compact_container() const { return p; }
void * & for_compact_container() { return p; } void for_compact_container(void* ptr) { p = ptr; }
}; };
// The traits class describes the way to access the pointer. // The traits class describes the way to access the pointer.
@ -156,7 +157,7 @@ public:
template < class T > template < class T >
struct Compact_container_traits { struct Compact_container_traits {
static void * pointer(const T &t) { return t.for_compact_container(); } static void * pointer(const T &t) { return t.for_compact_container(); }
static void * & pointer(T &t) { return t.for_compact_container(); } static void set_pointer(T &t, void* p) { t.for_compact_container(p); }
}; };
namespace internal { namespace internal {
@ -223,7 +224,8 @@ class Compact_container
public: public:
typedef typename Default::Get< TimeStamper_, typedef typename Default::Get< TimeStamper_,
CGAL::Time_stamper_impl<T> >::type CGAL::Time_stamper_impl<T> >::type
Time_stamper_impl; Time_stamper;
typedef Time_stamper Time_stamper_impl; // backward-compatibility
typedef T value_type; typedef T value_type;
typedef Allocator allocator_type; typedef Allocator allocator_type;
@ -250,16 +252,14 @@ public:
explicit Compact_container(const Allocator &a = Allocator()) explicit Compact_container(const Allocator &a = Allocator())
: alloc(a) : alloc(a)
, time_stamper(new Time_stamper_impl())
{ {
init (); init();
} }
template < class InputIterator > template < class InputIterator >
Compact_container(InputIterator first, InputIterator last, Compact_container(InputIterator first, InputIterator last,
const Allocator & a = Allocator()) const Allocator & a = Allocator())
: alloc(a) : alloc(a)
, time_stamper(new Time_stamper_impl())
{ {
init(); init();
std::copy(first, last, CGAL::inserter(*this)); std::copy(first, last, CGAL::inserter(*this));
@ -268,14 +268,19 @@ public:
// The copy constructor and assignment operator preserve the iterator order // The copy constructor and assignment operator preserve the iterator order
Compact_container(const Compact_container &c) Compact_container(const Compact_container &c)
: alloc(c.get_allocator()) : alloc(c.get_allocator())
, time_stamper(new Time_stamper_impl())
{ {
init(); init();
block_size = c.block_size; block_size = c.block_size;
*time_stamper = *c.time_stamper; time_stamp = c.time_stamp.load();
std::copy(c.begin(), c.end(), CGAL::inserter(*this)); std::copy(c.begin(), c.end(), CGAL::inserter(*this));
} }
Compact_container(Compact_container&& c) noexcept
: alloc(c.get_allocator())
{
c.swap(*this);
}
Compact_container & operator=(const Compact_container &c) Compact_container & operator=(const Compact_container &c)
{ {
if (&c != this) { if (&c != this) {
@ -285,10 +290,16 @@ public:
return *this; return *this;
} }
Compact_container & operator=(Compact_container&& c) noexcept
{
Self tmp(std::move(c));
tmp.swap(*this);
return *this;
}
~Compact_container() ~Compact_container()
{ {
clear(); clear();
delete time_stamper;
} }
bool is_used(const_iterator ptr) const bool is_used(const_iterator ptr) const
@ -328,17 +339,8 @@ public:
return all_items[block_number].first[index_in_block]; return all_items[block_number].first[index_in_block];
} }
void swap(Self &c) friend void swap(Compact_container& a, Compact_container b) {
{ a.swap(b);
std::swap(alloc, c.alloc);
std::swap(capacity_, c.capacity_);
std::swap(size_, c.size_);
std::swap(block_size, c.block_size);
std::swap(first_item, c.first_item);
std::swap(last_item, c.last_item);
std::swap(free_list, c.free_list);
all_items.swap(c.all_items);
std::swap(time_stamper, c.time_stamper);
} }
iterator begin() { return iterator(first_item, 0, 0); } iterator begin() { return iterator(first_item, 0, 0); }
@ -383,7 +385,7 @@ public:
new (ret) value_type(args...); new (ret) value_type(args...);
CGAL_assertion(type(ret) == USED); CGAL_assertion(type(ret) == USED);
++size_; ++size_;
time_stamper->set_time_stamp(ret); Time_stamper::set_time_stamp(ret, time_stamp);
return iterator(ret, 0); return iterator(ret, 0);
} }
@ -397,7 +399,7 @@ public:
std::allocator_traits<allocator_type>::construct(alloc, ret, t); std::allocator_traits<allocator_type>::construct(alloc, ret, t);
CGAL_assertion(type(ret) == USED); CGAL_assertion(type(ret) == USED);
++size_; ++size_;
time_stamper->set_time_stamp(ret); Time_stamper::set_time_stamp(ret, time_stamp);
return iterator(ret, 0); return iterator(ret, 0);
} }
@ -643,8 +645,8 @@ private:
// This out of range compare is always true and causes lots of // This out of range compare is always true and causes lots of
// unnecessary warnings. // unnecessary warnings.
// CGAL_precondition(0 <= t && t < 4); // CGAL_precondition(0 <= t && t < 4);
Traits::pointer(*ptr) = reinterpret_cast<void *> Traits::set_pointer(*ptr, reinterpret_cast<void *>
(reinterpret_cast<std::ptrdiff_t>(clean_pointer((char *) p)) + (int) t); (reinterpret_cast<std::ptrdiff_t>(clean_pointer((char *) p)) + (int) t));
} }
public: public:
@ -652,7 +654,21 @@ public:
static bool is_begin_or_end(const_pointer ptr) static bool is_begin_or_end(const_pointer ptr)
{ return type(ptr)==START_END; } { return type(ptr)==START_END; }
void swap(Self &c)
{
std::swap(alloc, c.alloc);
std::swap(capacity_, c.capacity_);
std::swap(size_, c.size_);
std::swap(block_size, c.block_size);
std::swap(first_item, c.first_item);
std::swap(last_item, c.last_item);
std::swap(free_list, c.free_list);
all_items.swap(c.all_items);
// non-atomic swap of time_stamp:
c.time_stamp = time_stamp.exchange(c.time_stamp.load());
}
private:
// We store a vector of pointers to all allocated blocks and their sizes. // We store a vector of pointers to all allocated blocks and their sizes.
// Knowing all pointers, we don't have to walk to the end of a block to reach // Knowing all pointers, we don't have to walk to the end of a block to reach
// the pointer to the next block. // the pointer to the next block.
@ -660,7 +676,9 @@ public:
// by walking through the block till its end. // by walking through the block till its end.
// This opens up the possibility for the compiler to optimize the clear() // This opens up the possibility for the compiler to optimize the clear()
// function considerably when has_trivial_destructor<T>. // function considerably when has_trivial_destructor<T>.
typedef std::vector<std::pair<pointer, size_type> > All_items; using All_items = std::vector<std::pair<pointer, size_type> >;
using time_stamp_t = std::atomic<std::size_t>;
void init() void init()
{ {
@ -671,21 +689,18 @@ public:
first_item = nullptr; first_item = nullptr;
last_item = nullptr; last_item = nullptr;
all_items = All_items(); all_items = All_items();
time_stamper->reset(); time_stamp = 0;
} }
allocator_type alloc; allocator_type alloc;
size_type capacity_; size_type capacity_ = 0;
size_type size_; size_type size_ = 0;
size_type block_size; size_type block_size = Increment_policy::first_block_size;
pointer free_list; pointer free_list = nullptr;
pointer first_item; pointer first_item = nullptr;
pointer last_item; pointer last_item = nullptr;
All_items all_items; All_items all_items = {};
time_stamp_t time_stamp = {};
// This is a pointer, so that the definition of Compact_container does
// not require a complete type `T`.
Time_stamper_impl* time_stamper;
}; };
template < class T, class Allocator, class Increment_policy, class TimeStamper > template < class T, class Allocator, class Increment_policy, class TimeStamper >
@ -759,7 +774,7 @@ void Compact_container<T, Allocator, Increment_policy, TimeStamper>::allocate_ne
for (size_type i = block_size; i >= 1; --i) for (size_type i = block_size; i >= 1; --i)
{ {
EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); EraseCounterStrategy::set_erase_counter(*(new_block + i), 0);
time_stamper->initialize_time_stamp(new_block + i); Time_stamper::initialize_time_stamp(new_block + i);
put_on_free_list(new_block + i); put_on_free_list(new_block + i);
} }
// We insert this new block at the end. // We insert this new block at the end.
@ -839,7 +854,6 @@ namespace internal {
template < class DSC, bool Const > template < class DSC, bool Const >
class CC_iterator class CC_iterator
{ {
typedef typename DSC::iterator iterator;
typedef CC_iterator<DSC, Const> Self; typedef CC_iterator<DSC, Const> Self;
public: public:
typedef DSC CC; typedef DSC CC;
@ -858,25 +872,30 @@ namespace internal {
: ts(0) : ts(0)
#endif #endif
{ {
m_ptr.p = nullptr; m_ptr = nullptr;
} }
// Either a harmless copy-ctor, // Converting constructor from mutable to constant iterator
// or a conversion from iterator to const_iterator. template <bool OtherConst>
CC_iterator (const iterator &it) CC_iterator(const CC_iterator<
typename std::enable_if<(!OtherConst && Const), DSC>::type,
OtherConst> &const_it)
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
: ts(Time_stamper_impl::time_stamp(it.operator->())) : ts(Time_stamper::time_stamp(const_it.operator->()))
#endif #endif
{ {
m_ptr.p = it.operator->(); m_ptr = const_it.operator->();
} }
// Same for assignment operator (otherwise MipsPro warns) // Assignment operator from mutable to constant iterator
CC_iterator & operator= (const iterator &it) template <bool OtherConst>
CC_iterator & operator= (const CC_iterator<
typename std::enable_if<(!OtherConst && Const), DSC>::type,
OtherConst> &const_it)
{ {
m_ptr.p = it.operator->(); m_ptr = const_it.operator->();
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
ts = Time_stamper_impl::time_stamp(it.operator->()); ts = Time_stamper::time_stamp(const_it.operator->());
#endif #endif
return *this; return *this;
} }
@ -888,19 +907,16 @@ namespace internal {
#endif #endif
{ {
//CGAL_assertion (n == nullptr); //CGAL_assertion (n == nullptr);
m_ptr.p = nullptr; m_ptr = nullptr;
} }
private: private:
typedef typename DSC::Time_stamper_impl Time_stamper_impl; typedef typename DSC::Time_stamper Time_stamper;
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
std::size_t ts; std::size_t ts;
#endif #endif
union { pointer m_ptr;
pointer p;
void *vp;
} m_ptr;
// Only Compact_container and Concurrent_compact_container should // Only Compact_container and Concurrent_compact_container should
// access these constructors. // access these constructors.
@ -916,16 +932,16 @@ namespace internal {
: ts(0) : ts(0)
#endif #endif
{ {
m_ptr.p = ptr; m_ptr = ptr;
if (m_ptr.p == nullptr) // empty container. if (m_ptr == nullptr) // empty container.
return; return;
++(m_ptr.p); // if not empty, p = start ++(m_ptr); // if not empty, p = start
if (DSC::type(m_ptr.p) == DSC::FREE) if (DSC::type(m_ptr) == DSC::FREE)
increment(); increment();
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
else else
ts = Time_stamper_impl::time_stamp(m_ptr.p); ts = Time_stamper::time_stamp(m_ptr);
#endif // CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #endif // CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
} }
@ -935,10 +951,10 @@ namespace internal {
: ts(0) : ts(0)
#endif #endif
{ {
m_ptr.p = ptr; m_ptr = ptr;
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
if(ptr != nullptr){ if(ptr != nullptr){
ts = Time_stamper_impl::time_stamp(m_ptr.p); ts = Time_stamper::time_stamp(m_ptr);
} }
#endif // end CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #endif // end CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
} }
@ -947,49 +963,49 @@ namespace internal {
void increment() void increment()
{ {
// It's either pointing to end(), or valid. // It's either pointing to end(), or valid.
CGAL_assertion_msg(m_ptr.p != nullptr, CGAL_assertion_msg(m_ptr != nullptr,
"Incrementing a singular iterator or an empty container iterator ?"); "Incrementing a singular iterator or an empty container iterator ?");
CGAL_assertion_msg(DSC::type(m_ptr.p) != DSC::START_END, CGAL_assertion_msg(DSC::type(m_ptr) != DSC::START_END,
"Incrementing end() ?"); "Incrementing end() ?");
// If it's not end(), then it's valid, we can do ++. // If it's not end(), then it's valid, we can do ++.
do { do {
++(m_ptr.p); ++(m_ptr);
if (DSC::type(m_ptr.p) == DSC::USED || if (DSC::type(m_ptr) == DSC::USED ||
DSC::type(m_ptr.p) == DSC::START_END) DSC::type(m_ptr) == DSC::START_END)
{ {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
ts = Time_stamper_impl::time_stamp(m_ptr.p); ts = Time_stamper::time_stamp(m_ptr);
#endif #endif
return; return;
} }
if (DSC::type(m_ptr.p) == DSC::BLOCK_BOUNDARY) if (DSC::type(m_ptr) == DSC::BLOCK_BOUNDARY)
m_ptr.p = DSC::clean_pointee(m_ptr.p); m_ptr = DSC::clean_pointee(m_ptr);
} while (true); } while (true);
} }
void decrement() void decrement()
{ {
// It's either pointing to end(), or valid. // It's either pointing to end(), or valid.
CGAL_assertion_msg(m_ptr.p != nullptr, CGAL_assertion_msg(m_ptr != nullptr,
"Decrementing a singular iterator or an empty container iterator ?"); "Decrementing a singular iterator or an empty container iterator ?");
CGAL_assertion_msg(DSC::type(m_ptr.p - 1) != DSC::START_END, CGAL_assertion_msg(DSC::type(m_ptr - 1) != DSC::START_END,
"Decrementing begin() ?"); "Decrementing begin() ?");
// If it's not begin(), then it's valid, we can do --. // If it's not begin(), then it's valid, we can do --.
do { do {
--m_ptr.p; --m_ptr;
if (DSC::type(m_ptr.p) == DSC::USED || if (DSC::type(m_ptr) == DSC::USED ||
DSC::type(m_ptr.p) == DSC::START_END) DSC::type(m_ptr) == DSC::START_END)
{ {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
ts = Time_stamper_impl::time_stamp(m_ptr.p); ts = Time_stamper::time_stamp(m_ptr);
#endif #endif
return; return;
} }
if (DSC::type(m_ptr.p) == DSC::BLOCK_BOUNDARY) if (DSC::type(m_ptr) == DSC::BLOCK_BOUNDARY)
m_ptr.p = DSC::clean_pointee(m_ptr.p); m_ptr = DSC::clean_pointee(m_ptr);
} while (true); } while (true);
} }
@ -997,9 +1013,9 @@ namespace internal {
Self & operator++() Self & operator++()
{ {
CGAL_assertion_msg(m_ptr.p != nullptr, CGAL_assertion_msg(m_ptr != nullptr,
"Incrementing a singular iterator or an empty container iterator ?"); "Incrementing a singular iterator or an empty container iterator ?");
/* CGAL_assertion_msg(DSC::type(m_ptr.p) == DSC::USED, /* CGAL_assertion_msg(DSC::type(m_ptr) == DSC::USED,
"Incrementing an invalid iterator."); */ "Incrementing an invalid iterator."); */
increment(); increment();
return *this; return *this;
@ -1007,10 +1023,10 @@ namespace internal {
Self & operator--() Self & operator--()
{ {
CGAL_assertion_msg(m_ptr.p != nullptr, CGAL_assertion_msg(m_ptr != nullptr,
"Decrementing a singular iterator or an empty container iterator ?"); "Decrementing a singular iterator or an empty container iterator ?");
/*CGAL_assertion_msg(DSC::type(m_ptr.p) == DSC::USED /*CGAL_assertion_msg(DSC::type(m_ptr) == DSC::USED
|| DSC::type(m_ptr.p) == DSC::START_END, || DSC::type(m_ptr) == DSC::START_END,
"Decrementing an invalid iterator.");*/ "Decrementing an invalid iterator.");*/
decrement(); decrement();
return *this; return *this;
@ -1022,13 +1038,13 @@ namespace internal {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
bool is_time_stamp_valid() const bool is_time_stamp_valid() const
{ {
return (ts == 0) || (ts == Time_stamper_impl::time_stamp(m_ptr.p)); return (ts == 0) || (ts == Time_stamper::time_stamp(m_ptr));
} }
#endif // CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #endif // CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
reference operator*() const { return *(m_ptr.p); } reference operator*() const { return *(m_ptr); }
pointer operator->() const { return (m_ptr.p); } pointer operator->() const { return (m_ptr); }
// For std::less... // For std::less...
bool operator<(const CC_iterator& other) const bool operator<(const CC_iterator& other) const
@ -1036,7 +1052,7 @@ namespace internal {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
assert( is_time_stamp_valid() ); assert( is_time_stamp_valid() );
#endif #endif
return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p); return Time_stamper::less(m_ptr, other.m_ptr);
} }
bool operator>(const CC_iterator& other) const bool operator>(const CC_iterator& other) const
@ -1044,7 +1060,7 @@ namespace internal {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
assert( is_time_stamp_valid() ); assert( is_time_stamp_valid() );
#endif #endif
return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p); return Time_stamper::less(other.m_ptr, m_ptr);
} }
bool operator<=(const CC_iterator& other) const bool operator<=(const CC_iterator& other) const
@ -1052,7 +1068,7 @@ namespace internal {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
assert( is_time_stamp_valid() ); assert( is_time_stamp_valid() );
#endif #endif
return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p) return Time_stamper::less(m_ptr, other.m_ptr)
|| (*this == other); || (*this == other);
} }
@ -1061,13 +1077,13 @@ namespace internal {
#ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP #ifdef CGAL_COMPACT_CONTAINER_DEBUG_TIME_STAMP
assert( is_time_stamp_valid() ); assert( is_time_stamp_valid() );
#endif #endif
return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p) return Time_stamper::less(other.m_ptr, m_ptr)
|| (*this == other); || (*this == other);
} }
// Can itself be used for bit-squatting. // Can itself be used for bit-squatting.
void * for_compact_container() const { return (m_ptr.vp); } void * for_compact_container() const { return m_ptr; }
void * & for_compact_container() { return (m_ptr.vp); } void for_compact_container(void* p) { m_ptr = static_cast<pointer>(p); }
}; };
template < class DSC, bool Const1, bool Const2 > template < class DSC, bool Const1, bool Const2 >

View File

@ -66,7 +66,7 @@ template<typename T> class has_##X { \
template < class T > template < class T >
struct Concurrent_compact_container_traits { struct Concurrent_compact_container_traits {
static void * pointer(const T &t) { return t.for_compact_container(); } static void * pointer(const T &t) { return t.for_compact_container(); }
static void * & pointer(T &t) { return t.for_compact_container(); } static void set_pointer(T &t, void* p) { t.for_compact_container(p); }
}; };
namespace CCC_internal { namespace CCC_internal {
@ -114,6 +114,8 @@ namespace CCC_internal {
// Free list (head and size) // Free list (head and size)
template< typename pointer, typename size_type, typename CCC > template< typename pointer, typename size_type, typename CCC >
class Free_list { class Free_list {
// Not that the implicitly-defined member functions copy the
// pointer, and not the pointed data.
public: public:
Free_list() : m_head(nullptr), m_size(0) { Free_list() : m_head(nullptr), m_size(0) {
#if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
@ -150,13 +152,6 @@ public:
#endif // CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #endif // CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
} }
bool empty() { return size() == 0; } bool empty() { return size() == 0; }
// Warning: copy the pointer, not the data!
Free_list& operator= (const Free_list& other)
{
m_head = other.m_head;
m_size = other.m_size;
return *this;
}
void merge(Free_list &other) void merge(Free_list &other)
{ {
@ -210,7 +205,8 @@ class Concurrent_compact_container
typedef Concurrent_compact_container_traits <T> Traits; typedef Concurrent_compact_container_traits <T> Traits;
public: public:
typedef CGAL::Time_stamper_impl<T> Time_stamper_impl; typedef CGAL::Time_stamper_impl<T> Time_stamper;
typedef Time_stamper Time_stamper_impl; // backward compatibility
typedef T value_type; typedef T value_type;
typedef Allocator allocator_type; typedef Allocator allocator_type;
@ -241,7 +237,6 @@ public:
explicit Concurrent_compact_container(const Allocator &a = Allocator()) explicit Concurrent_compact_container(const Allocator &a = Allocator())
: m_alloc(a) : m_alloc(a)
, m_time_stamper(new Time_stamper_impl())
{ {
init (); init ();
} }
@ -250,7 +245,6 @@ public:
Concurrent_compact_container(InputIterator first, InputIterator last, Concurrent_compact_container(InputIterator first, InputIterator last,
const Allocator & a = Allocator()) const Allocator & a = Allocator())
: m_alloc(a) : m_alloc(a)
, m_time_stamper(new Time_stamper_impl())
{ {
init(); init();
std::copy(first, last, CGAL::inserter(*this)); std::copy(first, last, CGAL::inserter(*this));
@ -259,13 +253,18 @@ public:
// The copy constructor and assignment operator preserve the iterator order // The copy constructor and assignment operator preserve the iterator order
Concurrent_compact_container(const Concurrent_compact_container &c) Concurrent_compact_container(const Concurrent_compact_container &c)
: m_alloc(c.get_allocator()) : m_alloc(c.get_allocator())
, m_time_stamper(new Time_stamper_impl())
{ {
init(); init();
m_block_size = c.m_block_size; m_block_size = c.m_block_size;
std::copy(c.begin(), c.end(), CGAL::inserter(*this)); std::copy(c.begin(), c.end(), CGAL::inserter(*this));
} }
Concurrent_compact_container(Concurrent_compact_container&& c) noexcept
: m_alloc(c.get_allocator())
{
c.swap(*this);
}
Concurrent_compact_container & operator=(const Concurrent_compact_container &c) Concurrent_compact_container & operator=(const Concurrent_compact_container &c)
{ {
if (&c != this) { if (&c != this) {
@ -275,10 +274,16 @@ public:
return *this; return *this;
} }
Concurrent_compact_container & operator=(Concurrent_compact_container&& c) noexcept
{
Self tmp(std::move(c));
tmp.swap(*this);
return *this;
}
~Concurrent_compact_container() ~Concurrent_compact_container()
{ {
clear(); clear();
delete m_time_stamper;
} }
bool is_used(const_iterator ptr) const bool is_used(const_iterator ptr) const
@ -290,11 +295,8 @@ public:
{ {
std::swap(m_alloc, c.m_alloc); std::swap(m_alloc, c.m_alloc);
#if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
{ // non-atomic swap // non-atomic swap of m_capacity
size_type other_capacity = c.m_capacity; c.m_capacity = m_capacity.exchange(c.m_capacity.load());
c.m_capacity = size_type(m_capacity);
m_capacity = other_capacity;
}
#else // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #else // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
std::swap(m_capacity, c.m_capacity); std::swap(m_capacity, c.m_capacity);
#endif // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #endif // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
@ -304,7 +306,12 @@ public:
std::swap(m_last_item, c.m_last_item); std::swap(m_last_item, c.m_last_item);
std::swap(m_free_lists, c.m_free_lists); std::swap(m_free_lists, c.m_free_lists);
m_all_items.swap(c.m_all_items); m_all_items.swap(c.m_all_items);
std::swap(m_time_stamper, c.m_time_stamper); // non-atomic swap of m_time_stamp
c.m_time_stamp = m_time_stamp.exchange(c.m_time_stamp.load());
}
friend void swap(Concurrent_compact_container& a, Concurrent_compact_container& b) {
a.swap(b);
} }
iterator begin() { return iterator(m_first_item, 0, 0); } iterator begin() { return iterator(m_first_item, 0, 0); }
@ -544,7 +551,7 @@ private:
{ {
CGAL_assertion(type(ret) == USED); CGAL_assertion(type(ret) == USED);
fl->dec_size(); fl->dec_size();
m_time_stamper->set_time_stamp(ret); Time_stamper::set_time_stamp(ret, m_time_stamp);
return iterator(ret, 0); return iterator(ret, 0);
} }
@ -606,8 +613,8 @@ private:
// This out of range compare is always true and causes lots of // This out of range compare is always true and causes lots of
// unnecessary warnings. // unnecessary warnings.
// CGAL_precondition(0 <= t && t < 4); // CGAL_precondition(0 <= t && t < 4);
Traits::pointer(*ptr) = reinterpret_cast<void *> Traits::set_pointer(*ptr, reinterpret_cast<void *>
(reinterpret_cast<std::ptrdiff_t>(clean_pointer((char *) p)) + (int) t); (reinterpret_cast<std::ptrdiff_t>(clean_pointer((char *) p)) + (int) t));
} }
typedef tbb::queuing_mutex Mutex; typedef tbb::queuing_mutex Mutex;
@ -619,8 +626,9 @@ private:
// by walking through the block till its end. // by walking through the block till its end.
// This opens up the possibility for the compiler to optimize the clear() // This opens up the possibility for the compiler to optimize the clear()
// function considerably when has_trivial_destructor<T>. // function considerably when has_trivial_destructor<T>.
typedef std::vector<std::pair<pointer, size_type> > All_items; using All_items = std::vector<std::pair<pointer, size_type> >;
using time_stamp_t = std::atomic<std::size_t>;
void init() void init()
{ {
@ -636,25 +644,23 @@ private:
m_first_item = nullptr; m_first_item = nullptr;
m_last_item = nullptr; m_last_item = nullptr;
m_all_items = All_items(); m_all_items = All_items();
m_time_stamper->reset(); m_time_stamp = 0;
} }
allocator_type m_alloc; allocator_type m_alloc;
#if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
std::atomic<size_type> m_capacity; std::atomic<size_type> m_capacity = {};
#else // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #else // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
size_type m_capacity; size_type m_capacity = {};
#endif // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE #endif // not CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE
size_type m_block_size; size_type m_block_size = CGAL_INIT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE;
Free_lists m_free_lists; Free_lists m_free_lists;
pointer m_first_item; pointer m_first_item = nullptr;
pointer m_last_item; pointer m_last_item = nullptr;
All_items m_all_items; All_items m_all_items = {};
mutable Mutex m_mutex; mutable Mutex m_mutex;
time_stamp_t m_time_stamp = {};
// This is a pointer, so that the definition of Compact_container does
// not require a complete type `T`.
Time_stamper_impl* m_time_stamper;
}; };
template < class T, class Allocator > template < class T, class Allocator >
@ -770,7 +776,7 @@ void Concurrent_compact_container<T, Allocator>::
for (size_type i = old_block_size; i >= 1; --i) for (size_type i = old_block_size; i >= 1; --i)
{ {
EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); EraseCounterStrategy::set_erase_counter(*(new_block + i), 0);
m_time_stamper->initialize_time_stamp(new_block + i); Time_stamper::initialize_time_stamp(new_block + i);
put_on_free_list(new_block + i, fl); put_on_free_list(new_block + i, fl);
} }
} }

View File

@ -40,31 +40,31 @@ class Handle
typedef std::ptrdiff_t Id_type ; typedef std::ptrdiff_t Id_type ;
Handle() noexcept Handle() noexcept
: PTR{static_cast<Rep*>(0)} {} : PTR(static_cast<Rep*>(0)) {}
// FIXME: if the precondition throws in a noexcept function, the program terminates // FIXME: if the precondition throws in a noexcept function, the program terminates
Handle(const Handle& x) noexcept Handle(const Handle& x) noexcept
{ {
CGAL_precondition( x.PTR.p != static_cast<Rep*>(0) ); CGAL_precondition( x.PTR != static_cast<Rep*>(0) );
PTR.p = x.PTR.p; PTR = x.PTR;
CGAL_assume (PTR.p->count > 0); CGAL_assume (PTR->count > 0);
PTR.p->count++; PTR->count++;
} }
~Handle() ~Handle()
{ {
if ( PTR.p && (--PTR.p->count == 0)) if ( PTR && (--PTR->count == 0))
delete PTR.p; delete PTR;
} }
Handle& Handle&
operator=(const Handle& x) noexcept operator=(const Handle& x) noexcept
{ {
CGAL_precondition( x.PTR.p != static_cast<Rep*>(0) ); CGAL_precondition( x.PTR != static_cast<Rep*>(0) );
x.PTR.p->count++; x.PTR->count++;
if ( PTR.p && (--PTR.p->count == 0)) if ( PTR && (--PTR->count == 0))
delete PTR.p; delete PTR;
PTR.p = x.PTR.p; PTR = x.PTR;
return *this; return *this;
} }
@ -72,29 +72,25 @@ class Handle
void reset() void reset()
{ {
if (PTR.p) if (PTR)
{ {
if (--PTR.p->count==0) if (--PTR->count==0)
delete PTR.p; delete PTR;
PTR.p=0; PTR=0;
} }
} }
int refs() const noexcept { return PTR.p->count; } int
refs() const noexcept { return PTR->count; }
Id_type id() const noexcept { return PTR.p - static_cast<Rep*>(0); } Id_type id() const noexcept { return PTR - static_cast<Rep*>(0); }
bool identical(const Handle& h) const noexcept { return PTR.p == h.PTR.p; } bool identical(const Handle& h) const noexcept { return PTR == h.PTR; }
void* for_compact_container() const { return PTR.vp; }
void*& for_compact_container() { return PTR.vp; }
void * for_compact_container() const { return PTR; }
void for_compact_container(void* p) { PTR = static_cast<Rep*>(p); }
protected: protected:
Rep* PTR;
union {
Rep* p;
void* vp;
} PTR;
}; };
//inline Handle::Id_type id(const Handle& x) { return x.id() ; } //inline Handle::Id_type id(const Handle& x) { return x.id() ; }

View File

@ -28,26 +28,12 @@ constexpr size_t rounded_down_log2(size_t n)
template <typename T> template <typename T>
struct Time_stamper struct Time_stamper
{ {
Time_stamper()
: time_stamp_() {}
Time_stamper(const Time_stamper& ts)
: time_stamp_()
{
time_stamp_ = std::size_t(ts.time_stamp_);
}
Time_stamper& operator=(const Time_stamper& ts)
{
time_stamp_ = std::size_t(ts.time_stamp_);
return *this;
}
static void initialize_time_stamp(T* pt) { static void initialize_time_stamp(T* pt) {
pt->set_time_stamp(std::size_t(-1)); pt->set_time_stamp(std::size_t(-1));
} }
void set_time_stamp(T* pt) { template <typename time_stamp_t>
static void set_time_stamp(T* pt, time_stamp_t& time_stamp_) {
if(pt->time_stamp() == std::size_t(-1)) { if(pt->time_stamp() == std::size_t(-1)) {
const std::size_t new_ts = time_stamp_++; const std::size_t new_ts = time_stamp_++;
pt->set_time_stamp(new_ts); pt->set_time_stamp(new_ts);
@ -96,23 +82,14 @@ struct Time_stamper
return time_stamp(p_t1) < time_stamp(p_t2); return time_stamp(p_t1) < time_stamp(p_t2);
} }
} }
void reset() {
time_stamp_ = 0;
}
private:
#ifdef CGAL_NO_ATOMIC
std::size_t time_stamp_;
#else
CGAL::cpp11::atomic<std::size_t> time_stamp_;
#endif
}; // end class template Time_stamper<T> }; // end class template Time_stamper<T>
template <typename T> template <typename T>
struct No_time_stamp struct No_time_stamp
{ {
public: public:
void set_time_stamp(T*) {} template <typename time_stamp_t>
static void set_time_stamp(T*, time_stamp_t&) {}
static bool less(const T* p_t1,const T* p_t2) { static bool less(const T* p_t1,const T* p_t2) {
return p_t1 < p_t2; return p_t1 < p_t2;
} }
@ -130,8 +107,6 @@ public:
constexpr std::size_t shift = internal::rounded_down_log2(sizeof(T)); constexpr std::size_t shift = internal::rounded_down_log2(sizeof(T));
return reinterpret_cast<std::size_t>(p) >> shift; return reinterpret_cast<std::size_t>(p) >> shift;
} }
void reset() {}
}; // end class template No_time_stamp<T> }; // end class template No_time_stamp<T>
// That class template is an auxiliary class. It has a // That class template is an auxiliary class. It has a

View File

@ -4,6 +4,7 @@
#include <cstddef> #include <cstddef>
#include <list> #include <list>
#include <vector> #include <vector>
#include <type_traits>
#include <CGAL/Compact_container.h> #include <CGAL/Compact_container.h>
#include <CGAL/Random.h> #include <CGAL/Random.h>
@ -71,7 +72,7 @@ public:
bool operator< (const Node_2 &n) const { return rnd < n.rnd; } bool operator< (const Node_2 &n) const { return rnd < n.rnd; }
void * for_compact_container() const { return p_cc; } void * for_compact_container() const { return p_cc; }
void * & for_compact_container() { return p_cc; } void for_compact_container(void *p) { p_cc = p; }
}; };
template < class Cont > template < class Cont >
@ -83,6 +84,11 @@ inline bool check_empty(const Cont &c)
template < class Cont > template < class Cont >
void test(const Cont &) void test(const Cont &)
{ {
static_assert(std::is_nothrow_move_constructible<Cont>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Cont>::value,
"move assignment is missing");
// Testing if all types are provided. // Testing if all types are provided.
typename Cont::value_type t0; typename Cont::value_type t0;
@ -319,22 +325,22 @@ int main()
// Check the time stamper policies // Check the time stamper policies
if(! boost::is_base_of<CGAL::Time_stamper<T1>, if(! boost::is_base_of<CGAL::Time_stamper<T1>,
C1::Time_stamper_impl>::value) C1::Time_stamper>::value)
{ {
std::cerr << "Error timestamper of C1\n"; return 1; std::cerr << "Error timestamper of C1\n"; return 1;
} }
if(! boost::is_base_of<CGAL::No_time_stamp<T2>, if(! boost::is_base_of<CGAL::No_time_stamp<T2>,
C2::Time_stamper_impl>::value) C2::Time_stamper>::value)
{ {
std::cerr << "Error timestamper of C2\n"; return 1; std::cerr << "Error timestamper of C2\n"; return 1;
} }
if(! boost::is_base_of<CGAL::No_time_stamp<T3>, if(! boost::is_base_of<CGAL::No_time_stamp<T3>,
C3::Time_stamper_impl>::value) C3::Time_stamper>::value)
{ {
std::cerr << "Error timestamper of C3\n"; return 1; std::cerr << "Error timestamper of C3\n"; return 1;
} }
if(! boost::is_base_of<CGAL::Time_stamper<T2>, if(! boost::is_base_of<CGAL::Time_stamper<T2>,
C4::Time_stamper_impl>::value) C4::Time_stamper>::value)
{ {
std::cerr << "Error timestamper of C4\n"; return 1; std::cerr << "Error timestamper of C4\n"; return 1;
} }

View File

@ -15,7 +15,7 @@ public:
{} {}
void * for_compact_container() const { return p_cc; } void * for_compact_container() const { return p_cc; }
void * & for_compact_container() { return p_cc; } void for_compact_container(void *p) { p_cc = p; }
}; };
int main() int main()

View File

@ -33,7 +33,6 @@ struct Node_1
: public CGAL::Compact_container_base : public CGAL::Compact_container_base
{ {
Node_1() {} Node_1() {}
Node_1(const Node_1& o) : time_stamp_(o.time_stamp_) {}
bool operator==(const Node_1 &) const { return true; } bool operator==(const Node_1 &) const { return true; }
bool operator!=(const Node_1 &) const { return false; } bool operator!=(const Node_1 &) const { return false; }
bool operator< (const Node_1 &) const { return false; } bool operator< (const Node_1 &) const { return false; }
@ -61,14 +60,14 @@ public:
int rnd; int rnd;
Node_2() Node_2()
: p(NULL), rnd(CGAL::get_default_random().get_int(0, 100)) {} : p(nullptr), rnd(CGAL::get_default_random().get_int(0, 100)) {}
bool operator==(const Node_2 &n) const { return rnd == n.rnd; } bool operator==(const Node_2 &n) const { return rnd == n.rnd; }
bool operator!=(const Node_2 &n) const { return rnd != n.rnd; } bool operator!=(const Node_2 &n) const { return rnd != n.rnd; }
bool operator< (const Node_2 &n) const { return rnd < n.rnd; } bool operator< (const Node_2 &n) const { return rnd < n.rnd; }
void * for_compact_container() const { return p_cc; } void * for_compact_container() const { return p_cc; }
void * & for_compact_container() { return p_cc; } void for_compact_container(void *p) { p_cc = p; }
}; };
template < class Cont > template < class Cont >
@ -89,11 +88,6 @@ public:
: m_values(values), m_cont(cont), m_iterators(iterators) : m_values(values), m_cont(cont), m_iterators(iterators)
{} {}
Insert_in_CCC_functor(const Insert_in_CCC_functor &other)
: m_values(other.m_values), m_cont(other.m_cont),
m_iterators(other.m_iterators)
{}
void operator() (const tbb::blocked_range<size_t>& r) const void operator() (const tbb::blocked_range<size_t>& r) const
{ {
for( size_t i = r.begin() ; i != r.end() ; ++i) for( size_t i = r.begin() ; i != r.end() ; ++i)
@ -118,11 +112,6 @@ public:
: m_cont(cont), m_iterators(iterators) : m_cont(cont), m_iterators(iterators)
{} {}
Erase_in_CCC_functor(const Erase_in_CCC_functor &other)
: m_cont(other.m_cont),
m_iterators(other.m_iterators)
{}
void operator() (const tbb::blocked_range<size_t>& r) const void operator() (const tbb::blocked_range<size_t>& r) const
{ {
for( size_t i = r.begin() ; i != r.end() ; ++i) for( size_t i = r.begin() ; i != r.end() ; ++i)
@ -149,19 +138,13 @@ public:
m_free_elements(free_elements), m_num_erasures(num_erasures) m_free_elements(free_elements), m_num_erasures(num_erasures)
{} {}
Insert_and_erase_in_CCC_functor(const Insert_and_erase_in_CCC_functor &other)
: m_values(other.m_values), m_cont(other.m_cont),
m_iterators(other.m_iterators), m_free_elements(other.m_free_elements),
m_num_erasures(other.m_num_erasures)
{}
void operator() (const tbb::blocked_range<size_t>& r) const void operator() (const tbb::blocked_range<size_t>& r) const
{ {
for( size_t i = r.begin() ; i != r.end() ; ++i) for( size_t i = r.begin() ; i != r.end() ; ++i)
{ {
m_iterators[i] = m_cont.insert(m_values[i]); m_iterators[i] = m_cont.insert(m_values[i]);
// Random-pick an element to erase // Random-pick an element to erase
int index_to_erase = rand() % m_values.size(); auto index_to_erase = rand() % m_values.size();
// If it exists // If it exists
bool comparand = false; bool comparand = false;
if (m_free_elements[index_to_erase].compare_exchange_weak(comparand, true) ) if (m_free_elements[index_to_erase].compare_exchange_weak(comparand, true) )
@ -183,6 +166,10 @@ private:
template < class Cont > template < class Cont >
void test(const Cont &) void test(const Cont &)
{ {
static_assert(std::is_nothrow_move_constructible<Cont>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Cont>::value,
"move assignment is missing");
// Testing if all types are provided. // Testing if all types are provided.
typename Cont::value_type t0; typename Cont::value_type t0;

View File

@ -111,7 +111,7 @@ void spatial_sort (RandomAccessIterator begin, RandomAccessIterator end,
typedef std::iterator_traits<RandomAccessIterator> ITraits; typedef std::iterator_traits<RandomAccessIterator> ITraits;
typedef typename ITraits::value_type value_type; typedef typename ITraits::value_type value_type;
internal::spatial_sort<ConcurrencyTag>(begin, end, k, policy, static_cast<value_type *> (0), internal::spatial_sort<ConcurrencyTag>(begin, end, k, policy, static_cast<value_type *> (nullptr),
threshold_hilbert,threshold_multiscale,ratio); threshold_hilbert,threshold_multiscale,ratio);
} }

View File

@ -183,7 +183,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void *p);
/// @} /// @}

View File

@ -118,7 +118,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void* p);
/// @} /// @}

View File

@ -105,8 +105,13 @@ protected:
public: public:
Triangulation_data_structure_2(); Triangulation_data_structure_2();
Triangulation_data_structure_2(const Tds &tds); Triangulation_data_structure_2(const Tds &tds);
Triangulation_data_structure_2(Triangulation_data_structure_2&& tds)
noexcept(noexcept(Face_range(std::move(tds._faces))) &&
noexcept(Vertex_range(std::move(tds._vertices))));
~Triangulation_data_structure_2(); ~Triangulation_data_structure_2();
Tds& operator= (const Tds &tds); Tds& operator= (const Tds &tds);
Tds& operator= (Tds&& tds) noexcept(noexcept(Tds(std::move(tds))));
void swap(Tds &tds); void swap(Tds &tds);
//ACCESS FUNCTIONS //ACCESS FUNCTIONS
@ -642,9 +647,6 @@ public:
Triangulation_default_data_structure_2(const Geom_traits& = Geom_traits()) Triangulation_default_data_structure_2(const Geom_traits& = Geom_traits())
: Tds() {} : Tds() {}
Triangulation_default_data_structure_2(const Tdds &tdds)
: Tds(tdds) {}
}; };
//for backward compatibility //for backward compatibility
@ -657,8 +659,6 @@ public:
typedef Triangulation_data_structure_using_list_2<Vb,Fb> Tdsul; typedef Triangulation_data_structure_using_list_2<Vb,Fb> Tdsul;
Triangulation_data_structure_using_list_2(): Tds() {} Triangulation_data_structure_using_list_2(): Tds() {}
Triangulation_data_structure_using_list_2(const Tdsul &tdsul)
: Tds(tdsul) {}
}; };
@ -675,6 +675,17 @@ Triangulation_data_structure_2(const Tds &tds)
copy_tds(tds); copy_tds(tds);
} }
template < class Vb, class Fb>
Triangulation_data_structure_2<Vb,Fb> ::
Triangulation_data_structure_2(Tds &&tds)
noexcept(noexcept(Face_range(std::move(tds._faces))) &&
noexcept(Vertex_range(std::move(tds._vertices))))
: _dimension(std::exchange(tds._dimension, -2))
, _faces(std::move(tds._faces))
, _vertices(std::move(tds._vertices))
{
}
template < class Vb, class Fb> template < class Vb, class Fb>
Triangulation_data_structure_2<Vb,Fb> :: Triangulation_data_structure_2<Vb,Fb> ::
~Triangulation_data_structure_2() ~Triangulation_data_structure_2()
@ -682,7 +693,7 @@ Triangulation_data_structure_2<Vb,Fb> ::
clear(); clear();
} }
//assignement //copy-assignment
template < class Vb, class Fb> template < class Vb, class Fb>
Triangulation_data_structure_2<Vb,Fb>& Triangulation_data_structure_2<Vb,Fb>&
Triangulation_data_structure_2<Vb,Fb> :: Triangulation_data_structure_2<Vb,Fb> ::
@ -692,6 +703,18 @@ operator= (const Tds &tds)
return *this; return *this;
} }
//move-assignment
template < class Vb, class Fb>
Triangulation_data_structure_2<Vb,Fb>&
Triangulation_data_structure_2<Vb,Fb> ::
operator= (Tds &&tds) noexcept(noexcept(Tds(std::move(tds))))
{
_faces = std::move(tds._faces);
_vertices = std::move(tds._vertices);
_dimension = std::exchange(tds._dimension, -2);
return *this;
}
template < class Vb, class Fb> template < class Vb, class Fb>
void void
Triangulation_data_structure_2<Vb,Fb>:: Triangulation_data_structure_2<Vb,Fb>::
@ -799,7 +822,7 @@ is_edge(Vertex_handle va, Vertex_handle vb,
{ {
Face_handle fc = va->face(); Face_handle fc = va->face();
Face_handle start = fc; Face_handle start = fc;
if (fc == 0) return false; if (fc == nullptr) return false;
int inda, indb; int inda, indb;
do { do {
inda=fc->index(va); inda=fc->index(va);

View File

@ -79,7 +79,7 @@ public:
// For use by Compact_container. // For use by Compact_container.
void * for_compact_container() const {return N[0].for_compact_container(); } void * for_compact_container() const {return N[0].for_compact_container(); }
void * & for_compact_container() { return N[0].for_compact_container();} void for_compact_container(void* p) { N[0].for_compact_container(p);}
static int ccw(int i) {return Triangulation_cw_ccw_2::ccw(i);} static int ccw(int i) {return Triangulation_cw_ccw_2::ccw(i);}

View File

@ -49,7 +49,7 @@ public:
// For use by the Compact_container. // For use by the Compact_container.
void * for_compact_container() const { return _f.for_compact_container(); } void * for_compact_container() const { return _f.for_compact_container(); }
void * & for_compact_container() { return _f.for_compact_container(); } void for_compact_container(void* p) { _f.for_compact_container(p); }
private: private:
Face_handle _f; Face_handle _f;

View File

@ -44,6 +44,11 @@ template <class Tds>
void void
_test_cls_tds_2( const Tds &) _test_cls_tds_2( const Tds &)
{ {
static_assert(std::is_nothrow_move_constructible<Tds>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Tds>::value,
"move assignment is missing");
typedef typename Tds::Vertex_range Vertex_range; typedef typename Tds::Vertex_range Vertex_range;
typedef typename Tds::Face_range Face_range; typedef typename Tds::Face_range Face_range;
@ -129,6 +134,34 @@ _test_cls_tds_2( const Tds &)
assert(tds3.number_of_vertices() == 4); assert(tds3.number_of_vertices() == 4);
assert(tds3.is_valid() ); assert(tds3.is_valid() );
// Test move-constructors and move-assignments
{
Tds tds7 = tds3;
Tds tds8{std::move(tds7)};
Tds tds9 = tds3;
Tds tds10;
tds10 = std::move(tds9);
Tds tds11 = Tds(tds3); // construct from a temporary
Tds tds12 = std::move(tds11);
assert(tds7.is_valid());
assert(tds8.is_valid());
assert(tds9.is_valid());
assert(tds10.is_valid());
assert(tds11.is_valid());
assert(tds12.is_valid());
assert(tds7.dimension()==-2);
assert(tds8.dimension()==1);
assert(tds9.dimension()==-2);
assert(tds10.dimension()==1);
assert(tds11.dimension()==-2);
assert(tds12.dimension()==1);
tds11.~Tds();
// check tds12 is still valid after the destruction of tds11
assert(tds12.is_valid());
assert(tds12.dimension()==1);
}
Vertex_handle w4 = tds4.insert_first(); Vertex_handle w4 = tds4.insert_first();
Vertex_handle v4_1 = tds4.insert_second(); Vertex_handle v4_1 = tds4.insert_second();
Vertex_handle v4_2 = tds4.insert_dim_up(w4,true); Vertex_handle v4_2 = tds4.insert_dim_up(w4,true);

View File

@ -136,7 +136,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void *p);
/// @} /// @}

View File

@ -116,7 +116,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void *);
/*! /*!
Inputs the non-combinatorial information given by the vertex. Inputs the non-combinatorial information given by the vertex.

View File

@ -231,6 +231,15 @@ public:
copy_tds(tds); copy_tds(tds);
} }
Triangulation_data_structure_3(Tds && tds)
noexcept(noexcept(Cell_range(std::move(tds._cells))) &&
noexcept(Vertex_range(std::move(tds._vertices))))
: _dimension(std::exchange(tds._dimension, -2))
, _cells(std::move(tds._cells))
, _vertices(std::move(tds._vertices))
{
}
Tds & operator= (const Tds & tds) Tds & operator= (const Tds & tds)
{ {
if (&tds != this) { if (&tds != this) {
@ -240,6 +249,17 @@ public:
return *this; return *this;
} }
Tds & operator= (Tds && tds)
noexcept(noexcept(Tds(std::move(tds))))
{
_cells = std::move(tds._cells);
_vertices = std::move(tds._vertices);
_dimension = std::exchange(tds._dimension, -2);
return *this;
}
~Triangulation_data_structure_3() = default; // for the rule-of-five
size_type number_of_vertices() const { return vertices().size(); } size_type number_of_vertices() const { return vertices().size(); }
int dimension() const {return _dimension;} int dimension() const {return _dimension;}
@ -917,12 +937,6 @@ public:
*output++ = e; *output++ = e;
return *this; return *this;
} }
Facet_it& operator=(const Facet_it& f) {
output = f.output;
filter = f.filter;
return *this;
}
Facet_it(const Facet_it&)=default;
}; };
Facet_it facet_it() { Facet_it facet_it() {
return Facet_it(output, filter); return Facet_it(output, filter);
@ -1047,6 +1061,15 @@ public:
} }
} }
// Implement the rule-of-five, to please the diagnostic
// `cppcoreguidelines-special-member-functions` of clang-tidy.
// Instead of defaulting those special member functions, let's
// delete them, to prevent any misuse.
Vertex_extractor(const Vertex_extractor&) = delete;
Vertex_extractor(Vertex_extractor&&) = delete;
Vertex_extractor& operator=(const Vertex_extractor&) = delete;
Vertex_extractor& operator=(Vertex_extractor&&) = delete;
~Vertex_extractor() ~Vertex_extractor()
{ {
for(std::size_t i=0; i < tmp_vertices.size(); ++i){ for(std::size_t i=0; i < tmp_vertices.size(); ++i){

View File

@ -180,7 +180,7 @@ public:
// For use by Compact_container. // For use by Compact_container.
void * for_compact_container() const { return N[0].for_compact_container(); } void * for_compact_container() const { return N[0].for_compact_container(); }
void * & for_compact_container() { return N[0].for_compact_container(); } void for_compact_container(void* p) { N[0].for_compact_container(p); }
// TDS internal data access functions. // TDS internal data access functions.
TDS_data& tds_data() { return _tds_data; } TDS_data& tds_data() { return _tds_data; }

View File

@ -59,8 +59,8 @@ public:
// For use by the Compact_container. // For use by the Compact_container.
void * for_compact_container() const void * for_compact_container() const
{ return _c.for_compact_container(); } { return _c.for_compact_container(); }
void * & for_compact_container() void for_compact_container(void* p)
{ return _c.for_compact_container(); } { _c.for_compact_container(p); }
private: private:
Cell_handle _c; Cell_handle _c;

View File

@ -26,6 +26,11 @@ template <class Tds>
void void
_test_cls_tds_3( const Tds &) _test_cls_tds_3( const Tds &)
{ {
static_assert(std::is_nothrow_move_constructible<Tds>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Tds>::value,
"move assignment is missing");
typedef typename Tds::Vertex_range Vertex_range; typedef typename Tds::Vertex_range Vertex_range;
typedef typename Tds::Cell_range Cell_range; typedef typename Tds::Cell_range Cell_range;
@ -115,6 +120,34 @@ _test_cls_tds_3( const Tds &)
std::cout << "ok" << std::endl; std::cout << "ok" << std::endl;
assert(tds6.is_valid()); assert(tds6.is_valid());
// Test move-constructors and move-assignments
{
Tds tds7 = tds5;
Tds tds8{std::move(tds7)};
Tds tds9 = tds5;
Tds tds10;
tds10 = std::move(tds9);
Tds tds11 = Tds(tds5); // construct from a temporary
Tds tds12 = std::move(tds11);
assert(tds7.is_valid());
assert(tds8.is_valid());
assert(tds9.is_valid());
assert(tds10.is_valid());
assert(tds11.is_valid());
assert(tds12.is_valid());
assert(tds7.dimension()==-2);
assert(tds8.dimension()==2);
assert(tds9.dimension()==-2);
assert(tds10.dimension()==2);
assert(tds11.dimension()==-2);
assert(tds12.dimension()==2);
tds11.~Tds();
// check tds12 is still valid after the destruction of tds11
assert(tds12.is_valid());
assert(tds12.dimension()==2);
}
std::cout << " Insert are tested in test_triangulation_3 " << std::endl; std::cout << " Insert are tested in test_triangulation_3 " << std::endl;
std::cout << " Iterator and circulator are tested in test_triangulation_3 " << std::endl; std::cout << " Iterator and circulator are tested in test_triangulation_3 " << std::endl;

View File

@ -107,7 +107,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void *p);
/// @} /// @}

View File

@ -106,7 +106,7 @@ void * for_compact_container() const;
/*! /*!
*/ */
void * & for_compact_container(); void for_compact_container(void *p);
/// @} /// @}

View File

@ -44,7 +44,7 @@ struct TFC_data< Vertex_handle, Full_cell_handle, Dimen, TDS_full_cell_default_s
: vertices_(dmax+1), neighbors_(dmax+1) : vertices_(dmax+1), neighbors_(dmax+1)
{} {}
void* for_compact_container() const { return vertices_.for_compact_container(); } void* for_compact_container() const { return vertices_.for_compact_container(); }
void* & for_compact_container() { return vertices_.for_compact_container(); } void for_compact_container(void *p){ vertices_.for_compact_container(p); }
int dimension() const { return ( vertices_.size() - 1 ); } int dimension() const { return ( vertices_.size() - 1 ); }
void set_mirror_index(const int, const int) {} void set_mirror_index(const int, const int) {}
#ifdef BOOST_NO_INT64_T #ifdef BOOST_NO_INT64_T

View File

@ -204,7 +204,7 @@ public:
TDS_data & tds_data() { return tds_data_; } /* Concept */ TDS_data & tds_data() { return tds_data_; } /* Concept */
void* for_compact_container() const { return combinatorics_.for_compact_container(); } void* for_compact_container() const { return combinatorics_.for_compact_container(); }
void* & for_compact_container() { return combinatorics_.for_compact_container(); } void for_compact_container(void* p){ combinatorics_.for_compact_container(p); }
bool is_valid(bool verbose = false, int = 0) const /* Concept */ bool is_valid(bool verbose = false, int = 0) const /* Concept */
{ {

View File

@ -102,7 +102,7 @@ public:
public: // FOR MEMORY MANAGEMENT public: // FOR MEMORY MANAGEMENT
void* for_compact_container() const { return full_cell_.for_compact_container(); } void* for_compact_container() const { return full_cell_.for_compact_container(); }
void* & for_compact_container() { return full_cell_.for_compact_container(); } void for_compact_container(void *p){ full_cell_.for_compact_container(p); }
}; // end of Triangulation_ds_vertex }; // end of Triangulation_ds_vertex

View File

@ -66,9 +66,9 @@ struct S_or_D_array< Containee, Dimension_tag< D >, WithCompactContainerHelper >
{ {
return (*this)[0].for_compact_container(); return (*this)[0].for_compact_container();
} }
void* & for_compact_container() void for_compact_container(void *p)
{ {
return (*this)[0].for_compact_container(); (*this)[0].for_compact_container(p);
} }
}; };
@ -101,7 +101,7 @@ struct S_or_D_array< Containee, Dynamic_dimension_tag, true >
{} {}
void* fcc_; void* fcc_;
void* for_compact_container() const { return fcc_; } void* for_compact_container() const { return fcc_; }
void* & for_compact_container() { return fcc_; } void for_compact_container(void* p) { fcc_ = p; }
}; };
} // end of namespace internal } // end of namespace internal

View File

@ -179,6 +179,19 @@ public:
virtual ~Constrained_Delaunay_triangulation_2() {} virtual ~Constrained_Delaunay_triangulation_2() {}
// Ensure rule-of-five: define the copy- and move- constructors
// as well as the copy- and move- assignment operators.
Constrained_Delaunay_triangulation_2(
const Constrained_Delaunay_triangulation_2 &) = default;
Constrained_Delaunay_triangulation_2(
Constrained_Delaunay_triangulation_2 &&) = default;
Constrained_Delaunay_triangulation_2 &
operator=(const Constrained_Delaunay_triangulation_2 &) = default;
Constrained_Delaunay_triangulation_2 &
operator=(Constrained_Delaunay_triangulation_2 &&) = default;
// FLIPS // FLIPS
bool is_flipable(Face_handle f, int i, bool perturb = true) const; bool is_flipable(Face_handle f, int i, bool perturb = true) const;
void flip(Face_handle& f, int i); void flip(Face_handle& f, int i);

View File

@ -220,6 +220,17 @@ public:
//TODO Is that destructor correct ? //TODO Is that destructor correct ?
virtual ~Constrained_triangulation_2() {} virtual ~Constrained_triangulation_2() {}
// Ensure rule-of-five: define the copy- and move- constructors
// as well as the copy- and move- assignment operators.
Constrained_triangulation_2(const Constrained_triangulation_2 &) = default;
Constrained_triangulation_2(Constrained_triangulation_2 &&) = default;
Constrained_triangulation_2 &
operator=(const Constrained_triangulation_2 &) = default;
Constrained_triangulation_2 &
operator=(Constrained_triangulation_2 &&) = default;
Constrained_edges_iterator constrained_edges_begin() const Constrained_edges_iterator constrained_edges_begin() const
{ {
@ -560,7 +571,7 @@ public:
{ {
Edge_circulator ec=incident_edges(v), done(ec); Edge_circulator ec=incident_edges(v), done(ec);
bool are_there = false; bool are_there = false;
if (ec == 0) return are_there; if (ec == nullptr) return are_there;
do { do {
if(is_constrained(*ec)) { if(is_constrained(*ec)) {
*out++ = *ec; *out++ = *ec;
@ -576,7 +587,7 @@ public:
OutputItEdges incident_constraints(Vertex_handle v, OutputItEdges incident_constraints(Vertex_handle v,
OutputItEdges out) const { OutputItEdges out) const {
Edge_circulator ec=incident_edges(v), done(ec); Edge_circulator ec=incident_edges(v), done(ec);
if (ec == 0) return out; if (ec == nullptr) return out;
do { do {
if(is_constrained(*ec)) *out++ = *ec; if(is_constrained(*ec)) *out++ = *ec;
ec++; ec++;
@ -1161,7 +1172,7 @@ update_constraints_incident(Vertex_handle va,
//dimension() ==2 //dimension() ==2
int cwi, ccwi, indf; int cwi, ccwi, indf;
Face_circulator fc=incident_faces(va), done(fc); Face_circulator fc=incident_faces(va), done(fc);
CGAL_triangulation_assertion(fc != 0); CGAL_triangulation_assertion(fc != nullptr);
do { do {
indf = fc->index(va); indf = fc->index(va);
cwi=cw(indf); cwi=cw(indf);
@ -1188,7 +1199,7 @@ clear_constraints_incident(Vertex_handle va)
Edge_circulator ec=incident_edges(va), done(ec); Edge_circulator ec=incident_edges(va), done(ec);
Face_handle f; Face_handle f;
int indf; int indf;
if ( ec != 0){ if ( ec != nullptr){
do { do {
f = (*ec).first ; f = (*ec).first ;
indf = (*ec).second; indf = (*ec).second;
@ -1383,7 +1394,7 @@ Constrained_triangulation_2<Gt,Tds,Itag>::
remove_incident_constraints(Vertex_handle v) remove_incident_constraints(Vertex_handle v)
{ {
Edge_circulator ec=incident_edges(v), done(ec); Edge_circulator ec=incident_edges(v), done(ec);
if (ec == 0) return; if (ec == nullptr) return;
do { do {
if(is_constrained(*ec)) { remove_constrained_edge((*ec).first, if(is_constrained(*ec)) { remove_constrained_edge((*ec).first,
(*ec).second);} (*ec).second);}

View File

@ -217,6 +217,8 @@ public:
, hierarchy(Vh_less_xy(this)) , hierarchy(Vh_less_xy(this))
{ copy_triangulation(ctp);} { copy_triangulation(ctp);}
Constrained_triangulation_plus_2(Constrained_triangulation_plus_2&&) = default;
virtual ~Constrained_triangulation_plus_2() {} virtual ~Constrained_triangulation_plus_2() {}
Constrained_triangulation_plus_2 & operator=(const Constrained_triangulation_plus_2& ctp) Constrained_triangulation_plus_2 & operator=(const Constrained_triangulation_plus_2& ctp)
@ -225,6 +227,8 @@ public:
return *this; return *this;
} }
Constrained_triangulation_plus_2& operator=(Constrained_triangulation_plus_2&&) = default;
template<class InputIterator> template<class InputIterator>
Constrained_triangulation_plus_2(InputIterator first, Constrained_triangulation_plus_2(InputIterator first,
InputIterator last, InputIterator last,
@ -415,7 +419,7 @@ public:
++beg; ++beg;
Face_container<Constrained_triangulation_plus_2> fc(*this); Face_container<Constrained_triangulation_plus_2> fc(*this);
Constraint_id head = 0, tail = 0; Constraint_id head = nullptr, tail = nullptr;
if(pos != beg){ if(pos != beg){
// split off head // split off head
--pos; --pos;
@ -496,7 +500,7 @@ public:
return pos; return pos;
} }
Constraint_id head = 0, tail = 0; Constraint_id head = nullptr, tail = nullptr;
Vertices_in_constraint_iterator bit = vertices_in_constraint_begin(cid); Vertices_in_constraint_iterator bit = vertices_in_constraint_begin(cid);
Vertices_in_constraint_iterator pred = pos; Vertices_in_constraint_iterator pred = pos;
--pred; --pred;

View File

@ -90,6 +90,11 @@ public:
: Triangulation_2<Gt,Tds>(tr) : Triangulation_2<Gt,Tds>(tr)
{ CGAL_triangulation_postcondition(is_valid()); } { CGAL_triangulation_postcondition(is_valid()); }
Delaunay_triangulation_2(Delaunay_triangulation_2&&) = default;
Delaunay_triangulation_2& operator=(const Delaunay_triangulation_2&) = default;
Delaunay_triangulation_2& operator=(Delaunay_triangulation_2&&) = default;
~Delaunay_triangulation_2() = default;
template <class InputIterator> template <class InputIterator>
Delaunay_triangulation_2(InputIterator first, InputIterator last, Delaunay_triangulation_2(InputIterator first, InputIterator last,
const Gt& gt = Gt()) const Gt& gt = Gt())

View File

@ -242,6 +242,7 @@ public:
// CONSTRUCTORS // CONSTRUCTORS
Triangulation_2(const Geom_traits& geom_traits=Geom_traits()); Triangulation_2(const Geom_traits& geom_traits=Geom_traits());
Triangulation_2(const Triangulation_2<Gt,Tds> &tr); Triangulation_2(const Triangulation_2<Gt,Tds> &tr);
Triangulation_2(Triangulation_2&&) = default;
template <class InputIterator> template <class InputIterator>
Triangulation_2(InputIterator first, InputIterator last, Triangulation_2(InputIterator first, InputIterator last,
@ -254,6 +255,10 @@ public:
//Assignement //Assignement
Triangulation_2 &operator=(const Triangulation_2 &tr); Triangulation_2 &operator=(const Triangulation_2 &tr);
Triangulation_2 &operator=(Triangulation_2 &&) = default;
// Destructor
~Triangulation_2() = default;
//Helping //Helping
void copy_triangulation(const Triangulation_2 &tr); void copy_triangulation(const Triangulation_2 &tr);
@ -628,7 +633,7 @@ std::ptrdiff_t insert(InputIterator first, InputIterator last,
typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::value_type,
Point Point
> >
>::type* = NULL) >::type* = nullptr)
#else #else
template < class InputIterator > template < class InputIterator >
std::ptrdiff_t std::ptrdiff_t
@ -1016,7 +1021,7 @@ includes_edge(Vertex_handle va, Vertex_handle vb,
Orientation orient; Orientation orient;
int indv; int indv;
Edge_circulator ec = incident_edges(va), done(ec); Edge_circulator ec = incident_edges(va), done(ec);
if (ec != 0) { if (ec != nullptr) {
do { do {
//find the index of the other vertex of *ec //find the index of the other vertex of *ec
indv = 3 - ((*ec).first)->index(va) - (*ec).second ; indv = 3 - ((*ec).first)->index(va) - (*ec).second ;
@ -2597,7 +2602,7 @@ march_locate_2D_LFC(Face_handle start,
}else { }else {
lfc = Line_face_circulator(start->vertex(0), this, t); lfc = Line_face_circulator(start->vertex(0), this, t);
} }
if(lfc==0 || lfc.collinear_outside()){ if(lfc==nullptr || lfc.collinear_outside()){
// point t lies outside or on the convex hull // point t lies outside or on the convex hull
// we walk on the convex hull to find it out // we walk on the convex hull to find it out
Face_circulator fc = incident_faces(infinite_vertex()); Face_circulator fc = incident_faces(infinite_vertex());

View File

@ -154,10 +154,6 @@ public:
public: public:
Context() : enclosing(nullptr) {} Context() : enclosing(nullptr) {}
Context(const Context& hc)
: enclosing(hc.enclosing), pos(hc.pos)
{}
Vertex_it vertices_begin()const { return enclosing->skip_begin();} Vertex_it vertices_begin()const { return enclosing->skip_begin();}
Vertex_it current()const {return pos;} Vertex_it current()const {return pos;}
Vertex_it vertices_end()const {return enclosing->skip_end();} Vertex_it vertices_end()const {return enclosing->skip_end();}
@ -187,9 +183,11 @@ public:
, sc_to_c_map(Pair_compare(comp)) , sc_to_c_map(Pair_compare(comp))
{ } { }
Polyline_constraint_hierarchy_2(const Polyline_constraint_hierarchy_2& ch); Polyline_constraint_hierarchy_2(const Polyline_constraint_hierarchy_2& ch);
Polyline_constraint_hierarchy_2(Polyline_constraint_hierarchy_2&&) = default;
~Polyline_constraint_hierarchy_2(){ clear();} ~Polyline_constraint_hierarchy_2(){ clear();}
void clear(); void clear();
Polyline_constraint_hierarchy_2& operator=(const Polyline_constraint_hierarchy_2& ch); Polyline_constraint_hierarchy_2& operator=(const Polyline_constraint_hierarchy_2& ch);
Polyline_constraint_hierarchy_2& operator=(Polyline_constraint_hierarchy_2&& ch) = default;
// Query // Query
bool is_subconstrained_edge(T va, T vb) const; bool is_subconstrained_edge(T va, T vb) const;
@ -499,7 +497,7 @@ swap(Constraint_id first, Constraint_id second){
// and replace the context of the constraint // and replace the context of the constraint
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) { for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
if(ctit->enclosing == first.vl_ptr()){ if(ctit->enclosing == first.vl_ptr()){
ctit->enclosing = 0; ctit->enclosing = nullptr;
break; break;
} }
} }
@ -530,7 +528,7 @@ swap(Constraint_id first, Constraint_id second){
// and replace the context of the constraint // and replace the context of the constraint
for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) { for(Context_iterator ctit=hcl->begin(); ctit != hcl->end(); ctit++) {
if(ctit->enclosing == 0){ if(ctit->enclosing == nullptr){
ctit->enclosing = second.vl_ptr(); ctit->enclosing = second.vl_ptr();
break; break;
} }

View File

@ -36,6 +36,7 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <vector> #include <vector>
#include <array>
namespace CGAL { namespace CGAL {
@ -82,13 +83,25 @@ public:
private: private:
// here is the stack of triangulations which form the hierarchy // here is the stack of triangulations which form the hierarchy
Tr_Base* hierarchy[Triangulation_hierarchy_2__maxlevel]; std::array<Tr_Base*,Triangulation_hierarchy_2__maxlevel> hierarchy;
boost::rand48 random; boost::rand48 random;
public: public:
Triangulation_hierarchy_2(const Geom_traits& traits = Geom_traits()); Triangulation_hierarchy_2(const Geom_traits& traits = Geom_traits());
Triangulation_hierarchy_2(const Triangulation_hierarchy_2& tr); Triangulation_hierarchy_2(const Triangulation_hierarchy_2& tr);
Triangulation_hierarchy_2(Triangulation_hierarchy_2&& other)
noexcept( noexcept(Tr_Base(std::move(other))) )
: Tr_Base(std::move(other))
, random(std::move(other.random))
{
hierarchy[0] = this;
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
}
template<class InputIterator> template<class InputIterator>
Triangulation_hierarchy_2(InputIterator first, InputIterator beyond, Triangulation_hierarchy_2(InputIterator first, InputIterator beyond,
const Geom_traits& traits = Geom_traits()) const Geom_traits& traits = Geom_traits())
@ -102,6 +115,19 @@ public:
} }
Triangulation_hierarchy_2 &operator=(const Triangulation_hierarchy_2& tr); Triangulation_hierarchy_2 &operator=(const Triangulation_hierarchy_2& tr);
Triangulation_hierarchy_2 & operator=(Triangulation_hierarchy_2&& other)
noexcept( noexcept(Triangulation_hierarchy_2(std::move(other))) )
{
static_cast<Tr_Base&>(*this) = std::move(other);
hierarchy[0] = this;
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
return *this;
}
~Triangulation_hierarchy_2(); ~Triangulation_hierarchy_2();
//Helping //Helping
@ -391,7 +417,7 @@ Triangulation_hierarchy_2<Tr_>::
clear() clear()
{ {
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i) for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i]->clear(); if(hierarchy[i]) hierarchy[i]->clear();
} }
@ -723,7 +749,7 @@ locate_in_all(const Point& p,
level--; level--;
} }
for (int i=level+1; i<Triangulation_hierarchy_2__maxlevel;++i) pos[i]=0; for (int i=level+1; i<Triangulation_hierarchy_2__maxlevel;++i) pos[i]=nullptr;
while(level > 0) { while(level > 0) {
pos[level]=position=hierarchy[level]->locate(p, position); pos[level]=position=hierarchy[level]->locate(p, position);
// locate at that level from "position" // locate at that level from "position"

View File

@ -41,13 +41,13 @@ public:
}; };
Triangulation_hierarchy_vertex_base_2() Triangulation_hierarchy_vertex_base_2()
: Base(), _up(0), _down(0) : Base()
{} {}
Triangulation_hierarchy_vertex_base_2(const Point & p, Face_handle f) Triangulation_hierarchy_vertex_base_2(const Point & p, Face_handle f)
: Base(p,f), _up(0), _down(0) : Base(p,f)
{} {}
Triangulation_hierarchy_vertex_base_2(const Point & p) Triangulation_hierarchy_vertex_base_2(const Point & p)
: Base(p), _up(0), _down(0) : Base(p)
{} {}
Vertex_handle up() {return _up;} Vertex_handle up() {return _up;}
@ -57,8 +57,8 @@ public:
private: private:
Vertex_handle _up; // same vertex one level above Vertex_handle _up = nullptr; // same vertex one level above
Vertex_handle _down; // same vertex one level below Vertex_handle _down = nullptr; // same vertex one level below
}; };
} //namespace CGAL } //namespace CGAL

View File

@ -30,6 +30,16 @@ template <class Triangul>
void void
_test_cls_const_Del_triangulation(const Triangul&) _test_cls_const_Del_triangulation(const Triangul&)
{ {
// The following assertion is commented, because, in CT_plus_2,
// one uses `std::set` and `std::map`, and their move-constructors
// may throw.
//
// static_assert(std::is_nothrow_move_constructible<Triangul>::value,
// "move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Triangul>::value,
"move assignment is missing");
//typedef Triangulation Cls; //typedef Triangulation Cls;
typedef typename Triangul::Geom_traits Gt; typedef typename Triangul::Geom_traits Gt;

View File

@ -92,6 +92,16 @@ template <class Triang>
void void
_test_cls_constrained_triangulation(const Triang &) _test_cls_constrained_triangulation(const Triang &)
{ {
// The following assertion is commented, because, in CT_plus_2,
// one uses `std::set` and `std::map`, and their move-constructors
// may throw.
//
// static_assert(std::is_nothrow_move_constructible<Triang>::value,
// "move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Triang>::value,
"move assignment is missing");
// typedef Triangulation Cls; // typedef Triangulation Cls;
typedef typename Triang::Geom_traits Gt; typedef typename Triang::Geom_traits Gt;

View File

@ -39,6 +39,11 @@ template <class Del>
void void
_test_cls_delaunay_triangulation_2( const Del & ) _test_cls_delaunay_triangulation_2( const Del & )
{ {
static_assert(std::is_nothrow_move_constructible<Del>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Del>::value,
"move assignment is missing");
//typedef Del Delaunay; //typedef Del Delaunay;
typedef typename Del::Point Point; typedef typename Del::Point Point;
typedef typename Del::Locate_type Locate_type; typedef typename Del::Locate_type Locate_type;

View File

@ -39,6 +39,10 @@ template <class Triangul>
void void
_test_cls_triangulation_2( const Triangul & ) _test_cls_triangulation_2( const Triangul & )
{ {
static_assert(std::is_nothrow_move_constructible<Triangul>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Triangul>::value,
"move assignment is missing");
//typedef Triangulation Cls; //typedef Triangulation Cls;
// We assume the traits class has been tested already // We assume the traits class has been tested already

View File

@ -36,7 +36,6 @@ protected:
double _x, _y; double _x, _y;
public: public:
Triangulation_test_point() {} Triangulation_test_point() {}
Triangulation_test_point(const Point &p) : _x(p.test_x()), _y(p.test_y()) {}
Triangulation_test_point(double x, double y) : _x(x), _y(y) {} Triangulation_test_point(double x, double y) : _x(x), _y(y) {}
Triangulation_test_point(double hx, double hy, double hw) : Triangulation_test_point(double hx, double hy, double hw) :
_x(hx/hw), _y(hy/hw) _x(hx/hw), _y(hy/hw)
@ -47,7 +46,6 @@ public:
bool compare(const Point &p) const bool compare(const Point &p) const
{ return test_x()==p.test_x() && test_y()==p.test_y(); } { return test_x()==p.test_x() && test_y()==p.test_y(); }
bool uncompare(const Point &p) const { return !compare(p); } bool uncompare(const Point &p) const { return !compare(p); }
Point &operator=(const Point &p) { _x=p.test_x(); _y=p.test_y(); return *this; }
void test_set(TESTFT x, TESTFT y) { _x=x; _y=y; } void test_set(TESTFT x, TESTFT y) { _x=x; _y=y; }
bool operator==(const Point &p) const {return this->compare(p);} bool operator==(const Point &p) const {return this->compare(p);}
}; };
@ -436,11 +434,6 @@ public:
typedef Triangulation_test_Construct_ray_2 Construct_ray_2; typedef Triangulation_test_Construct_ray_2 Construct_ray_2;
_Triangulation_test_traits() {}
_Triangulation_test_traits(const _Triangulation_test_traits &) {}
_Triangulation_test_traits &operator=
(const _Triangulation_test_traits &) { return *this; }
Less_x_2 Less_x_2
less_x_2_object() const less_x_2_object() const
{ return Less_x_2();} { return Less_x_2();}

View File

@ -888,11 +888,6 @@ protected:
: m_dt(dt), m_points(points), m_tls_hint(tls_hint) : m_dt(dt), m_points(points), m_tls_hint(tls_hint)
{} {}
// Constructor
Insert_point(const Insert_point& ip)
: m_dt(ip.m_dt), m_points(ip.m_points), m_tls_hint(ip.m_tls_hint)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {
@ -968,12 +963,6 @@ protected:
m_tls_hint(tls_hint) m_tls_hint(tls_hint)
{} {}
// Constructor
Insert_point_with_info(const Insert_point_with_info& ip)
: m_dt(ip.m_dt), m_points(ip.m_points), m_infos(ip.m_infos),
m_indices(ip.m_indices), m_tls_hint(ip.m_tls_hint)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {
@ -1047,12 +1036,6 @@ protected:
m_vertices_to_remove_sequentially(vertices_to_remove_sequentially) m_vertices_to_remove_sequentially(vertices_to_remove_sequentially)
{} {}
// Constructor
Remove_point(const Remove_point& rp)
: m_dt(rp.m_dt), m_vertices(rp.m_vertices),
m_vertices_to_remove_sequentially(rp.m_vertices_to_remove_sequentially)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {

View File

@ -63,6 +63,12 @@ public:
: Cb(c), circumcenter_(c.circumcenter_ != nullptr ? new Point(*(c.circumcenter_)) : nullptr) : Cb(c), circumcenter_(c.circumcenter_ != nullptr ? new Point(*(c.circumcenter_)) : nullptr)
{} {}
Delaunay_triangulation_cell_base_with_circumcenter_3
(Delaunay_triangulation_cell_base_with_circumcenter_3 &&c)
: Cb(std::move(c)), circumcenter_(std::exchange(c.circumcenter_, nullptr))
{
}
Delaunay_triangulation_cell_base_with_circumcenter_3& Delaunay_triangulation_cell_base_with_circumcenter_3&
operator=(const Delaunay_triangulation_cell_base_with_circumcenter_3 &c) operator=(const Delaunay_triangulation_cell_base_with_circumcenter_3 &c)
{ {
@ -71,6 +77,14 @@ public:
return *this; return *this;
} }
Delaunay_triangulation_cell_base_with_circumcenter_3&
operator=(Delaunay_triangulation_cell_base_with_circumcenter_3 &&c)
{
Cb::operator=(std::move(c));
circumcenter_ = std::exchange(c.circumcenter_, nullptr);
return *this;
}
Delaunay_triangulation_cell_base_with_circumcenter_3( Delaunay_triangulation_cell_base_with_circumcenter_3(
Vertex_handle v0, Vertex_handle v1, Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3) Vertex_handle v2, Vertex_handle v3)

View File

@ -199,21 +199,38 @@ public:
CGAL_triangulation_postcondition(is_valid()); CGAL_triangulation_postcondition(is_valid());
} }
Regular_triangulation_3(Regular_triangulation_3&& rt)
noexcept(noexcept(Tr_Base(std::move(rt))))
: Tr_Base(std::move(rt)), hidden_point_visitor(this)
{
CGAL_triangulation_postcondition(is_valid());
}
~Regular_triangulation_3() = default;
void swap(Regular_triangulation_3& tr) void swap(Regular_triangulation_3& tr)
{ {
// The 'vertices' and 'hidden_points' members of 'hidden_point_visitor' should be empty // The 'vertices' and 'hidden_points' members of
// as they are only filled (and cleared) during the insertion of a point. // 'hidden_point_visitor' should be empty as they are only filled
// Hidden points are not stored there, but rather in cells. Thus, the only thing that must be set // (and cleared) during the insertion of a point. Hidden points
// is the triangulation pointer. // are not stored there, but rather in cells. Thus, the only thing
Hidden_point_visitor<Concurrency_tag> new_hpv(this); // that must be set is the triangulation pointer, and it is
std::swap(hidden_point_visitor, new_hpv); // already correctly set. There is nothing to do about
// 'hidden_point_visitor'.
Tr_Base::swap(tr); Tr_Base::swap(tr);
} }
Regular_triangulation_3& operator=(Regular_triangulation_3 tr) Regular_triangulation_3& operator=(const Regular_triangulation_3& tr)
{ {
swap(tr); Regular_triangulation_3 copy(tr);
copy.swap(*this);
return *this;
}
Regular_triangulation_3& operator=(Regular_triangulation_3&& tr)
noexcept(noexcept(Regular_triangulation_3(std::move(tr))))
{
Tr_Base::operator=(std::move(tr));
return *this; return *this;
} }
@ -1393,11 +1410,6 @@ protected:
: m_rt(rt), m_points(points), m_tls_hint(tls_hint) : m_rt(rt), m_points(points), m_tls_hint(tls_hint)
{} {}
// Constructor
Insert_point(const Insert_point& ip)
: m_rt(ip.m_rt), m_points(ip.m_points), m_tls_hint(ip.m_tls_hint)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {
@ -1504,12 +1516,6 @@ protected:
m_tls_hint(tls_hint) m_tls_hint(tls_hint)
{} {}
// Constructor
Insert_point_with_info(const Insert_point_with_info &ip)
: m_rt(ip.m_rt), m_points(ip.m_points), m_infos(ip.m_infos),
m_indices(ip.m_indices), m_tls_hint(ip.m_tls_hint)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {
@ -1621,12 +1627,6 @@ protected:
m_vertices_to_remove_sequentially(vertices_to_remove_sequentially) m_vertices_to_remove_sequentially(vertices_to_remove_sequentially)
{} {}
// Constructor
Remove_point(const Remove_point& rp)
: m_rt(rp.m_rt), m_vertices(rp.m_vertices),
m_vertices_to_remove_sequentially(rp.m_vertices_to_remove_sequentially)
{}
// operator() // operator()
void operator()(const tbb::blocked_range<size_t>& r) const void operator()(const tbb::blocked_range<size_t>& r) const
{ {

View File

@ -179,7 +179,7 @@ public:
void *get_lock_data_structure() const void *get_lock_data_structure() const
{ {
return 0; return nullptr;
} }
void set_lock_data_structure(void *) const {} void set_lock_data_structure(void *) const {}
@ -245,7 +245,7 @@ protected:
public: public:
bool is_parallel() const bool is_parallel() const
{ {
return m_lock_ds != 0; return m_lock_ds != nullptr;
} }
// LOCKS // LOCKS
@ -731,6 +731,9 @@ public:
CGAL_triangulation_expensive_postcondition(*this == tr); CGAL_triangulation_expensive_postcondition(*this == tr);
} }
Triangulation_3(Triangulation_3&& tr) = default;
~Triangulation_3() = default;
template < typename InputIterator > template < typename InputIterator >
Triangulation_3(InputIterator first, InputIterator last, Triangulation_3(InputIterator first, InputIterator last,
const GT& gt = GT(), Lock_data_structure *lock_ds = nullptr) const GT& gt = GT(), Lock_data_structure *lock_ds = nullptr)
@ -757,21 +760,21 @@ public:
init_tds(); init_tds();
} }
Triangulation_3& operator=(Triangulation_3 tr) Triangulation_3& operator=(const Triangulation_3& tr)
{ {
// Because the parameter tr is passed by value, the triangulation passed Triangulation_3 copy(tr);
// as argument has been copied. swap(copy);
// The following 'swap' consumes the *copy* and the original triangulation
// is left untouched.
swap(tr);
return *this; return *this;
} }
Triangulation_3& operator=(Triangulation_3&& tr) = default;
// HELPING FUNCTIONS // HELPING FUNCTIONS
void swap(Triangulation_3& tr) void swap(Triangulation_3& tr) noexcept
{ {
std::swap(tr._gt, _gt); using std::swap;
std::swap(tr.infinite, infinite); swap(tr._gt, _gt);
swap(tr.infinite, infinite);
_tds.swap(tr._tds); _tds.swap(tr._tds);
Base::swap(tr); Base::swap(tr);
} }
@ -1139,7 +1142,7 @@ public:
typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::value_type,
Point Point
> >
>::type* = NULL) >::type* = nullptr)
#else #else
template < class InputIterator > template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last) std::ptrdiff_t insert(InputIterator first, InputIterator last)

View File

@ -50,6 +50,8 @@
#include <boost/mpl/identity.hpp> #include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <array>
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
namespace CGAL { namespace CGAL {
@ -91,7 +93,7 @@ public:
private: private:
// here is the stack of triangulations which form the hierarchy // here is the stack of triangulations which form the hierarchy
Tr_Base* hierarchy[maxlevel]; std::array<Tr_Base*,maxlevel> hierarchy;
boost::rand48 random; boost::rand48 random;
void set_up_down(Vertex_handle up, Vertex_handle down) void set_up_down(Vertex_handle up, Vertex_handle down)
@ -106,6 +108,18 @@ public:
Triangulation_hierarchy_3(const Triangulation_hierarchy_3& tr); Triangulation_hierarchy_3(const Triangulation_hierarchy_3& tr);
Triangulation_hierarchy_3(Triangulation_hierarchy_3&& other)
noexcept( noexcept(Tr_Base(std::move(other))) )
: Tr_Base(std::move(other))
, random(std::move(other.random))
{
hierarchy[0] = this;
for(int i=1; i<maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
}
template < typename InputIterator > template < typename InputIterator >
Triangulation_hierarchy_3(InputIterator first, InputIterator last, Triangulation_hierarchy_3(InputIterator first, InputIterator last,
const Geom_traits& traits = Geom_traits()) const Geom_traits& traits = Geom_traits())
@ -124,9 +138,32 @@ public:
return *this; return *this;
} }
~Triangulation_hierarchy_3(); Triangulation_hierarchy_3 & operator=(Triangulation_hierarchy_3&& other)
noexcept( noexcept(Triangulation_hierarchy_3(std::move(other))) )
{
static_cast<Tr_Base&>(*this) = std::move(other);
hierarchy[0] = this;
for(int i=1; i<maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
return *this;
}
void swap(Triangulation_hierarchy_3 &tr); ~Triangulation_hierarchy_3()
{
clear();
for(int i=1; i<maxlevel; ++i) {
delete hierarchy[i];
}
};
void swap(Triangulation_hierarchy_3 &tr)
{
Tr_Base::swap(tr);
for(int i=1; i<maxlevel; ++i)
std::swap(hierarchy[i], tr.hierarchy[i]);
};
void clear(); void clear();
@ -461,26 +498,6 @@ Triangulation_hierarchy_3(const Triangulation_hierarchy_3<Tr> &tr)
} }
} }
template <class Tr>
void
Triangulation_hierarchy_3<Tr>::
swap(Triangulation_hierarchy_3<Tr> &tr)
{
Tr_Base::swap(tr);
for(int i=1; i<maxlevel; ++i)
std::swap(hierarchy[i], tr.hierarchy[i]);
}
template <class Tr>
Triangulation_hierarchy_3<Tr>::
~Triangulation_hierarchy_3()
{
clear();
for(int i=1; i<maxlevel; ++i) {
delete hierarchy[i];
}
}
template <class Tr> template <class Tr>
void void
Triangulation_hierarchy_3<Tr>:: Triangulation_hierarchy_3<Tr>::

View File

@ -19,6 +19,7 @@
#include <fstream> #include <fstream>
#include <list> #include <list>
#include <vector> #include <vector>
#include <type_traits>
#include <boost/mpl/identity.hpp> #include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
@ -170,6 +171,11 @@ _test_cls_delaunay_3(const Triangulation &)
{ {
typedef Triangulation Cls; typedef Triangulation Cls;
static_assert(std::is_nothrow_move_constructible<Cls>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Cls>::value,
"move assignment is missing");
typedef typename Test_location_policy<Cls>::Location_policy Location_policy; typedef typename Test_location_policy<Cls>::Location_policy Location_policy;
// We assume the traits class has been tested already // We assume the traits class has been tested already

View File

@ -15,12 +15,19 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <list> #include <list>
#include <type_traits>
#include <CGAL/use.h> #include <CGAL/use.h>
template <class Triangulation> template <class Triangulation>
void void
_test_cls_regular_3(const Triangulation &) _test_cls_regular_3(const Triangulation &)
{ {
typedef Triangulation Cls; typedef Triangulation Cls;
static_assert(std::is_nothrow_move_constructible<Cls>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Cls>::value,
"move assignment is missing");
typedef typename Triangulation::Geom_traits Gt; typedef typename Triangulation::Geom_traits Gt;
CGAL_USE_TYPE(Gt); CGAL_USE_TYPE(Gt);

View File

@ -15,6 +15,7 @@
#include <fstream> #include <fstream>
#include <list> #include <list>
#include <vector> #include <vector>
#include <type_traits>
#include "_test_cls_iterator.h" #include "_test_cls_iterator.h"
#include "_test_cls_circulator.h" #include "_test_cls_circulator.h"
@ -79,6 +80,11 @@ _test_cls_triangulation_3(const Triangulation &)
{ {
typedef Triangulation Cls; typedef Triangulation Cls;
static_assert(std::is_nothrow_move_constructible<Cls>::value,
"move cstr is missing");
static_assert(std::is_nothrow_move_assignable<Cls>::value,
"move assignment is missing");
// We assume the traits class has been tested already // We assume the traits class has been tested already
// actually, any traits is good if it has been tested // actually, any traits is good if it has been tested