Index: include/debug/vector =================================================================== --- include/debug/vector (revision 130096) +++ include/debug/vector (working copy) @@ -354,7 +354,7 @@ bool __realloc = _M_requires_reallocation(this->size() + 1); difference_type __offset = __position - begin(); typename _Base::iterator __res = _Base::insert(__position.base(), - std::forward<_Tp>(__x)); + std::move(__x)); if (__realloc) this->_M_invalidate_all(); else Index: include/debug/deque =================================================================== --- include/debug/deque (revision 130096) +++ include/debug/deque (working copy) @@ -254,6 +254,7 @@ } // 23.2.1.3 modifiers: +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_front(const _Tp& __x) { @@ -267,6 +268,34 @@ _Base::push_back(__x); this->_M_invalidate_all(); } +#else + template + void + push_front(_Args&&... __args) + { + _Base::push_front(std::forward<_Args>(__args)...); + this->_M_invalidate_all(); + } + + template + void + push_back(_Args&&... __args) + { + _Base::push_back(std::forward<_Args>(__args)...); + this->_M_invalidate_all(); + } + + template + iterator + emplace(iterator __position, _Args&&... __args) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::emplace(__position.base(), + std::forward<_Args>(__args)...); + this->_M_invalidate_all(); + return iterator(__res, this); + } +#endif iterator insert(iterator __position, const _Tp& __x) @@ -277,6 +306,18 @@ return iterator(__res, this); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + iterator + insert(iterator __position, _Tp&& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::insert(__position.base(), + std::move(__x)); + this->_M_invalidate_all(); + return iterator(__res, this); + } +#endif + void insert(iterator __position, size_type __n, const _Tp& __x) { Index: include/bits/stl_deque.h =================================================================== --- include/bits/stl_deque.h (revision 130096) +++ include/bits/stl_deque.h (working copy) @@ -1129,6 +1129,7 @@ * data to it. Due to the nature of a %deque this operation * can be done in constant time. */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_front(const value_type& __x) { @@ -1140,6 +1141,21 @@ else _M_push_front_aux(__x); } +#else + template + void + push_front(_Args&&... __args) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, + std::forward<_Args>(__args)...); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(std::forward<_Args>(__args)...); + } +#endif /** * @brief Add data to the end of the %deque. @@ -1150,6 +1166,7 @@ * to it. Due to the nature of a %deque this operation can be * done in constant time. */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_back(const value_type& __x) { @@ -1162,6 +1179,22 @@ else _M_push_back_aux(__x); } +#else + template + void + push_back(_Args&&... __args) + { + if (this->_M_impl._M_finish._M_cur + != this->_M_impl._M_finish._M_last - 1) + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, + std::forward<_Args>(__args)...); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(std::forward<_Args>(__args)...); + } +#endif /** * @brief Removes first element. @@ -1205,6 +1238,21 @@ _M_pop_back_aux(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Inserts an object in %deque before specified iterator. + * @param position An iterator into the %deque. + * @param args Arguments. + * @return An iterator that points to the inserted data. + * + * This function will insert an object of type T constructed + * with T(std::forward(args)...) before the specified location. + */ + template + iterator + emplace(iterator __position, _Args&&... __args); +#endif + /** * @brief Inserts given value into %deque before specified iterator. * @param position An iterator into the %deque. @@ -1217,6 +1265,20 @@ iterator insert(iterator __position, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Inserts given rvalue into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given rvalue before the + * specified location. + */ + iterator + insert(iterator __position, value_type&& __x); +#endif + /** * @brief Inserts a number of copies of given data into the %deque. * @param position An iterator into the %deque. @@ -1459,9 +1521,17 @@ * @brief Helper functions for push_* and pop_*. * @endif */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void _M_push_back_aux(const value_type&); void _M_push_front_aux(const value_type&); +#else + template + void _M_push_back_aux(_Args&&... __args); + + template + void _M_push_front_aux(_Args&&... __args); +#endif void _M_pop_back_aux(); @@ -1512,8 +1582,14 @@ _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); // called by insert(p,x) +#ifndef __GXX_EXPERIMENTAL_CXX0X__ iterator _M_insert_aux(iterator __pos, const value_type& __x); +#else + template + iterator + _M_insert_aux(iterator __pos, _Args&&... __args); +#endif // called by insert(p,n,x) via fill_insert void Index: include/bits/stl_uninitialized.h =================================================================== --- include/bits/stl_uninitialized.h (revision 130096) +++ include/bits/stl_uninitialized.h (working copy) @@ -323,19 +323,19 @@ { std::uninitialized_fill_n(__first, __n, __x); } - // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, - // __uninitialized_fill_copy. All of these algorithms take a user- - // supplied allocator, which is used for construction and destruction. + // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, + // __uninitialized_fill_move, __uninitialized_move_fill. + // All of these algorithms take a user-supplied allocator, which is used + // for construction and destruction. - // __uninitialized_copy_copy + // __uninitialized_copy_move // Copies [first1, last1) into [result, result + (last1 - first1)), and - // copies [first2, last2) into + // move [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). - template inline _ForwardIterator - __uninitialized_copy_copy(_InputIterator1 __first1, + __uninitialized_copy_move(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, @@ -347,7 +347,7 @@ __alloc); try { - return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); + return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); } catch(...) { @@ -356,20 +356,48 @@ } } - // __uninitialized_fill_copy - // Fills [result, mid) with x, and copies [first, last) into + // __uninitialized_move_copy + // Moves [first1, last1) into [result, result + (last1 - first1)), and + // copies [first2, last2) into + // [result, result + (last1 - first1) + (last2 - first2)). + template + inline _ForwardIterator + __uninitialized_move_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result, + _Allocator& __alloc) + { + _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, + __result, + __alloc); + try + { + return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); + } + catch(...) + { + std::_Destroy(__result, __mid, __alloc); + __throw_exception_again; + } + } + + // __uninitialized_fill_move + // Fills [result, mid) with x, and moves [first, last) into // [mid, mid + (last - first)). template inline _ForwardIterator - __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, const _Tp& __x, _InputIterator __first, _InputIterator __last, _Allocator& __alloc) { std::__uninitialized_fill_a(__result, __mid, __x, __alloc); try { - return std::__uninitialized_copy_a(__first, __last, __mid, __alloc); + return std::__uninitialized_move_a(__first, __last, __mid, __alloc); } catch(...) { @@ -378,18 +406,18 @@ } } - // __uninitialized_copy_fill - // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and + // __uninitialized_move_fill + // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. template inline void - __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, _ForwardIterator __last2, const _Tp& __x, _Allocator& __alloc) { - _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1, + _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, __first2, __alloc); try Index: include/bits/deque.tcc =================================================================== --- include/bits/deque.tcc (revision 130096) +++ include/bits/deque.tcc (working copy) @@ -106,6 +106,51 @@ return _M_insert_aux(__position, __x); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + insert(iterator __position, value_type&& __x) + { + if (__position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(std::move(__x)); + return this->_M_impl._M_start; + } + else if (__position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(std::move(__x)); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(__position, std::move(__x)); + } + + template + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + emplace(iterator __position, _Args&&... __args) + { + if (__position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(std::forward<_Args>(__args)...); + return this->_M_impl._M_start; + } + else if (__position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(std::forward<_Args>(__args)...); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(__position, std::forward<_Args>(__args)...); + } +#endif + template typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: @@ -299,51 +344,71 @@ } // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. - template - void - deque<_Tp, _Alloc>:: - _M_push_back_aux(const value_type& __t) - { - value_type __t_copy = __t; - _M_reserve_map_at_back(); - *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); - try - { - this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t_copy); - this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - + 1); - this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; - } - catch(...) - { - _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); - __throw_exception_again; - } - } + template +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + deque<_Tp, _Alloc>:: + _M_push_back_aux(_Args&&... __args) + { + value_type __t_copy(std::forward<_Args>(__args)...); +#else + void + deque<_Tp, _Alloc>:: + _M_push_back_aux(const value_type& __t) + { + value_type __t_copy = __t; +#endif + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, + _GLIBCXX_MOVE(__t_copy)); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + __throw_exception_again; + } + } // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. - template - void - deque<_Tp, _Alloc>:: - _M_push_front_aux(const value_type& __t) - { - value_type __t_copy = __t; - _M_reserve_map_at_front(); - *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); - try - { - this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - - 1); - this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; - this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t_copy); - } - catch(...) - { - ++this->_M_impl._M_start; - _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); - __throw_exception_again; - } - } + template +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + deque<_Tp, _Alloc>:: + _M_push_front_aux(_Args&&... __args) + { + value_type __t_copy(std::forward<_Args>(__args)...); +#else + void + deque<_Tp, _Alloc>:: + _M_push_front_aux(const value_type& __t) + { + value_type __t_copy = __t; +#endif + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + this->_M_impl.construct(this->_M_impl._M_start._M_cur, + _GLIBCXX_MOVE(__t_copy)); + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + __throw_exception_again; + } + } // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. template @@ -426,38 +491,47 @@ _M_insert_aux(__pos, __first, __last, __n); } - template + template +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, _Args&&... __args) + { + value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy +#else typename deque<_Tp, _Alloc>::iterator - deque<_Tp, _Alloc>:: - _M_insert_aux(iterator __pos, const value_type& __x) - { - difference_type __index = __pos - this->_M_impl._M_start; - value_type __x_copy = __x; // XXX copy - if (static_cast(__index) < size() / 2) - { - push_front(front()); - iterator __front1 = this->_M_impl._M_start; - ++__front1; - iterator __front2 = __front1; - ++__front2; - __pos = this->_M_impl._M_start + __index; - iterator __pos1 = __pos; - ++__pos1; - std::copy(__front2, __pos1, __front1); - } - else - { - push_back(back()); - iterator __back1 = this->_M_impl._M_finish; - --__back1; - iterator __back2 = __back1; - --__back2; - __pos = this->_M_impl._M_start + __index; - std::copy_backward(__pos, __back2, __back1); - } - *__pos = __x_copy; - return __pos; - } + deque<_Tp, _Alloc>:: + _M_insert_aux(iterator __pos, const value_type& __x) + { + value_type __x_copy = __x; // XXX copy +#endif + difference_type __index = __pos - this->_M_impl._M_start; + if (static_cast(__index) < size() / 2) + { + push_front(_GLIBCXX_MOVE(front())); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + _GLIBCXX_MOVE3(__front2, __pos1, __front1); + } + else + { + push_back(_GLIBCXX_MOVE(back())); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1); + } + *__pos = _GLIBCXX_MOVE(__x_copy); + return __pos; + } template void @@ -478,16 +552,16 @@ { iterator __start_n = (this->_M_impl._M_start + difference_type(__n)); - std::__uninitialized_copy_a(this->_M_impl._M_start, + std::__uninitialized_move_a(this->_M_impl._M_start, __start_n, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; - std::copy(__start_n, __pos, __old_start); + _GLIBCXX_MOVE3(__start_n, __pos, __old_start); std::fill(__pos - difference_type(__n), __pos, __x_copy); } else { - std::__uninitialized_copy_fill(this->_M_impl._M_start, + std::__uninitialized_move_fill(this->_M_impl._M_start, __pos, __new_start, this->_M_impl._M_start, __x_copy, @@ -516,17 +590,17 @@ { iterator __finish_n = (this->_M_impl._M_finish - difference_type(__n)); - std::__uninitialized_copy_a(__finish_n, + std::__uninitialized_move_a(__finish_n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; - std::copy_backward(__pos, __finish_n, __old_finish); + _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); std::fill(__pos, __pos + difference_type(__n), __x_copy); } else { - std::__uninitialized_fill_copy(this->_M_impl._M_finish, + std::__uninitialized_fill_move(this->_M_impl._M_finish, __pos + difference_type(__n), __x_copy, __pos, this->_M_impl._M_finish, @@ -565,18 +639,18 @@ { iterator __start_n = (this->_M_impl._M_start + difference_type(__n)); - std::__uninitialized_copy_a(this->_M_impl._M_start, + std::__uninitialized_move_a(this->_M_impl._M_start, __start_n, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; - std::copy(__start_n, __pos, __old_start); + _GLIBCXX_MOVE3(__start_n, __pos, __old_start); std::copy(__first, __last, __pos - difference_type(__n)); } else { _ForwardIterator __mid = __first; std::advance(__mid, difference_type(__n) - __elemsbefore); - std::__uninitialized_copy_copy(this->_M_impl._M_start, + std::__uninitialized_move_copy(this->_M_impl._M_start, __pos, __first, __mid, __new_start, _M_get_Tp_allocator()); @@ -604,19 +678,19 @@ { iterator __finish_n = (this->_M_impl._M_finish - difference_type(__n)); - std::__uninitialized_copy_a(__finish_n, + std::__uninitialized_move_a(__finish_n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; - std::copy_backward(__pos, __finish_n, __old_finish); + _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); std::copy(__first, __last, __pos); } else { _ForwardIterator __mid = __first; std::advance(__mid, __elemsafter); - std::__uninitialized_copy_copy(__mid, __last, __pos, + std::__uninitialized_copy_move(__mid, __last, __pos, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); Index: testsuite/23_containers/deque/modifiers/moveable.cc =================================================================== --- testsuite/23_containers/deque/modifiers/moveable.cc (revision 130096) +++ testsuite/23_containers/deque/modifiers/moveable.cc (working copy) @@ -1,4 +1,3 @@ -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2007 Free Software Foundation, Inc. Index: testsuite/23_containers/deque/cons/moveable.cc =================================================================== --- testsuite/23_containers/deque/cons/moveable.cc (revision 130096) +++ testsuite/23_containers/deque/cons/moveable.cc (working copy) @@ -1,5 +1,4 @@ // { dg-do compile } -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2007 Free Software Foundation, Inc. Index: testsuite/23_containers/deque/requirements/dr438/assign_neg.cc =================================================================== --- testsuite/23_containers/deque/requirements/dr438/assign_neg.cc (revision 130096) +++ testsuite/23_containers/deque/requirements/dr438/assign_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1402 } +// { dg-error "no matching" "" { target *-*-* } 1464 } // { dg-excess-errors "" } #include Index: testsuite/23_containers/deque/requirements/dr438/insert_neg.cc =================================================================== --- testsuite/23_containers/deque/requirements/dr438/insert_neg.cc (revision 130096) +++ testsuite/23_containers/deque/requirements/dr438/insert_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1482 } +// { dg-error "no matching" "" { target *-*-* } 1552 } // { dg-excess-errors "" } #include Index: testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc =================================================================== --- testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc (revision 130096) +++ testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1337 } +// { dg-error "no matching" "" { target *-*-* } 1399 } // { dg-excess-errors "" } #include Index: testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc =================================================================== --- testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc (revision 130096) +++ testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1337 } +// { dg-error "no matching" "" { target *-*-* } 1399 } // { dg-excess-errors "" } #include Index: testsuite/23_containers/deque/capacity/moveable.cc =================================================================== --- testsuite/23_containers/deque/capacity/moveable.cc (revision 130096) +++ testsuite/23_containers/deque/capacity/moveable.cc (working copy) @@ -1,4 +1,3 @@ -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.