[libcxx-commits] [libcxx] 12b5582 - [libc++][NFC] Inline most of `__vector_base` into `vector`.

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 8 00:46:39 PST 2021


Author: Konstantin Varlamov
Date: 2021-11-08T00:45:48-08:00
New Revision: 12b55821a578929a7b03448a22c3a678aa649bd5

URL: https://github.com/llvm/llvm-project/commit/12b55821a578929a7b03448a22c3a678aa649bd5
DIFF: https://github.com/llvm/llvm-project/commit/12b55821a578929a7b03448a22c3a678aa649bd5.diff

LOG: [libc++][NFC] Inline most of `__vector_base` into `vector`.

`__vector_base` exists for historical reasons and cannot be eliminated
entirely without breaking the ABI. Member variables are left
untouched -- this patch only does changes that clearly cannot affect the
ABI.

Differential Revision: https://reviews.llvm.org/D112976

Added: 
    

Modified: 
    libcxx/include/vector

Removed: 
    


################################################################################
diff  --git a/libcxx/include/vector b/libcxx/include/vector
index 80819080a9fbe..f19aaa1cbd7b6 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -315,167 +315,37 @@ template <class _Tp, class _Allocator>
 class __vector_base
     : protected __vector_base_common<true> // This base class is historical, but it needs to remain for ABI compatibility
 {
-public:
-    typedef _Allocator                               allocator_type;
-    typedef allocator_traits<allocator_type>         __alloc_traits;
-    typedef typename __alloc_traits::size_type       size_type;
-protected:
-    typedef _Tp                                      value_type;
-    typedef value_type&                              reference;
-    typedef const value_type&                        const_reference;
-    typedef typename __alloc_traits::
diff erence_type 
diff erence_type;
-    typedef typename __alloc_traits::pointer         pointer;
-    typedef typename __alloc_traits::const_pointer   const_pointer;
-    typedef pointer                                  iterator;
-    typedef const_pointer                            const_iterator;
+    typedef _Allocator                                           allocator_type;
+    typedef typename allocator_traits<allocator_type>::pointer   pointer;
 
-    pointer                                         __begin_;
-    pointer                                         __end_;
-    __compressed_pair<pointer, allocator_type> __end_cap_;
-
-    _LIBCPP_INLINE_VISIBILITY
-    allocator_type& __alloc() _NOEXCEPT
-        {return __end_cap_.second();}
-    _LIBCPP_INLINE_VISIBILITY
-    const allocator_type& __alloc() const _NOEXCEPT
-        {return __end_cap_.second();}
-    _LIBCPP_INLINE_VISIBILITY
-    pointer& __end_cap() _NOEXCEPT
-        {return __end_cap_.first();}
-    _LIBCPP_INLINE_VISIBILITY
-    const pointer& __end_cap() const _NOEXCEPT
-        {return __end_cap_.first();}
+protected:
+    pointer                                                      __begin_;
+    pointer                                                      __end_;
+    __compressed_pair<pointer, allocator_type>                   __end_cap_;
 
     _LIBCPP_INLINE_VISIBILITY
     __vector_base()
-        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
-    _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);
-#ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT;
-#endif
-    ~__vector_base();
-
-    _LIBCPP_INLINE_VISIBILITY
-    void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
-    _LIBCPP_INLINE_VISIBILITY
-    size_type capacity() const _NOEXCEPT
-        {return static_cast<size_type>(__end_cap() - __begin_);}
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(pointer __new_last) _NOEXCEPT;
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __copy_assign_alloc(const __vector_base& __c)
-        {__copy_assign_alloc(__c, integral_constant<bool,
-                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __move_assign_alloc(__vector_base& __c)
-        _NOEXCEPT_(
-            !__alloc_traits::propagate_on_container_move_assignment::value ||
-            is_nothrow_move_assignable<allocator_type>::value)
-        {__move_assign_alloc(__c, integral_constant<bool,
-                      __alloc_traits::propagate_on_container_move_assignment::value>());}
-
-    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
-    void __throw_length_error() const {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        __vector_base_common<true>::__throw_length_error();
-#else
-        _VSTD::abort();
-#endif
-    }
-
-    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
-    void __throw_out_of_range() const {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-        __vector_base_common<true>::__throw_out_of_range();
-#else
-        _VSTD::abort();
-#endif
-    }
-
-private:
-    _LIBCPP_INLINE_VISIBILITY
-    void __copy_assign_alloc(const __vector_base& __c, true_type)
-        {
-            if (__alloc() != __c.__alloc())
-            {
-                clear();
-                __alloc_traits::deallocate(__alloc(), __begin_, capacity());
-                __begin_ = __end_ = __end_cap() = nullptr;
-            }
-            __alloc() = __c.__alloc();
-        }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __copy_assign_alloc(const __vector_base&, false_type)
-        {}
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __move_assign_alloc(__vector_base& __c, true_type)
-        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
-        {
-            __alloc() = _VSTD::move(__c.__alloc());
-        }
-
-    _LIBCPP_INLINE_VISIBILITY
-    void __move_assign_alloc(__vector_base&, false_type)
-        _NOEXCEPT
-        {}
-};
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
-{
-    pointer __soon_to_be_end = __end_;
-    while (__new_last != __soon_to_be_end)
-        __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__soon_to_be_end));
-    __end_ = __new_last;
-}
-
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-__vector_base<_Tp, _Allocator>::__vector_base()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __begin_(nullptr),
-      __end_(nullptr),
-      __end_cap_(nullptr, __default_init_tag())
-{
-}
+      : __begin_(nullptr),
+        __end_(nullptr),
+        __end_cap_(nullptr, __default_init_tag()) {}
 
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
-    : __begin_(nullptr),
-      __end_(nullptr),
-      __end_cap_(nullptr, __a)
-{
-}
+    _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a)
+      : __begin_(nullptr),
+        __end_(nullptr),
+        __end_cap_(nullptr, __a) {}
 
 #ifndef _LIBCPP_CXX03_LANG
-template <class _Tp, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-__vector_base<_Tp, _Allocator>::__vector_base(allocator_type&& __a) _NOEXCEPT
-    : __begin_(nullptr),
-      __end_(nullptr),
-      __end_cap_(nullptr, _VSTD::move(__a)) {}
+    _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT
+      : __begin_(nullptr),
+        __end_(nullptr),
+        __end_cap_(nullptr, _VSTD::move(__a)) {}
 #endif
-
-template <class _Tp, class _Allocator>
-__vector_base<_Tp, _Allocator>::~__vector_base()
-{
-    if (__begin_ != nullptr)
-    {
-        clear();
-        __alloc_traits::deallocate(__alloc(), __begin_, capacity());
-    }
-}
+};
 
 template <class _Tp, class _Allocator /* = allocator<_Tp> */>
 class _LIBCPP_TEMPLATE_VIS vector
+    // This base class is historical, but it needs to remain for ABI compatibility.
     : private __vector_base<_Tp, _Allocator>
 {
 private:
@@ -485,17 +355,17 @@ public:
     typedef vector                                   __self;
     typedef _Tp                                      value_type;
     typedef _Allocator                               allocator_type;
-    typedef typename __base::__alloc_traits          __alloc_traits;
-    typedef typename __base::reference               reference;
-    typedef typename __base::const_reference         const_reference;
-    typedef typename __base::size_type               size_type;
-    typedef typename __base::
diff erence_type         
diff erence_type;
-    typedef typename __base::pointer                 pointer;
-    typedef typename __base::const_pointer           const_pointer;
+    typedef allocator_traits<allocator_type>         __alloc_traits;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::
diff erence_type 
diff erence_type;
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
     typedef __wrap_iter<pointer>                     iterator;
     typedef __wrap_iter<const_pointer>               const_iterator;
-    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;
-    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;
+    typedef _VSTD::reverse_iterator<iterator>        reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>  const_reverse_iterator;
 
     static_assert((is_same<typename allocator_type::value_type, value_type>::value),
                   "Allocator::value_type must be same type as value_type");
@@ -557,10 +427,16 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     ~vector()
     {
-        __annotate_delete();
+      __annotate_delete();
 #if _LIBCPP_DEBUG_LEVEL == 2
-        __get_db()->__erase_c(this);
+      __get_db()->__erase_c(this);
 #endif
+
+      if (this->__begin_ != nullptr)
+      {
+        __clear();
+        __alloc_traits::deallocate(__alloc(), this->__begin_, capacity());
+      }
     }
 
     vector(const vector& __x);
@@ -665,7 +541,7 @@ public:
         {return static_cast<size_type>(this->__end_ - this->__begin_);}
     _LIBCPP_INLINE_VISIBILITY
     size_type capacity() const _NOEXCEPT
-        {return __base::capacity();}
+        {return static_cast<size_type>(__end_cap() - this->__begin_);}
     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
     bool empty() const _NOEXCEPT
         {return this->__begin_ == this->__end_;}
@@ -778,7 +654,7 @@ public:
     void clear() _NOEXCEPT
     {
         size_type __old_size = size();
-        __base::clear();
+        __clear();
         __annotate_shrink(__old_size);
         __invalidate_all_iterators();
     }
@@ -839,7 +715,7 @@ private:
     {
         __invalidate_iterators_past(__new_last);
         size_type __old_size = size();
-        __base::__destruct_at_end(__new_last);
+        __base_destruct_at_end(__new_last);
         __annotate_shrink(__old_size);
     }
 
@@ -934,6 +810,89 @@ private:
         _VSTD::forward<_Args>(__args)...);
     ++__tx.__pos_;
   }
+
+  _LIBCPP_INLINE_VISIBILITY
+  allocator_type& __alloc() _NOEXCEPT
+      {return this->__end_cap_.second();}
+  _LIBCPP_INLINE_VISIBILITY
+  const allocator_type& __alloc() const _NOEXCEPT
+      {return this->__end_cap_.second();}
+  _LIBCPP_INLINE_VISIBILITY
+  pointer& __end_cap() _NOEXCEPT
+      {return this->__end_cap_.first();}
+  _LIBCPP_INLINE_VISIBILITY
+  const pointer& __end_cap() const _NOEXCEPT
+      {return this->__end_cap_.first();}
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __clear() _NOEXCEPT {__base_destruct_at_end(this->__begin_);}
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
+    pointer __soon_to_be_end = this->__end_;
+    while (__new_last != __soon_to_be_end)
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__soon_to_be_end));
+    this->__end_ = __new_last;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __copy_assign_alloc(const vector& __c)
+      {__copy_assign_alloc(__c, integral_constant<bool,
+                    __alloc_traits::propagate_on_container_copy_assignment::value>());}
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __move_assign_alloc(vector& __c)
+      _NOEXCEPT_(
+          !__alloc_traits::propagate_on_container_move_assignment::value ||
+          is_nothrow_move_assignable<allocator_type>::value)
+      {__move_assign_alloc(__c, integral_constant<bool,
+                    __alloc_traits::propagate_on_container_move_assignment::value>());}
+
+  _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
+  void __throw_length_error() const {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    __vector_base_common<true>::__throw_length_error();
+#else
+    _VSTD::abort();
+#endif
+  }
+
+  _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
+  void __throw_out_of_range() const {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    __vector_base_common<true>::__throw_out_of_range();
+#else
+    _VSTD::abort();
+#endif
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __copy_assign_alloc(const vector& __c, true_type)
+  {
+    if (__alloc() != __c.__alloc())
+    {
+      __clear();
+      __alloc_traits::deallocate(__alloc(), this->__begin_, capacity());
+      this->__begin_ = this->__end_ = __end_cap() = nullptr;
+    }
+    __alloc() = __c.__alloc();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __copy_assign_alloc(const vector&, false_type)
+  {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __move_assign_alloc(vector& __c, true_type)
+      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+  {
+    __alloc() = _VSTD::move(__c.__alloc());
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __move_assign_alloc(vector&, false_type)
+      _NOEXCEPT
+  {}
 };
 
 #if _LIBCPP_STD_VER >= 17
@@ -1374,7 +1333,7 @@ void
 vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
     _NOEXCEPT_(__alloc_traits::is_always_equal::value)
 {
-    if (__base::__alloc() != __c.__alloc())
+    if (__alloc() != __c.__alloc())
     {
         typedef move_iterator<iterator> _Ip;
         assign(_Ip(__c.begin()), _Ip(__c.end()));
@@ -1389,7 +1348,7 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
 {
     __vdeallocate();
-    __base::__move_assign_alloc(__c); // this can throw
+    __move_assign_alloc(__c); // this can throw
     this->__begin_ = __c.__begin_;
     this->__end_ = __c.__end_;
     this->__end_cap() = __c.__end_cap();
@@ -1408,7 +1367,7 @@ vector<_Tp, _Allocator>::operator=(const vector& __x)
 {
     if (this != _VSTD::addressof(__x))
     {
-        __base::__copy_assign_alloc(__x);
+        __copy_assign_alloc(__x);
         assign(__x.__begin_, __x.__end_);
     }
     return *this;


        


More information about the libcxx-commits mailing list