diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 35175d135255..3c1e7a979062 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,19 @@ +2013-05-19 Jonathan Wakely + + * 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 * Revert last commit. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index ee2b2e1d4c20..69f5bd1f72f4 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -772,6 +772,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return std::forward>::type&&>(get<__i>(__t)); } +#if __cplusplus > 201103L + template + 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 + 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 + constexpr _Tp& + get(tuple<_Types...>& __t) noexcept + { return __get_helper2<_Tp>(__t); } + + template + constexpr _Tp&& + get(tuple<_Types...>&& __t) noexcept + { return std::move(__get_helper2<_Tp>(__t)); } + + template + 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 diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index ee8c6b19609e..ad30ad7a9a3e 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 + constexpr _Tp& + get(pair<_Tp, _Up>& __p) noexcept + { return __p.first; } + + template + constexpr const _Tp& + get(const pair<_Tp, _Up>& __p) noexcept + { return __p.first; } + + template + constexpr _Tp&& + get(pair<_Tp, _Up>&& __p) noexcept + { return std::move(__p.first); } + + template + constexpr _Tp& + get(pair<_Up, _Tp>& __p) noexcept + { return __p.second; } + + template + constexpr const _Tp& + get(const pair<_Up, _Tp>& __p) noexcept + { return __p.second; } + + template + 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 + template 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 000000000000..32c22b884eba --- /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 +// . + +#include +#include + +typedef std::pair test_type; + +static_assert( std::tuple_size::value == 2, "size is 2" ); + +template + using Tuple_elt = typename std::tuple_element::type; + +using std::is_same; + +static_assert( is_same, test_type::first_type>::value, + "first type is int" ); + +static_assert( is_same, 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 000000000000..d01dcc5eecb4 --- /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 +// . + +// Tuple-like access to pair + +#include + +std::pair p; +const std::pair 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 000000000000..1b18dab988d6 --- /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 +// . + +// Tuple-like access to pair + +#include + +std::pair p; +const std::pair cp; + +constexpr const int& cri = std::get(cp); +constexpr int& ri = std::get(p); +constexpr int&& rri = std::get(std::move(p)); + +constexpr const char& crc = std::get(cp); +constexpr char& rc = std::get(p); +constexpr char&& rrc = std::get(std::move(p)); diff --git a/libstdc++-v3/testsuite/20_util/pair/get.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/get.cc similarity index 100% rename from libstdc++-v3/testsuite/20_util/pair/get.cc rename to libstdc++-v3/testsuite/20_util/pair/astuple/get.cc 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 000000000000..dd26d2d91137 --- /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 +// . + +#include + +void test01() +{ + std::pair p; + + float&& pfirst __attribute__((unused)) = std::get(std::move(p)); + int&& psecond __attribute__((unused)) = std::get(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 000000000000..4f7f41400145 --- /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 +// . + +#include + +void test01() +{ + std::pair p; + + std::get(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 000000000000..95fe4579227f --- /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 +// . + +#include + +void test01() +{ + std::pair 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 index 000000000000..9d0239a4855d --- /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 +// . + +// Tuple + +#include + +std::tuple ti; +const std::tuple cti; + +constexpr const int& cri = std::get(cti); +constexpr int& ri = std::get(ti); +constexpr int&& rri = std::get(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 000000000000..dbe5f5430b93 --- /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 +// . + +#include + +void test01() +{ + std::tuple t1; + + int&& t1one __attribute__((unused)) = std::get(std::move(t1)); + + std::tuple t2; + + float&& t2one __attribute__((unused)) = std::get<0>(std::move(t2)); + int&& t2two __attribute__((unused)) = std::get(std::move(t2)); + + std::tuple t3; + + short&& t3one __attribute__((unused)) = std::get(std::move(t3)); + int&& t3two __attribute__((unused)) = std::get(std::move(t3)); + double&& t3thr __attribute__((unused)) = std::get(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 000000000000..5bd15d97891f --- /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 +// . + +// Tuple + +#include +#include + +using namespace std; + +int +main() +{ + bool test __attribute__((unused)) = true; + + int j=1; + const int k=2; + tuple a(0,j,k); + const tuple b(1,j,k); + VERIFY(get(a)==0 && get(a)==1 && get(a)==2); + get<0>(a)=3; + get<1>(a)=4; + VERIFY(get(a)==3 && get(a)==4); + VERIFY(j==4); + get<1>(b)=5; + VERIFY(get(b)==1 && get(b)==5 && get(b)==2); + VERIFY(j==5); +}