Skip to content

Commit

Permalink
Merge pull request #6495 from afabri/Surface_mesh-move-GF
Browse files Browse the repository at this point in the history
Surface_mesh: Add move semantics
  • Loading branch information
lrineau committed May 6, 2022
2 parents 3177ec9 + 3072b93 commit 6da2784
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "id_printing.h"
#include <unordered_map>
#include <functional>
#include <utility>
#endif

typedef CGAL::Three::Triangle_container Tri;
Expand Down Expand Up @@ -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); }
Expand Down
3 changes: 2 additions & 1 deletion Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
34 changes: 31 additions & 3 deletions Surface_mesh/include/CGAL/Surface_mesh/Properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,19 @@ class Property_container
public:

// default constructor
Property_container() : size_(0), capacity_(0) {}
Property_container() = default;

// destructor (deletes all property arrays)
virtual ~Property_container() { clear(); }

// 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)
{
Expand All @@ -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; i<parrays_.size(); ++i){
Expand Down Expand Up @@ -495,12 +508,13 @@ class Property_container
{
this->parrays_.swap (other.parrays_);
std::swap(this->size_, other.size_);
std::swap(this->capacity_, other.capacity_);
}

private:
std::vector<Base_property_array*> parrays_;
size_t size_;
size_t capacity_;
size_t size_ = 0;
size_t capacity_ = 0;
};

/// @endcond
Expand Down Expand Up @@ -554,6 +568,20 @@ class Property_map_base
/// @cond CGAL_DOCUMENT_INTERNALS
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()
{
parray_ = nullptr;
Expand Down
51 changes: 50 additions & 1 deletion Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class Surface_mesh
{
typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base;
typedef typename Base::reference reference;
Property_map() : Base() {}
Property_map() = default;
Property_map(const Base& pm): Base(pm) {}
};

Expand Down Expand Up @@ -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<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.
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.
Surface_mesh& assign(const Surface_mesh& rhs);

Expand Down
35 changes: 35 additions & 0 deletions Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -244,6 +278,7 @@ int main()
border_vertex_check();
point_position_accessor();
properties();
move();
std::cout << "done" << std::endl;
return 0;
}

0 comments on commit 6da2784

Please sign in to comment.