diff liboctave/array/Array.h @ 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 823b4bcf79fc
children e69da2dae19c
line wrap: on
line diff
--- 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);