// Copyright 2020 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifdef UNSAFE_BUFFERS_BUILD // TODO(crbug.com/40284755): Remove this and spanify to fix the errors. #pragma allow_unsafe_buffers #endif #ifndef BASE_STRINGS_STRCAT_INTERNAL_H_ #define BASE_STRINGS_STRCAT_INTERNAL_H_ #include <concepts> #include <string> #include "base/containers/span.h" namespace base { namespace internal { // Optimized version of `std::basic_string::resize()` that skips zero // initialization of appended characters. Reading from the newly allocated // characters results in undefined behavior if they are not explicitly // initialized afterwards. Currently proposed for standardization as // std::basic_string::resize_and_overwrite: https://wg21.link/P1072R6 template <typename CharT> requires requires(std::basic_string<CharT>& str, size_t total_size) { … } // Fallback to regular std::basic_string::resize() if invoking // __resize_default_init is ill-formed. template <typename CharT> void Resize(std::basic_string<CharT>& str, size_t total_size) { … } // Appends `pieces` to `dest`. Instead of simply calling `dest.append()` // `pieces.size()` times, this method first resizes `dest` to be of the desired // size, and then appends each piece via `std::char_traits::copy`. This achieves // two goals: // 1) Allocating the desired size all at once avoids other allocations that // could happen if intermediate allocations did not reserve enough capacity. // 2) Invoking std::char_traits::copy instead of std::basic_string::append // avoids having to write the terminating '\0' character n times. template <typename CharT, typename StringT> void StrAppendT(std::basic_string<CharT>& dest, span<const StringT> pieces) { … } template <typename StringT> auto StrCatT(span<const StringT> pieces) { … } } // namespace internal } // namespace base #endif // BASE_STRINGS_STRCAT_INTERNAL_H_