diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-05 19:46:07 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-05 19:46:07 +0000 |
commit | f7dcde8abdf70c559837f0e4c24146fb75998e6e (patch) | |
tree | 01d64cc281df436959d334dee7ca39fcc4c91e94 /libstdc++-v3 | |
parent | 1891b5fbbccd00e7544d03624cbb96801328f2fa (diff) | |
download | gcc-f7dcde8abdf70c559837f0e4c24146fb75998e6e.tar.gz |
2007-11-05 Chris Jefferson <chris@bubblescope.net>
Paolo Carlini <pcarlini@suse.de>
* include/bits/stl_vector.h (vector<>::push_back<>(_Args...),
emplace<>(iterator, _Args...), insert(iterator, _Tp&&),
_M_insert_aux<>(iterator, _Args&&...)): Add.
* include/bits/vector.tcc (insert(iterator, value_type&&),
emplace<>(iterator, _Args...), _M_insert_aux<>(iterator, _Args&&...)):
Define.
(_M_fill_insert(iterator, size_type, const value_type&),
_M_range_insert(iterator, _ForwardIterator, _ForwardIterator,
std::forward_iterator_tag)): Use __uninitialized_move_a,
_GLIBCXX_MOVE_BACKWARD3 when possible.
* include/bits/stl_uninitialized.h (__uninitialized_move_a): Add.
* include/debug/vector (vector<>::push_back<>(_Args...),
emplace<>(iterator, _Args...), insert(iterator, _Tp&&)): Add.
* testsuite/23_containers/vector/modifiers/moveable.cc: Enable.
* testsuite/23_containers/vector/resize/moveable.cc: Likewise.
* testsuite/23_containers/vector/cons/moveable.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
Adjust dg-error line numbers.
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_2_neg.cc: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129907 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
12 files changed, 235 insertions, 27 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 968789991fc..36c9f4bfb4f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,31 @@ +2007-11-05 Chris Jefferson <chris@bubblescope.net> + Paolo Carlini <pcarlini@suse.de> + + * include/bits/stl_vector.h (vector<>::push_back<>(_Args...), + emplace<>(iterator, _Args...), insert(iterator, _Tp&&), + _M_insert_aux<>(iterator, _Args&&...)): Add. + * include/bits/vector.tcc (insert(iterator, value_type&&), + emplace<>(iterator, _Args...), _M_insert_aux<>(iterator, _Args&&...)): + Define. + (_M_fill_insert(iterator, size_type, const value_type&), + _M_range_insert(iterator, _ForwardIterator, _ForwardIterator, + std::forward_iterator_tag)): Use __uninitialized_move_a, + _GLIBCXX_MOVE_BACKWARD3 when possible. + * include/bits/stl_uninitialized.h (__uninitialized_move_a): Add. + * include/debug/vector (vector<>::push_back<>(_Args...), + emplace<>(iterator, _Args...), insert(iterator, _Tp&&)): Add. + * testsuite/23_containers/vector/modifiers/moveable.cc: Enable. + * testsuite/23_containers/vector/resize/moveable.cc: Likewise. + * testsuite/23_containers/vector/cons/moveable.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: + Adjust dg-error line numbers. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: + Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_2_neg.cc: Likewise. + 2007-11-03 Paolo Carlini <pcarlini@suse.de> Kai-Uwe Bux <bux@kubux.net> diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index d3e7a2c8c3f..6f7437aaf10 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -261,6 +261,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _ForwardIterator __result, allocator<_Tp>&) { return std::uninitialized_copy(__first, __last, __result); } + template<typename _InputIterator, typename _ForwardIterator, + typename _Allocator> + inline _ForwardIterator + __uninitialized_move_a(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, _Allocator& __alloc) + { + return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), + _GLIBCXX_MAKE_MOVE_ITERATOR(__last), + __result, __alloc); + } + template<typename _ForwardIterator, typename _Tp, typename _Allocator> void __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index f48fbdbbc6b..bf2cc277ad6 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -683,6 +683,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) * done in constant time if the %vector has preallocated space * available. */ +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_back(const value_type& __x) { @@ -694,6 +695,21 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) else _M_insert_aux(end(), __x); } +#else + template<typename... _Args> + void + push_back(_Args&&... __args) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + this->_M_impl.construct(this->_M_impl._M_finish, + std::forward<_Args>(__args)...); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(end(), std::forward<_Args>(__args)...); + } +#endif /** * @brief Removes last element. @@ -711,6 +727,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) this->_M_impl.destroy(this->_M_impl._M_finish); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Inserts an object in %vector before specified iterator. + * @param position An iterator into the %vector. + * @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>(args)...) before the specified location. + * Note that this kind of operation could be expensive for a %vector + * and if it is frequently used the user should consider using + * std::list. + */ + template<typename... _Args> + iterator + emplace(iterator __position, _Args&&... __args); +#endif + /** * @brief Inserts given value into %vector before specified iterator. * @param position An iterator into the %vector. @@ -725,6 +759,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) iterator insert(iterator __position, const value_type& __x); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Inserts given rvalue into %vector before specified iterator. + * @param position An iterator into the %vector. + * @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. Note that this kind of operation + * could be expensive for a %vector and if it is frequently + * used the user should consider using std::list. + */ + iterator + insert(iterator __position, value_type&& __x); +#endif + /** * @brief Inserts a number of copies of given data into the %vector. * @param position An iterator into the %vector. @@ -1014,8 +1064,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); // Called by insert(p,x) +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void _M_insert_aux(iterator __position, const value_type& __x); +#else + template<typename... _Args> + void + _M_insert_aux(iterator __position, _Args&&... __args); +#endif // Called by the latter. size_type diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index e15d80d59b7..b097f44d285 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -105,6 +105,26 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) return iterator(this->_M_impl._M_start + __n); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template<typename _Tp, typename _Alloc> + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + insert(iterator __position, value_type&& __x) + { + const size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage + && __position == end()) + { + this->_M_impl.construct(this->_M_impl._M_finish, + std::forward<value_type>(__x)); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, std::forward<value_type>(__x)); + return iterator(this->_M_impl._M_start + __n); + } +#endif + template<typename _Tp, typename _Alloc> typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: @@ -241,21 +261,53 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template<typename _Tp, typename _Alloc> + template<typename... _Args> + typename vector<_Tp, _Alloc>::iterator + vector<_Tp, _Alloc>:: + emplace(iterator __position, _Args&&... __args) + { + const size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage + && __position == end()) + { + this->_M_impl.construct(this->_M_impl._M_finish, + std::forward<_Args>(__args)...); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, std::forward<_Args>(__args)...); + return iterator(this->_M_impl._M_start + __n); + } + + template<typename _Tp, typename _Alloc> + template<typename... _Args> + void + vector<_Tp, _Alloc>:: + _M_insert_aux(iterator __position, _Args&&... __args) + { + _Tp __x_copy(std::forward<_Args>(__args)...); +#else template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) { +#endif if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { this->_M_impl.construct(this->_M_impl._M_finish, - *(this->_M_impl._M_finish - 1)); + _GLIBCXX_MOVE(*(this->_M_impl._M_finish + - 1))); ++this->_M_impl._M_finish; +#ifndef __GXX_EXPERIMENTAL_CXX0X__ _Tp __x_copy = __x; - std::copy_backward(__position.base(), - this->_M_impl._M_finish - 2, - this->_M_impl._M_finish - 1); - *__position = __x_copy; +#endif + _GLIBCXX_MOVE_BACKWARD3(__position.base(), + this->_M_impl._M_finish - 2, + this->_M_impl._M_finish - 1); + *__position = _GLIBCXX_MOVE(__x_copy); } else { @@ -266,13 +318,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) try { __new_finish = - std::__uninitialized_copy_a(this->_M_impl._M_start, + std::__uninitialized_move_a(this->_M_impl._M_start, __position.base(), __new_start, _M_get_Tp_allocator()); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + this->_M_impl.construct(__new_finish, std::move(__x_copy)); +#else this->_M_impl.construct(__new_finish, __x); +#endif ++__new_finish; __new_finish = - std::__uninitialized_copy_a(__position.base(), + std::__uninitialized_move_a(__position.base(), this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); @@ -301,21 +357,26 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) { if (__n != 0) { +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + value_type __x_copy = __x; +#endif if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { +#ifndef __GXX_EXPERIMENTAL_CXX0X__ value_type __x_copy = __x; +#endif const size_type __elems_after = end() - __position; pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { - std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, + std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; - std::copy_backward(__position.base(), __old_finish - __n, - __old_finish); + _GLIBCXX_MOVE_BACKWARD3(__position.base(), + __old_finish - __n, __old_finish); std::fill(__position.base(), __position.base() + __n, __x_copy); } @@ -326,7 +387,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) __x_copy, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n - __elems_after; - std::__uninitialized_copy_a(__position.base(), __old_finish, + std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __elems_after; @@ -342,15 +403,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) try { __new_finish = - std::__uninitialized_copy_a(this->_M_impl._M_start, + std::__uninitialized_move_a(this->_M_impl._M_start, __position.base(), __new_start, _M_get_Tp_allocator()); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy, +#else std::__uninitialized_fill_n_a(__new_finish, __n, __x, +#endif _M_get_Tp_allocator()); __new_finish += __n; __new_finish = - std::__uninitialized_copy_a(__position.base(), + std::__uninitialized_move_a(__position.base(), this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); @@ -405,13 +470,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { - std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, + std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; - std::copy_backward(__position.base(), __old_finish - __n, - __old_finish); + _GLIBCXX_MOVE_BACKWARD3(__position.base(), + __old_finish - __n, __old_finish); std::copy(__first, __last, __position); } else @@ -422,7 +487,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n - __elems_after; - std::__uninitialized_copy_a(__position.base(), + std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); @@ -439,15 +504,16 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) try { __new_finish = - std::__uninitialized_copy_a(this->_M_impl._M_start, + std::__uninitialized_move_a(this->_M_impl._M_start, __position.base(), __new_start, _M_get_Tp_allocator()); __new_finish = - std::__uninitialized_copy_a(__first, __last, __new_finish, + std::__uninitialized_copy_a(__first, __last, + __new_finish, _M_get_Tp_allocator()); __new_finish = - std::__uninitialized_copy_a(__position.base(), + std::__uninitialized_move_a(__position.base(), this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index ce44241004b..977fbbd9cee 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -278,6 +278,7 @@ namespace __debug using _Base::data; // 23.2.4.3 modifiers: +#ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_back(const _Tp& __x) { @@ -287,6 +288,18 @@ namespace __debug this->_M_invalidate_all(); _M_update_guaranteed_capacity(); } +#else + template<typename... _Args> + void + push_back(_Args... __args) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(std::forward<_Args>(__args)...); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } +#endif void pop_back() @@ -297,6 +310,25 @@ namespace __debug _Base::pop_back(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template<typename... _Args> + iterator + emplace(iterator __position, _Args... __args) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::emplace(__position.base(), + std::forward<_Args>(__args)...); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } +#endif + iterator insert(iterator __position, const _Tp& __x) { @@ -312,6 +344,24 @@ namespace __debug return iterator(__res, this); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + iterator + insert(iterator __position, _Tp&& __x) + { + __glibcxx_check_insert(__position); + 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)); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } +#endif + void insert(iterator __position, size_type __n, const _Tp& __x) { diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc index 7184a256f94..688423e39b3 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc @@ -1,5 +1,4 @@ // { dg-do compile } -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2007 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc index ef4410a92b2..15adafc2671 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc @@ -1,4 +1,3 @@ -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2007 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index c5b20cbbb1d..6e7d587300b 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 945 } +// { dg-error "no matching" "" { target *-*-* } 995 } // { dg-excess-errors "" } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index 28e0c4dd853..532d89aea34 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 885 } +// { dg-error "no matching" "" { target *-*-* } 935 } // { dg-excess-errors "" } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index 717bbc6c8c4..640aa798592 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 885 } +// { dg-error "no matching" "" { target *-*-* } 935 } // { dg-excess-errors "" } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index 62b331a49b4..19713176566 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 986 } +// { dg-error "no matching" "" { target *-*-* } 1036 } // { dg-excess-errors "" } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc index 84136f4e04d..f4dbc19da41 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc @@ -1,4 +1,3 @@ -// { dg-require-rvalref "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. |