From: Paolo Carlini Date: Thu, 4 Oct 2012 00:02:29 +0000 (+0000) Subject: re PR libstdc++/53248 (std::array doesn't work when T is not default-constructible) X-Git-Tag: releases/gcc-4.8.0~3029 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=90f9c94e02d8b8ce71d6f5793b25a3b3849fc133;p=thirdparty%2Fgcc.git re PR libstdc++/53248 (std::array doesn't work when T is not default-constructible) 2012-10-03 Paolo Carlini PR libstdc++/53248 * include/std/array (__array_traits<>): Add. (array<>): Allow for zero-size arrays of non default-constructible elements. * testsuite/23_containers/array/requirements/ non_default_constructible.cc: New. * testsuite/23_containers/array/requirements/zero_sized_arrays.cc: Adjust. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers. * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: Likewise. From-SVN: r192056 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c02a660a2306..5f3564077503 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2012-10-03 Paolo Carlini + + PR libstdc++/53248 + * include/std/array (__array_traits<>): Add. + (array<>): Allow for zero-size arrays of non default-constructible + elements. + * testsuite/23_containers/array/requirements/ + non_default_constructible.cc: New. + * testsuite/23_containers/array/requirements/zero_sized_arrays.cc: + Adjust. + * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust + dg-error line numbers. + * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: + Likewise. + 2012-10-02 Jonathan Wakely PR other/53889 diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 4ee21998b014..c7c0a5ae8245 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -1,7 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 -// Free Software Foundation, Inc. +// Copyright (C) 2007-2012 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 @@ -44,6 +43,26 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION + template + struct __array_traits + { + typedef _Tp _Type[_Nm]; + + static constexpr _Tp& + _S_ref(const _Type& __t, std::size_t __n) noexcept + { return const_cast<_Tp&>(__t[__n]); } + }; + + template + struct __array_traits<_Tp, 0> + { + struct _Type { }; + + static constexpr _Tp& + _S_ref(const _Type&, std::size_t) noexcept + { return *static_cast<_Tp*>(nullptr); } + }; + /** * @brief A standard container for storing a fixed size sequence of elements. * @@ -74,7 +93,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef std::reverse_iterator const_reverse_iterator; // Support for zero-sized arrays mandatory. - value_type _M_instance[_Nm ? _Nm : 1]; + typedef std::__array_traits<_Tp, _Nm> _AT_Type; + typename _AT_Type::_Type _M_elems; // No explicit construct/copy/destroy for aggregate type. @@ -123,11 +143,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const_iterator cbegin() const noexcept - { return const_iterator(std::__addressof(_M_instance[0])); } + { return const_iterator(data()); } const_iterator cend() const noexcept - { return const_iterator(std::__addressof(_M_instance[_Nm])); } + { return const_iterator(data() + _Nm); } const_reverse_iterator crbegin() const noexcept @@ -150,18 +170,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Element access. reference operator[](size_type __n) - { return _M_instance[__n]; } + { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference operator[](size_type __n) const noexcept - { return _M_instance[__n]; } + { return _AT_Type::_S_ref(_M_elems, __n); } reference at(size_type __n) { if (__n >= _Nm) std::__throw_out_of_range(__N("array::at")); - return _M_instance[__n]; + return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference @@ -169,8 +189,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) - return __n < _Nm ? _M_instance[__n] - : (std::__throw_out_of_range(__N("array::at")), _M_instance[0]); + return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) + : (std::__throw_out_of_range(__N("array::at")), + _AT_Type::_S_ref(_M_elems, 0)); } reference @@ -191,11 +212,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION pointer data() noexcept - { return std::__addressof(_M_instance[0]); } + { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } const_pointer data() const noexcept - { return std::__addressof(_M_instance[0]); } + { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } }; // Array comparisons. @@ -265,7 +286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); - return __arr._M_instance[_Int]; + return std::__array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int); } template @@ -281,7 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(const array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); - return __arr._M_instance[_Int]; + return std::__array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc b/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc new file mode 100644 index 000000000000..28cc9959bb91 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc @@ -0,0 +1,48 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2012 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 +#include + +template < typename ...Types > +union super_union; + +template < > +union super_union<> +{ + static auto optioned_types() -> std::array + { return std::array{ {} }; } +}; + +template < typename Head, typename ...Tail > +union super_union +{ + static + auto optioned_types() -> std::array + { + using std::type_index; + + return { {type_index(typeid(Head)), type_index(typeid(Tail))...} }; + } + + Head data; + super_union rest; +}; diff --git a/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc b/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc index ed29e2a1eafa..86e237583bae 100644 --- a/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc +++ b/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc @@ -1,6 +1,6 @@ // { dg-options "-std=gnu++0x" } // -// Copyright (C) 2011 Free Software Foundation, Inc. +// Copyright (C) 2011-2012 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 @@ -38,18 +38,6 @@ test01() // begin() == end() VERIFY( a.begin() == a.end() ); VERIFY( b.begin() == b.end() ); - - // 4: ? - // begin() == end() == unique value. - { - typedef std::array array_type1; - typedef std::array array_type2; - array_type1 one; - array_type2 two; - void* v1 = one.begin(); - void* v2 = two.begin(); - VERIFY( v1 != v2 ); - } } int main() diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc index 2fc443edad6b..e74af1b4f43a 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc @@ -27,6 +27,6 @@ int n1 = std::get<1>(a); int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 275 } -// { dg-error "static assertion failed" "" { target *-*-* } 283 } -// { dg-error "static assertion failed" "" { target *-*-* } 267 } +// { dg-error "static assertion failed" "" { target *-*-* } 288 } +// { dg-error "static assertion failed" "" { target *-*-* } 296 } +// { dg-error "static assertion failed" "" { target *-*-* } 304 } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc index 97938ba669a7..b9ce910f61a4 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc @@ -22,4 +22,4 @@ typedef std::tuple_element<1, std::array>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 259 } +// { dg-error "static assertion failed" "" { target *-*-* } 280 }