diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8cd719cae24..265fcf23d45 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2011-09-12 Daniel Krugler + Paolo Carlini + + * include/std/tuple (_Head_base<>::_M_head, _Head_base<>::_M_tail, + _Tuple_impl<>::_M_head, _Tuple_impl<>::_M_tail): Change to static + constexpr functions; adjust everywhere. + (__get_helper, get): Declare constexpr all three overloads. + (tuple_cat): Declare constexpr; use late return type to improve + error messages. + * include/std/utility (__pair_get<>::__get, __pair_get<>::__move_get, + __pair_get<>::__const_get, get): Declare all constexpr. + * include/std/array (get): Likewise. + * testsuite/20_util/tuple/creation_functions/constexpr.cc: Re-enable + tuple_cat test. + * testsuite/23_containers/array/constexpr_get.cc: New. + * testsuite/20_util/tuple/element_access/constexpr_get.cc: Likewise. + * testsuite/20_util/pair/constexpr_get.cc: Likewise. + * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust dg-error + line number. + 2011-09-12 Jason Merrill * testsuite/20_util/is_constructible/value-2.cc: Adjust diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 4d6b688843e..ae7445d0b21 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -264,19 +264,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef _Tp type; }; template - inline _Tp& + constexpr _Tp& get(array<_Tp, _Nm>& __arr) noexcept - { return __arr[_Int]; } + { return __arr._M_instance[_Int]; } template - inline _Tp&& + constexpr _Tp&& get(array<_Tp, _Nm>&& __arr) noexcept { return std::move(get<_Int>(__arr)); } template - inline const _Tp& + constexpr const _Tp& get(const array<_Tp, _Nm>& __arr) noexcept - { return __arr[_Int]; } + { return __arr._M_instance[_Int]; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 1b4a8238276..1eec951fd15 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -140,11 +140,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } - _Head& - _M_head() noexcept { return *this; } + static constexpr _Head& + _M_head(_Head_base& __b) noexcept { return __b; } - constexpr const _Head& - _M_head() const noexcept { return *this; } + static constexpr const _Head& + _M_head(const _Head_base& __b) noexcept { return __b; } }; template @@ -186,13 +186,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } - _Head& - _M_head() noexcept { return _M_head_impl; } + static constexpr _Head& + _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } - constexpr const _Head& - _M_head() const noexcept { return _M_head_impl; } + static constexpr const _Head& + _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } - _Head _M_head_impl; + _Head _M_head_impl; }; /** @@ -245,17 +245,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; - _Head& - _M_head() noexcept { return _Base::_M_head(); } + static constexpr _Head& + _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } - constexpr const _Head& - _M_head() const noexcept { return _Base::_M_head(); } + static constexpr const _Head& + _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } - _Inherited& - _M_tail() noexcept { return *this; } + static constexpr _Inherited& + _M_tail(_Tuple_impl& __t) noexcept { return __t; } - constexpr const _Inherited& - _M_tail() const noexcept { return *this; } + static constexpr const _Inherited& + _M_tail(const _Tuple_impl& __t) noexcept { return __t; } constexpr _Tuple_impl() : _Inherited(), _Base() { } @@ -276,17 +276,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_, is_nothrow_move_constructible<_Inherited>>::value) - : _Inherited(std::move(__in._M_tail())), - _Base(std::forward<_Head>(__in._M_head())) { } + : _Inherited(std::move(_M_tail(__in))), + _Base(std::forward<_Head>(_M_head(__in))) { } template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) - : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } + : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), + _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) - : _Inherited(std::move(__in._M_tail())), - _Base(std::forward<_UHead>(__in._M_head())) { } + : _Inherited(std::move + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), + _Base(std::forward<_UHead> + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) @@ -311,34 +314,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) - : _Inherited(__tag, __a, __in._M_tail()), - _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __in._M_head()) { } + : _Inherited(__tag, __a, _M_tail(__in)), + _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) - : _Inherited(__tag, __a, std::move(__in._M_tail())), + : _Inherited(__tag, __a, std::move(_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), - std::forward<_Head>(__in._M_head())) { } + std::forward<_Head>(_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UElements...>& __in) - : _Inherited(__tag, __a, __in._M_tail()), - _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __in._M_head()) { } + : _Inherited(__tag, __a, + _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), + _Base(__use_alloc<_Head, _Alloc, _Head>(__a), + _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) - : _Inherited(__tag, __a, std::move(__in._M_tail())), + : _Inherited(__tag, __a, std::move + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), - std::forward<_UHead>(__in._M_head())) { } + std::forward<_UHead> + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { - _M_head() = __in._M_head(); - _M_tail() = __in._M_tail(); + _M_head(*this) = _M_head(__in); + _M_tail(*this) = _M_tail(__in); return *this; } @@ -347,8 +354,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(__and_, is_nothrow_move_assignable<_Inherited>>::value) { - _M_head() = std::forward<_Head>(__in._M_head()); - _M_tail() = std::move(__in._M_tail()); + _M_head(*this) = std::forward<_Head>(_M_head(__in)); + _M_tail(*this) = std::move(_M_tail(__in)); return *this; } @@ -356,8 +363,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UElements...>& __in) { - _M_head() = __in._M_head(); - _M_tail() = __in._M_tail(); + _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); + _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); return *this; } @@ -365,8 +372,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { - _M_head() = std::forward<_UHead>(__in._M_head()); - _M_tail() = std::move(__in._M_tail()); + _M_head(*this) = std::forward<_UHead> + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); + _M_tail(*this) = std::move + (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); return *this; } @@ -375,11 +384,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_swap(_Tuple_impl& __in) noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())) - && noexcept(__in._M_tail()._M_swap(__in._M_tail()))) + && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; - swap(this->_M_head(), __in._M_head()); - _Inherited::_M_swap(__in._M_tail()); + swap(_M_head(*this), _M_head(__in)); + _Inherited::_M_swap(_M_tail(__in)); } }; @@ -656,8 +665,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(const pair<_U1, _U2>& __in) { - this->_M_head() = __in.first; - this->_M_tail()._M_head() = __in.second; + this->_M_head(*this) = __in.first; + this->_M_tail(*this)._M_head(*this) = __in.second; return *this; } @@ -665,8 +674,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(pair<_U1, _U2>&& __in) { - this->_M_head() = std::forward<_U1>(__in.first); - this->_M_tail()._M_head() = std::forward<_U2>(__in.second); + this->_M_head(*this) = std::forward<_U1>(__in.first); + this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); return *this; } @@ -747,34 +756,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public integral_constant { }; template - inline typename __add_ref<_Head>::type + constexpr typename __add_ref<_Head>::type __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept - { return __t._M_head(); } + { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template - inline constexpr typename __add_c_ref<_Head>::type + constexpr typename __add_c_ref<_Head>::type __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept - { return __t._M_head(); } + { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } // Return a reference (const reference, rvalue reference) to the ith element // of a tuple. Any const or non-const ref elements are returned with their // original type. template - inline typename __add_ref< + constexpr typename __add_ref< typename tuple_element<__i, tuple<_Elements...>>::type >::type get(tuple<_Elements...>& __t) noexcept { return __get_helper<__i>(__t); } template - inline constexpr typename __add_c_ref< + constexpr typename __add_c_ref< typename tuple_element<__i, tuple<_Elements...>>::type >::type get(const tuple<_Elements...>& __t) noexcept { return __get_helper<__i>(__t); } template - inline typename __add_r_ref< + constexpr typename __add_r_ref< typename tuple_element<__i, tuple<_Elements...>>::type >::type get(tuple<_Elements...>&& __t) noexcept @@ -880,13 +889,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct array; template - _Tp& get(array<_Tp, _Nm>&) noexcept; + constexpr _Tp& get(array<_Tp, _Nm>&) noexcept; template - _Tp&& get(array<_Tp, _Nm>&&) noexcept; + constexpr _Tp&& get(array<_Tp, _Nm>&&) noexcept; template - const _Tp& get(const array<_Tp, _Nm>&) noexcept; + constexpr const _Tp& get(const array<_Tp, _Nm>&) noexcept; template struct __is_tuple_like_impl : false_type @@ -1022,7 +1031,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> { template - static _Ret + static constexpr _Ret _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) { typedef typename __make_1st_indices<_Tpls...>::__type __idx; @@ -1037,18 +1046,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __tuple_concater<_Ret, std::_Index_tuple<>> { template - static _Ret + static constexpr _Ret _S_do(_Us&&... __us) { return _Ret(std::forward<_Us>(__us)...); } }; - template - inline typename - std::enable_if<__and_<__is_tuple_like<_Tpls>...>::value, - typename __tuple_cat_result<_Tpls...>::__type>::type + template...>::value>::type> + constexpr auto tuple_cat(_Tpls&&... __tpls) + -> typename __tuple_cat_result<_Tpls...>::__type { typedef typename __tuple_cat_result<_Tpls...>::__type __ret; typedef typename __make_1st_indices<_Tpls...>::__type __idx; diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index f433e46acee..11efd74335b 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -105,17 +105,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __pair_get<0> { template - static _Tp1& + static constexpr _Tp1& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } template - static _Tp1&& + static constexpr _Tp1&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp1>(__pair.first); } template - static const _Tp1& + static constexpr const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } }; @@ -124,33 +124,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __pair_get<1> { template - static _Tp2& + static constexpr _Tp2& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } template - static _Tp2&& + static constexpr _Tp2&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp2>(__pair.second); } template - static const _Tp2& + static constexpr const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } }; template - inline typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& + constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__get(__in); } template - inline typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& + constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& get(std::pair<_Tp1, _Tp2>&& __in) noexcept { return __pair_get<_Int>::__move_get(std::move(__in)); } template - inline const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& + constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(const std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__const_get(__in); } diff --git a/libstdc++-v3/testsuite/20_util/pair/constexpr_get.cc b/libstdc++-v3/testsuite/20_util/pair/constexpr_get.cc new file mode 100644 index 00000000000..c72f049ac6e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/constexpr_get.cc @@ -0,0 +1,28 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 + +std::pair pi; +const std::pair cpi; + +constexpr const int& cri = std::get<0>(cpi); +constexpr int& ri = std::get<0>(pi); +constexpr int&& rri = std::get<0>(std::move(pi)); diff --git a/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc index 82bbe1f104b..5b816a59bbb 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc @@ -63,7 +63,6 @@ test_get() } // tuple_cat -#if 0 void test_tuple_cat() { @@ -74,7 +73,6 @@ test_tuple_cat() constexpr tuple_type2 t2 { 55, 99, 77.77 }; constexpr auto cat1 = std::tuple_cat(t1, t2); } -#endif int main() @@ -84,10 +82,7 @@ main() #endif test_get(); - -#if 0 test_tuple_cat(); -#endif return 0; } diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get.cc new file mode 100644 index 00000000000..4dfad5333e4 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/constexpr_get.cc @@ -0,0 +1,30 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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<0>(cti); +constexpr int& ri = std::get<0>(ti); +constexpr int&& rri = std::get<0>(std::move(ti)); diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc index 001c57acde8..cb4b4a9bbd9 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc @@ -51,7 +51,7 @@ main() // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } // { dg-warning "note" "" { target *-*-* } 468 } -// { dg-warning "note" "" { target *-*-* } 831 } +// { dg-warning "note" "" { target *-*-* } 840 } // { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } // { dg-warning "note" "" { target *-*-* } 342 } diff --git a/libstdc++-v3/testsuite/23_containers/array/constexpr_get.cc b/libstdc++-v3/testsuite/23_containers/array/constexpr_get.cc new file mode 100644 index 00000000000..3346ffd3448 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/constexpr_get.cc @@ -0,0 +1,30 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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::array ai; +const std::array cai(ai); + +constexpr const int& cri = std::get<0>(cai); +constexpr int& ri = std::get<0>(ai); +constexpr int&& rri = std::get<0>(std::move(ai));