]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tuple (get): Implement N3670.
authorJonathan Wakely <jwakely.gcc@gmail.com>
Sun, 19 May 2013 13:31:36 +0000 (13:31 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Sun, 19 May 2013 13:31:36 +0000 (14:31 +0100)
* include/std/tuple (get): Implement N3670.
* include/std/utility (get): Likewise.
* testsuite/20_util/pair/get.cc: Move to ...
* testsuite/20_util/pair/astuple/get.cc: Here.
* testsuite/20_util/pair/astuple/astuple.cc: New.
* testsuite/20_util/pair/astuple/constexpr_get.cc: New.
* testsuite/20_util/pair/astuple/constexpr_get_by_type.cc: New.
* testsuite/20_util/pair/astuple/get_by_type.cc: New.
* testsuite/20_util/pair/astuple/get_by_type_neg.cc: New.
* testsuite/20_util/pair/astuple/get_neg.cc: New.
* testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc: New.
* testsuite/20_util/tuple/element_access/get2_by_type.cc: New.
* testsuite/20_util/tuple/element_access/get_by_type.cc: New.

From-SVN: r199082

13 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/std/tuple
libstdc++-v3/include/std/utility
libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get_by_type.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/pair/astuple/get.cc [moved from libstdc++-v3/testsuite/20_util/pair/get.cc with 100% similarity]
libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/pair/astuple/get_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc [new file with mode: 0644]

index 35175d135255930bc9c6445f8b2160a82d9f2cbb..3c1e7a97906290ebba80990f985976625a555228 100644 (file)
@@ -1,3 +1,19 @@
+2013-05-19  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+       * include/std/tuple (get): Implement N3670.
+       * include/std/utility (get): Likewise.
+       * testsuite/20_util/pair/get.cc: Move to ...
+       * testsuite/20_util/pair/astuple/get.cc: Here.
+       * testsuite/20_util/pair/astuple/astuple.cc: New.
+       * testsuite/20_util/pair/astuple/constexpr_get.cc: New.
+       * testsuite/20_util/pair/astuple/constexpr_get_by_type.cc: New.
+       * testsuite/20_util/pair/astuple/get_by_type.cc: New.
+       * testsuite/20_util/pair/astuple/get_by_type_neg.cc: New.
+       * testsuite/20_util/pair/astuple/get_neg.cc: New.
+       * testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc: New.
+       * testsuite/20_util/tuple/element_access/get2_by_type.cc: New.
+       * testsuite/20_util/tuple/element_access/get_by_type.cc: New.
+
 2013-05-19  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * Revert last commit.
index ee2b2e1d4c20dc625cc77e776dd69fa4685bf54b..69f5bd1f72f42b24219482c9c42f5a313ead4ce2 100644 (file)
@@ -772,6 +772,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return std::forward<typename tuple_element<__i,
        tuple<_Elements...>>::type&&>(get<__i>(__t)); }
 
+#if __cplusplus > 201103L
+  template<typename _Head, size_t __i, typename... _Tail>
+    constexpr typename __add_ref<_Head>::type
+    __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
+    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
+
+  template<typename _Head, size_t __i, typename... _Tail>
+    constexpr typename __add_c_ref<_Head>::type
+    __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
+    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
+
+  template <typename _Tp, typename... _Types>
+    constexpr _Tp&
+    get(tuple<_Types...>& __t) noexcept
+    { return __get_helper2<_Tp>(__t); }
+
+  template <typename _Tp, typename... _Types>
+    constexpr _Tp&&
+    get(tuple<_Types...>&& __t) noexcept
+    { return std::move(__get_helper2<_Tp>(__t)); }
+
+  template <typename _Tp, typename... _Types>
+    constexpr const _Tp&
+    get(const tuple<_Types...>& __t) noexcept
+    { return __get_helper2<_Tp>(__t); }
+#endif
+
   // This class helps construct the various comparison operations on tuples
   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
           typename _Tp, typename _Up>
index ee8c6b19609e62be1abe5c4709db0b66e260fec8..ad30ad7a9a3e969a7f4ad8a9e505b3ff843cf0f3 100644 (file)
@@ -153,8 +153,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __pair_get<_Int>::__const_get(__in); }
 
 #if __cplusplus > 201103L
+  template <typename _Tp, typename _Up>
+    constexpr _Tp&
+    get(pair<_Tp, _Up>& __p) noexcept
+    { return __p.first; }
+
+  template <typename _Tp, typename _Up>
+    constexpr const _Tp&
+    get(const pair<_Tp, _Up>& __p) noexcept
+    { return __p.first; }
+
+  template <typename _Tp, typename _Up>
+    constexpr _Tp&&
+    get(pair<_Tp, _Up>&& __p) noexcept
+    { return std::move(__p.first); }
+
+  template <typename _Tp, typename _Up>
+    constexpr _Tp&
+    get(pair<_Up, _Tp>& __p) noexcept
+    { return __p.second; }
+
+  template <typename _Tp, typename _Up>
+    constexpr const _Tp&
+    get(const pair<_Up, _Tp>& __p) noexcept
+    { return __p.second; }
+
+  template <typename _Tp, typename _Up>
+    constexpr _Tp&&
+    get(pair<_Up, _Tp>&& __p) noexcept
+    { return std::move(__p.second); }
+
   /// Assign @p __new_val to @p __obj and return its previous value.
-  template <class _Tp, class _Up = _Tp>
+  template <typename _Tp, typename _Up = _Tp>
     inline _Tp
     exchange(_Tp& __obj, _Up&& __new_val)
     {
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc
new file mode 100644 (file)
index 0000000..32c22b8
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++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 <type_traits>
+
+typedef std::pair<int, long> test_type;
+
+static_assert( std::tuple_size<test_type>::value == 2, "size is 2" );
+
+template<std::size_t N, typename T>
+  using Tuple_elt = typename std::tuple_element<N, T>::type;
+
+using std::is_same;
+
+static_assert( is_same<Tuple_elt<0, test_type>, test_type::first_type>::value,
+               "first type is int" );
+
+static_assert( is_same<Tuple_elt<1, test_type>, test_type::second_type>::value,
+               "second type is long" );
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get.cc
new file mode 100644 (file)
index 0000000..d01dcc5
--- /dev/null
@@ -0,0 +1,34 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// 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/>.
+
+// Tuple-like access to pair
+
+#include <utility>
+
+std::pair<int, char> p;
+const std::pair<int, char> cp;
+
+constexpr const int& cri = std::get<0>(cp);
+constexpr int&  ri = std::get<0>(p);
+constexpr int&& rri = std::get<0>(std::move(p));
+
+constexpr const char& crc = std::get<1>(cp);
+constexpr char&  rc = std::get<1>(p);
+constexpr char&& rrc = std::get<1>(std::move(p));
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get_by_type.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get_by_type.cc
new file mode 100644 (file)
index 0000000..1b18dab
--- /dev/null
@@ -0,0 +1,34 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// 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/>.
+
+// Tuple-like access to pair
+
+#include <utility>
+
+std::pair<int, char> p;
+const std::pair<int, char> cp;
+
+constexpr const int& cri = std::get<int>(cp);
+constexpr int&  ri = std::get<int>(p);
+constexpr int&& rri = std::get<int>(std::move(p));
+
+constexpr const char& crc = std::get<char>(cp);
+constexpr char&  rc = std::get<char>(p);
+constexpr char&& rrc = std::get<char>(std::move(p));
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc
new file mode 100644 (file)
index 0000000..dd26d2d
--- /dev/null
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// 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<float, int> p;
+
+  float&& pfirst __attribute__((unused)) = std::get<float>(std::move(p));
+  int&&  psecond __attribute__((unused)) = std::get<int>(std::move(p));
+}
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type_neg.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type_neg.cc
new file mode 100644 (file)
index 0000000..4f7f414
--- /dev/null
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// 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<int, int> p;
+
+  std::get<int>(p);  // { dg-error "ambiguous" }
+}
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/get_neg.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get_neg.cc
new file mode 100644 (file)
index 0000000..95fe457
--- /dev/null
@@ -0,0 +1,30 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// 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<int, int> p;
+
+  std::get<2>(p);  // { dg-error "no matching function" }
+}
+
+// { dg-prune-output "tuple_element<2" }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc
new file mode 100644 (file)
index 0000000..9d0239a
--- /dev/null
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++1y" }
+// { dg-do compile }
+
+// 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/>.
+
+// Tuple
+
+#include <tuple>
+
+std::tuple<long, int, const int, long> ti;
+const std::tuple<long, int, const int, long> cti;
+
+constexpr const int& cri = std::get<int>(cti);
+constexpr int&  ri = std::get<int>(ti);
+constexpr int&& rri = std::get<int>(std::move(ti));
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc
new file mode 100644 (file)
index 0000000..dbe5f54
--- /dev/null
@@ -0,0 +1,39 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// 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 <tuple>
+
+void test01()
+{
+  std::tuple<int> t1;
+
+  int&&   t1one __attribute__((unused)) = std::get<int>(std::move(t1));
+
+  std::tuple<float, int> t2;
+
+  float&& t2one __attribute__((unused)) = std::get<0>(std::move(t2));
+  int&&   t2two __attribute__((unused)) = std::get<int>(std::move(t2));
+
+  std::tuple<short, int, double> t3;
+
+  short&&  t3one __attribute__((unused)) = std::get<short>(std::move(t3));
+  int&&    t3two __attribute__((unused)) = std::get<int>(std::move(t3));
+  double&& t3thr __attribute__((unused)) = std::get<double>(std::move(t3));
+}
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc
new file mode 100644 (file)
index 0000000..5bd15d9
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++1y" }
+
+// 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/>.
+
+// Tuple
+
+#include <tuple>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int
+main()
+{
+  bool test __attribute__((unused)) = true;
+
+  int j=1;
+  const int k=2;
+  tuple<int,int &,const int&> a(0,j,k);
+  const tuple<int,int &,const int&> b(1,j,k);
+  VERIFY(get<int>(a)==0 && get<int&>(a)==1 && get<const int&>(a)==2);
+  get<0>(a)=3;
+  get<1>(a)=4;
+  VERIFY(get<int>(a)==3 && get<int&>(a)==4);
+  VERIFY(j==4);
+  get<1>(b)=5;
+  VERIFY(get<int>(b)==1 && get<int&>(b)==5 && get<const int&>(b)==2);
+  VERIFY(j==5);
+}