[libcxx-commits] [libcxx] d260ea7 - Inline basic_string::erase for fastpath where __n == npos

Martijn Vels via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 26 10:38:12 PST 2020


Author: Martijn Vels
Date: 2020-02-26T13:37:45-05:00
New Revision: d260ea7199bce566fb4229eac5cc4c5d4843c5f0

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

LOG: Inline basic_string::erase for fastpath where __n == npos

Summary:
This change checks for the case where people want to erase a string to the end, i.e., __n == npos, and inlines the call if so.

This also demonstrates keeping the ABI intact for V1, but inlining the erase() method for unstable.

Reviewers: EricWF, mclow.lists, ldionne

Reviewed By: EricWF, ldionne

Subscribers: smeenai, dexonsmith, christof, libcxx-commits

Tags: #libc

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

Added: 
    

Modified: 
    libcxx/include/__string
    libcxx/include/string

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__string b/libcxx/include/__string
index 6a9524562d7b..2aeaeb8aecdf 100644
--- a/libcxx/include/__string
+++ b/libcxx/include/__string
@@ -170,7 +170,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
   _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
   _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
   _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
-  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
+  _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
   _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
   _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
   _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \

diff  --git a/libcxx/include/string b/libcxx/include/string
index 42767e25e8d3..2c90dae2f735 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1574,6 +1574,10 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void __erase_to_end(size_type __pos);
 
+    // __erase_external_with_move is invoked for erase() invocations where
+    // `n ~= npos`, likely requiring memory moves on the string data.
+    void __erase_external_with_move(size_type __pos, size_type __n);
+
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const basic_string& __str)
         {__copy_assign_alloc(__str, integral_constant<bool,
@@ -2997,15 +3001,16 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
 
 // erase
 
+// 'externally instantiated' erase() implementation, called when __n != npos.
+// Does not check __pos against size()
 template <class _CharT, class _Traits, class _Allocator>
-basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
+void
+basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
+    size_type __pos, size_type __n)
 {
-    size_type __sz = size();
-    if (__pos > __sz)
-        this->__throw_out_of_range();
     if (__n)
     {
+        size_type __sz = size();
         value_type* __p = _VSTD::__to_address(__get_pointer());
         __n = _VSTD::min(__n, __sz - __pos);
         size_type __n_move = __sz - __pos - __n;
@@ -3016,7 +3021,19 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
         __invalidate_iterators_past(__sz);
         traits_type::assign(__p[__sz], value_type());
     }
-    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
+                                                 size_type __n) {
+  if (__pos > size()) this->__throw_out_of_range();
+  if (__n == npos) {
+    __erase_to_end(__pos);
+  } else {
+    __erase_external_with_move(__pos, __n);
+  }
+  return *this;
 }
 
 template <class _CharT, class _Traits, class _Allocator>


        


More information about the libcxx-commits mailing list