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
This commit is contained in:
Jonathan Wakely 2014-09-25 16:27:18 +01:00 committed by Jonathan Wakely
parent 72b497da48
commit e51cf2f559
7 changed files with 126 additions and 42 deletions

View 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> 2014-09-25 Jonathan Wakely <jwakely@redhat.com>
* include/bits/vector.tcc (vector::_M_fill_assign): Use _M_swap_data. * include/bits/vector.tcc (vector::_M_fill_assign): Use _M_swap_data.

View File

@ -600,11 +600,10 @@ particular release.
<entry/> <entry/>
</row> </row>
<row> <row>
<?dbhtml bgcolor="#B0B0B0" ?>
<entry>20.6.12.3</entry> <entry>20.6.12.3</entry>
<entry><code>uninitialized_fill</code></entry> <entry><code>uninitialized_fill</code></entry>
<entry>Partial</entry> <entry>Y</entry>
<entry>Returns <code>void</code>..</entry> <entry/>
</row> </row>
<row> <row>
<?dbhtml bgcolor="#B0B0B0" ?> <?dbhtml bgcolor="#B0B0B0" ?>

View File

@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __uninitialized_fill_n struct __uninitialized_fill_n
{ {
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
static void static _ForwardIterator
__uninit_fill_n(_ForwardIterator __first, _Size __n, __uninit_fill_n(_ForwardIterator __first, _Size __n,
const _Tp& __x) const _Tp& __x)
{ {
@ -199,6 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ {
for (; __n > 0; --__n, ++__cur) for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur), __x); std::_Construct(std::__addressof(*__cur), __x);
return __cur;
} }
__catch(...) __catch(...)
{ {
@ -212,12 +213,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __uninitialized_fill_n<true> struct __uninitialized_fill_n<true>
{ {
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
static void static _ForwardIterator
__uninit_fill_n(_ForwardIterator __first, _Size __n, __uninit_fill_n(_ForwardIterator __first, _Size __n,
const _Tp& __x) 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). * @brief Copies the value x into the range [first,first+n).
* @param __first An input iterator. * @param __first An input iterator.
@ -228,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Like fill_n(), but does not require an initialized output range. * Like fill_n(), but does not require an initialized output range.
*/ */
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
inline void inline _ForwardIterator
uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
{ {
typedef typename iterator_traits<_ForwardIterator>::value_type typedef typename iterator_traits<_ForwardIterator>::value_type
@ -239,8 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// trivial types can have deleted assignment // trivial types can have deleted assignment
const bool __assignable = is_copy_assignable<_ValueType>::value; const bool __assignable = is_copy_assignable<_ValueType>::value;
#endif #endif
return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
std::__uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
__uninit_fill_n(__first, __n, __x); __uninit_fill_n(__first, __n, __x);
} }
@ -328,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator, typename _Size, typename _Tp, template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Allocator> typename _Allocator>
void _ForwardIterator
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x, _Allocator& __alloc) const _Tp& __x, _Allocator& __alloc)
{ {
@ -338,6 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur) for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), __x); __traits::construct(__alloc, std::__addressof(*__cur), __x);
return __cur;
} }
__catch(...) __catch(...)
{ {
@ -348,10 +351,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator, typename _Size, typename _Tp, template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Tp2> typename _Tp2>
inline void inline _ForwardIterator
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x, allocator<_Tp2>&) 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, // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
@ -505,7 +508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __uninitialized_default_n_1 struct __uninitialized_default_n_1
{ {
template<typename _ForwardIterator, typename _Size> template<typename _ForwardIterator, typename _Size>
static void static _ForwardIterator
__uninit_default_n(_ForwardIterator __first, _Size __n) __uninit_default_n(_ForwardIterator __first, _Size __n)
{ {
_ForwardIterator __cur = __first; _ForwardIterator __cur = __first;
@ -513,6 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ {
for (; __n > 0; --__n, ++__cur) for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur)); std::_Construct(std::__addressof(*__cur));
return __cur;
} }
__catch(...) __catch(...)
{ {
@ -526,13 +530,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __uninitialized_default_n_1<true> struct __uninitialized_default_n_1<true>
{ {
template<typename _ForwardIterator, typename _Size> template<typename _ForwardIterator, typename _Size>
static void static _ForwardIterator
__uninit_default_n(_ForwardIterator __first, _Size __n) __uninit_default_n(_ForwardIterator __first, _Size __n)
{ {
typedef typename iterator_traits<_ForwardIterator>::value_type typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType; _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 // __uninitialized_default_n
// Fills [first, first + n) with n default constructed value_type(s). // Fills [first, first + n) with n default constructed value_type(s).
template<typename _ForwardIterator, typename _Size> template<typename _ForwardIterator, typename _Size>
inline void inline _ForwardIterator
__uninitialized_default_n(_ForwardIterator __first, _Size __n) __uninitialized_default_n(_ForwardIterator __first, _Size __n)
{ {
typedef typename iterator_traits<_ForwardIterator>::value_type typedef typename iterator_traits<_ForwardIterator>::value_type
@ -565,7 +569,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// trivial types can have deleted assignment // trivial types can have deleted assignment
const bool __assignable = is_copy_assignable<_ValueType>::value; 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>:: && __assignable>::
__uninit_default_n(__first, __n); __uninit_default_n(__first, __n);
} }
@ -606,7 +610,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Fills [first, first + n) with n default constructed value_types(s), // Fills [first, first + n) with n default constructed value_types(s),
// constructed with the allocator alloc. // constructed with the allocator alloc.
template<typename _ForwardIterator, typename _Size, typename _Allocator> template<typename _ForwardIterator, typename _Size, typename _Allocator>
void _ForwardIterator
__uninitialized_default_n_a(_ForwardIterator __first, _Size __n, __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
_Allocator& __alloc) _Allocator& __alloc)
{ {
@ -616,6 +620,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur) for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur)); __traits::construct(__alloc, std::__addressof(*__cur));
return __cur;
} }
__catch(...) __catch(...)
{ {
@ -625,10 +630,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
inline void inline _ForwardIterator
__uninitialized_default_n_a(_ForwardIterator __first, _Size __n, __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
allocator<_Tp>&) allocator<_Tp>&)
{ std::__uninitialized_default_n(__first, __n); } { return std::__uninitialized_default_n(__first, __n); }
template<typename _InputIterator, typename _Size, template<typename _InputIterator, typename _Size,

View File

@ -1297,9 +1297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void void
_M_fill_initialize(size_type __n, const value_type& __value) _M_fill_initialize(size_type __n, const value_type& __value)
{ {
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, this->_M_impl._M_finish =
_M_get_Tp_allocator()); std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; _M_get_Tp_allocator());
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
@ -1307,9 +1307,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void void
_M_default_initialize(size_type __n) _M_default_initialize(size_type __n)
{ {
std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, this->_M_impl._M_finish =
_M_get_Tp_allocator()); std::__uninitialized_default_n_a(this->_M_impl._M_start, __n,
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; _M_get_Tp_allocator());
} }
#endif #endif

View File

@ -233,10 +233,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
else if (__n > size()) else if (__n > size())
{ {
std::fill(begin(), end(), __val); std::fill(begin(), end(), __val);
std::__uninitialized_fill_n_a(this->_M_impl._M_finish, this->_M_impl._M_finish =
__n - size(), __val, std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
_M_get_Tp_allocator()); __n - size(), __val,
this->_M_impl._M_finish += __n - size(); _M_get_Tp_allocator());
} }
else else
_M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
@ -471,11 +471,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
} }
else else
{ {
std::__uninitialized_fill_n_a(this->_M_impl._M_finish, this->_M_impl._M_finish =
__n - __elems_after, std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
__x_copy, __n - __elems_after,
_M_get_Tp_allocator()); __x_copy,
this->_M_impl._M_finish += __n - __elems_after; _M_get_Tp_allocator());
std::__uninitialized_move_a(__position.base(), __old_finish, std::__uninitialized_move_a(__position.base(), __old_finish,
this->_M_impl._M_finish, this->_M_impl._M_finish,
_M_get_Tp_allocator()); _M_get_Tp_allocator());
@ -545,9 +545,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (size_type(this->_M_impl._M_end_of_storage if (size_type(this->_M_impl._M_end_of_storage
- this->_M_impl._M_finish) >= __n) - this->_M_impl._M_finish) >= __n)
{ {
std::__uninitialized_default_n_a(this->_M_impl._M_finish, this->_M_impl._M_finish =
__n, _M_get_Tp_allocator()); std::__uninitialized_default_n_a(this->_M_impl._M_finish,
this->_M_impl._M_finish += __n; __n, _M_get_Tp_allocator());
} }
else else
{ {
@ -562,9 +562,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
= std::__uninitialized_move_if_noexcept_a = std::__uninitialized_move_if_noexcept_a
(this->_M_impl._M_start, this->_M_impl._M_finish, (this->_M_impl._M_start, this->_M_impl._M_finish,
__new_start, _M_get_Tp_allocator()); __new_start, _M_get_Tp_allocator());
std::__uninitialized_default_n_a(__new_finish, __n, __new_finish =
_M_get_Tp_allocator()); std::__uninitialized_default_n_a(__new_finish, __n,
__new_finish += __n; _M_get_Tp_allocator());
} }
__catch(...) __catch(...)
{ {

View File

@ -26,5 +26,5 @@
struct S { }; struct S { };
template template
void S*
std::uninitialized_fill_n<S*, int, S>(S*, int, const S&); std::uninitialized_fill_n<S*, int, S>(S*, int, const S&);

View File

@ -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();
}