From dc8e187cb7c16371cbbf90adec00b12ad5cba9e5 Mon Sep 17 00:00:00 2001 From: redi Date: Thu, 25 Sep 2014 15:27:18 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@215606 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 16 ++++++ libstdc++-v3/doc/xml/manual/status_cxx2011.xml | 5 +- libstdc++-v3/include/bits/stl_uninitialized.h | 39 +++++++------ libstdc++-v3/include/bits/stl_vector.h | 12 ++-- libstdc++-v3/include/bits/vector.tcc | 30 +++++----- .../uninitialized_fill_n/16505.cc | 2 +- .../uninitialized_fill_n/dr1339.cc | 64 ++++++++++++++++++++++ 7 files changed, 126 insertions(+), 42 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/dr1339.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4bbb952f6b5..f4478235623 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,21 @@ 2014-09-25 Jonathan Wakely + 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 + * include/bits/vector.tcc (vector::_M_fill_assign): Use _M_swap_data. 2014-09-25 Jonathan Wakely diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index 4433c896f2c..36630cee93f 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -600,11 +600,10 @@ particular release. - 20.6.12.3 uninitialized_fill - Partial - Returns void.. + Y + diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index cd2a4828361..c864fa14bd3 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __uninitialized_fill_n { template - 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 { template - 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 - 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 - 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 - 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 - 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 { template - 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 - 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 - 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 - 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_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 diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 4eacec3f516..19784c0ac2e 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -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(...) { diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/16505.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/16505.cc index cfe01ca4539..72c93a5a1c8 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/16505.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/16505.cc @@ -26,5 +26,5 @@ struct S { }; template - void + S* std::uninitialized_fill_n(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 index 00000000000..d3ba204ef67 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/dr1339.cc @@ -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 +// . + +#include +#include + +// 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(mem); + T* end = std::uninitialized_fill_n(p, n, T()); + VERIFY( end = p + n ); + VERIFY( T::counter == n ); + delete[] mem; +} + +int +main() +{ + test01(); + test02(); +} -- 2.11.4.GIT