aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2012-10-04 00:02:29 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2012-10-04 00:02:29 +0000
commit90f9c94e02d8b8ce71d6f5793b25a3b3849fc133 (patch)
treebd4ef8114921e12b4aeffda3a0699f1c5679f17b
parentbe4ba8aef398e6177b62d3ced6c9a086082d94f2 (diff)
downloadgcc-90f9c94e02d8b8ce71d6f5793b25a3b3849fc133.zip
gcc-90f9c94e02d8b8ce71d6f5793b25a3b3849fc133.tar.gz
gcc-90f9c94e02d8b8ce71d6f5793b25a3b3849fc133.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog15
-rw-r--r--libstdc++-v3/include/std/array49
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc48
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc14
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc2
6 files changed, 103 insertions, 31 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c02a660..5f35640 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 4ee2199..c7c0a5a 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -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
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 0000000..28cc995
--- /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
+// <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;
+};
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 ed29e2a..86e2375 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<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()
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 2fc443e..e74af1b 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 97938ba..b9ce910 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<int, 1>>::type type;
-// { dg-error "static assertion failed" "" { target *-*-* } 259 }
+// { dg-error "static assertion failed" "" { target *-*-* } 280 }