DR 1339
authorJonathan Wakely <jwakely@redhat.com>
Thu, 25 Sep 2014 15:27:18 +0000 (16:27 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 25 Sep 2014 15:27:18 +0000 (16:27 +0100)
DR 1339
* doc/xml/manual/status_cxx2011.xml: Update.
* include/bits/stl_uninitialized.h (uninitialized_fill_n): Return
an iterator.
(__uninitialized_fill_n_a, __uninitialized_default_n_a): Likewise.
* include/bits/stl_vector.h (vector::_M_fill_initialize,
vector::_M_default_initialize): Use returned iterator.
* include/bits/vector.tcc (vector::_M_fill_assign,
vector::_M_fill_insert, vector::_M_default_append): Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
16505.cc: Adjust return type.
* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
dr1339.cc: New.

From-SVN: r215606

libstdc++-v3/ChangeLog
libstdc++-v3/doc/xml/manual/status_cxx2011.xml
libstdc++-v3/include/bits/stl_uninitialized.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/16505.cc
libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/dr1339.cc [new file with mode: 0644]

index 4bbb952f6b556271f730faea5becda92421667e8..f4478235623a4d4801534b5d2436a05e28e1985a 100644 (file)
@@ -1,3 +1,19 @@
+2014-09-25  Jonathan Wakely  <jwakely@redhat.com>
+
+       DR 1339
+       * doc/xml/manual/status_cxx2011.xml: Update.
+       * include/bits/stl_uninitialized.h (uninitialized_fill_n): Return
+       an iterator.
+       (__uninitialized_fill_n_a, __uninitialized_default_n_a): Likewise.
+       * include/bits/stl_vector.h (vector::_M_fill_initialize,
+       vector::_M_default_initialize): Use returned iterator.
+       * include/bits/vector.tcc (vector::_M_fill_assign,
+       vector::_M_fill_insert, vector::_M_default_append): Likewise.
+       * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
+       16505.cc: Adjust return type.
+       * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
+       dr1339.cc: New.
+
 2014-09-25  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/vector.tcc (vector::_M_fill_assign): Use _M_swap_data.
index 4433c896f2ce08f608db3f6b43f5d790b19d399b..36630cee93f91ae31336c1044b4e97d715822b9f 100644 (file)
@@ -600,11 +600,10 @@ particular release.
       <entry/>
     </row>
     <row>
-      <?dbhtml bgcolor="#B0B0B0" ?>
       <entry>20.6.12.3</entry>
       <entry><code>uninitialized_fill</code></entry>
-      <entry>Partial</entry>
-      <entry>Returns <code>void</code>..</entry>
+      <entry>Y</entry>
+      <entry/>
     </row>
     <row>
       <?dbhtml bgcolor="#B0B0B0" ?>
index cd2a48283615dffa9d55c6e3ae035ae4dedf6ec0..c864fa14bd3c2ae4bbec0ce2b595153d2eb4131f 100644 (file)
@@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __uninitialized_fill_n
     {
       template<typename _ForwardIterator, typename _Size, typename _Tp>
-        static void
+        static _ForwardIterator
         __uninit_fill_n(_ForwardIterator __first, _Size __n,
                        const _Tp& __x)
         {
@@ -199,6 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            {
              for (; __n > 0; --__n, ++__cur)
                std::_Construct(std::__addressof(*__cur), __x);
+             return __cur;
            }
          __catch(...)
            {
@@ -212,12 +213,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __uninitialized_fill_n<true>
     {
       template<typename _ForwardIterator, typename _Size, typename _Tp>
-        static void
+        static _ForwardIterator
         __uninit_fill_n(_ForwardIterator __first, _Size __n,
                        const _Tp& __x)
-        { std::fill_n(__first, __n, __x); }
+        { return std::fill_n(__first, __n, __x); }
     };
 
+   // _GLIBCXX_RESOLVE_LIB_DEFECTS
+   // DR 1339. uninitialized_fill_n should return the end of its range
   /**
    *  @brief Copies the value x into the range [first,first+n).
    *  @param  __first  An input iterator.
@@ -228,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  Like fill_n(), but does not require an initialized output range.
   */
   template<typename _ForwardIterator, typename _Size, typename _Tp>
-    inline void
+    inline _ForwardIterator
     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
     {
       typedef typename iterator_traits<_ForwardIterator>::value_type
@@ -239,8 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // trivial types can have deleted assignment
       const bool __assignable = is_copy_assignable<_ValueType>::value;
 #endif
-
-      std::__uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
+      return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
        __uninit_fill_n(__first, __n, __x);
     }
 
@@ -328,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _ForwardIterator, typename _Size, typename _Tp,
           typename _Allocator>
-    void
+    _ForwardIterator
     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
                             const _Tp& __x, _Allocator& __alloc)
     {
@@ -338,6 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
          for (; __n > 0; --__n, ++__cur)
            __traits::construct(__alloc, std::__addressof(*__cur), __x);
+         return __cur;
        }
       __catch(...)
        {
@@ -348,10 +351,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _ForwardIterator, typename _Size, typename _Tp,
           typename _Tp2>
-    inline void
+    inline _ForwardIterator
     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
                             const _Tp& __x, allocator<_Tp2>&)
-    { std::uninitialized_fill_n(__first, __n, __x); }
+    { return std::uninitialized_fill_n(__first, __n, __x); }
 
 
   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
@@ -505,7 +508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __uninitialized_default_n_1
     {
       template<typename _ForwardIterator, typename _Size>
-        static void
+        static _ForwardIterator
         __uninit_default_n(_ForwardIterator __first, _Size __n)
         {
          _ForwardIterator __cur = __first;
@@ -513,6 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            {
              for (; __n > 0; --__n, ++__cur)
                std::_Construct(std::__addressof(*__cur));
+             return __cur;
            }
          __catch(...)
            {
@@ -526,13 +530,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __uninitialized_default_n_1<true>
     {
       template<typename _ForwardIterator, typename _Size>
-        static void
+        static _ForwardIterator
         __uninit_default_n(_ForwardIterator __first, _Size __n)
         {
          typedef typename iterator_traits<_ForwardIterator>::value_type
            _ValueType;
 
-         std::fill_n(__first, __n, _ValueType());
+         return std::fill_n(__first, __n, _ValueType());
        }
     };
 
@@ -557,7 +561,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // __uninitialized_default_n
   // Fills [first, first + n) with n default constructed value_type(s).
   template<typename _ForwardIterator, typename _Size>
-    inline void
+    inline _ForwardIterator
     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
     {
       typedef typename iterator_traits<_ForwardIterator>::value_type
@@ -565,7 +569,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // trivial types can have deleted assignment
       const bool __assignable = is_copy_assignable<_ValueType>::value;
 
-      std::__uninitialized_default_n_1<__is_trivial(_ValueType)
+      return __uninitialized_default_n_1<__is_trivial(_ValueType)
                                       && __assignable>::
        __uninit_default_n(__first, __n);
     }
@@ -606,7 +610,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Fills [first, first + n) with n default constructed value_types(s),
   // constructed with the allocator alloc.
   template<typename _ForwardIterator, typename _Size, typename _Allocator>
-    void
+    _ForwardIterator
     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
                                _Allocator& __alloc)
     {
@@ -616,6 +620,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
          for (; __n > 0; --__n, ++__cur)
            __traits::construct(__alloc, std::__addressof(*__cur));
+         return __cur;
        }
       __catch(...)
        {
@@ -625,10 +630,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   template<typename _ForwardIterator, typename _Size, typename _Tp>
-    inline void
+    inline _ForwardIterator
     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
                                allocator<_Tp>&)
-    { std::__uninitialized_default_n(__first, __n); }
+    { return std::__uninitialized_default_n(__first, __n); }
 
 
   template<typename _InputIterator, typename _Size,
index 0a56c65ed752c202f942cb31a1f3e361b2ddd070..dd2d4337d57242f5108616d3dd5cfff33aa7454b 100644 (file)
@@ -1297,9 +1297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       _M_fill_initialize(size_type __n, const value_type& __value)
       {
-       std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, 
-                                     _M_get_Tp_allocator());
-       this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
+       this->_M_impl._M_finish =
+         std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
+                                       _M_get_Tp_allocator());
       }
 
 #if __cplusplus >= 201103L
@@ -1307,9 +1307,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       _M_default_initialize(size_type __n)
       {
-       std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, 
-                                        _M_get_Tp_allocator());
-       this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
+       this->_M_impl._M_finish =
+         std::__uninitialized_default_n_a(this->_M_impl._M_start, __n,
+                                          _M_get_Tp_allocator());
       }
 #endif
 
index 4eacec3f5165117cfe8b5299369b789a43c3cbd2..19784c0ac2ecaeeabbe3cf6146114da036ebac6c 100644 (file)
@@ -233,10 +233,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       else if (__n > size())
        {
          std::fill(begin(), end(), __val);
-         std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
-                                       __n - size(), __val,
-                                       _M_get_Tp_allocator());
-         this->_M_impl._M_finish += __n - size();
+         this->_M_impl._M_finish =
+           std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
+                                         __n - size(), __val,
+                                         _M_get_Tp_allocator());
        }
       else
         _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
@@ -471,11 +471,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                }
              else
                {
-                 std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
-                                               __n - __elems_after,
-                                               __x_copy,
-                                               _M_get_Tp_allocator());
-                 this->_M_impl._M_finish += __n - __elems_after;
+                 this->_M_impl._M_finish =
+                   std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
+                                                 __n - __elems_after,
+                                                 __x_copy,
+                                                 _M_get_Tp_allocator());
                  std::__uninitialized_move_a(__position.base(), __old_finish,
                                              this->_M_impl._M_finish,
                                              _M_get_Tp_allocator());
@@ -545,9 +545,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          if (size_type(this->_M_impl._M_end_of_storage
                        - this->_M_impl._M_finish) >= __n)
            {
-             std::__uninitialized_default_n_a(this->_M_impl._M_finish,
-                                              __n, _M_get_Tp_allocator());
-             this->_M_impl._M_finish += __n;
+             this->_M_impl._M_finish =
+               std::__uninitialized_default_n_a(this->_M_impl._M_finish,
+                                                __n, _M_get_Tp_allocator());
            }
          else
            {
@@ -562,9 +562,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                    = std::__uninitialized_move_if_noexcept_a
                    (this->_M_impl._M_start, this->_M_impl._M_finish,
                     __new_start, _M_get_Tp_allocator());
-                 std::__uninitialized_default_n_a(__new_finish, __n,
-                                                  _M_get_Tp_allocator());
-                 __new_finish += __n;
+                 __new_finish =
+                   std::__uninitialized_default_n_a(__new_finish, __n,
+                                                    _M_get_Tp_allocator());
                }
              __catch(...)
                {
index cfe01ca453981a909569359158c53778dba4c390..72c93a5a1c8ec1e661c16e63ddea394361d9009d 100644 (file)
@@ -26,5 +26,5 @@
 struct S { };
 
 template
-  void
+  S*
   std::uninitialized_fill_n<S*, int, S>(S*, int, const S&);
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/dr1339.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/dr1339.cc
new file mode 100644 (file)
index 0000000..d3ba204
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2014 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 <memory>
+#include <testsuite_hooks.h>
+
+// test specialization for trivial types
+void
+test01()
+{
+  const int N = 10;
+  int arr[N] = { };
+  const int n = 5;
+  const int over9000 = 9001;
+  int* end = std::uninitialized_fill_n(arr, n, over9000);
+  VERIFY( end = arr + n );
+  for (int i = 0; i < n; ++i)
+    VERIFY( arr[i] == over9000 );
+  for (int i = n; i < N; ++i)
+    VERIFY( arr[i] == 0 );
+}
+
+struct T
+{
+  T() { }
+  T(const T&) { ++counter; }
+  static int counter;
+};
+
+int T::counter;
+
+// test non-trivial
+void
+test02()
+{
+  const int n = 5;
+  char* mem = new char[sizeof(T)*n];
+  T* p = reinterpret_cast<T*>(mem);
+  T* end = std::uninitialized_fill_n(p, n, T());
+  VERIFY( end = p + n );
+  VERIFY( T::counter == n );
+  delete[] mem;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}