diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp index 1c70997728ac..608fcc637305 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp @@ -168,7 +168,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_tr scene->addItem(group); 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->setColor(color_map[cc]); ++cc; diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 7e5d45a15b27..bf2ceccb0f71 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -51,6 +51,7 @@ #include "id_printing.h" #include #include +#include #endif typedef CGAL::Three::Triangle_container Tri; @@ -350,11 +351,16 @@ Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* 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)); } +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::clone() const { return new Scene_surface_mesh_item(*this); } diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h index d04f771899b3..68ffb958dfb9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h @@ -48,7 +48,8 @@ class SCENE_SURFACE_MESH_ITEM_EXPORT Scene_surface_mesh_item Scene_surface_mesh_item(); // Takes ownership of the argument. 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(); diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h index 825d414e7071..9fc752bb6639 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h @@ -234,7 +234,7 @@ class Property_container public: // default constructor - Property_container() : size_(0), capacity_(0) {} + Property_container() = default; // destructor (deletes all property arrays) virtual ~Property_container() { clear(); } @@ -242,6 +242,11 @@ class Property_container // copy constructor: performs deep copy of property arrays Property_container(const Property_container& _rhs) { operator=(_rhs); } + Property_container(Property_container&& c) noexcept + { + c.swap(*this); + } + // assignment: performs deep copy of property arrays Property_container& operator=(const Property_container& _rhs) { @@ -257,6 +262,14 @@ class Property_container 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) { for(std::size_t i=0; iparrays_.swap (other.parrays_); std::swap(this->size_, other.size_); + std::swap(this->capacity_, other.capacity_); } private: std::vector parrays_; - size_t size_; - size_t capacity_; + size_t size_ = 0; + size_t capacity_ = 0; }; /// @endcond @@ -554,6 +568,20 @@ class Property_map_base /// @cond CGAL_DOCUMENT_INTERNALS Property_map_base(Property_array* 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() { parray_ = nullptr; diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 2127f3c8ed34..580d8b6819c5 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -341,7 +341,7 @@ class Surface_mesh { typedef Properties::Property_map_base > Base; typedef typename Base::reference reference; - Property_map() : Base() {} + Property_map() = default; Property_map(const Base& pm): Base(pm) {} }; @@ -914,9 +914,58 @@ class Surface_mesh /// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties. 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::max)())) + , edges_freelist_(std::exchange(sm.edges_freelist_,(std::numeric_limits::max)())) + , faces_freelist_(std::exchange(sm.faces_freelist_,(std::numeric_limits::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. 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::max)()); + edges_freelist_ = std::exchange(sm.edges_freelist_,(std::numeric_limits::max)()); + faces_freelist_ = std::exchange(sm.faces_freelist_,(std::numeric_limits::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. Surface_mesh& assign(const Surface_mesh& rhs); diff --git a/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp b/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp index 949d2538bff6..16fb699982c5 100644 --- a/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp +++ b/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp @@ -230,6 +230,40 @@ void properties () { 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() { @@ -244,6 +278,7 @@ int main() border_vertex_check(); point_position_accessor(); properties(); + move(); std::cout << "done" << std::endl; return 0; }