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)
{
{
for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur), __x);
+ return __cur;
}
__catch(...)
{
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.
* 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
// 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);
}
template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Allocator>
- void
+ _ForwardIterator
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x, _Allocator& __alloc)
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), __x);
+ return __cur;
}
__catch(...)
{
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,
struct __uninitialized_default_n_1
{
template<typename _ForwardIterator, typename _Size>
- static void
+ static _ForwardIterator
__uninit_default_n(_ForwardIterator __first, _Size __n)
{
_ForwardIterator __cur = __first;
{
for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur));
+ return __cur;
}
__catch(...)
{
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());
}
};
// __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
// 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);
}
// 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)
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur));
+ return __cur;
}
__catch(...)
{
}
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,
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));
}
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());
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
{
= 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(...)
{
--- /dev/null
+// 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();
+}