Index: include/bits/move.h =================================================================== --- include/bits/move.h (revision 151122) +++ include/bits/move.h (working copy) @@ -84,8 +84,10 @@ _GLIBCXX_END_NAMESPACE #define _GLIBCXX_MOVE(_Tp) std::move(_Tp) +#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val) #else #define _GLIBCXX_MOVE(_Tp) (_Tp) +#define _GLIBCXX_FORWARD(_Tp, __val) (__val) #endif _GLIBCXX_BEGIN_NAMESPACE(std) Index: include/bits/stl_uninitialized.h =================================================================== --- include/bits/stl_uninitialized.h (revision 151122) +++ include/bits/stl_uninitialized.h (working copy) @@ -171,7 +171,69 @@ uninitialized_fill(__first, __last, __x); } + template + struct __uninitialized_construct_range_dispatch + { + template + static inline void + __ucr(_ForwardIterator __first, _ForwardIterator __last, + _Tp& __value) + { + if(__first == __last) + return; + _ForwardIterator __cur = __first; + __try + { + std::_Construct(&*__first, _GLIBCXX_MOVE(__value)); + __cur++; + for(; __cur != __last; ++__cur) + std::_Construct(&*__cur, _GLIBCXX_MOVE(*(__cur - 1))); + __value = _GLIBCXX_MOVE(*(__last - 1)); + } + __catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + }; + template<> + struct __uninitialized_construct_range_dispatch + { + template + static inline void + __ucr(_ForwardIterator, _ForwardIterator, _Tp&) + { } + }; + + + // Constructs objects in the range [first, last). + // Note that while these new objects will take valid values, + // their exact value is not defined. In particular they may + // be 'moved from'. + // + // While __value may altered during this algorithm, it will have + // the same value when the algorithm finishes, unless one of the + // constructions throws. + // + // Requirements: _ForwardIterator::value_type(_Tp&&) is valid. + + template + inline void + __uninitialized_construct_range(_ForwardIterator __first, + _ForwardIterator __last, + _Tp& __value) + { + typedef typename std::iterator_traits<_ForwardIterator>::value_type + _ValueType; + + __uninitialized_construct_range_dispatch< + __has_trivial_constructor(_ValueType)>:: + __ucr(__first, __last, __value); + } + + template struct __uninitialized_fill_n { Index: include/bits/stl_tempbuf.h =================================================================== --- include/bits/stl_tempbuf.h (revision 151122) +++ include/bits/stl_tempbuf.h (working copy) @@ -188,8 +188,9 @@ value_type>(_M_original_len)); _M_buffer = __p.first; _M_len = __p.second; - if (!__is_pod(_Tp) && _M_len > 0) - std::uninitialized_fill_n(_M_buffer, _M_len, *__first); + if(_M_buffer) + std::__uninitialized_construct_range(_M_buffer, _M_buffer + _M_len, + *__first); } __catch(...) { Index: include/bits/stl_construct.h =================================================================== --- include/bits/stl_construct.h (revision 151122) +++ include/bits/stl_construct.h (working copy) @@ -67,11 +67,16 @@ */ template inline void +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Allow perfect forwarding + _Construct(_T1* __p, _T2&& __value) +#else _Construct(_T1* __p, const _T2& __value) +#endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_]allocator::construct - ::new(static_cast(__p)) _T1(__value); + ::new(static_cast(__p)) _T1(_GLIBCXX_FORWARD(_T2, __value)); } /**