public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fwd: Fix std::pair std::is_copy_assignable behavior
       [not found] <51687815.6030507@gmail.com>
@ 2013-04-14 11:17 ` François Dumont
  2013-04-14 12:32   ` Paolo Carlini
  2013-04-14 13:03   ` Gabriel Dos Reis
  2013-04-17 22:14 ` François Dumont
  1 sibling, 2 replies; 11+ messages in thread
From: François Dumont @ 2013-04-14 11:17 UTC (permalink / raw)
  To: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 2078 bytes --]


Hider

     Here is a patch already posted to libstdc++ mailing but I am 
resending following libstdc++ maintainers advises to add gcc-patches 
mailing list.

     This patch proposal is to fix the behavior of std::pair regarding 
the std::is_*_assignable meta programming functions.

     As announced it is requiring a compiler patch to extend DR 1402 
resolution to all defaulted methods.

2013-04-12 François Dumont <fdumont@gcc.gnu.org>

     * call.c (joust): Extend DR 1402 to all defaulted methods.

     This modification is mandatory so that pair& operator=(const pair&) 
can be defaulted whereas leaving gcc consider the other operator= in 
some situations like std::pair<int&, int>. This way, with usage of 
std::enable_if on the template operator=, we can control when p1= p2 is 
a valid expression resulting in a correct behavior of 
std::is_copy_assignable.

     For the moment I preferred to add a dg-require-normal-mode option 
in the single test that fail to compile because of the compiler 
modification.

Does DR 1402 resolution generalization need a Standard committee 
validation first ?

2013-04-13  François Dumont  <fdumont@gcc.gnu.org>

     * include/bits/stl_pair.h (operator=(const pair&)): Defaulted.
     (operator=(pair&&)): Likewise.
     (template<> operator=(const pair&)): Add noexcept
     qualification. Enable if is_assignable<T&, const U&> true for both
     parameters.
     (template<> operator=(pair<>&&)): Add noexcept
     qualification. Enable if is_assignable<T&, U&&> true for both
     parameters.
     * testsuite/23_containers/unordered_set/55043.cc: Add
     dg-require-normal-mode.
     * testsuite/20_util/pair/is_move_assignable.cc: New.
     * testsuite/20_util/pair/is_copy_assignable.cc: Likewise.
     * testsuite/20_util/pair/is_assignable.cc: Likewise.
     * testsuite/20_util/pair/is_nothrow_move_assignable.cc: Likewise.
     * testsuite/20_util/pair/assign_neg.cc: Likewise.
     * testsuite/20_util/pair/is_nothrow_copy_assignable.cc: Likewise.
     * testsuite/20_util/pair/assign.cc: Likewise.

François


[-- Attachment #2: call.c.patch --]
[-- Type: text/x-patch, Size: 1460 bytes --]

Index: call.c
===================================================================
--- call.c	(revision 197829)
+++ call.c	(working copy)
@@ -8377,19 +8377,20 @@
       && (IS_TYPE_OR_DECL_P (cand1->fn)))
     return 1;
 
-  /* Prefer a non-deleted function over an implicitly deleted move
-     constructor or assignment operator.  This differs slightly from the
-     wording for issue 1402 (which says the move op is ignored by overload
-     resolution), but this way produces better error messages.  */
+  /* Prefer a non-deleted function over an implicitly deleted one. This
+     differs slightly from the wording for issue 1402 because:
+     - it is extended to all defaulted functions, not only the ones with
+     move semantic
+     - it says the op is ignored by overload resolution while we are
+     only making it a worst candidate, but this way produces better error
+     messages.  */
   if (TREE_CODE (cand1->fn) == FUNCTION_DECL
       && TREE_CODE (cand2->fn) == FUNCTION_DECL
       && DECL_DELETED_FN (cand1->fn) != DECL_DELETED_FN (cand2->fn))
     {
-      if (DECL_DELETED_FN (cand1->fn) && DECL_DEFAULTED_FN (cand1->fn)
-	  && move_fn_p (cand1->fn))
+      if (DECL_DELETED_FN (cand1->fn) && DECL_DEFAULTED_FN (cand1->fn))
 	return -1;
-      if (DECL_DELETED_FN (cand2->fn) && DECL_DEFAULTED_FN (cand2->fn)
-	  && move_fn_p (cand2->fn))
+      if (DECL_DELETED_FN (cand2->fn) && DECL_DEFAULTED_FN (cand2->fn))
 	return 1;
     }
 


[-- Attachment #3: pair.patch --]
[-- Type: text/x-patch, Size: 19879 bytes --]

Index: include/bits/stl_pair.h
===================================================================
--- include/bits/stl_pair.h	(revision 197829)
+++ include/bits/stl_pair.h	(working copy)
@@ -155,26 +155,18 @@
         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&
+	typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
+				  is_assignable<_T2&, const _U2&>>::value,
+			   pair&>::type
 	operator=(const pair<_U1, _U2>& __p)
+	noexcept(__and_<is_nothrow_assignable<_T1&, const _U1&>,
+			is_nothrow_assignable<_T2&, const _U2&>>::value)
 	{
 	  first = __p.first;
 	  second = __p.second;
@@ -182,8 +174,12 @@
 	}
 
       template<class _U1, class _U2>
-	pair&
+      	typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
+      				  is_assignable<_T2&, _U2&&>>::value,
+      			   pair&>::type
 	operator=(pair<_U1, _U2>&& __p)
+	noexcept(__and_<is_nothrow_assignable<_T1&, _U1&&>,
+			is_nothrow_assignable<_T2&, _U2&&>>::value)
 	{
 	  first = std::forward<_U1>(__p.first);
 	  second = std::forward<_U2>(__p.second);
Index: testsuite/23_containers/unordered_set/55043.cc
===================================================================
--- testsuite/23_containers/unordered_set/55043.cc	(revision 197829)
+++ testsuite/23_containers/unordered_set/55043.cc	(working copy)
@@ -1,5 +1,6 @@
 // { dg-options "-std=gnu++0x" }
 // { dg-do compile }
+// { dg-require-normal-mode "" }
 
 // Copyright (C) 2013 Free Software Foundation, Inc.
 //
Index: testsuite/20_util/pair/is_nothrow_move_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_nothrow_move_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_nothrow_move_assignable.cc	(revision 0)
@@ -0,0 +1,57 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt3;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt4;
+typedef std::pair<ExceptCopyAssignClass, double>			pt5;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt6;
+typedef std::pair<const int, int>					pt7;
+typedef std::pair<int, const int>					pt8;
+typedef std::pair<NoexceptMoveAssignClass, NoexceptMoveAssignClass>	pt9;
+typedef std::pair<ExceptMoveAssignClass, ExceptMoveAssignClass>		pt10;
+typedef std::pair<ExceptMoveAssignClass, NoexceptMoveAssignClass>	pt11;
+typedef std::pair<NoexceptMoveAssignClass, ExceptMoveAssignClass>	pt12;
+typedef std::pair<int, int&>						pt13;
+typedef std::pair<int&, int&>						pt14;
+typedef std::pair<int, const int&>					pt15;
+
+static_assert(std::is_nothrow_move_assignable<pt1>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt2>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt3>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt4>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt5>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt6>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt7>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt8>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt9>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt10>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt11>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt12>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt13>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt14>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt15>::value, "Error");
Index: testsuite/20_util/pair/assign_neg.cc
===================================================================
--- testsuite/20_util/pair/assign_neg.cc	(revision 0)
+++ testsuite/20_util/pair/assign_neg.cc	(revision 0)
@@ -0,0 +1,29 @@
+// { 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>
+
+void test01()
+{
+  std::pair<const int, int> p;
+  p = p; // { dg-error "use of deleted function" }
+}
+
+// { dg-error "can't use default assignment operator" "" { target *-*-* } 158 }
Index: testsuite/20_util/pair/is_nothrow_copy_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_nothrow_copy_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_nothrow_copy_assignable.cc	(revision 0)
@@ -0,0 +1,53 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<const int, int>					pt3;
+typedef std::pair<int, const int>					pt4;
+typedef std::pair<int, const int>&					pt5;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt6;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt7;
+typedef std::pair<ExceptCopyAssignClass, double>			pt8;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt9;
+typedef std::pair<int, DeletedCopyAssignClass>				pt10;
+typedef std::pair<int, int&>						pt11;
+typedef std::pair<int&, int&>						pt12;
+typedef std::pair<int, const int&>					pt13;
+
+static_assert(std::is_nothrow_copy_assignable<pt1>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt2>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt3>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt4>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt5>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt6>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt7>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt8>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt9>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt10>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt11>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt12>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt13>::value, "Error");
Index: testsuite/20_util/pair/assign.cc
===================================================================
--- testsuite/20_util/pair/assign.cc	(revision 0)
+++ testsuite/20_util/pair/assign.cc	(revision 0)
@@ -0,0 +1,124 @@
+// { 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_hooks.h>
+#include <testsuite_counter_type.h>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using __gnu_test::counter_type;
+
+  typedef std::pair<int, counter_type> ptype;
+  ptype p1(0, 0);
+  ptype p2(1, 1);
+
+  counter_type::reset();
+
+  p1 = p2;
+
+  VERIFY( p1.first == 1 );
+  VERIFY( p1.second.val == 1 );
+  VERIFY( counter_type::copy_assign_count == 1 );
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  using __gnu_test::counter_type;
+
+  typedef std::pair<int, counter_type> ptype;
+  ptype p1(0, 0);
+  ptype p2(1, 1);
+
+  counter_type::reset();
+
+  p1 = std::move(p2);
+
+  VERIFY( p1.first == 1 );
+  VERIFY( p1.second.val == 1 );
+  VERIFY( counter_type::move_assign_count == 1 );
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::pair<int&, int&> ptype;
+  int i = 0, j = 1;
+  ptype p1(i, j);
+  VERIFY( p1.first == 0 );
+  VERIFY( p1.second == 1 );
+
+  int k = 2, l = 3;
+  ptype p2(k, l);
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  p1 = p2;
+
+  VERIFY( p1.first == 2 );
+  VERIFY( p1.second == 3 );
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  VERIFY( i == 2 );
+
+  i = 0;
+  VERIFY( p1.first == 0 );
+}
+
+void test04()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::pair<int&, int> ptype;
+  int i = 0;
+  ptype p1(i, 1);
+  VERIFY( p1.first == 0 );
+  VERIFY( p1.second == 1 );
+
+  int j = 2;
+  ptype p2(j, 3);
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  p1 = p2;
+
+  VERIFY( p1.first == 2 );
+  VERIFY( p1.second == 3 );
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  VERIFY( i == 2 );
+
+  i = 0;
+  VERIFY( p1.first == 0 );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  return 0;
+}
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,59 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt3;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt4;
+typedef std::pair<ExceptCopyAssignClass, double>			pt5;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt6;
+typedef std::pair<const int, int>					pt7;
+typedef std::pair<int, const int>					pt8;
+typedef std::pair<NoexceptMoveAssignClass, NoexceptMoveAssignClass>	pt9;
+typedef std::pair<ExceptMoveAssignClass, ExceptMoveAssignClass>		pt10;
+typedef std::pair<ExceptMoveAssignClass, double>			pt11;
+typedef std::pair<DeletedMoveAssignClass, ExceptMoveAssignClass>	pt12;
+typedef std::pair<DeletedMoveAssignClass, DeletedMoveAssignClass>	pt13;
+typedef std::pair<ExceptMoveAssignClass, DeletedMoveAssignClass>	pt14;
+typedef std::pair<int, int&>						pt15;
+typedef std::pair<int, const int&>					pt16;
+
+static_assert(std::is_move_assignable<pt1>::value, "Error");
+static_assert(std::is_move_assignable<pt2>::value, "Error");
+static_assert(std::is_move_assignable<pt3>::value, "Error");
+static_assert(std::is_move_assignable<pt4>::value, "Error");
+static_assert(std::is_move_assignable<pt5>::value, "Error");
+static_assert(std::is_move_assignable<pt6>::value, "Error");
+static_assert(!std::is_move_assignable<pt7>::value, "Error");
+static_assert(!std::is_move_assignable<pt8>::value, "Error");
+static_assert(std::is_move_assignable<pt9>::value, "Error");
+static_assert(std::is_move_assignable<pt10>::value, "Error");
+static_assert(std::is_move_assignable<pt11>::value, "Error");
+static_assert(!std::is_move_assignable<pt12>::value, "Error");
+static_assert(!std::is_move_assignable<pt13>::value, "Error");
+static_assert(!std::is_move_assignable<pt14>::value, "Error");
+static_assert(std::is_move_assignable<pt15>::value, "Error");
+static_assert(!std::is_move_assignable<pt16>::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,53 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<const int, int>					pt3;
+typedef std::pair<int, const int>					pt4;
+typedef std::pair<int, const int>&					pt5;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt6;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt7;
+typedef std::pair<ExceptCopyAssignClass, double>			pt8;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt9;
+typedef std::pair<int, DeletedCopyAssignClass>				pt10;
+typedef std::pair<int, int&>						pt11;
+typedef std::pair<int&, int&>						pt12;
+typedef std::pair<int, const int&>					pt13;
+
+static_assert(std::is_copy_assignable<pt1>::value, "Error");
+static_assert(std::is_copy_assignable<pt2>::value, "Error");
+static_assert(!std::is_copy_assignable<pt3>::value, "Error");
+static_assert(!std::is_copy_assignable<pt4>::value, "Error");
+static_assert(!std::is_copy_assignable<pt5>::value, "Error");
+static_assert(std::is_copy_assignable<pt6>::value, "Error");
+static_assert(std::is_copy_assignable<pt7>::value, "Error");
+static_assert(std::is_copy_assignable<pt8>::value, "Error");
+static_assert(std::is_copy_assignable<pt9>::value, "Error");
+static_assert(!std::is_copy_assignable<pt10>::value, "Error");
+static_assert(std::is_copy_assignable<pt11>::value, "Error");
+static_assert(std::is_copy_assignable<pt12>::value, "Error");
+static_assert(!std::is_copy_assignable<pt13>::value, "Error");
Index: testsuite/20_util/pair/is_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_assignable.cc	(revision 0)
@@ -0,0 +1,48 @@
+// { 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 <type_traits>
+#include <utility>
+
+struct T1
+{
+};
+
+struct T2
+{
+  T2&
+  operator=(const T1&);
+};
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<short, short>						pt2;
+typedef std::pair<int, double> pt3;
+typedef std::pair<int, T1> pt4;
+typedef std::pair<int, T2> pt5;
+
+static_assert(std::is_assignable<pt1, pt2>::value, "Error");
+static_assert(std::is_assignable<pt2, pt1>::value, "Error");
+static_assert(std::is_assignable<pt1, pt3>::value, "Error");
+static_assert(!std::is_assignable<pt4, pt1>::value, "Error");
+static_assert(!std::is_assignable<pt1, pt4>::value, "Error");
+static_assert(std::is_assignable<pt5, pt4>::value, "Error");
+static_assert(!std::is_assignable<pt4, pt5>::value, "Error");
+
+


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fwd: Fix std::pair std::is_copy_assignable behavior
  2013-04-14 11:17 ` Fwd: Fix std::pair std::is_copy_assignable behavior François Dumont
@ 2013-04-14 12:32   ` Paolo Carlini
  2013-04-14 13:03   ` Gabriel Dos Reis
  1 sibling, 0 replies; 11+ messages in thread
From: Paolo Carlini @ 2013-04-14 12:32 UTC (permalink / raw)
  To: François Dumont; +Cc: gcc-patches, libstdc++

On 04/13/2013 09:21 PM, François Dumont wrote:
> Does DR 1402 resolution generalization need a Standard committee 
> validation first ?
In my opinion, it's much more clear to send the C++ front-end patch 
*separately* together with a simple C++-only (no library) testcase. I 
would also CC Jason.

Paolo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-14 11:17 ` Fwd: Fix std::pair std::is_copy_assignable behavior François Dumont
  2013-04-14 12:32   ` Paolo Carlini
@ 2013-04-14 13:03   ` Gabriel Dos Reis
  2013-04-14 21:22     ` François Dumont
  1 sibling, 1 reply; 11+ messages in thread
From: Gabriel Dos Reis @ 2013-04-14 13:03 UTC (permalink / raw)
  To: François Dumont; +Cc: gcc-patches, libstdc++

> Does DR 1402 resolution generalization need a Standard committee validation
> first ?

I cannot see why we would want otherwise :-)

-- Gaby

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-14 13:03   ` Gabriel Dos Reis
@ 2013-04-14 21:22     ` François Dumont
  0 siblings, 0 replies; 11+ messages in thread
From: François Dumont @ 2013-04-14 21:22 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: gcc-patches, libstdc++

On 04/14/2013 03:33 AM, Gabriel Dos Reis wrote:
>> Does DR 1402 resolution generalization need a Standard committee validation
>> first ?
> I cannot see why we would want otherwise :-)
>
> -- Gaby
>
I rather wonder if gcc only accept modifications that has been validated 
by the Standard committee first or if we can first apply the 
modification to challenge it as much as possible while discussing about 
it at the same time.

Of course I ask because the compiler modification has a relatively 
limited (bad) impact like libstdc++ testsuite have shown.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
       [not found] <51687815.6030507@gmail.com>
  2013-04-14 11:17 ` Fwd: Fix std::pair std::is_copy_assignable behavior François Dumont
@ 2013-04-17 22:14 ` François Dumont
  2013-04-18  2:13   ` Paolo Carlini
  1 sibling, 1 reply; 11+ messages in thread
From: François Dumont @ 2013-04-17 22:14 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1693 bytes --]

Hi

     Here is an other proposal to fix std::is_copy_assignable<std::pair<>>.

     This is not perfect because I have adapted it to current compiler 
behavior but it is still better than current behavior and enough to 
commit the unordered C++11 allocator adaptation afterward. It will give 
me more time to work on the Standard modification proposal to avoid the 
partial template specialization used for the moment.

     Thanks to current resolution of DR 1402 we can already define the 
move assignment operator as default, if deleted the template move 
assignment operator will be considered and potentially used instead.

2013-04-17  François Dumont <fdumont@gcc.gnu.org>

     * include/bits/stl_pair.h (operator=(const pair&)): Add noexcept
     qualification.
     (operator=(pair&&)): Use default implementation.
     (template<> operator=(const pair&)): Add noexcept
     qualification. Enable if is_assignable<T&, const U&> true for both
     parameter types.
     (template<> operator=(pair<>&&)): Add noexcept
     qualification. Enable if is_assignable<T&, U&&> true for both
     parameter types.
     (std::is_copy_assignable<>, std::is_move_assignable<>): Add
     partial specialization.
     * testsuite/20_util/pair/is_move_assignable.cc: New.
     * testsuite/20_util/pair/is_copy_assignable.cc: Likewise.
     * testsuite/20_util/pair/is_assignable.cc: Likewise.
     * testsuite/20_util/pair/is_nothrow_move_assignable.cc: Likewise.
     * testsuite/20_util/pair/assign_neg.cc: Likewise.
     * testsuite/20_util/pair/is_nothrow_copy_assignable.cc: Likewise.
     * testsuite/20_util/pair/assign.cc: Likewise.

Tested under Linux x86_64.

Ok to commit ?

François

[-- Attachment #2: pair.patch --]
[-- Type: text/x-patch, Size: 21108 bytes --]

Index: include/bits/stl_pair.h
===================================================================
--- include/bits/stl_pair.h	(revision 197829)
+++ include/bits/stl_pair.h	(working copy)
@@ -156,6 +156,8 @@
 
       pair&
       operator=(const pair& __p)
+      noexcept(__and_<is_nothrow_copy_assignable<_T1>,
+		      is_nothrow_copy_assignable<_T2>>::value)
       {
 	first = __p.first;
 	second = __p.second;
@@ -163,18 +165,15 @@
       }
 
       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&
+	typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
+				  is_assignable<_T2&, const _U2&>>::value,
+			   pair&>::type
 	operator=(const pair<_U1, _U2>& __p)
+	noexcept(__and_<is_nothrow_assignable<_T1&, const _U1&>,
+			is_nothrow_assignable<_T2&, const _U2&>>::value)
 	{
 	  first = __p.first;
 	  second = __p.second;
@@ -182,8 +181,12 @@
 	}
 
       template<class _U1, class _U2>
-	pair&
+      	typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
+      				  is_assignable<_T2&, _U2&&>>::value,
+      			   pair&>::type
 	operator=(pair<_U1, _U2>&& __p)
+	noexcept(__and_<is_nothrow_assignable<_T1&, _U1&&>,
+			is_nothrow_assignable<_T2&, _U2&&>>::value)
 	{
 	  first = std::forward<_U1>(__p.first);
 	  second = std::forward<_U2>(__p.second);
@@ -287,6 +290,19 @@
     { return pair<_T1, _T2>(__x, __y); }
 #endif
 
+#if __cplusplus >= 201103L
+  template<class _T1, class _T2>
+    struct is_copy_assignable<std::pair<_T1, _T2>>
+      : public __and_<std::is_copy_assignable<_T1>,
+		      std::is_copy_assignable<_T2>>::type
+    { };
+
+  template<class _T1, class _T2>
+    struct is_move_assignable<std::pair<_T1, _T2>>
+      : public __and_<std::is_move_assignable<_T1>,
+		      std::is_move_assignable<_T2>>::type
+    { };
+#endif
   /// @}
 
 _GLIBCXX_END_NAMESPACE_VERSION
Index: testsuite/20_util/pair/is_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_assignable.cc	(revision 0)
@@ -0,0 +1,48 @@
+// { 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 <type_traits>
+#include <utility>
+
+struct T1
+{
+};
+
+struct T2
+{
+  T2&
+  operator=(const T1&);
+};
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<short, short>						pt2;
+typedef std::pair<int, double> pt3;
+typedef std::pair<int, T1> pt4;
+typedef std::pair<int, T2> pt5;
+
+static_assert(std::is_assignable<pt1, pt2>::value, "Error");
+static_assert(std::is_assignable<pt2, pt1>::value, "Error");
+static_assert(std::is_assignable<pt1, pt3>::value, "Error");
+static_assert(!std::is_assignable<pt4, pt1>::value, "Error");
+static_assert(!std::is_assignable<pt1, pt4>::value, "Error");
+static_assert(std::is_assignable<pt5, pt4>::value, "Error");
+static_assert(!std::is_assignable<pt4, pt5>::value, "Error");
+
+
Index: testsuite/20_util/pair/is_nothrow_move_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_nothrow_move_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_nothrow_move_assignable.cc	(revision 0)
@@ -0,0 +1,57 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt3;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt4;
+typedef std::pair<ExceptCopyAssignClass, double>			pt5;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt6;
+typedef std::pair<const int, int>					pt7;
+typedef std::pair<int, const int>					pt8;
+typedef std::pair<NoexceptMoveAssignClass, NoexceptMoveAssignClass>	pt9;
+typedef std::pair<ExceptMoveAssignClass, ExceptMoveAssignClass>		pt10;
+typedef std::pair<ExceptMoveAssignClass, NoexceptMoveAssignClass>	pt11;
+typedef std::pair<NoexceptMoveAssignClass, ExceptMoveAssignClass>	pt12;
+typedef std::pair<int, int&>						pt13;
+typedef std::pair<int&, int&>						pt14;
+typedef std::pair<int, const int&>					pt15;
+
+static_assert(std::is_nothrow_move_assignable<pt1>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt2>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt3>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt4>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt5>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt6>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt7>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt8>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt9>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt10>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt11>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt12>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt13>::value, "Error");
+static_assert(std::is_nothrow_move_assignable<pt14>::value, "Error");
+static_assert(!std::is_nothrow_move_assignable<pt15>::value, "Error");
Index: testsuite/20_util/pair/assign_neg.cc
===================================================================
--- testsuite/20_util/pair/assign_neg.cc	(revision 0)
+++ testsuite/20_util/pair/assign_neg.cc	(revision 0)
@@ -0,0 +1,30 @@
+// { 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>
+
+void test01()
+{
+  std::pair<const int, int> p;
+  p = p;
+  p = std::move(p);
+}
+
+// { dg-error "assignment of read-only member" "" { target *-*-* } 162 }
Index: testsuite/20_util/pair/is_nothrow_copy_assignable.cc
===================================================================
--- testsuite/20_util/pair/is_nothrow_copy_assignable.cc	(revision 0)
+++ testsuite/20_util/pair/is_nothrow_copy_assignable.cc	(revision 0)
@@ -0,0 +1,53 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<const int, int>					pt3;
+typedef std::pair<int, const int>					pt4;
+typedef std::pair<int, const int>&					pt5;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt6;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt7;
+typedef std::pair<ExceptCopyAssignClass, double>			pt8;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt9;
+typedef std::pair<int, DeletedCopyAssignClass>				pt10;
+typedef std::pair<int, int&>						pt11;
+typedef std::pair<int&, int&>						pt12;
+typedef std::pair<int, const int&>					pt13;
+
+static_assert(std::is_nothrow_copy_assignable<pt1>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt2>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt3>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt4>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt5>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt6>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt7>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt8>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt9>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt10>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt11>::value, "Error");
+static_assert(std::is_nothrow_copy_assignable<pt12>::value, "Error");
+static_assert(!std::is_nothrow_copy_assignable<pt13>::value, "Error");
Index: testsuite/20_util/pair/assign.cc
===================================================================
--- testsuite/20_util/pair/assign.cc	(revision 0)
+++ testsuite/20_util/pair/assign.cc	(revision 0)
@@ -0,0 +1,177 @@
+// { 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 <tuple>
+#include <testsuite_hooks.h>
+#include <testsuite_counter_type.h>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using __gnu_test::counter_type;
+
+  typedef std::pair<int, counter_type> ptype;
+  ptype p1(0, 0);
+  ptype p2(1, 1);
+
+  counter_type::reset();
+
+  p1 = p2;
+
+  VERIFY( p1.first == 1 );
+  VERIFY( p1.second.val == 1 );
+  VERIFY( counter_type::copy_assign_count == 1 );
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  using __gnu_test::counter_type;
+
+  typedef std::pair<int, counter_type> ptype;
+  ptype p1(0, 0);
+  ptype p2(1, 1);
+
+  counter_type::reset();
+
+  p1 = std::move(p2);
+
+  VERIFY( p1.first == 1 );
+  VERIFY( p1.second.val == 1 );
+  VERIFY( counter_type::move_assign_count == 1 );
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::pair<int&, int&> ptype;
+  int i = 0, j = 1;
+  ptype p1(i, j);
+  VERIFY( p1.first == 0 );
+  VERIFY( p1.second == 1 );
+
+  int k = 2, l = 3;
+  ptype p2(k, l);
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  p1 = p2;
+
+  VERIFY( p1.first == 2 );
+  VERIFY( p1.second == 3 );
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  VERIFY( i == 2 );
+
+  i = 0;
+  VERIFY( p1.first == 0 );
+}
+
+void test04()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::pair<int&, int> ptype;
+  int i = 0;
+  ptype p1(i, 1);
+  VERIFY( p1.first == 0 );
+  VERIFY( p1.second == 1 );
+
+  int j = 2;
+  ptype p2(j, 3);
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  p1 = p2;
+
+  VERIFY( p1.first == 2 );
+  VERIFY( p1.second == 3 );
+  VERIFY( p2.first == 2 );
+  VERIFY( p2.second == 3 );
+
+  VERIFY( i == 2 );
+
+  i = 0;
+  VERIFY( p1.first == 0 );
+}
+
+namespace __gnu_test
+{
+  struct MyStruct
+  {
+    int _i;
+
+    MyStruct()
+      : _i() { }
+    MyStruct(int i)
+      : _i(i) { }
+    MyStruct(const MyStruct& other)
+      : _i(other._i) { }
+    MyStruct(MyStruct&& other)
+      : _i(other._i)
+    { other._i = -1; }
+
+    MyStruct&
+    operator=(const MyStruct& other)
+    { _i = other._i; }
+
+    MyStruct&
+    operator=(MyStruct&& other)
+    {
+      _i = other._i;
+      other._i = -1;
+    }
+  };
+}
+
+void test05()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::pair<__gnu_test::MyStruct, __gnu_test::MyStruct> ptype1;
+  typedef std::pair<__gnu_test::MyStruct, const __gnu_test::MyStruct> ptype2;
+  
+  static_assert(std::is_move_assignable<ptype1>::value, "Error");
+  static_assert(!std::is_move_assignable<ptype2>::value, "Error");
+  static_assert(std::is_assignable<ptype1&, ptype2&&>::value, "Error");
+
+  ptype1 p1(1, 2);
+  ptype2 p2(3, 4);
+
+  p1 = std::move(p2);
+
+  VERIFY( p1.first._i == 3 );
+  VERIFY( p1.second._i == 4 );
+  VERIFY( p2.first._i == -1 );
+  VERIFY( p2.second._i == 4 );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  test05();
+  return 0;
+}
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,59 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt3;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt4;
+typedef std::pair<ExceptCopyAssignClass, double>			pt5;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt6;
+typedef std::pair<const int, int>					pt7;
+typedef std::pair<int, const int>					pt8;
+typedef std::pair<NoexceptMoveAssignClass, NoexceptMoveAssignClass>	pt9;
+typedef std::pair<ExceptMoveAssignClass, ExceptMoveAssignClass>		pt10;
+typedef std::pair<ExceptMoveAssignClass, double>			pt11;
+typedef std::pair<DeletedMoveAssignClass, ExceptMoveAssignClass>	pt12;
+typedef std::pair<DeletedMoveAssignClass, DeletedMoveAssignClass>	pt13;
+typedef std::pair<ExceptMoveAssignClass, DeletedMoveAssignClass>	pt14;
+typedef std::pair<int, int&>						pt15;
+typedef std::pair<int, const int&>					pt16;
+
+static_assert(std::is_move_assignable<pt1>::value, "Error");
+static_assert(std::is_move_assignable<pt2>::value, "Error");
+static_assert(std::is_move_assignable<pt3>::value, "Error");
+static_assert(std::is_move_assignable<pt4>::value, "Error");
+static_assert(std::is_move_assignable<pt5>::value, "Error");
+static_assert(std::is_move_assignable<pt6>::value, "Error");
+static_assert(!std::is_move_assignable<pt7>::value, "Error");
+static_assert(!std::is_move_assignable<pt8>::value, "Error");
+static_assert(std::is_move_assignable<pt9>::value, "Error");
+static_assert(std::is_move_assignable<pt10>::value, "Error");
+static_assert(std::is_move_assignable<pt11>::value, "Error");
+static_assert(!std::is_move_assignable<pt12>::value, "Error");
+static_assert(!std::is_move_assignable<pt13>::value, "Error");
+static_assert(!std::is_move_assignable<pt14>::value, "Error");
+static_assert(std::is_move_assignable<pt15>::value, "Error");
+static_assert(!std::is_move_assignable<pt16>::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,53 @@
+// { 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 <type_traits>
+#include <utility>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+typedef std::pair<int, int>						pt1;
+typedef std::pair<int, double>						pt2;
+typedef std::pair<const int, int>					pt3;
+typedef std::pair<int, const int>					pt4;
+//typedef std::pair<int, const int>&					pt5;
+typedef std::pair<NoexceptCopyAssignClass, NoexceptCopyAssignClass>	pt6;
+typedef std::pair<ExceptCopyAssignClass, ExceptCopyAssignClass>		pt7;
+typedef std::pair<ExceptCopyAssignClass, double>			pt8;
+typedef std::pair<NoexceptCopyAssignClass, ExceptCopyAssignClass>	pt9;
+typedef std::pair<int, DeletedCopyAssignClass>				pt10;
+typedef std::pair<int, int&>						pt11;
+typedef std::pair<int&, int&>						pt12;
+typedef std::pair<int, const int&>					pt13;
+
+static_assert(std::is_copy_assignable<pt1>::value, "Error");
+static_assert(std::is_copy_assignable<pt2>::value, "Error");
+static_assert(!std::is_copy_assignable<pt3>::value, "Error");
+static_assert(!std::is_copy_assignable<pt4>::value, "Error");
+//static_assert(!std::is_copy_assignable<pt5>::value, "Error");
+static_assert(std::is_copy_assignable<pt6>::value, "Error");
+static_assert(std::is_copy_assignable<pt7>::value, "Error");
+static_assert(std::is_copy_assignable<pt8>::value, "Error");
+static_assert(std::is_copy_assignable<pt9>::value, "Error");
+static_assert(!std::is_copy_assignable<pt10>::value, "Error");
+static_assert(std::is_copy_assignable<pt11>::value, "Error");
+static_assert(std::is_copy_assignable<pt12>::value, "Error");
+static_assert(!std::is_copy_assignable<pt13>::value, "Error");


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-17 22:14 ` François Dumont
@ 2013-04-18  2:13   ` Paolo Carlini
  2013-04-18  6:32     ` François Dumont
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Carlini @ 2013-04-18  2:13 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

On 4/17/13 8:10 PM, François Dumont wrote:
> Hi
>
>     Here is an other proposal to fix 
> std::is_copy_assignable<std::pair<>>.
Sorry, I'm still missing something very, very basic: which behavior is 
conforming, the current one or what we would get instead? If the former, 
is there a DR arguing for the latter?

Paolo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-18  2:13   ` Paolo Carlini
@ 2013-04-18  6:32     ` François Dumont
  2013-04-18  6:35       ` Paolo Carlini
  0 siblings, 1 reply; 11+ messages in thread
From: François Dumont @ 2013-04-18  6:32 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: libstdc++, gcc-patches

On 04/17/2013 09:18 PM, Paolo Carlini wrote:
> On 4/17/13 8:10 PM, François Dumont wrote:
>> Hi
>>
>>     Here is an other proposal to fix 
>> std::is_copy_assignable<std::pair<>>.
> Sorry, I'm still missing something very, very basic: which behavior is 
> conforming, the current one or what we would get instead? If the 
> former, is there a DR arguing for the latter?
>
> Paolo.
>
     The behavior I am targeting is 
std::is_copy_asignable<std::pair<const int, int>> to be std::false_type 
for instance. I have added test for many other use cases. More generally 
I need that when std::is_copy_assignable<T> is std::true_type then 
writing a = b, with a and b being T, does compile.

     Otherwise this patch just make std::pair match the Standard 
requirements like at 20.3.2.17. Do you want me to add a bug report in 
Bugzilla first ?

François

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-18  6:32     ` François Dumont
@ 2013-04-18  6:35       ` Paolo Carlini
  2013-04-18  7:50         ` François Dumont
  2013-04-19 21:32         ` François Dumont
  0 siblings, 2 replies; 11+ messages in thread
From: Paolo Carlini @ 2013-04-18  6:35 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

Hi,

On 4/17/13 8:43 PM, François Dumont wrote:
> On 04/17/2013 09:18 PM, Paolo Carlini wrote:
>> On 4/17/13 8:10 PM, François Dumont wrote:
>>> Hi
>>>
>>>     Here is an other proposal to fix 
>>> std::is_copy_assignable<std::pair<>>.
>> Sorry, I'm still missing something very, very basic: which behavior 
>> is conforming, the current one or what we would get instead? If the 
>> former, is there a DR arguing for the latter?
>>
>> Paolo.
>>
>     The behavior I am targeting is 
> std::is_copy_asignable<std::pair<const int, int>> to be 
> std::false_type for instance. I have added test for many other use 
> cases. More generally I need that when std::is_copy_assignable<T> is 
> std::true_type then writing a = b, with a and b being T, does compile.
>
>     Otherwise this patch just make std::pair match the Standard 
> requirements like at 20.3.2.17. Do you want me to add a bug report in 
> Bugzilla first ?
I'm not talking about GCC's Bugzilla, I meant an ISO DR: if we don't 
have a DR and preferably a vague support of LWG people, I think we 
should not change the behavior of our std::is_copy_assignable only 
because it helps our implementation of other facilities.

Paolo.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-18  6:35       ` Paolo Carlini
@ 2013-04-18  7:50         ` François Dumont
  2013-04-19 21:32         ` François Dumont
  1 sibling, 0 replies; 11+ messages in thread
From: François Dumont @ 2013-04-18  7:50 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: libstdc++, gcc-patches

On 04/17/2013 10:02 PM, Paolo Carlini wrote:
> Hi,
>
> On 4/17/13 8:43 PM, François Dumont wrote:
>> On 04/17/2013 09:18 PM, Paolo Carlini wrote:
>>> On 4/17/13 8:10 PM, François Dumont wrote:
>>>> Hi
>>>>
>>>>     Here is an other proposal to fix 
>>>> std::is_copy_assignable<std::pair<>>.
>>> Sorry, I'm still missing something very, very basic: which behavior 
>>> is conforming, the current one or what we would get instead? If the 
>>> former, is there a DR arguing for the latter?
>>>
>>> Paolo.
>>>
>>     The behavior I am targeting is 
>> std::is_copy_asignable<std::pair<const int, int>> to be 
>> std::false_type for instance. I have added test for many other use 
>> cases. More generally I need that when std::is_copy_assignable<T> is 
>> std::true_type then writing a = b, with a and b being T, does compile.
>>
>>     Otherwise this patch just make std::pair match the Standard 
>> requirements like at 20.3.2.17. Do you want me to add a bug report in 
>> Bugzilla first ?
> I'm not talking about GCC's Bugzilla, I meant an ISO DR: if we don't 
> have a DR and preferably a vague support of LWG people, I think we 
> should not change the behavior of our std::is_copy_assignable only 
> because it helps our implementation of other facilities.
>
> Paolo.
>
     I really don't get it. Is current behavior really Standard compliant ?

     I don't think so and would like to fix it. The Standard says that 
pair& operator=(const pair&) requires that both 
is_copy_assignable<first_type> and is_copy_assignable<second_type> to be 
true. With std::pair<const int, int>, is_copy_assignable<const int> is 
false and then the operator is ill formed. It is if you try to call it 
but if you check is_copy_assignable<pair<const int, int>> it says true. 
Do you see it as a correct behavior ? Do you really think that it 
requires an ISO DR ?

François

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-18  6:35       ` Paolo Carlini
  2013-04-18  7:50         ` François Dumont
@ 2013-04-19 21:32         ` François Dumont
  2013-04-19 21:38           ` Paolo Carlini
  1 sibling, 1 reply; 11+ messages in thread
From: François Dumont @ 2013-04-19 21:32 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: libstdc++, gcc-patches

On 04/17/2013 10:02 PM, Paolo Carlini wrote:
> Hi,
>
> On 4/17/13 8:43 PM, François Dumont wrote:
>> On 04/17/2013 09:18 PM, Paolo Carlini wrote:
>>> On 4/17/13 8:10 PM, François Dumont wrote:
>>>> Hi
>>>>
>>>>     Here is an other proposal to fix 
>>>> std::is_copy_assignable<std::pair<>>.
>>> Sorry, I'm still missing something very, very basic: which behavior 
>>> is conforming, the current one or what we would get instead? If the 
>>> former, is there a DR arguing for the latter?
>>>
>>> Paolo.
>>>
>>     The behavior I am targeting is 
>> std::is_copy_asignable<std::pair<const int, int>> to be 
>> std::false_type for instance. I have added test for many other use 
>> cases. More generally I need that when std::is_copy_assignable<T> is 
>> std::true_type then writing a = b, with a and b being T, does compile.
>>
>>     Otherwise this patch just make std::pair match the Standard 
>> requirements like at 20.3.2.17. Do you want me to add a bug report in 
>> Bugzilla first ?
> I'm not talking about GCC's Bugzilla, I meant an ISO DR: if we don't 
> have a DR and preferably a vague support of LWG people, I think we 
> should not change the behavior of our std::is_copy_assignable only 
> because it helps our implementation of other facilities.
>
> Paolo.
>
Hi

     I check again the Standard and I really can't see any problem with 
the patch. As far as I understand it having std::is_copy_assignable 
being true is not a guaranty that the expression will compile but making 
std::pair is_copy_assignable friendly doesn't violate it neither.

     I also see that std::pair is already using std::enable_if to 
disable some constructors. I check the ChangeLog and it was not 
associated to a any ISO DR. I don't know why at that moment the same 
kind of modification hadn't been done for the assignment operators but 
the patch is not doing more than what has been done at that time.

     Ok to commit ?

François

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix std::pair std::is_copy_assignable behavior
  2013-04-19 21:32         ` François Dumont
@ 2013-04-19 21:38           ` Paolo Carlini
  0 siblings, 0 replies; 11+ messages in thread
From: Paolo Carlini @ 2013-04-19 21:38 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

Hi,

"François Dumont" <frs.dumont@gmail.com> ha scritto:

>     Ok to commit ?

No, it's definitely not Ok, we don't want to add std::is_copy_assignable specializations like this.

Jon will send you more comments.

Thanks,
Paolo


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-04-19 21:17 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <51687815.6030507@gmail.com>
2013-04-14 11:17 ` Fwd: Fix std::pair std::is_copy_assignable behavior François Dumont
2013-04-14 12:32   ` Paolo Carlini
2013-04-14 13:03   ` Gabriel Dos Reis
2013-04-14 21:22     ` François Dumont
2013-04-17 22:14 ` François Dumont
2013-04-18  2:13   ` Paolo Carlini
2013-04-18  6:32     ` François Dumont
2013-04-18  6:35       ` Paolo Carlini
2013-04-18  7:50         ` François Dumont
2013-04-19 21:32         ` François Dumont
2013-04-19 21:38           ` Paolo Carlini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).