Merge pull request #6495 from afabri/Surface_mesh-move-GF

Surface_mesh: Add move semantics
This commit is contained in:
Laurent Rineau 2022-05-06 14:22:06 +02:00
commit 6da27847c5
6 changed files with 126 additions and 7 deletions

View File

@ -168,7 +168,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_tr
scene->addItem(group); scene->addItem(group);
for(FaceGraph& poly : new_polyhedra) for(FaceGraph& poly : new_polyhedra)
{ {
Scene_facegraph_item* new_item=new Scene_facegraph_item(poly); Scene_facegraph_item* new_item=new Scene_facegraph_item(std::move(poly));
new_item->setName(tr("%1 - CC %2").arg(item->name()).arg(cc)); new_item->setName(tr("%1 - CC %2").arg(item->name()).arg(cc));
new_item->setColor(color_map[cc]); new_item->setColor(color_map[cc]);
++cc; ++cc;

View File

@ -51,6 +51,7 @@
#include "id_printing.h" #include "id_printing.h"
#include <unordered_map> #include <unordered_map>
#include <functional> #include <functional>
#include <utility>
#endif #endif
typedef CGAL::Three::Triangle_container Tri; typedef CGAL::Three::Triangle_container Tri;
@ -350,11 +351,16 @@ Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* sm)
standard_constructor(sm); standard_constructor(sm);
} }
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh sm) Scene_surface_mesh_item::Scene_surface_mesh_item(const SMesh& sm)
{ {
standard_constructor(new SMesh(sm)); standard_constructor(new SMesh(sm));
} }
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh&& sm)
{
standard_constructor(new SMesh(std::move(sm)));
}
Scene_surface_mesh_item* Scene_surface_mesh_item*
Scene_surface_mesh_item::clone() const Scene_surface_mesh_item::clone() const
{ return new Scene_surface_mesh_item(*this); } { return new Scene_surface_mesh_item(*this); }

View File

@ -48,7 +48,8 @@ public:
Scene_surface_mesh_item(); Scene_surface_mesh_item();
// Takes ownership of the argument. // Takes ownership of the argument.
Scene_surface_mesh_item(SMesh*); Scene_surface_mesh_item(SMesh*);
Scene_surface_mesh_item(SMesh); Scene_surface_mesh_item(const SMesh&);
Scene_surface_mesh_item(SMesh&&);
Scene_surface_mesh_item(const Scene_surface_mesh_item& other); Scene_surface_mesh_item(const Scene_surface_mesh_item& other);
~Scene_surface_mesh_item(); ~Scene_surface_mesh_item();

View File

@ -234,7 +234,7 @@ class Property_container
public: public:
// default constructor // default constructor
Property_container() : size_(0), capacity_(0) {} Property_container() = default;
// destructor (deletes all property arrays) // destructor (deletes all property arrays)
virtual ~Property_container() { clear(); } virtual ~Property_container() { clear(); }
@ -242,6 +242,11 @@ public:
// copy constructor: performs deep copy of property arrays // copy constructor: performs deep copy of property arrays
Property_container(const Property_container& _rhs) { operator=(_rhs); } Property_container(const Property_container& _rhs) { operator=(_rhs); }
Property_container(Property_container&& c) noexcept
{
c.swap(*this);
}
// assignment: performs deep copy of property arrays // assignment: performs deep copy of property arrays
Property_container& operator=(const Property_container& _rhs) Property_container& operator=(const Property_container& _rhs)
{ {
@ -257,6 +262,14 @@ public:
return *this; return *this;
} }
Property_container& operator=(Property_container&& c) noexcept
{
Property_container tmp(std::move(c));
tmp.swap(*this);
return *this;
}
void transfer(const Property_container& _rhs) void transfer(const Property_container& _rhs)
{ {
for(std::size_t i=0; i<parrays_.size(); ++i){ for(std::size_t i=0; i<parrays_.size(); ++i){
@ -495,12 +508,13 @@ public:
{ {
this->parrays_.swap (other.parrays_); this->parrays_.swap (other.parrays_);
std::swap(this->size_, other.size_); std::swap(this->size_, other.size_);
std::swap(this->capacity_, other.capacity_);
} }
private: private:
std::vector<Base_property_array*> parrays_; std::vector<Base_property_array*> parrays_;
size_t size_; size_t size_ = 0;
size_t capacity_; size_t capacity_ = 0;
}; };
/// @endcond /// @endcond
@ -554,6 +568,20 @@ public:
/// @cond CGAL_DOCUMENT_INTERNALS /// @cond CGAL_DOCUMENT_INTERNALS
Property_map_base(Property_array<T>* p=nullptr) : parray_(p) {} Property_map_base(Property_array<T>* p=nullptr) : parray_(p) {}
Property_map_base(Property_map_base&& pm) noexcept
: parray_(std::exchange(pm.parray_, nullptr))
{}
Property_map_base(const Property_map_base& pm)
: parray_(pm.parray_)
{}
Property_map_base& operator=(const Property_map_base& pm)
{
parray_ = pm.parray_;
return *this;
}
void reset() void reset()
{ {
parray_ = nullptr; parray_ = nullptr;

View File

@ -341,7 +341,7 @@ public:
{ {
typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base; typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base;
typedef typename Base::reference reference; typedef typename Base::reference reference;
Property_map() : Base() {} Property_map() = default;
Property_map(const Base& pm): Base(pm) {} Property_map(const Base& pm): Base(pm) {}
}; };
@ -914,9 +914,58 @@ public:
/// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties. /// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh(const Surface_mesh& rhs) { *this = rhs; } Surface_mesh(const Surface_mesh& rhs) { *this = rhs; }
Surface_mesh(Surface_mesh&& sm)
: vprops_(std::move(sm.vprops_))
, hprops_(std::move(sm.hprops_))
, eprops_(std::move(sm.eprops_))
, fprops_(std::move(sm.fprops_))
, vconn_(std::move(sm.vconn_))
, hconn_(std::move(sm.hconn_))
, fconn_(std::move(sm.fconn_))
, vremoved_(std::move(sm.vremoved_))
, eremoved_(std::move(sm.eremoved_))
, fremoved_(std::move(sm.fremoved_))
, vpoint_(std::move(sm.vpoint_))
, removed_vertices_(std::exchange(sm.removed_vertices_, 0))
, removed_edges_(std::exchange(sm.removed_edges_, 0))
, removed_faces_(std::exchange(sm.removed_faces_, 0))
, vertices_freelist_(std::exchange(sm.vertices_freelist_,(std::numeric_limits<size_type>::max)()))
, edges_freelist_(std::exchange(sm.edges_freelist_,(std::numeric_limits<size_type>::max)()))
, faces_freelist_(std::exchange(sm.faces_freelist_,(std::numeric_limits<size_type>::max)()))
, garbage_(std::exchange(sm.garbage_, false))
, recycle_(std::exchange(sm.recycle_, true))
, anonymous_property_(std::exchange(sm.anonymous_property_, 0))
{}
/// assigns `rhs` to `*this`. Performs a deep copy of all properties. /// assigns `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh& operator=(const Surface_mesh& rhs); Surface_mesh& operator=(const Surface_mesh& rhs);
Surface_mesh& operator=(Surface_mesh&& sm)
{
vprops_ = std::move(sm.vprops_);
hprops_ = std::move(sm.hprops_);
eprops_ = std::move(sm.eprops_);
fprops_ = std::move(sm.fprops_);
vconn_ = std::move(sm.vconn_);
hconn_ = std::move(sm.hconn_);
fconn_ = std::move(sm.fconn_);
vremoved_ = std::move(sm.vremoved_);
eremoved_ = std::move(sm.eremoved_);
fremoved_ = std::move(sm.fremoved_);
vpoint_ = std::move(sm.vpoint_);
removed_vertices_ = std::exchange(sm.removed_vertices_, 0);
removed_edges_ = std::exchange(sm.removed_edges_, 0);
removed_faces_ = std::exchange(sm.removed_faces_, 0);
vertices_freelist_ = std::exchange(sm.vertices_freelist_, (std::numeric_limits<size_type>::max)());
edges_freelist_ = std::exchange(sm.edges_freelist_,(std::numeric_limits<size_type>::max)());
faces_freelist_ = std::exchange(sm.faces_freelist_,(std::numeric_limits<size_type>::max)());
garbage_ = std::exchange(sm.garbage_, false);
recycle_ = std::exchange(sm.recycle_, true);
anonymous_property_ = std::exchange(sm.anonymous_property_, 0);
return *this;
}
/// assigns `rhs` to `*this`. Does not copy custom properties. /// assigns `rhs` to `*this`. Does not copy custom properties.
Surface_mesh& assign(const Surface_mesh& rhs); Surface_mesh& assign(const Surface_mesh& rhs);

View File

@ -230,6 +230,40 @@ void properties () {
assert(created == false); assert(created == false);
} }
void move () {
Surface_fixture f;
auto nf = num_faces(f.m);
// test move-constructor
Sm m2{std::move(f.m)};
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(m2) == nf);
assert(num_faces(f.m) == 0);
// test move-assignment
f.m = std::move(m2);
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == 0);
// test copy-assignment
m2 = f.m;
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == nf);
// test copy-constructor
Sm m3 {f.m};
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == nf);
}
int main() int main()
{ {
@ -244,6 +278,7 @@ int main()
border_vertex_check(); border_vertex_check();
point_position_accessor(); point_position_accessor();
properties(); properties();
move();
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
return 0; return 0;
} }