Pushed On Fri, 15 Nov 2024 at 15:26, Jonathan Wakely <jwak...@redhat.com> wrote: > > Remove some preprocessor conditionals by moving the _M_size member for > the cxx11 ABI into a new base class, which is empty for the gcc4-compat > ABI. > > Move some unused members that are only retained for ABI compatibility to > the end of _List_base and add an explanatory comment. Stop using > list::_M_node_count and list::_D_distance and then move them to the end > of std::list with a comment too. > > libstdc++-v3/ChangeLog: > > * include/bits/stl_list.h (_List_size): New struct. > (_List_node_header): Replace _M_size member with _List_size base > class. > (_List_node_header(_List_node_header&&)): Replace explicit uses > of _M_size with initializing the base. > (_List_node_header::_M_init): Likewise. > (_List_base::_S_distance, _List_base::_M_distance) > (_List_base::_M_node_count): Move to end of class body and add > comment. > (list::_S_distance, list::_M_node_count): Likewise. > (list::size): Inline _M_node_count effects to here. > (list::splice(iterator, list&, iterator, iterator)): Use #if and > call std::distance instead of _S_distance. > --- > > Tested x86_64-linux. > > Pull request at https://forge.sourceware.org/gcc/gcc-TEST/pulls/25 > > libstdc++-v3/include/bits/stl_list.h | 179 +++++++++++++++------------ > 1 file changed, 97 insertions(+), 82 deletions(-) > > diff --git a/libstdc++-v3/include/bits/stl_list.h > b/libstdc++-v3/include/bits/stl_list.h > index 7deb04b4bfe..d51fde90e2b 100644 > --- a/libstdc++-v3/include/bits/stl_list.h > +++ b/libstdc++-v3/include/bits/stl_list.h > @@ -104,22 +104,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > _M_unhook() _GLIBCXX_USE_NOEXCEPT; > }; > > - /// The %list node header. > - struct _List_node_header : public _List_node_base > + struct _List_size > { > #if _GLIBCXX_USE_CXX11_ABI > - std::size_t _M_size; > + // Store the size here so that std::list::size() is fast. > + size_t _M_size; > #endif > + }; > > + > + /// The %list node header. > + struct _List_node_header : public _List_node_base, _List_size > + { > _List_node_header() _GLIBCXX_NOEXCEPT > { _M_init(); } > > #if __cplusplus >= 201103L > _List_node_header(_List_node_header&& __x) noexcept > - : _List_node_base{ __x._M_next, __x._M_prev } > -# if _GLIBCXX_USE_CXX11_ABI > - , _M_size(__x._M_size) > -# endif > + : _List_node_base(__x), _List_size(__x) > { > if (__x._M_base()->_M_next == __x._M_base()) > this->_M_next = this->_M_prev = this; > @@ -142,9 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > __node->_M_next = __xnode->_M_next; > __node->_M_prev = __xnode->_M_prev; > __node->_M_next->_M_prev = __node->_M_prev->_M_next = __node; > -# if _GLIBCXX_USE_CXX11_ABI > - _M_size = __x._M_size; > -# endif > + _List_size::operator=(__x); > __x._M_init(); > } > } > @@ -154,9 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > _M_init() _GLIBCXX_NOEXCEPT > { > this->_M_next = this->_M_prev = this; > -#if _GLIBCXX_USE_CXX11_ABI > - this->_M_size = 0; > -#endif > + _List_size::operator=(_List_size()); > } > > private: > @@ -436,21 +434,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > rebind<_List_node<_Tp> >::other _Node_alloc_type; > typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; > > -#if !_GLIBCXX_INLINE_VERSION > - static size_t > - _S_distance(const __detail::_List_node_base* __first, > - const __detail::_List_node_base* __last) > - { > - size_t __n = 0; > - while (__first != __last) > - { > - __first = __first->_M_next; > - ++__n; > - } > - return __n; > - } > -#endif > - > struct _List_impl > : public _Node_alloc_type > { > @@ -488,33 +471,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > void _M_inc_size(size_t __n) { _M_impl._M_node._M_size += __n; } > > void _M_dec_size(size_t __n) { _M_impl._M_node._M_size -= __n; } > - > -# if !_GLIBCXX_INLINE_VERSION > - size_t > - _M_distance(const __detail::_List_node_base* __first, > - const __detail::_List_node_base* __last) const > - { return _S_distance(__first, __last); } > - > - // return the stored size > - size_t _M_node_count() const { return _M_get_size(); } > -# endif > #else > // dummy implementations used when the size is not stored > size_t _M_get_size() const { return 0; } > void _M_set_size(size_t) { } > void _M_inc_size(size_t) { } > void _M_dec_size(size_t) { } > - > -# if !_GLIBCXX_INLINE_VERSION > - size_t _M_distance(const void*, const void*) const { return 0; } > - > - // count the number of nodes > - size_t _M_node_count() const > - { > - return _S_distance(_M_impl._M_node._M_next, > - std::__addressof(_M_impl._M_node)); > - } > -# endif > #endif > > typename _Node_alloc_traits::pointer > @@ -549,16 +511,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > #if __cplusplus >= 201103L > _List_base(_List_base&&) = default; > > -# if !_GLIBCXX_INLINE_VERSION > - _List_base(_List_base&& __x, _Node_alloc_type&& __a) > - : _M_impl(std::move(__a)) > - { > - if (__x._M_get_Node_allocator() == _M_get_Node_allocator()) > - _M_move_nodes(std::move(__x)); > - // else caller must move individual elements. > - } > -# endif > - > // Used when allocator is_always_equal. > _List_base(_Node_alloc_type&& __a, _List_base&& __x) > : _M_impl(std::move(__a), std::move(__x._M_impl)) > @@ -584,6 +536,57 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > void > _M_init() _GLIBCXX_NOEXCEPT > { this->_M_impl._M_node._M_init(); } > + > +#if !_GLIBCXX_INLINE_VERSION > + // XXX GLIBCXX_ABI Deprecated > + // These members are unused by std::list now, but we keep them here > + // so that an explicit instantiation of std::list will define them. > + // This ensures that explicit instantiations still define these > symbols, > + // so that explicit instantiation declarations of std::list that were > + // compiled with old versions of GCC can still find these old symbols. > + > +# if __cplusplus >= 201103L > + _List_base(_List_base&& __x, _Node_alloc_type&& __a) > + : _M_impl(std::move(__a)) > + { > + if (__x._M_get_Node_allocator() == _M_get_Node_allocator()) > + _M_move_nodes(std::move(__x)); > + // else caller must move individual elements. > + } > +# endif > + > + static size_t > + _S_distance(const __detail::_List_node_base* __first, > + const __detail::_List_node_base* __last) > + { > + size_t __n = 0; > + while (__first != __last) > + { > + __first = __first->_M_next; > + ++__n; > + } > + return __n; > + } > + > +#if _GLIBCXX_USE_CXX11_ABI > + size_t > + _M_distance(const __detail::_List_node_base* __first, > + const __detail::_List_node_base* __last) const > + { return _S_distance(__first, __last); } > + > + // return the stored size > + size_t _M_node_count() const { return _M_get_size(); } > +#else > + size_t _M_distance(const void*, const void*) const { return 0; } > + > + // count the number of nodes > + size_t _M_node_count() const > + { > + return _S_distance(_M_impl._M_node._M_next, > + std::__addressof(_M_impl._M_node)); > + } > +#endif > +#endif // ! INLINE_VERSION > }; > > /** > @@ -721,27 +724,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > } > #endif > > -#if _GLIBCXX_USE_CXX11_ABI > - static size_t > - _S_distance(const_iterator __first, const_iterator __last) > - { return std::distance(__first, __last); } > - > - // return the stored size > - size_t > - _M_node_count() const > - { return this->_M_get_size(); } > -#else > - // dummy implementations used when the size is not stored > - static size_t > - _S_distance(const_iterator, const_iterator) > - { return 0; } > - > - // count the number of nodes > - size_t > - _M_node_count() const > - { return std::distance(begin(), end()); } > -#endif > - > public: > // [23.2.2.1] construct/copy/destroy > // (assign() and get_allocator() are also listed in this section) > @@ -1193,7 +1175,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > _GLIBCXX_NODISCARD > size_type > size() const _GLIBCXX_NOEXCEPT > - { return _M_node_count(); } > + { > +#if _GLIBCXX_USE_CXX11_ABI > + return this->_M_get_size(); // return the stored size > +#else > + return std::distance(begin(), end()); // count the number of nodes > +#endif > + } > > /** Returns the size() of the largest possible %list. */ > _GLIBCXX_NODISCARD > @@ -1851,9 +1839,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > if (this != std::__addressof(__x)) > _M_check_equal_allocators(__x); > > - size_t __n = _S_distance(__first, __last); > +#if _GLIBCXX_USE_CXX11_ABI > + size_t __n = std::distance(__first, __last); > this->_M_inc_size(__n); > __x._M_dec_size(__n); > +#endif > > this->_M_transfer(__position._M_const_cast(), > __first._M_const_cast(), > @@ -2213,6 +2203,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > { explicit _Finalize_merge(list&, list&, const iterator&) { } }; > #endif > > +#if !_GLIBCXX_INLINE_VERSION > + // XXX GLIBCXX_ABI Deprecated > + // These members are unused by std::list now, but we keep them here > + // so that an explicit instantiation of std::list will define them. > + // This ensures that any objects or libraries compiled against old > + // versions of GCC will still be able to use the symbols. > + > +#if _GLIBCXX_USE_CXX11_ABI > + static size_t > + _S_distance(const_iterator __first, const_iterator __last) > + { return std::distance(__first, __last); } > + > + size_t > + _M_node_count() const > + { return this->_M_get_size(); } > +#else > + static size_t > + _S_distance(const_iterator, const_iterator) > + { return 0; } > + > + size_t > + _M_node_count() const > + { return std::distance(begin(), end()); } > +#endif > +#endif // ! INLINE_VERSION > }; > > #if __cpp_deduction_guides >= 201606 > -- > 2.47.0 >