]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/53248 (std::array<T,0> doesn't work when T is not default-constructible)
authorPaolo Carlini <paolo.carlini@oracle.com>
Thu, 4 Oct 2012 00:02:29 +0000 (00:02 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 4 Oct 2012 00:02:29 +0000 (00:02 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/array
libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc

index c02a660a23065548599ff4eea0bbbbf6fcd91210..5f3564077503e216a4acd54af71f1f678887384b 100644 (file)
@@ -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
index 4ee21998b01476fec4bc110815f9292ab3239225..c7c0a5ae82457c96ed3321f57026160214541132 100644 (file)
@@ -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 (file)
index 0000000..28cc995
--- /dev/null
@@ -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;
+};
index ed29e2a1eafa62c6160800748b79c9398b3c1937..86e237583bae8228efa715e4d6ab1d04a9c9e28d 100644 (file)
@@ -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()
index 2fc443edad6b0321015c97d478d8902d7584073b..e74af1b4f43adac5d06d7fb88f4c496258db7469 100644 (file)
@@ -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 }
index 97938ba669a742cc5d9c95988cb9696ade913cd0..b9ce910f61a4073dd7a7b0845232e0e9099b2620 100644 (file)
@@ -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 }