* 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.
Tested x86_64-linux, committed to trunk.
commit 336fca0d178e8717f5cb9de45ce26d1cf70e3b06 Author: Jonathan Wakely <jwakely....@gmail.com> Date: Sun May 19 13:54:45 2013 +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. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index ee2b2e1..69f5bd1 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -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> diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index ee8c6b1..ad30ad7 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -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 index 0000000..32c22b8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc @@ -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 index 0000000..d01dcc5 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get.cc @@ -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 index 0000000..1b18dab --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/constexpr_get_by_type.cc @@ -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.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc new file mode 100644 index 0000000..0ff807a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc @@ -0,0 +1,31 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-05-16 Paolo Carlini <paolo.carl...@oracle.com> +// +// Copyright (C) 2011-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<0>(std::move(p)); + int&& psecond __attribute__((unused)) = std::get<1>(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 index 0000000..dd26d2d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type.cc @@ -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 index 0000000..4f7f414 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get_by_type_neg.cc @@ -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 index 0000000..95fe457 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/astuple/get_neg.cc @@ -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/pair/get.cc b/libstdc++-v3/testsuite/20_util/pair/get.cc deleted file mode 100644 index 0ff807a..0000000 --- a/libstdc++-v3/testsuite/20_util/pair/get.cc +++ /dev/null @@ -1,31 +0,0 @@ -// { dg-do compile } -// { dg-options "-std=gnu++0x" } - -// 2011-05-16 Paolo Carlini <paolo.carl...@oracle.com> -// -// Copyright (C) 2011-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<0>(std::move(p)); - int&& psecond __attribute__((unused)) = std::get<1>(std::move(p)); -} 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 index 0000000..9d0239a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get_by_type.cc @@ -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 index 0000000..dbe5f54 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2_by_type.cc @@ -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 index 0000000..5bd15d9 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_by_type.cc @@ -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); +}