Patchwork std::pair copy and move constructor

login
register
mail settings
Submitter François Dumont
Date Feb. 15, 2013, 8:54 p.m.
Message ID <511EA09D.8000704@gmail.com>
Download mbox | patch
Permalink /patch/220850/
State New
Headers show

Comments

François Dumont - Feb. 15, 2013, 8:54 p.m.
Hi

     I had a problem with the result of 
std::is_copy_assignable<std::pair<const int, int>>::type which used to 
be true_type. So here is a patch to fix that.

2013-02-15  François Dumont  <fdumont@gcc.gnu.org>

     * include/bits/stl_pair.h (pair): Use default implementation for
     copy and move constructors.
     * testsuite/20_util/pair/is_copy_assignable.cc: New.
     * testsuite/20_util/pair/is_move_assignable.cc: New.

     I kept some checks commented. For is_copy_assignable.cc is looks 
like DeletedMoveAssignClass has also its copy assignment operator 
deleted. In is_move_assignable.cc even when pair is only composed of 
DeletedMoveAssignClass it looks like the pair still have a move 
assignment operator.

     I was surprised to see that those operator were not already using 
the default implementation so sorry if I miss the mails explaining why.

     Tested under Linux x86_64.

François
Daniel Krügler - Feb. 15, 2013, 9 p.m.
2013/2/15 François Dumont <frs.dumont@gmail.com>:
> Hi
>
>     I had a problem with the result of
> std::is_copy_assignable<std::pair<const int, int>>::type which used to be
> true_type. So here is a patch to fix that.

This patch would break with the requirements of the library. In
particular it would prevent that std::pair's of references are
copy-assignable and that exactly is the purpose for the user-provided
copy-assignment operators of pair (and tuple).

- Daniel

> 2013-02-15  François Dumont  <fdumont@gcc.gnu.org>
>
>     * include/bits/stl_pair.h (pair): Use default implementation for
>     copy and move constructors.
>     * testsuite/20_util/pair/is_copy_assignable.cc: New.
>     * testsuite/20_util/pair/is_move_assignable.cc: New.
>
>     I kept some checks commented. For is_copy_assignable.cc is looks like
> DeletedMoveAssignClass has also its copy assignment operator deleted. In
> is_move_assignable.cc even when pair is only composed of
> DeletedMoveAssignClass it looks like the pair still have a move assignment
> operator.
>
>     I was surprised to see that those operator were not already using the
> default implementation so sorry if I miss the mails explaining why.
>
>     Tested under Linux x86_64.
>
> François
>

Patch

Index: include/bits/stl_pair.h
===================================================================
--- include/bits/stl_pair.h	(revision 196091)
+++ include/bits/stl_pair.h	(working copy)
@@ -150,22 +150,10 @@ 
         pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
 
       pair&
-      operator=(const pair& __p)
-      {
-	first = __p.first;
-	second = __p.second;
-	return *this;
-      }
+      operator=(const pair&) = default;
 
       pair&
-      operator=(pair&& __p)
-      noexcept(__and_<is_nothrow_move_assignable<_T1>,
-	              is_nothrow_move_assignable<_T2>>::value)
-      {
-	first = std::forward<first_type>(__p.first);
-	second = std::forward<second_type>(__p.second);
-	return *this;
-      }
+      operator=(pair&&) = default;
 
       template<class _U1, class _U2>
 	pair&
Index: testsuite/20_util/pair/is_move_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_move_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_move_assignable.cc	(revision 0)
@@ -0,0 +1,54 @@ 
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+// Copyright (C) 2013 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 <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>					tt1;
+typedef std::pair<int, double>					tt2;
+typedef std::pair<const int, int>				tt3;
+typedef std::pair<int, const int>				tt4;
+typedef std::pair<NoexceptCopyAssignClass,
+		  NoexceptCopyAssignClass>			tt5;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>	tt6;
+typedef std::pair<ExceptCopyAssignClass, double>		tt7;
+typedef std::pair<NoexceptCopyAssignClass,
+		  ExceptCopyAssignClass>			tt8;
+typedef std::pair<int,
+		  DeletedCopyAssignClass>			tt9;
+typedef std::pair<int,
+		  DeletedMoveAssignClass>			tt10;
+//typedef std::pair<DeletedMoveAssignClass,
+//		  DeletedMoveAssignClass>			tt11;
+
+
+static_assert(std::is_move_assignable<tt1>::value, "Error");
+static_assert(std::is_move_assignable<tt2>::value, "Error");
+static_assert(std::is_move_assignable<tt3>::value, "Error");
+static_assert(std::is_move_assignable<tt4>::value, "Error");
+static_assert(std::is_move_assignable<tt5>::value, "Error");
+static_assert(std::is_move_assignable<tt6>::value, "Error");
+static_assert(std::is_move_assignable<tt7>::value, "Error");
+static_assert(std::is_move_assignable<tt8>::value, "Error");
+static_assert(std::is_move_assignable<tt9>::value, "Error");
+static_assert(std::is_move_assignable<tt10>::value, "Error");
+//static_assert(!std::is_move_assignable<tt11>::value, "Error");
Index: testsuite/20_util/pair/is_copy_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_copy_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_copy_assignable.cc	(revision 0)
@@ -0,0 +1,51 @@ 
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+// Copyright (C) 2013 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 <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>					tt1;
+typedef std::pair<int, double>					tt2;
+typedef std::pair<const int, int>				tt3;
+typedef std::pair<int, const int>				tt4;
+typedef std::pair<NoexceptCopyAssignClass,
+		  NoexceptCopyAssignClass>			tt5;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>	tt6;
+typedef std::pair<ExceptCopyAssignClass, double>		tt7;
+typedef std::pair<NoexceptCopyAssignClass,
+		  ExceptCopyAssignClass>			tt8;
+typedef std::pair<int,
+		  DeletedCopyAssignClass>			tt9;
+//typedef std::pair<int,
+//		  DeletedMoveAssignClass>			tt10;
+
+
+static_assert(std::is_copy_assignable<tt1>::value, "Error");
+static_assert(std::is_copy_assignable<tt2>::value, "Error");
+static_assert(!std::is_copy_assignable<tt3>::value, "Error");
+static_assert(!std::is_copy_assignable<tt4>::value, "Error");
+static_assert(std::is_copy_assignable<tt5>::value, "Error");
+static_assert(std::is_copy_assignable<tt6>::value, "Error");
+static_assert(std::is_copy_assignable<tt7>::value, "Error");
+static_assert(std::is_copy_assignable<tt8>::value, "Error");
+static_assert(!std::is_copy_assignable<tt9>::value, "Error");
+//static_assert(std::is_copy_assignable<tt10>::value, "Error");