This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fwd: Fix std::pair std::is_copy_assignable behavior



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

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;
     }
 

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");
+
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]