aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrançois Dumont <fdumont@gcc.gnu.org>2016-07-11 20:17:56 +0000
committerFrançois Dumont <fdumont@gcc.gnu.org>2016-07-11 20:17:56 +0000
commit76225d2ca77038233f5af5903ab0bd10aa78e611 (patch)
tree2cbe770d616acb22f925cbe299cd8edd0f6e5c08
parent4368a420fb0679a0ef78fd0806dbdf7917cd948d (diff)
downloadgcc-76225d2ca77038233f5af5903ab0bd10aa78e611.zip
gcc-76225d2ca77038233f5af5903ab0bd10aa78e611.tar.gz
gcc-76225d2ca77038233f5af5903ab0bd10aa78e611.tar.bz2
stl_vector.h (push_back(const value_type&)): Forward to _M_realloc_insert.
2016-07-11 François Dumont <fdumont@gcc.gnu.org> * include/bits/stl_vector.h (push_back(const value_type&)): Forward to _M_realloc_insert. (insert(const_iterator, value_type&&)): Forward to _M_insert_rval. (_M_realloc_insert): Declare new function. (_M_emplace_back_aux): Remove definition. * include/bits/vector.tcc (emplace_back(_Args...)): Use _M_realloc_insert. (insert(const_iterator, const value_type&)): Likewise. (_M_insert_rval, _M_emplace_aux): Likewise. (_M_emplace_back_aux): Remove declaration. (_M_realloc_insert): Define. * testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc: Adjust expected results for emplacing an lvalue with reallocation. From-SVN: r238226
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h19
-rw-r--r--libstdc++-v3/include/bits/vector.tcc261
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc7
4 files changed, 147 insertions, 156 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0aee680..1d0abe1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,19 @@
+2016-07-11 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/stl_vector.h (push_back(const value_type&)): Forward
+ to _M_realloc_insert.
+ (insert(const_iterator, value_type&&)): Forward to _M_insert_rval.
+ (_M_realloc_insert): Declare new function.
+ (_M_emplace_back_aux): Remove definition.
+ * include/bits/vector.tcc (emplace_back(_Args...)):
+ Use _M_realloc_insert.
+ (insert(const_iterator, const value_type&)): Likewise.
+ (_M_insert_rval, _M_emplace_aux): Likewise.
+ (_M_emplace_back_aux): Remove declaration.
+ (_M_realloc_insert): Define.
+ * testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc:
+ Adjust expected results for emplacing an lvalue with reallocation.
+
2016-07-10 Ville Voutilainen <ville.voutilainen@gmail.com>
Implement std::optional.
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 8e8aa7c..85abf4a 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -946,11 +946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
++this->_M_impl._M_finish;
}
else
-#if __cplusplus >= 201103L
- _M_emplace_back_aux(__x);
-#else
- _M_insert_aux(end(), __x);
-#endif
+ _M_realloc_insert(end(), __x);
}
#if __cplusplus >= 201103L
@@ -1436,6 +1432,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by insert(p,x)
void
_M_insert_aux(iterator __position, const value_type& __x);
+
+ void
+ _M_realloc_insert(iterator __position, const value_type& __x);
#else
// A value_type object constructed with _Alloc_traits::construct()
// and destroyed with _Alloc_traits::destroy().
@@ -1469,16 +1468,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_insert_aux(iterator __position, _Arg&& __arg);
+ template<typename... _Args>
+ void
+ _M_realloc_insert(iterator __position, _Args&&... __args);
+
// Either move-construct at the end, or forward to _M_insert_aux.
iterator
_M_insert_rval(const_iterator __position, value_type&& __v);
- // Called by push_back(x) and emplace_back(args) when they need to
- // reallocate.
- template<typename... _Args>
- void
- _M_emplace_back_aux(_Args&&... __args);
-
// Try to emplace at the end, otherwise forward to _M_insert_aux.
template<typename... _Args>
iterator
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index dd0d288..9717b74 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -98,7 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
++this->_M_impl._M_finish;
}
else
- _M_emplace_back_aux(std::forward<_Args>(__args)...);
+ _M_realloc_insert(end(), std::forward<_Args>(__args)...);
}
#endif
@@ -112,29 +112,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
{
const size_type __n = __position - begin();
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
- && __position == end())
- {
- _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x);
- ++this->_M_impl._M_finish;
- }
- else
- {
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == end())
+ {
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ __x);
+ ++this->_M_impl._M_finish;
+ }
+ else
+ {
#if __cplusplus >= 201103L
- const auto __pos = begin() + (__position - cbegin());
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
- {
- // __x could be an existing element of this vector, so make a
- // copy of it before _M_insert_aux moves elements around.
- _Temporary_value __x_copy(this, __x);
- _M_insert_aux(__pos, std::move(__x_copy._M_val()));
- }
- else
- _M_insert_aux(__pos, __x);
+ const auto __pos = begin() + (__position - cbegin());
+ // __x could be an existing element of this vector, so make a
+ // copy of it before _M_insert_aux moves elements around.
+ _Temporary_value __x_copy(this, __x);
+ _M_insert_aux(__pos, std::move(__x_copy._M_val()));
#else
_M_insert_aux(__position, __x);
#endif
- }
+ }
+ else
+#if __cplusplus >= 201103L
+ _M_realloc_insert(begin() + (__position - cbegin()), __x);
+#else
+ _M_realloc_insert(__position, __x);
+#endif
+
return iterator(this->_M_impl._M_start + __n);
}
@@ -304,15 +307,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_insert_rval(const_iterator __position, value_type&& __v) -> iterator
{
const auto __n = __position - cbegin();
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
- && __position == cend())
- {
- _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
- std::move(__v));
- ++this->_M_impl._M_finish;
- }
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == cend())
+ {
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ std::move(__v));
+ ++this->_M_impl._M_finish;
+ }
+ else
+ _M_insert_aux(begin() + __n, std::move(__v));
else
- _M_insert_aux(begin() + __n, std::move(__v));
+ _M_realloc_insert(begin() + __n, std::move(__v));
+
return iterator(this->_M_impl._M_start + __n);
}
@@ -324,16 +330,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
-> iterator
{
const auto __n = __position - cbegin();
- if (__position == cend())
- emplace_back(std::forward<_Args>(__args)...);
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+ if (__position == cend())
+ {
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ std::forward<_Args>(__args)...);
+ ++this->_M_impl._M_finish;
+ }
+ else
+ {
+ // We need to construct a temporary because something in __args...
+ // could alias one of the elements of the container and so we
+ // need to use it before _M_insert_aux moves elements around.
+ _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
+ _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
+ }
else
- {
- // We need to construct a temporary because something in __args...
- // could alias one of the elements of the container and so we
- // need to use it before _M_insert_aux moves elements around.
- _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
- _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
- }
+ _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...);
+
return iterator(this->_M_impl._M_start + __n);
}
@@ -349,78 +363,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_insert_aux(iterator __position, const _Tp& __x)
#endif
{
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
- {
- _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
- _GLIBCXX_MOVE(*(this->_M_impl._M_finish
- - 1)));
- ++this->_M_impl._M_finish;
+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+ _GLIBCXX_MOVE(*(this->_M_impl._M_finish
+ - 1)));
+ ++this->_M_impl._M_finish;
#if __cplusplus < 201103L
- _Tp __x_copy = __x;
+ _Tp __x_copy = __x;
#endif
- _GLIBCXX_MOVE_BACKWARD3(__position.base(),
- this->_M_impl._M_finish - 2,
- this->_M_impl._M_finish - 1);
+ _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+ this->_M_impl._M_finish - 2,
+ this->_M_impl._M_finish - 1);
#if __cplusplus < 201103L
- *__position = __x_copy;
-#else
- *__position = std::forward<_Arg>(__arg);
-#endif
- }
- else
- {
- const size_type __len =
- _M_check_len(size_type(1), "vector::_M_insert_aux");
- const size_type __elems_before = __position - begin();
- pointer __new_start(this->_M_allocate(__len));
- pointer __new_finish(__new_start);
- __try
- {
- // The order of the three operations is dictated by the C++11
- // case, where the moves could alter a new element belonging
- // to the existing vector. This is an issue only for callers
- // taking the element by lvalue ref (see last bullet of C++11
- // [res.on.arguments]).
- _Alloc_traits::construct(this->_M_impl,
- __new_start + __elems_before,
-#if __cplusplus >= 201103L
- std::forward<_Arg>(__arg));
+ *__position = __x_copy;
#else
- __x);
+ *__position = std::forward<_Arg>(__arg);
#endif
- __new_finish = pointer();
-
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (this->_M_impl._M_start, __position.base(),
- __new_start, _M_get_Tp_allocator());
-
- ++__new_finish;
-
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (__position.base(), this->_M_impl._M_finish,
- __new_finish, _M_get_Tp_allocator());
- }
- __catch(...)
- {
- if (!__new_finish)
- _Alloc_traits::destroy(this->_M_impl,
- __new_start + __elems_before);
- else
- std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
- _M_deallocate(__new_start, __len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- _M_get_Tp_allocator());
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage
- - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start;
- this->_M_impl._M_finish = __new_finish;
- this->_M_impl._M_end_of_storage = __new_start + __len;
- }
}
#if __cplusplus >= 201103L
@@ -428,44 +385,66 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename... _Args>
void
vector<_Tp, _Alloc>::
- _M_emplace_back_aux(_Args&&... __args)
- {
- const size_type __len =
- _M_check_len(size_type(1), "vector::_M_emplace_back_aux");
- pointer __new_start(this->_M_allocate(__len));
- pointer __new_finish(__new_start);
- __try
- {
- _Alloc_traits::construct(this->_M_impl, __new_start + size(),
- std::forward<_Args>(__args)...);
- __new_finish = pointer();
+ _M_realloc_insert(iterator __position, _Args&&... __args)
+#else
+ template<typename _Tp, typename _Alloc>
+ void
+ vector<_Tp, _Alloc>::
+ _M_realloc_insert(iterator __position, const _Tp& __x)
+#endif
+ {
+ const size_type __len =
+ _M_check_len(size_type(1), "vector::_M_realloc_insert");
+ const size_type __elems_before = __position - begin();
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
+ __try
+ {
+ // The order of the three operations is dictated by the C++11
+ // case, where the moves could alter a new element belonging
+ // to the existing vector. This is an issue only for callers
+ // taking the element by lvalue ref (see last bullet of C++11
+ // [res.on.arguments]).
+ _Alloc_traits::construct(this->_M_impl,
+ __new_start + __elems_before,
+#if __cplusplus >= 201103L
+ std::forward<_Args>(__args)...);
+#else
+ __x);
+#endif
+ __new_finish = pointer();
- __new_finish
- = std::__uninitialized_move_if_noexcept_a
- (this->_M_impl._M_start, this->_M_impl._M_finish,
- __new_start, _M_get_Tp_allocator());
+ __new_finish
+ = std::__uninitialized_move_if_noexcept_a
+ (this->_M_impl._M_start, __position.base(),
+ __new_start, _M_get_Tp_allocator());
- ++__new_finish;
- }
- __catch(...)
- {
- if (!__new_finish)
- _Alloc_traits::destroy(this->_M_impl, __new_start + size());
- else
- std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
- _M_deallocate(__new_start, __len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- _M_get_Tp_allocator());
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage
- - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start;
- this->_M_impl._M_finish = __new_finish;
- this->_M_impl._M_end_of_storage = __new_start + __len;
- }
-#endif
+ ++__new_finish;
+
+ __new_finish
+ = std::__uninitialized_move_if_noexcept_a
+ (__position.base(), this->_M_impl._M_finish,
+ __new_finish, _M_get_Tp_allocator());
+ }
+ __catch(...)
+ {
+ if (!__new_finish)
+ _Alloc_traits::destroy(this->_M_impl,
+ __new_start + __elems_before);
+ else
+ std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
+ _M_deallocate(__new_start, __len);
+ __throw_exception_again;
+ }
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+ _M_get_Tp_allocator());
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
+ }
template<typename _Tp, typename _Alloc>
void
@@ -520,7 +499,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
pointer __new_finish(__new_start);
__try
{
- // See _M_insert_aux above.
+ // See _M_realloc_insert above.
std::__uninitialized_fill_n_a(__new_start + __elems_before,
__n, __x,
_M_get_Tp_allocator());
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc
index 1b46124..39a3f03 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc
@@ -223,8 +223,7 @@ test03()
void
test04()
{
- const X::special expected_ins{ 0, 3, 1, 0, 3, 0 };
- const X::special expected_emp{ 0, 4, 1, 0, 4, 0 };
+ const X::special expected{ 0, 3, 1, 0, 3, 0 };
X::special ins, emp;
{
std::vector<X> v;
@@ -254,8 +253,8 @@ test04()
// std::cout << "----\n";
emp = X::sp;
}
- VERIFY( ins == expected_ins );
- VERIFY( emp == expected_emp );
+ VERIFY( ins == emp );
+ VERIFY( ins == expected );
}
// insert vs emplace xvalue reallocation