C++0x changed the signature of std::list::merge to take an rvalue reference, and then LWG DR 1133 [1] added the lvalue reference signature back as an overload. Our implementation follows that history rather literally, as we changed list::merge to take an rvalue in C++0x mode, then later [2] added back an overload taking an lvalue and calling merge(std::move(__x)).
It seems to me that it would be simpler to consistently have the lvalue version do all the work, and just make the rvalue one forward to that. That's what patch1.txt does (the same change can be done to debug and profile mode lists). Any objections to this change? patch2.txt then does the same thing for splice(), introducing a __const_iterator typedef [3] to make the signatures consistent for different language modes. I think this makes the code more maintainable, as there are fewer #if blocks with subtly different signatures. Any objections to this one too, including doing the same for debug mode and profile mode? [1] http://cplusplus.github.io/LWG/lwg-defects.html#1133 [2] https://gcc.gnu.org/ml/gcc-patches/2009-12/msg00699.html [3] https://gcc.gnu.org/ml/libstdc++/2014-08/msg00151.html
commit d37a4ae4a9e4883978f1817b01995c2608624070 Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Jul 8 12:15:36 2015 +0100 * include/bits/list.tcc (list::merge): Always define lvalue overload. * include/bits/stl_list.h (list::merge): Make rvalue overload forward to lvalue overload. diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 714d9b5..4b8418e 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -370,11 +370,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: -#if __cplusplus >= 201103L - merge(list&& __x) -#else merge(list& __x) -#endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 300. list::merge() specification incomplete @@ -407,11 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template <typename _StrictWeakOrdering> void list<_Tp, _Alloc>:: -#if __cplusplus >= 201103L - merge(list&& __x, _StrictWeakOrdering __comp) -#else merge(list& __x, _StrictWeakOrdering __comp) -#endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 300. list::merge() specification incomplete diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 409f1fc..d0f0fd6 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -1611,16 +1611,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * sorted order, leaving @a __x empty when complete. Elements in * this list precede elements in @a __x that are equal. */ -#if __cplusplus >= 201103L void - merge(list&& __x); + merge(list&); +#if __cplusplus >= 201103L void - merge(list& __x) - { merge(std::move(__x)); } -#else - void - merge(list& __x); + merge(list&& __x) + { merge(__x); } #endif /** @@ -1636,19 +1633,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * in this list precede elements in @a __x that are equivalent * according to StrictWeakOrdering(). */ -#if __cplusplus >= 201103L template<typename _StrictWeakOrdering> void - merge(list&& __x, _StrictWeakOrdering __comp); + merge(list&, _StrictWeakOrdering); +#if __cplusplus >= 201103L template<typename _StrictWeakOrdering> void - merge(list& __x, _StrictWeakOrdering __comp) - { merge(std::move(__x), __comp); } -#else - template<typename _StrictWeakOrdering> - void - merge(list& __x, _StrictWeakOrdering __comp); + merge(list&& __x, _StrictWeakOrdering __comp) + { merge(__x, __comp); } #endif /**
commit 682940254cdb55b30b76ce28d3910897bba6673a Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Jul 8 12:50:10 2015 +0100 * include/bits/list.tcc (list::insert, list::erase): Use __const_iterator to make declarations consistent for C++98 and C++11. * include/bits/stl_list.h (list::__const_iterator): Define. (list::insert, list::erase): Use __const_iterator to make declarations consistent for C++98 and C++11. (list::splice): Likewise, and forward from the overloads taking lvalues to the overloads taking rvalues, instead of vice versa. diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 4b8418e..7421e02 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -98,11 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: -#if __cplusplus >= 201103L - insert(const_iterator __position, const value_type& __x) -#else - insert(iterator __position, const value_type& __x) -#endif + insert(__const_iterator __position, const value_type& __x) { _Node* __tmp = _M_create_node(__x); __tmp->_M_hook(__position._M_const_cast()._M_node); @@ -147,11 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: -#if __cplusplus >= 201103L - erase(const_iterator __position) noexcept -#else - erase(iterator __position) -#endif + erase(__const_iterator __position) _GLIBCXX_NOEXCEPT { iterator __ret = iterator(__position._M_node->_M_next); _M_erase(__position._M_const_cast()); diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index d0f0fd6..41a6767 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -537,6 +537,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 using _Base::_M_get_node; using _Base::_M_get_Node_allocator; + // type used for positions in insert, erase etc. +#if __cplusplus < 201103L + typedef iterator __const_iterator; +#else + typedef const_iterator __const_iterator; +#endif + /** * @param __args An instance of user data. * @@ -1139,23 +1146,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename... _Args> iterator emplace(const_iterator __position, _Args&&... __args); +#endif /** * @brief Inserts given value into %list before specified iterator. - * @param __position A const_iterator into the %list. - * @param __x Data to be inserted. - * @return An iterator that points to the inserted data. - * - * This function will insert a copy of the given value before - * the specified location. Due to the nature of a %list this - * operation can be done in constant time, and does not - * invalidate iterators and references. - */ - iterator - insert(const_iterator __position, const value_type& __x); -#else - /** - * @brief Inserts given value into %list before specified iterator. * @param __position An iterator into the %list. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. @@ -1166,8 +1160,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * invalidate iterators and references. */ iterator - insert(iterator __position, const value_type& __x); -#endif + insert(__const_iterator __position, const value_type& __x); #if __cplusplus >= 201103L /** @@ -1205,24 +1198,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->insert(__p, __l.begin(), __l.end()); } #endif -#if __cplusplus >= 201103L - /** - * @brief Inserts a number of copies of given data into the %list. - * @param __position A const_iterator into the %list. - * @param __n Number of elements to be inserted. - * @param __x Data to be inserted. - * @return An iterator pointing to the first element inserted - * (or __position). - * - * This function will insert a specified number of copies of the - * given data before the location specified by @a position. - * - * This operation is linear in the number of elements inserted and - * does not invalidate iterators and references. - */ - iterator - insert(const_iterator __position, size_type __n, const value_type& __x); -#else /** * @brief Inserts a number of copies of given data into the %list. * @param __position An iterator into the %list. @@ -1236,12 +1211,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * does not invalidate iterators and references. */ void - insert(iterator __position, size_type __n, const value_type& __x) + insert(__const_iterator __position, size_type __n, const value_type& __x) { list __tmp(__n, __x, get_allocator()); splice(__position, __tmp); } -#endif #if __cplusplus >= 201103L /** @@ -1304,11 +1278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * any way. Managing the pointer is the user's responsibility. */ iterator -#if __cplusplus >= 201103L - erase(const_iterator __position) noexcept; -#else - erase(iterator __position); -#endif + erase(__const_iterator __position) _GLIBCXX_NOEXCEPT; /** * @brief Remove a range of elements. @@ -1329,11 +1299,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * is the user's responsibility. */ iterator -#if __cplusplus >= 201103L - erase(const_iterator __first, const_iterator __last) noexcept -#else - erase(iterator __first, iterator __last) -#endif + erase(__const_iterator __first, __const_iterator __last) + _GLIBCXX_NOEXCEPT { while (__first != __last) __first = erase(__first); @@ -1392,11 +1359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * Requires this != @a __x. */ void -#if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x) noexcept -#else - splice(iterator __position, list& __x) -#endif + splice(__const_iterator __position, list& __x) _GLIBCXX_NOEXCEPT { if (!__x.empty()) { @@ -1412,24 +1375,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if __cplusplus >= 201103L void - splice(const_iterator __position, list& __x) noexcept - { splice(__position, std::move(__x)); } + splice(const_iterator __position, list&& __x) noexcept + { splice(__position, __x); } #endif -#if __cplusplus >= 201103L - /** - * @brief Insert element from another %list. - * @param __position Const_iterator referencing the element to - * insert before. - * @param __x Source list. - * @param __i Const_iterator referencing the element to move. - * - * Removes the element in list @a __x referenced by @a __i and - * inserts it into the current list before @a __position. - */ - void - splice(const_iterator __position, list&& __x, const_iterator __i) noexcept -#else /** * @brief Insert element from another %list. * @param __position Iterator referencing the element to insert before. @@ -1440,8 +1389,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * inserts it into the current list before @a __position. */ void - splice(iterator __position, list& __x, iterator __i) -#endif + splice(__const_iterator __position, list& __x, __const_iterator __i) + _GLIBCXX_USE_NOEXCEPT { iterator __j = __i._M_const_cast(); ++__j; @@ -1470,28 +1419,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * inserts it into the current list before @a __position. */ void - splice(const_iterator __position, list& __x, const_iterator __i) noexcept - { splice(__position, std::move(__x), __i); } + splice(const_iterator __position, list&& __x, const_iterator __i) + noexcept + { splice(__position, __x, __i); } #endif -#if __cplusplus >= 201103L - /** - * @brief Insert range from another %list. - * @param __position Const_iterator referencing the element to - * insert before. - * @param __x Source list. - * @param __first Const_iterator referencing the start of range in x. - * @param __last Const_iterator referencing the end of range in x. - * - * Removes elements in the range [__first,__last) and inserts them - * before @a __position in constant time. - * - * Undefined if @a __position is in [__first,__last). - */ - void - splice(const_iterator __position, list&& __x, const_iterator __first, - const_iterator __last) noexcept -#else /** * @brief Insert range from another %list. * @param __position Iterator referencing the element to insert before. @@ -1505,9 +1437,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * Undefined if @a __position is in [__first,__last). */ void - splice(iterator __position, list& __x, iterator __first, - iterator __last) -#endif + splice(__const_iterator __position, list& __x, __const_iterator __first, + __const_iterator __last) _GLIBCXX_NOEXCEPT { if (__first != __last) { @@ -1539,9 +1470,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * Undefined if @a __position is in [__first,__last). */ void - splice(const_iterator __position, list& __x, const_iterator __first, + splice(const_iterator __position, list&& __x, const_iterator __first, const_iterator __last) noexcept - { splice(__position, std::move(__x), __first, __last); } + { splice(__position, __x, __first, __last); } #endif /**