fix handling of std::move()

This commit is contained in:
conrad
2022-09-06 13:06:23 +10:00
parent afa69f6559
commit 47219263d8
5 changed files with 108 additions and 22 deletions
+30 -6
View File
@@ -421,14 +421,38 @@ Col<eT>::operator=(Col<eT>&& 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<eT>::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<eT>::n_rows) = X.n_rows;
access::rw(Mat<eT>::n_elem) = X.n_elem;
access::rw(Mat<eT>::n_alloc) = X.n_alloc;
access::rw(Mat<eT>::mem_state) = X.mem_state;
access::rw(Mat<eT>::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<eT>& 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;
+2 -1
View File
@@ -428,7 +428,8 @@ class Cube : public BaseCube< eT, Cube<eT> >
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<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> class fixed;
+15 -3
View File
@@ -291,7 +291,7 @@ Cube<eT>::Cube(Cube<eT>&& 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<eT>::operator=(Cube<eT>&& 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<eT>::steal_mem(Cube<eT>& x)
{
arma_extra_debug_sigprint();
(*this).steal_mem(x, false);
}
template<typename eT>
inline
void
Cube<eT>::steal_mem(Cube<eT>& 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");
+31 -6
View File
@@ -792,14 +792,39 @@ Mat<eT>::operator=(Mat<eT>&& 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<eT>& 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;
+30 -6
View File
@@ -421,14 +421,38 @@ Row<eT>::operator=(Row<eT>&& 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<eT>::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<eT>::n_cols) = X.n_cols;
access::rw(Mat<eT>::n_elem) = X.n_elem;
access::rw(Mat<eT>::n_alloc) = X.n_alloc;
access::rw(Mat<eT>::mem_state) = X.mem_state;
access::rw(Mat<eT>::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<eT>& 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;