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:
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
@ -323,7 +323,7 @@ public:
{
//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
PTR.p = new Trpz_parameter_space
PTR = new Trpz_parameter_space
(Traits::vtx_at_left_infinity(),
Traits::vtx_at_right_infinity(),
Traits::he_at_bottom_infinity(),
@ -353,7 +353,7 @@ public:
else //tp == 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);
m_dag_node = node;
}
@ -370,7 +370,7 @@ public:
Self* rb = 0, Self* rt = 0,
Dag_node* node = 0)
{
PTR.p = new Trpz_parameter_space
PTR = new Trpz_parameter_space
(l ? *l : Traits::vtx_at_left_infinity(),
r ? *r : Traits::vtx_at_right_infinity(),
b ? *b : Traits::he_at_bottom_infinity(),
@ -436,7 +436,7 @@ public:
/*! Access the trapezoid id (PTR). */
CGAL_TD_INLINE unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
/*! Access trapezoid left. */

View File

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

View File

@ -129,7 +129,7 @@ public:
};
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const
{
@ -180,14 +180,14 @@ public:
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. */
Td_active_fictitious_vertex(Vertex_const_handle v,
Halfedge_const_handle cw_he,
Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); }
{ PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */
@ -224,7 +224,7 @@ public:
inline const Self& self() const { return *this; }
/*! 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.
* filters out the infinite case which returns predefined dummy values

View File

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

View File

@ -134,7 +134,7 @@ public:
};
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const
{
@ -184,14 +184,14 @@ public:
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. */
Td_active_vertex(Vertex_const_handle v, Halfedge_const_handle cw_he,
Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); }
{ PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */
@ -228,7 +228,7 @@ public:
inline const Self& self() const { return *this; }
/*! 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; }

View File

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

View File

@ -39,7 +39,7 @@ template<class Traits>
class Td_dag_node_base : public Handle
{
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:
//c'tors
@ -57,12 +57,12 @@ public:
return *this;
}
//bool operator!() const { return PTR.p == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar
bool is_null() const { return PTR.p == 0; }
Rep * ptr() const { return (Rep*) PTR.p; }
//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 == 0; }
Rep * ptr() const { return (Rep*) PTR; }
protected:
//Rep *& ptr() { return (Rep*) PTR.p; }
void set_ptr(Rep* rep) { PTR.p = rep; }
//Rep *& ptr() { return (Rep*) PTR; }
void set_ptr(Rep* rep) { PTR = rep; }
};
@ -94,7 +94,7 @@ public:
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
public:
//using Td_dag_node_handle::PTR.p;
//using Td_dag_node_handle::PTR;
//using Td_dag_node_handle::operator!;
#endif //CGAL_CFG_USING_BASE_MEMBER_BUG_2
@ -549,7 +549,7 @@ protected:
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:
The code is Handle designed.
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*() returns data type
output is done as a binary tree.

View File

@ -128,7 +128,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -161,7 +161,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */
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. */
@ -215,7 +215,7 @@ public:
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
inline X_monotone_curve_2& curve() const

View File

@ -133,7 +133,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
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));
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). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}

View File

@ -127,7 +127,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -162,7 +162,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */
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). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
inline Point& point() const

View File

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

View File

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

View File

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

View File

@ -87,7 +87,7 @@ public:
void* 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
LEDA_MEMORY(RC_vertex_d)
@ -153,7 +153,7 @@ public:
void* pp;
void* for_compact_container() const { return pp; }
void* & for_compact_container() { return pp; }
void for_compact_container(void *p) { pp = p; }
#if 0
struct Point_const_iterator {

View File

@ -718,17 +718,17 @@ public :
Lazy(Self_rep *r)
{
PTR.p = r;
PTR = r;
}
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)
{
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
@ -768,7 +768,7 @@ public :
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>

View File

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

View File

@ -491,7 +491,7 @@ public:
// For use by 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_data& tds_data() { return _tds_data; }

View File

@ -233,7 +233,7 @@ public:
// For use by 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_data& tds_data() { return _tds_data; }

View File

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

View File

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

View File

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

View File

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

View File

@ -40,31 +40,31 @@ class Handle
typedef std::ptrdiff_t Id_type ;
Handle() noexcept
: PTR{static_cast<Rep*>(0)} {}
: PTR(static_cast<Rep*>(0)) {}
// FIXME: if the precondition throws in a noexcept function, the program terminates
Handle(const Handle& x) noexcept
{
CGAL_precondition( x.PTR.p != static_cast<Rep*>(0) );
PTR.p = x.PTR.p;
CGAL_assume (PTR.p->count > 0);
PTR.p->count++;
CGAL_precondition( x.PTR != static_cast<Rep*>(0) );
PTR = x.PTR;
CGAL_assume (PTR->count > 0);
PTR->count++;
}
~Handle()
{
if ( PTR.p && (--PTR.p->count == 0))
delete PTR.p;
if ( PTR && (--PTR->count == 0))
delete PTR;
}
Handle&
operator=(const Handle& x) noexcept
{
CGAL_precondition( x.PTR.p != static_cast<Rep*>(0) );
x.PTR.p->count++;
if ( PTR.p && (--PTR.p->count == 0))
delete PTR.p;
PTR.p = x.PTR.p;
CGAL_precondition( x.PTR != static_cast<Rep*>(0) );
x.PTR->count++;
if ( PTR && (--PTR->count == 0))
delete PTR;
PTR = x.PTR;
return *this;
}
@ -72,29 +72,25 @@ class Handle
void reset()
{
if (PTR.p)
if (PTR)
{
if (--PTR.p->count==0)
delete PTR.p;
PTR.p=0;
if (--PTR->count==0)
delete PTR;
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; }
void* for_compact_container() const { return PTR.vp; }
void*& for_compact_container() { return PTR.vp; }
bool identical(const Handle& h) const noexcept { return PTR == h.PTR; }
void * for_compact_container() const { return PTR; }
void for_compact_container(void* p) { PTR = static_cast<Rep*>(p); }
protected:
union {
Rep* p;
void* vp;
} PTR;
Rep* PTR;
};
//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>
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) {
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)) {
const std::size_t new_ts = time_stamp_++;
pt->set_time_stamp(new_ts);
@ -96,23 +82,14 @@ struct Time_stamper
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>
template <typename T>
struct No_time_stamp
{
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) {
return p_t1 < p_t2;
}
@ -130,8 +107,6 @@ public:
constexpr std::size_t shift = internal::rounded_down_log2(sizeof(T));
return reinterpret_cast<std::size_t>(p) >> shift;
}
void reset() {}
}; // end class template No_time_stamp<T>
// That class template is an auxiliary class. It has a

View File

@ -4,6 +4,7 @@
#include <cstddef>
#include <list>
#include <vector>
#include <type_traits>
#include <CGAL/Compact_container.h>
#include <CGAL/Random.h>
@ -71,7 +72,7 @@ public:
bool operator< (const Node_2 &n) const { return rnd < n.rnd; }
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 >
@ -83,6 +84,11 @@ inline bool check_empty(const Cont &c)
template < class 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.
typename Cont::value_type t0;
@ -319,22 +325,22 @@ int main()
// Check the time stamper policies
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;
}
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;
}
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;
}
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;
}

View File

@ -15,7 +15,7 @@ public:
{}
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()

View File

@ -33,7 +33,6 @@ struct Node_1
: public CGAL::Compact_container_base
{
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 false; }
bool operator< (const Node_1 &) const { return false; }
@ -61,14 +60,14 @@ public:
int rnd;
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; }
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 >
@ -89,11 +88,6 @@ public:
: 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
{
for( size_t i = r.begin() ; i != r.end() ; ++i)
@ -118,11 +112,6 @@ public:
: 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
{
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)
{}
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
{
for( size_t i = r.begin() ; i != r.end() ; ++i)
{
m_iterators[i] = m_cont.insert(m_values[i]);
// 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
bool comparand = false;
if (m_free_elements[index_to_erase].compare_exchange_weak(comparand, true) )
@ -183,6 +166,10 @@ private:
template < class 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.
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 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);
}

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:
Triangulation_data_structure_2();
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();
Tds& operator= (const Tds &tds);
Tds& operator= (Tds&& tds) noexcept(noexcept(Tds(std::move(tds))));
void swap(Tds &tds);
//ACCESS FUNCTIONS
@ -642,9 +647,6 @@ public:
Triangulation_default_data_structure_2(const Geom_traits& = Geom_traits())
: Tds() {}
Triangulation_default_data_structure_2(const Tdds &tdds)
: Tds(tdds) {}
};
//for backward compatibility
@ -657,8 +659,6 @@ public:
typedef Triangulation_data_structure_using_list_2<Vb,Fb> Tdsul;
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);
}
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>
Triangulation_data_structure_2<Vb,Fb> ::
~Triangulation_data_structure_2()
@ -682,7 +693,7 @@ Triangulation_data_structure_2<Vb,Fb> ::
clear();
}
//assignement
//copy-assignment
template < class Vb, class Fb>
Triangulation_data_structure_2<Vb,Fb>&
Triangulation_data_structure_2<Vb,Fb> ::
@ -692,6 +703,18 @@ operator= (const Tds &tds)
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>
void
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 start = fc;
if (fc == 0) return false;
if (fc == nullptr) return false;
int inda, indb;
do {
inda=fc->index(va);

View File

@ -79,7 +79,7 @@ public:
// For use by 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);}

View File

@ -49,7 +49,7 @@ public:
// For use by the 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:
Face_handle _f;

View File

@ -44,6 +44,11 @@ template <class Tds>
void
_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::Face_range Face_range;
@ -129,6 +134,34 @@ _test_cls_tds_2( const Tds &)
assert(tds3.number_of_vertices() == 4);
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 v4_1 = tds4.insert_second();
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.

View File

@ -231,6 +231,15 @@ public:
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)
{
if (&tds != this) {
@ -240,6 +249,17 @@ public:
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(); }
int dimension() const {return _dimension;}
@ -917,12 +937,6 @@ public:
*output++ = e;
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() {
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()
{
for(std::size_t i=0; i < tmp_vertices.size(); ++i){

View File

@ -180,7 +180,7 @@ public:
// For use by 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_data& tds_data() { return _tds_data; }

View File

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

View File

@ -26,6 +26,11 @@ template <class Tds>
void
_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::Cell_range Cell_range;
@ -115,6 +120,34 @@ _test_cls_tds_3( const Tds &)
std::cout << "ok" << std::endl;
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 << " 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)
{}
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 ); }
void set_mirror_index(const int, const int) {}
#ifdef BOOST_NO_INT64_T

View File

@ -204,7 +204,7 @@ public:
TDS_data & tds_data() { return tds_data_; } /* Concept */
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 */
{

View File

@ -102,7 +102,7 @@ public:
public: // FOR MEMORY MANAGEMENT
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

View File

@ -66,9 +66,9 @@ struct S_or_D_array< Containee, Dimension_tag< D >, WithCompactContainerHelper >
{
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* for_compact_container() const { return fcc_; }
void* & for_compact_container() { return fcc_; }
void for_compact_container(void* p) { fcc_ = p; }
};
} // end of namespace internal

View File

@ -179,6 +179,19 @@ public:
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
bool is_flipable(Face_handle f, int i, bool perturb = true) const;
void flip(Face_handle& f, int i);

View File

@ -220,6 +220,17 @@ public:
//TODO Is that destructor correct ?
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
{
@ -560,7 +571,7 @@ public:
{
Edge_circulator ec=incident_edges(v), done(ec);
bool are_there = false;
if (ec == 0) return are_there;
if (ec == nullptr) return are_there;
do {
if(is_constrained(*ec)) {
*out++ = *ec;
@ -576,7 +587,7 @@ public:
OutputItEdges incident_constraints(Vertex_handle v,
OutputItEdges out) const {
Edge_circulator ec=incident_edges(v), done(ec);
if (ec == 0) return out;
if (ec == nullptr) return out;
do {
if(is_constrained(*ec)) *out++ = *ec;
ec++;
@ -1161,7 +1172,7 @@ update_constraints_incident(Vertex_handle va,
//dimension() ==2
int cwi, ccwi, indf;
Face_circulator fc=incident_faces(va), done(fc);
CGAL_triangulation_assertion(fc != 0);
CGAL_triangulation_assertion(fc != nullptr);
do {
indf = fc->index(va);
cwi=cw(indf);
@ -1188,7 +1199,7 @@ clear_constraints_incident(Vertex_handle va)
Edge_circulator ec=incident_edges(va), done(ec);
Face_handle f;
int indf;
if ( ec != 0){
if ( ec != nullptr){
do {
f = (*ec).first ;
indf = (*ec).second;
@ -1383,7 +1394,7 @@ Constrained_triangulation_2<Gt,Tds,Itag>::
remove_incident_constraints(Vertex_handle v)
{
Edge_circulator ec=incident_edges(v), done(ec);
if (ec == 0) return;
if (ec == nullptr) return;
do {
if(is_constrained(*ec)) { remove_constrained_edge((*ec).first,
(*ec).second);}

View File

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

View File

@ -90,6 +90,11 @@ public:
: Triangulation_2<Gt,Tds>(tr)
{ 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>
Delaunay_triangulation_2(InputIterator first, InputIterator last,
const Gt& gt = Gt())

View File

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

View File

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

View File

@ -36,6 +36,7 @@
#include <iostream>
#include <map>
#include <vector>
#include <array>
namespace CGAL {
@ -82,13 +83,25 @@ public:
private:
// 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;
public:
Triangulation_hierarchy_2(const Geom_traits& traits = Geom_traits());
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>
Triangulation_hierarchy_2(InputIterator first, InputIterator beyond,
const Geom_traits& traits = Geom_traits())
@ -102,6 +115,19 @@ public:
}
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();
//Helping
@ -390,8 +416,8 @@ void
Triangulation_hierarchy_2<Tr_>::
clear()
{
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i]->clear();
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
if(hierarchy[i]) hierarchy[i]->clear();
}
@ -723,7 +749,7 @@ locate_in_all(const Point& p,
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) {
pos[level]=position=hierarchy[level]->locate(p, position);
// locate at that level from "position"

View File

@ -41,13 +41,13 @@ public:
};
Triangulation_hierarchy_vertex_base_2()
: Base(), _up(0), _down(0)
: Base()
{}
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)
: Base(p), _up(0), _down(0)
: Base(p)
{}
Vertex_handle up() {return _up;}
@ -57,8 +57,8 @@ public:
private:
Vertex_handle _up; // same vertex one level above
Vertex_handle _down; // same vertex one level below
Vertex_handle _up = nullptr; // same vertex one level above
Vertex_handle _down = nullptr; // same vertex one level below
};
} //namespace CGAL

View File

@ -30,6 +30,16 @@ template <class Triangul>
void
_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 typename Triangul::Geom_traits Gt;

View File

@ -92,6 +92,16 @@ template <class Triang>
void
_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 typename Triang::Geom_traits Gt;

View File

@ -39,6 +39,11 @@ template <class Del>
void
_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 typename Del::Point Point;
typedef typename Del::Locate_type Locate_type;

View File

@ -39,6 +39,10 @@ template <class Triangul>
void
_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;
// We assume the traits class has been tested already

View File

@ -36,7 +36,6 @@ protected:
double _x, _y;
public:
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 hx, double hy, double hw) :
_x(hx/hw), _y(hy/hw)
@ -47,7 +46,6 @@ public:
bool compare(const Point &p) const
{ return test_x()==p.test_x() && test_y()==p.test_y(); }
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; }
bool operator==(const Point &p) const {return this->compare(p);}
};
@ -436,11 +434,6 @@ public:
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_object() const
{ return Less_x_2();}

View File

@ -888,11 +888,6 @@ protected:
: 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()
void operator()(const tbb::blocked_range<size_t>& r) const
{
@ -968,12 +963,6 @@ protected:
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()
void operator()(const tbb::blocked_range<size_t>& r) const
{
@ -1047,12 +1036,6 @@ protected:
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()
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)
{}
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&
operator=(const Delaunay_triangulation_cell_base_with_circumcenter_3 &c)
{
@ -71,6 +77,14 @@ public:
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(
Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3)

View File

@ -199,21 +199,38 @@ public:
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)
{
// The 'vertices' and 'hidden_points' members of 'hidden_point_visitor' should be empty
// as they are only filled (and cleared) during the insertion of a point.
// Hidden points are not stored there, but rather in cells. Thus, the only thing that must be set
// is the triangulation pointer.
Hidden_point_visitor<Concurrency_tag> new_hpv(this);
std::swap(hidden_point_visitor, new_hpv);
// The 'vertices' and 'hidden_points' members of
// 'hidden_point_visitor' should be empty as they are only filled
// (and cleared) during the insertion of a point. Hidden points
// are not stored there, but rather in cells. Thus, the only thing
// that must be set is the triangulation pointer, and it is
// already correctly set. There is nothing to do about
// 'hidden_point_visitor'.
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;
}
@ -1393,11 +1410,6 @@ protected:
: 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()
void operator()(const tbb::blocked_range<size_t>& r) const
{
@ -1504,12 +1516,6 @@ protected:
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()
void operator()(const tbb::blocked_range<size_t>& r) const
{
@ -1621,12 +1627,6 @@ protected:
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()
void operator()(const tbb::blocked_range<size_t>& r) const
{

View File

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

View File

@ -50,6 +50,8 @@
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <array>
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
namespace CGAL {
@ -91,7 +93,7 @@ public:
private:
// here is the stack of triangulations which form the hierarchy
Tr_Base* hierarchy[maxlevel];
std::array<Tr_Base*,maxlevel> hierarchy;
boost::rand48 random;
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(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 >
Triangulation_hierarchy_3(InputIterator first, InputIterator last,
const Geom_traits& traits = Geom_traits())
@ -124,9 +138,32 @@ public:
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();
@ -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>
void
Triangulation_hierarchy_3<Tr>::

View File

@ -19,6 +19,7 @@
#include <fstream>
#include <list>
#include <vector>
#include <type_traits>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
@ -170,6 +171,11 @@ _test_cls_delaunay_3(const Triangulation &)
{
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;
// We assume the traits class has been tested already

View File

@ -15,12 +15,19 @@
#include <iostream>
#include <fstream>
#include <list>
#include <type_traits>
#include <CGAL/use.h>
template <class Triangulation>
void
_test_cls_regular_3(const Triangulation &)
{
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;
CGAL_USE_TYPE(Gt);

View File

@ -15,6 +15,7 @@
#include <fstream>
#include <list>
#include <vector>
#include <type_traits>
#include "_test_cls_iterator.h"
#include "_test_cls_circulator.h"
@ -79,6 +80,11 @@ _test_cls_triangulation_3(const Triangulation &)
{
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
// actually, any traits is good if it has been tested