Patchwork [v3] libstdc++/48848

login
register
mail settings
Submitter Paolo Carlini
Date May 3, 2011, 10:33 p.m.
Message ID <4DC082CC.3020302@oracle.com>
Download mbox | patch
Permalink /patch/93928/
State New
Headers show

Comments

Paolo Carlini - May 3, 2011, 10:33 p.m.
Hi,

tested x86_64-linux, committed to mainline.

As regards the move assignment operator, the only non-trivial bit of the 
patch, per today's discussion on the reflector, essentially we want to 
be consistent with the resolution of LWG 675, thus make sure first that 
the move-assigned-to object releases any owned resources. This implies 
that at minimum the FDIS should be amended to a linear in size(), 
instead of constant, complexity (also, the "as-if" verbiage about 
resize(v.size()) is evidently bogus, likely a pasto from the preceding 
copy-assignment operator).

Thanks,
Paolo.

////////////////////////////
2011-05-03  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/48848
	* include/std/valarray (valarray<>::valarray(valarray&&),
	valarray<>::operator=(valarray&&), valarray<>::swap): Add.
	* doc/xml/manual/status_cxx200x.xml: Update.
	* testsuite/26_numerics/valarray/moveable.cc: New.
	* testsuite/26_numerics/valarray/swap.cc: Likewise.

Patch

Index: doc/xml/manual/status_cxx200x.xml
===================================================================
--- doc/xml/manual/status_cxx200x.xml	(revision 173337)
+++ doc/xml/manual/status_cxx200x.xml	(working copy)
@@ -1960,11 +1960,10 @@ 
       <entry/>
     </row>
     <row>
-      <?dbhtml bgcolor="#B0B0B0" ?>
       <entry>26.6.2</entry>
       <entry>Class template <code>valarray</code></entry>
-      <entry>Partial</entry>
-      <entry>Missing move and swap operations</entry>
+      <entry>Y</entry>
+      <entry/>
     </row>
     <row>
       <entry>26.6.3</entry>
Index: include/std/valarray
===================================================================
--- include/std/valarray	(revision 173337)
+++ include/std/valarray	(working copy)
@@ -1,7 +1,7 @@ 
 // The template and inlines for the -*- C++ -*- valarray class.
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010
+// 2006, 2007, 2008, 2009, 2010, 2011
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -140,6 +140,11 @@ 
       ///  Copy constructor.
       valarray(const valarray&);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      ///  Move constructor.
+      valarray(valarray&&) noexcept;
+#endif
+
       ///  Construct an array with the same size and values in @a sa.
       valarray(const slice_array<_Tp>&);
 
@@ -166,14 +171,24 @@ 
       /**
        *  @brief  Assign elements to an array.
        *
-       *  Assign elements of array to values in @a v.  Results are undefined
-       *  if @a v does not have the same size as this array.
+       *  Assign elements of array to values in @a v.
        *
        *  @param  v  Valarray to get values from.
        */
       valarray<_Tp>& operator=(const valarray<_Tp>&);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
       /**
+       *  @brief  Move assign elements to an array.
+       *
+       *  Move assign elements of array to values in @a v.
+       *
+       *  @param  v  Valarray to get values from.
+       */
+      valarray<_Tp>& operator=(valarray<_Tp>&&) noexcept;
+#endif
+
+      /**
        *  @brief  Assign elements to a value.
        *
        *  Assign all elements of array to @a t.
@@ -450,6 +465,11 @@ 
 	valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
 
       // _lib.valarray.members_ member functions:
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      ///  Swap.
+      void swap(valarray<_Tp>& __v) noexcept;
+#endif
+
       ///  Return the number of elements in array.
       size_t size() const;
 
@@ -612,8 +632,19 @@ 
     { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
 				     _M_data); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
   template<typename _Tp>
     inline
+    valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
+    : _M_size(__v._M_size), _M_data(__v._M_data)
+    {
+      __v._M_size = 0;
+      __v._M_data = 0;
+    }
+#endif
+
+  template<typename _Tp>
+    inline
     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
     : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
     {
@@ -655,7 +686,7 @@ 
     inline
     valarray<_Tp>::valarray(initializer_list<_Tp> __l)
     : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
-    { std::__valarray_copy_construct (__l.begin(), __l.end(), _M_data); }
+    { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
 #endif
 
   template<typename _Tp> template<class _Dom>
@@ -698,6 +729,22 @@ 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
   template<typename _Tp>
     inline valarray<_Tp>&
+    valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
+    {
+      if (_M_data)
+	{
+	  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
+	  std::__valarray_release_memory(_M_data);
+	}
+      _M_size = __v._M_size;
+      _M_data = __v._M_data;
+      __v._M_size = 0;
+      __v._M_data = 0;
+      return *this;
+    }
+
+  template<typename _Tp>
+    inline valarray<_Tp>&
     valarray<_Tp>::operator=(initializer_list<_Tp> __l)
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -846,7 +893,17 @@ 
 				 _Array<size_t>(__i));
     }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
   template<class _Tp>
+    inline void
+    valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
+    {
+      std::swap(_M_size, __v._M_size);
+      std::swap(_M_data, __v._M_data);
+    }
+#endif
+
+  template<class _Tp>
     inline size_t 
     valarray<_Tp>::size() const
     { return _M_size; }
Index: testsuite/26_numerics/valarray/swap.cc
===================================================================
--- testsuite/26_numerics/valarray/swap.cc	(revision 0)
+++ testsuite/26_numerics/valarray/swap.cc	(revision 0)
@@ -0,0 +1,37 @@ 
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <valarray>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::valarray<int> a(1, 1), b(-1, 2);
+  b.swap(a);
+  VERIFY( b.size() == 1 && b[0] == 1
+	  && a.size() == 2 && a[0] == -1 && a[1] == -1 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/26_numerics/valarray/moveable.cc
===================================================================
--- testsuite/26_numerics/valarray/moveable.cc	(revision 0)
+++ testsuite/26_numerics/valarray/moveable.cc	(revision 0)
@@ -0,0 +1,40 @@ 
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <valarray>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::valarray<int> a(1, 1), b(-1, 2);
+  b = std::move(a);
+  VERIFY( b.size() == 1 && b[0] == 1 && a.size() == 0 );
+
+  std::valarray<int> c(std::move(b));
+  VERIFY( c.size() == 1 && c[0] == 1 );
+  VERIFY( b.size() == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}