mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-27 13:05:24 +08:00
re PR libstdc++/53248 (std::array<T,0> doesn't work when T is not default-constructible)
2012-10-03 Paolo Carlini <paolo.carlini@oracle.com> 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
This commit is contained in:
parent
be4ba8aef3
commit
90f9c94e02
@ -1,3 +1,18 @@
|
||||
2012-10-03 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
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 <jwakely.gcc@gmail.com>
|
||||
|
||||
PR other/53889
|
||||
|
@ -1,7 +1,6 @@
|
||||
// <array> -*- 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<typename _Tp, std::size_t _Nm>
|
||||
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<typename _Tp>
|
||||
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_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<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
@ -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
|
||||
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <array>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
|
||||
template < typename ...Types >
|
||||
union super_union;
|
||||
|
||||
template < >
|
||||
union super_union<>
|
||||
{
|
||||
static auto optioned_types() -> std::array<std::type_index, 0>
|
||||
{ return std::array<std::type_index, 0>{ {} }; }
|
||||
};
|
||||
|
||||
template < typename Head, typename ...Tail >
|
||||
union super_union<Head, Tail...>
|
||||
{
|
||||
static
|
||||
auto optioned_types() -> std::array<std::type_index, 1 + sizeof...(Tail)>
|
||||
{
|
||||
using std::type_index;
|
||||
|
||||
return { {type_index(typeid(Head)), type_index(typeid(Tail))...} };
|
||||
}
|
||||
|
||||
Head data;
|
||||
super_union<Tail...> rest;
|
||||
};
|
@ -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<long, len> array_type1;
|
||||
typedef std::array<char, len> array_type2;
|
||||
array_type1 one;
|
||||
array_type2 two;
|
||||
void* v1 = one.begin();
|
||||
void* v2 = two.begin();
|
||||
VERIFY( v1 != v2 );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -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 }
|
||||
|
@ -22,4 +22,4 @@
|
||||
|
||||
typedef std::tuple_element<1, std::array<int, 1>>::type type;
|
||||
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 259 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 280 }
|
||||
|
Loading…
Reference in New Issue
Block a user