From e04d124a96311d3714522125bf703950863e0540 Mon Sep 17 00:00:00 2001 From: Christopher Di Bella Date: Mon, 26 Aug 2024 08:58:35 -0700 Subject: [PATCH] [libc++] Call basic_string_view's assume-valid constructor from basic_string operations (#105863) `basic_string` frequently calls `basic_string_view(data(), size())`, which accounts for ~15% of the observed overhead when hardening is enabled. This commit removes unnecessary checks when `basic_string` is known to already have valid data, by bypassing the public constructor, so that we eliminate that overhead. --- libcxx/include/string | 12 ++++++------ libcxx/include/string_view | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libcxx/include/string b/libcxx/include/string index 6e93a6230cc2c0..cdc1afedbdf52f 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1213,7 +1213,7 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT { - return __self_view(data(), size()); + return __self_view(typename __self_view::__assume_valid(), data(), size()); } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& @@ -1822,7 +1822,7 @@ public: #if _LIBCPP_STD_VER >= 20 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { - return __self_view(data(), size()).starts_with(__sv); + return __self_view(typename __self_view::__assume_valid(), data(), size()).starts_with(__sv); } constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { @@ -1834,7 +1834,7 @@ public: } constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { - return __self_view(data(), size()).ends_with(__sv); + return __self_view(typename __self_view::__assume_valid(), data(), size()).ends_with(__sv); } constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { @@ -1848,15 +1848,15 @@ public: #if _LIBCPP_STD_VER >= 23 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { - return __self_view(data(), size()).contains(__sv); + return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__sv); } constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { - return __self_view(data(), size()).contains(__c); + return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__c); } constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { - return __self_view(data(), size()).contains(__s); + return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__s); } #endif diff --git a/libcxx/include/string_view b/libcxx/include/string_view index 2a03ee99e9ab52..cf97e3a9be314d 100644 --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -211,6 +211,7 @@ namespace std { #include <__functional/hash.h> #include <__functional/unary_function.h> #include <__fwd/ostream.h> +#include <__fwd/string.h> #include <__fwd/string_view.h> #include <__iterator/bounded_iter.h> #include <__iterator/concepts.h> @@ -689,6 +690,9 @@ private: const value_type* __data_; size_type __size_; + + template + friend class basic_string; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);