Mercurial > octave
changeset 27352:7335ebd4c798
define some move constructors and assignment operators
* Array.h, dim-vector.h, str-vec.h, ov.h: Define move constructors and
assignment operators for the Array, dim_vector, string_vector, and
octave_value classes.
* ovl.h: Use default move constructor and assignment operator.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 21 Aug 2019 16:00:37 -0400 |
parents | 367066c92535 |
children | 8db55255c9d1 |
files | libinterp/octave-value/ov.h libinterp/octave-value/ovl.h liboctave/array/Array.h liboctave/array/dim-vector.h liboctave/util/str-vec.h |
diffstat | 5 files changed, 109 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov.h Wed Aug 21 05:49:38 2019 -0400 +++ b/libinterp/octave-value/ov.h Wed Aug 21 16:00:37 2019 -0400 @@ -302,11 +302,17 @@ // Copy constructor. octave_value (const octave_value& a) + : rep (a.rep) { - rep = a.rep; rep->count++; } + octave_value (octave_value&& a) + : rep (a.rep) + { + a.rep = nullptr; + } + // This should only be called for derived types. octave_base_value * clone (void) const; @@ -318,7 +324,11 @@ ~octave_value (void) { - if (--rep->count == 0) + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the move assignment operator in a similar way. + + if (rep && --rep->count == 0) delete rep; } @@ -367,6 +377,24 @@ return *this; } + octave_value& operator = (octave_value&& a) + { + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the destructor in a similar way. + + if (this != &a) + { + if (rep && --rep->count == 0) + delete rep; + + rep = a.rep; + a.rep = nullptr; + } + + return *this; + } + octave_idx_type get_count (void) const { return rep->count; } octave_base_value::type_conv_info numeric_conversion_function (void) const
--- a/libinterp/octave-value/ovl.h Wed Aug 21 05:49:38 2019 -0400 +++ b/libinterp/octave-value/ovl.h Wed Aug 21 16:00:37 2019 -0400 @@ -75,6 +75,8 @@ octave_value_list (const octave_value_list& obj) : m_data (obj.m_data), m_names (obj.m_names) { } + octave_value_list (octave_value_list&& obj) = default; + // Concatenation constructor. octave_value_list (const std::list<octave_value_list>&); @@ -91,6 +93,8 @@ return *this; } + octave_value_list& operator = (octave_value_list&& obj) = default; + Array<octave_value> array_value (void) const { Array<octave_value> retval;
--- a/liboctave/array/Array.h Wed Aug 21 05:49:38 2019 -0400 +++ b/liboctave/array/Array.h Wed Aug 21 16:00:37 2019 -0400 @@ -300,11 +300,24 @@ rep->count++; } + Array (Array<T>&& a) + : dimensions (std::move (a.dimensions)), rep (a.rep), + slice_data (a.slice_data), slice_len (a.slice_len) + { + a.rep = nullptr; + a.slice_data = nullptr; + a.slice_len = 0; + } + public: virtual ~Array (void) { - if (--rep->count == 0) + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the move assignment operator in a similar way. + + if (rep && --rep->count == 0) delete rep; } @@ -326,6 +339,31 @@ return *this; } + Array<T>& operator = (Array<T>&& a) + { + if (this != &a) + { + dimensions = std::move (a.dimensions); + + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the destructor in a similar way. + + if (rep && --rep->count == 0) + delete rep; + + rep = a.rep; + slice_data = a.slice_data; + slice_len = a.slice_len; + + a.rep = nullptr; + a.slice_data = nullptr; + a.slice_len = 0; + } + + return *this; + } + void fill (const T& val); void clear (void);
--- a/liboctave/array/dim-vector.h Wed Aug 21 05:49:38 2019 -0400 +++ b/liboctave/array/dim-vector.h Wed Aug 21 16:00:37 2019 -0400 @@ -258,7 +258,9 @@ dim_vector (const dim_vector& dv) : rep (dv.rep) { OCTAVE_ATOMIC_INCREMENT (&(count ())); } - // FIXME: Should be private, but required by array constructor for jit + dim_vector (dim_vector&& dv) : rep (dv.rep) { dv.rep = nullptr; } + +// FIXME: Should be private, but required by array constructor for jit explicit dim_vector (octave_idx_type *r) : rep (r) { } static dim_vector alloc (int n) @@ -280,9 +282,31 @@ return *this; } + dim_vector& operator = (dim_vector&& dv) + { + if (&dv != this) + { + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the destructor in a similar way. + + if (rep && OCTAVE_ATOMIC_DECREMENT (&(count ())) == 0) + freerep (); + + rep = dv.rep; + dv.rep = nullptr; + } + + return *this; + } + ~dim_vector (void) { - if (OCTAVE_ATOMIC_DECREMENT (&(count ())) == 0) + // Because we define a move constructor and a move assignment + // operator, rep may be a nullptr here. We should only need to + // protect the move assignment operator in a similar way. + + if (rep && OCTAVE_ATOMIC_DECREMENT (&(count ())) == 0) freerep (); }
--- a/liboctave/util/str-vec.h Wed Aug 21 05:49:38 2019 -0400 +++ b/liboctave/util/str-vec.h Wed Aug 21 16:00:37 2019 -0400 @@ -47,6 +47,8 @@ string_vector (const string_vector& s) : m_data (s.m_data) { } + string_vector (string_vector&& s) : m_data (std::move (s.m_data)) { } + //! Constructor for STL containers of std::string. //! //! Templated constructor for any template class with std::string as the @@ -71,6 +73,14 @@ return *this; } + string_vector& operator = (string_vector&& s) + { + if (this != &s) + m_data = std::move (s.m_data); + + return *this; + } + ~string_vector (void) = default; bool empty (void) const { return numel () == 0; }