mirror of https://github.com/CGAL/cgal
Merge pull request #5409 from lrineau/Triangulation_3-fix__move__semantic__of__Triangulation_hierarchy_3-GF
Fix the move-semantic of Triangulation_hierarchy_3
This commit is contained in:
commit
0539b1ab3a
|
|
@ -13,11 +13,8 @@
|
|||
#define CGAL_ARRAY_H
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#ifndef CGAL_CFG_NO_CPP0X_ARRAY
|
||||
# include <array>
|
||||
#else
|
||||
# include <boost/array.hpp>
|
||||
#endif
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -49,7 +46,7 @@ namespace CGAL {
|
|||
// It's also untrue that this is not documented... It is !
|
||||
|
||||
template< typename T, typename... Args >
|
||||
inline
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
std::array< T, 1 + sizeof...(Args) >
|
||||
make_array(const T & t, const Args & ... args)
|
||||
{
|
||||
|
|
@ -62,12 +59,27 @@ make_array(const T & t, const Args & ... args)
|
|||
struct Construct_array
|
||||
{
|
||||
template <typename T, typename... Args>
|
||||
std::array<T, 1 + sizeof...(Args)> operator()(const T& t, const Args& ... args)
|
||||
constexpr
|
||||
std::array<T, 1 + sizeof...(Args)>
|
||||
operator()(const T& t, const Args& ... args) const
|
||||
{
|
||||
return make_array (t, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t...Is, typename T>
|
||||
constexpr std::array<T, sizeof...(Is)>
|
||||
make_filled_array_aux(const T& value, std::index_sequence<Is...>)
|
||||
{
|
||||
return {(static_cast<void>(Is), value)...};
|
||||
}
|
||||
|
||||
template <std::size_t N, typename T>
|
||||
constexpr std::array<T, N> make_filled_array(const T& value)
|
||||
{
|
||||
return make_filled_array_aux(value, std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_ARRAY_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2021 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Laurent Rineau
|
||||
//
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Testsuite {
|
||||
namespace Triangulation_23 {
|
||||
template <typename Tr>
|
||||
void test_move_semantic(Tr source_tr) {
|
||||
const auto dimension = source_tr.dimension();
|
||||
const auto nb_of_vertices = source_tr.number_of_vertices();
|
||||
auto check_triangulation_validity = [&](const Tr& tr) {
|
||||
assert(tr.is_valid());
|
||||
assert(tr.number_of_vertices() == nb_of_vertices);
|
||||
assert(tr.dimension() == dimension);
|
||||
};
|
||||
auto check_moved_from_triangulation = [](const Tr& tr_copy) {
|
||||
assert(tr_copy.dimension() == -2);
|
||||
assert(tr_copy.number_of_vertices() + 1 == 0);
|
||||
};
|
||||
auto check_empty_triangulation = [](const Tr& tr_copy2) {
|
||||
assert(tr_copy2.dimension() == -1);
|
||||
assert(tr_copy2.number_of_vertices() == 0);
|
||||
};
|
||||
// move constructor
|
||||
{
|
||||
Tr tr_copy(source_tr);
|
||||
check_triangulation_validity(tr_copy);
|
||||
|
||||
Tr tr_move_constructed(std::move(tr_copy));
|
||||
check_triangulation_validity(tr_move_constructed);
|
||||
check_moved_from_triangulation(tr_copy);
|
||||
|
||||
Tr tr_copy2(source_tr);
|
||||
Tr tr_move_constructed2(std::move(tr_copy2));
|
||||
check_moved_from_triangulation(tr_copy2);
|
||||
tr_copy2.clear();
|
||||
check_empty_triangulation(tr_copy2);
|
||||
|
||||
Tr tr_copy3(source_tr);
|
||||
Tr tr_move_constructed3(std::move(tr_copy3));
|
||||
check_moved_from_triangulation(tr_copy3);
|
||||
tr_copy3 = source_tr;
|
||||
check_triangulation_validity(tr_copy3);
|
||||
}
|
||||
// move-assignment
|
||||
{
|
||||
Tr tr_copy4(source_tr);
|
||||
Tr tr_move_assigned;
|
||||
tr_move_assigned = std::move(tr_copy4);
|
||||
check_triangulation_validity(tr_move_assigned);
|
||||
check_moved_from_triangulation(tr_copy4);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <CGAL/array.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -82,7 +83,14 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
// here is the stack of triangulations which form the hierarchy
|
||||
void init_hierarchy() {
|
||||
hierarchy[0] = this;
|
||||
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i)
|
||||
hierarchy[i] = &hierarchy_triangulations[i-1];
|
||||
}
|
||||
|
||||
// here is the stack of triangulations which form the hierarchy
|
||||
std::array<Tr_Base,Triangulation_hierarchy_2__maxlevel-1> hierarchy_triangulations;
|
||||
std::array<Tr_Base*,Triangulation_hierarchy_2__maxlevel> hierarchy;
|
||||
boost::rand48 random;
|
||||
|
||||
|
|
@ -93,13 +101,10 @@ public:
|
|||
Triangulation_hierarchy_2(Triangulation_hierarchy_2&& other)
|
||||
noexcept( noexcept(Tr_Base(std::move(other))) )
|
||||
: Tr_Base(std::move(other))
|
||||
, hierarchy_triangulations(std::move(other.hierarchy_triangulations))
|
||||
, 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;
|
||||
}
|
||||
init_hierarchy();
|
||||
}
|
||||
|
||||
template<class InputIterator>
|
||||
|
|
@ -107,10 +112,7 @@ public:
|
|||
const Geom_traits& traits = Geom_traits())
|
||||
: Tr_Base(traits)
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
|
||||
hierarchy[i] = new Tr_Base(traits);
|
||||
|
||||
init_hierarchy();
|
||||
insert (first, beyond);
|
||||
}
|
||||
|
||||
|
|
@ -120,15 +122,11 @@ public:
|
|||
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;
|
||||
}
|
||||
hierarchy_triangulations = std::move(other.hierarchy_triangulations);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Triangulation_hierarchy_2();
|
||||
~Triangulation_hierarchy_2() = default;
|
||||
|
||||
//Helping
|
||||
void copy_triangulation(const Triangulation_hierarchy_2 &tr);
|
||||
|
|
@ -293,10 +291,11 @@ template <class Tr_>
|
|||
Triangulation_hierarchy_2<Tr_>::
|
||||
Triangulation_hierarchy_2(const Geom_traits& traits)
|
||||
: Tr_Base(traits)
|
||||
, hierarchy_triangulations(
|
||||
make_filled_array<Triangulation_hierarchy_2__maxlevel-1,
|
||||
Tr_Base>(traits))
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
|
||||
hierarchy[i] = new Tr_Base(traits);
|
||||
init_hierarchy();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -304,12 +303,8 @@ Triangulation_hierarchy_2(const Geom_traits& traits)
|
|||
template <class Tr_>
|
||||
Triangulation_hierarchy_2<Tr_>::
|
||||
Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr_> &tr)
|
||||
: Tr_Base()
|
||||
: Triangulation_hierarchy_2(tr.geom_traits())
|
||||
{
|
||||
// create an empty triangulation to be able to delete it !
|
||||
hierarchy[0] = this;
|
||||
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
|
||||
hierarchy[i] = new Tr_Base(tr.geom_traits());
|
||||
copy_triangulation(tr);
|
||||
}
|
||||
|
||||
|
|
@ -392,23 +387,9 @@ void
|
|||
Triangulation_hierarchy_2<Tr_>::
|
||||
swap(Triangulation_hierarchy_2<Tr_> &tr)
|
||||
{
|
||||
Tr_Base* temp;
|
||||
Tr_Base::swap(tr);
|
||||
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){
|
||||
temp = hierarchy[i];
|
||||
hierarchy[i] = tr.hierarchy[i];
|
||||
tr.hierarchy[i]= temp;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tr_>
|
||||
Triangulation_hierarchy_2<Tr_>::
|
||||
~Triangulation_hierarchy_2()
|
||||
{
|
||||
clear();
|
||||
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){
|
||||
delete hierarchy[i];
|
||||
}
|
||||
using std::swap;
|
||||
swap(hierarchy_triangulations, tr.hierarchy_triangulations);
|
||||
}
|
||||
|
||||
template <class Tr_>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <CGAL/_test_fct_is_infinite.h>
|
||||
#include <CGAL/_test_triangulation_iterators.h>
|
||||
#include <CGAL/_test_triangulation_circulators.h>
|
||||
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
|
||||
|
||||
|
||||
template <class Triangul>
|
||||
|
|
@ -281,6 +282,15 @@ _test_cls_triangulation_short_2( const Triangul &)
|
|||
assert( T2_3_4.number_of_vertices() == 11 );
|
||||
assert( T2_3_4.is_valid() );
|
||||
|
||||
/****************************/
|
||||
/******* MOVE SEMANTIC*******/
|
||||
|
||||
std::cout << " move constructors and move assignment" << std::endl;
|
||||
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
|
||||
test_tr_23::test_move_semantic(T0_1);
|
||||
test_tr_23::test_move_semantic(T1_5);
|
||||
test_tr_23::test_move_semantic(T2_8);
|
||||
test_tr_23::test_move_semantic(T2_3);
|
||||
|
||||
/*********************************************/
|
||||
/****** FINITE/INFINITE VERTICES/FACES *******/
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <CGAL/array.h>
|
||||
|
||||
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||
|
||||
|
|
@ -92,7 +93,14 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void init_hierarchy() {
|
||||
hierarchy[0] = this;
|
||||
for(int i=1; i<maxlevel; ++i)
|
||||
hierarchy[i] = &hierarchy_triangulations[i-1];
|
||||
}
|
||||
|
||||
// here is the stack of triangulations which form the hierarchy
|
||||
std::array<Tr_Base,maxlevel-1> hierarchy_triangulations;
|
||||
std::array<Tr_Base*,maxlevel> hierarchy;
|
||||
boost::rand48 random;
|
||||
|
||||
|
|
@ -111,24 +119,20 @@ public:
|
|||
Triangulation_hierarchy_3(Triangulation_hierarchy_3&& other)
|
||||
noexcept( noexcept(Tr_Base(std::move(other))) )
|
||||
: Tr_Base(std::move(other))
|
||||
, hierarchy_triangulations(std::move(other.hierarchy_triangulations))
|
||||
, random(std::move(other.random))
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1; i<maxlevel; ++i) {
|
||||
hierarchy[i] = other.hierarchy[i];
|
||||
other.hierarchy[i] = nullptr;
|
||||
}
|
||||
init_hierarchy();
|
||||
}
|
||||
|
||||
template < typename InputIterator >
|
||||
Triangulation_hierarchy_3(InputIterator first, InputIterator last,
|
||||
const Geom_traits& traits = Geom_traits())
|
||||
: Tr_Base(traits)
|
||||
, hierarchy_triangulations(make_filled_array<maxlevel-1, Tr_Base>(traits))
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1; i<maxlevel; ++i)
|
||||
hierarchy[i] = new Tr_Base(traits);
|
||||
insert(first, last);
|
||||
init_hierarchy();
|
||||
insert(first, last);
|
||||
}
|
||||
|
||||
Triangulation_hierarchy_3 & operator=(const Triangulation_hierarchy_3& tr)
|
||||
|
|
@ -142,27 +146,17 @@ public:
|
|||
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;
|
||||
}
|
||||
hierarchy_triangulations = std::move(other.hierarchy_triangulations);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Triangulation_hierarchy_3()
|
||||
{
|
||||
clear();
|
||||
for(int i=1; i<maxlevel; ++i) {
|
||||
delete hierarchy[i];
|
||||
}
|
||||
};
|
||||
~Triangulation_hierarchy_3() = default;
|
||||
|
||||
void swap(Triangulation_hierarchy_3 &tr)
|
||||
{
|
||||
Tr_Base::swap(tr);
|
||||
for(int i=1; i<maxlevel; ++i)
|
||||
std::swap(hierarchy[i], tr.hierarchy[i]);
|
||||
using std::swap;
|
||||
swap(hierarchy_triangulations, tr.hierarchy_triangulations);
|
||||
};
|
||||
|
||||
void clear();
|
||||
|
|
@ -460,10 +454,9 @@ template <class Tr >
|
|||
Triangulation_hierarchy_3<Tr>::
|
||||
Triangulation_hierarchy_3(const Geom_traits& traits)
|
||||
: Tr_Base(traits)
|
||||
, hierarchy_triangulations(make_filled_array<maxlevel-1, Tr_Base>(traits))
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1;i<maxlevel;++i)
|
||||
hierarchy[i] = new Tr_Base(traits);
|
||||
init_hierarchy();
|
||||
}
|
||||
|
||||
// copy constructor duplicates vertices and cells
|
||||
|
|
@ -471,10 +464,9 @@ template <class Tr>
|
|||
Triangulation_hierarchy_3<Tr>::
|
||||
Triangulation_hierarchy_3(const Triangulation_hierarchy_3<Tr> &tr)
|
||||
: Tr_Base(tr)
|
||||
, hierarchy_triangulations(tr.hierarchy_triangulations)
|
||||
{
|
||||
hierarchy[0] = this;
|
||||
for(int i=1; i<maxlevel; ++i)
|
||||
hierarchy[i] = new Tr_Base(*tr.hierarchy[i]);
|
||||
init_hierarchy();
|
||||
|
||||
// up and down have been copied in straightforward way
|
||||
// compute a map at lower level
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Testsuite/use.h>
|
||||
#include <CGAL/internal/Has_nested_type_Bare_point.h>
|
||||
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
|
||||
|
||||
// Accessory set of functions to differentiate between
|
||||
// Delaunay::nearest_vertex[_in_cell] and
|
||||
|
|
@ -421,7 +422,8 @@ _test_cls_delaunay_3(const Triangulation &)
|
|||
assert(T1.number_of_vertices() == 0);
|
||||
assert(T1.is_valid());
|
||||
|
||||
|
||||
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
|
||||
test_tr_23::test_move_semantic(T0);
|
||||
|
||||
// Affectation :
|
||||
T1=T0;
|
||||
|
|
@ -454,6 +456,7 @@ _test_cls_delaunay_3(const Triangulation &)
|
|||
assert(T1_0.dimension()==1);
|
||||
assert(T1_0.number_of_vertices()==n);
|
||||
assert(T1_0.is_valid());
|
||||
test_tr_23::test_move_semantic(T1_0);
|
||||
std::cout << " Constructor7 " << std::endl;
|
||||
Cls T1_1;
|
||||
n = T1_1.insert(l2.begin(),l2.end());
|
||||
|
|
@ -514,6 +517,8 @@ _test_cls_delaunay_3(const Triangulation &)
|
|||
assert(T2_0.dimension()==2);
|
||||
assert(T2_0.number_of_vertices()==8);
|
||||
|
||||
test_tr_23::test_move_semantic(T2_0);
|
||||
|
||||
{
|
||||
Cls Tfromfile;
|
||||
std::cout << " I/O" << std::endl;
|
||||
|
|
@ -562,6 +567,8 @@ _test_cls_delaunay_3(const Triangulation &)
|
|||
assert(T3_0.number_of_vertices()==125);
|
||||
assert(T3_0.dimension()==3);
|
||||
|
||||
test_tr_23::test_move_semantic(T3_0);
|
||||
|
||||
if (del) {
|
||||
std::cout << " deletion in Delaunay - grid case - (dim 3) " <<
|
||||
std::endl;
|
||||
|
|
@ -1194,6 +1201,19 @@ _test_cls_delaunay_3(const Triangulation &)
|
|||
_test_remove_cluster<Triangulation>();
|
||||
}
|
||||
|
||||
// Test from issue https://github.com/CGAL/cgal/issues/5396
|
||||
{
|
||||
auto Triangulate = []() -> Triangulation
|
||||
{
|
||||
Triangulation tri;
|
||||
for (int i=0; i<10; i++)
|
||||
tri.insert(Point(i+1, i+2, i+3));
|
||||
|
||||
return tri;
|
||||
};
|
||||
auto t = Triangulate();
|
||||
auto t2 = std::move(t);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CGAL_TEST_CLS_DELAUNAY_C
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include <list>
|
||||
#include <type_traits>
|
||||
#include <CGAL/use.h>
|
||||
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
|
||||
|
||||
template <class Triangulation>
|
||||
void
|
||||
_test_cls_regular_3(const Triangulation &)
|
||||
|
|
@ -205,6 +207,7 @@ _test_cls_regular_3(const Triangulation &)
|
|||
<< T.number_of_vertices() << std::endl;
|
||||
assert(T.is_valid());
|
||||
assert(T.dimension()==3);
|
||||
|
||||
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
|
||||
test_tr_23::test_move_semantic(T);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Testsuite/use.h>
|
||||
#include <CGAL/use.h>
|
||||
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
|
||||
|
||||
template <class Triangulation, class Container>
|
||||
bool check_all_are_finite(Triangulation* tr, const Container& cont)
|
||||
|
|
@ -286,7 +287,8 @@ _test_cls_triangulation_3(const Triangulation &)
|
|||
assert(T1.number_of_vertices() == 0);
|
||||
assert(T1.is_valid());
|
||||
|
||||
|
||||
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
|
||||
test_tr_23::test_move_semantic(T0);
|
||||
|
||||
// Assignment
|
||||
T1=T0;
|
||||
|
|
@ -363,12 +365,14 @@ _test_cls_triangulation_3(const Triangulation &)
|
|||
assert(T2_0.dimension()==1);
|
||||
assert(T2_0.number_of_vertices()==3);
|
||||
|
||||
test_tr_23::test_move_semantic(T2_0);
|
||||
|
||||
v0=T2_0.insert(p4);
|
||||
assert(T2_0.is_valid());
|
||||
assert(T2_0.dimension()==2);
|
||||
assert(T2_0.number_of_vertices()==4);
|
||||
|
||||
test_tr_23::test_move_semantic(T2_0);
|
||||
|
||||
v0=T2_0.insert(p5);
|
||||
v0=T2_0.insert(p6);
|
||||
|
|
@ -380,6 +384,8 @@ _test_cls_triangulation_3(const Triangulation &)
|
|||
assert(T2_0.dimension()==2);
|
||||
assert(T2_0.number_of_vertices()==8);
|
||||
|
||||
test_tr_23::test_move_semantic(T2_0);
|
||||
|
||||
if (! del) // to avoid doing the following tests for both Delaunay
|
||||
// and non Delaunay triangulations
|
||||
{
|
||||
|
|
@ -403,6 +409,8 @@ _test_cls_triangulation_3(const Triangulation &)
|
|||
assert( T2_1.dimension()==2 );
|
||||
assert( T2_1.is_valid() );
|
||||
|
||||
test_tr_23::test_move_semantic(T2_1);
|
||||
|
||||
std::cout << " Constructor11 " << std::endl;
|
||||
// 3-dimensional triangulations
|
||||
// This is a simple grid :
|
||||
|
|
|
|||
Loading…
Reference in New Issue