diff --git a/include/armadillo_bits/Col_meat.hpp b/include/armadillo_bits/Col_meat.hpp index 6026343f..3a226e32 100644 --- a/include/armadillo_bits/Col_meat.hpp +++ b/include/armadillo_bits/Col_meat.hpp @@ -421,14 +421,38 @@ Col::operator=(Col&& X) { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); + if(this == &X) { return *this; } - if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) + if( (Mat::mem_state <= 1) && (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2)) { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 1; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = nullptr; + (*this).reset(); + + access::rw(Mat::n_rows) = X.n_rows; + access::rw(Mat::n_elem) = X.n_elem; + access::rw(Mat::n_alloc) = X.n_alloc; + access::rw(Mat::mem_state) = X.mem_state; + access::rw(Mat::mem) = X.mem; + + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 1; + access::rw(X.n_elem) = 0; + access::rw(X.n_alloc) = 0; + access::rw(X.mem_state) = 0; + access::rw(X.mem) = nullptr; + } + else + { + const Col& X_plain = X; // change && to & + + (*this).operator=(X_plain); + + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) + { + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 1; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; + } } return *this; diff --git a/include/armadillo_bits/Cube_bones.hpp b/include/armadillo_bits/Cube_bones.hpp index 2c0fd1bb..bce44c03 100644 --- a/include/armadillo_bits/Cube_bones.hpp +++ b/include/armadillo_bits/Cube_bones.hpp @@ -428,7 +428,8 @@ class Cube : public BaseCube< eT, Cube > inline void swap(Cube& B); - inline void steal_mem(Cube& X); //!< don't use this unless you're writing code internal to Armadillo + inline void steal_mem(Cube& X); //!< don't use this unless you're writing code internal to Armadillo + inline void steal_mem(Cube& X, const bool is_move); //!< don't use this unless you're writing code internal to Armadillo template class fixed; diff --git a/include/armadillo_bits/Cube_meat.hpp b/include/armadillo_bits/Cube_meat.hpp index d2c95afc..eeef8e6e 100644 --- a/include/armadillo_bits/Cube_meat.hpp +++ b/include/armadillo_bits/Cube_meat.hpp @@ -291,7 +291,7 @@ Cube::Cube(Cube&& in_cube) arma_extra_debug_sigprint_this(this); arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - (*this).steal_mem(in_cube); + (*this).steal_mem(in_cube, true); } @@ -303,7 +303,7 @@ Cube::operator=(Cube&& in_cube) { arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - (*this).steal_mem(in_cube); + (*this).steal_mem(in_cube, true); return *this; } @@ -5202,9 +5202,21 @@ Cube::steal_mem(Cube& x) { arma_extra_debug_sigprint(); + (*this).steal_mem(x, false); + } + + + +template +inline +void +Cube::steal_mem(Cube& x, const bool is_move) + { + arma_extra_debug_sigprint(); + if(this == &x) { return; } - if( (mem_state <= 1) && ( (x.n_alloc > Cube_prealloc::mem_n_elem) || (x.mem_state == 1) ) ) + if( (mem_state <= 1) && ( (x.n_alloc > Cube_prealloc::mem_n_elem) || (x.mem_state == 1) || (is_move && (x.mem_state == 2)) ) ) { arma_extra_debug_print("Cube::steal_mem(): stealing memory"); diff --git a/include/armadillo_bits/Mat_meat.hpp b/include/armadillo_bits/Mat_meat.hpp index aa94e99a..c5fd8cad 100644 --- a/include/armadillo_bits/Mat_meat.hpp +++ b/include/armadillo_bits/Mat_meat.hpp @@ -792,14 +792,39 @@ Mat::operator=(Mat&& X) { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); + if(this == &X) { return *this; } - if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) + if( (mem_state <= 1) && (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2)) { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = nullptr; + (*this).reset(); + + access::rw(n_rows) = X.n_rows; + access::rw(n_cols) = X.n_cols; + access::rw(n_elem) = X.n_elem; + access::rw(n_alloc) = X.n_alloc; + access::rw(mem_state) = X.mem_state; + access::rw(mem) = X.mem; + + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.n_alloc) = 0; + access::rw(X.mem_state) = 0; + access::rw(X.mem) = nullptr; + } + else + { + const Mat& X_plain = X; // change && to & + + (*this).operator=(X_plain); + + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) + { + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; + } } return *this; diff --git a/include/armadillo_bits/Row_meat.hpp b/include/armadillo_bits/Row_meat.hpp index 97ad4670..d838a9fe 100644 --- a/include/armadillo_bits/Row_meat.hpp +++ b/include/armadillo_bits/Row_meat.hpp @@ -421,14 +421,38 @@ Row::operator=(Row&& X) { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); + if(this == &X) { return *this; } - if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) + if( (Mat::mem_state <= 1) && (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2)) { - access::rw(X.n_rows) = 1; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = nullptr; + (*this).reset(); + + access::rw(Mat::n_cols) = X.n_cols; + access::rw(Mat::n_elem) = X.n_elem; + access::rw(Mat::n_alloc) = X.n_alloc; + access::rw(Mat::mem_state) = X.mem_state; + access::rw(Mat::mem) = X.mem; + + access::rw(X.n_rows) = 1; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.n_alloc) = 0; + access::rw(X.mem_state) = 0; + access::rw(X.mem) = nullptr; + } + else + { + const Row& X_plain = X; // change && to & + + (*this).operator=(X_plain); + + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) + { + access::rw(X.n_rows) = 1; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; + } } return *this;