修改pods
This commit is contained in:
151
Pods/abseil/absl/strings/str_cat.h
generated
151
Pods/abseil/absl/strings/str_cat.h
generated
@@ -93,6 +93,8 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -312,6 +314,10 @@ class AlphaNum {
|
||||
// No bool ctor -- bools convert to an integral type.
|
||||
// A bool ctor would also convert incoming pointers (bletch).
|
||||
|
||||
// Prevent brace initialization
|
||||
template <typename T>
|
||||
AlphaNum(std::initializer_list<T>) = delete; // NOLINT(runtime/explicit)
|
||||
|
||||
AlphaNum(int x) // NOLINT(runtime/explicit)
|
||||
: piece_(digits_, static_cast<size_t>(
|
||||
numbers_internal::FastIntToBuffer(x, digits_) -
|
||||
@@ -448,36 +454,77 @@ std::string CatPieces(std::initializer_list<absl::string_view> pieces);
|
||||
void AppendPieces(absl::Nonnull<std::string*> dest,
|
||||
std::initializer_list<absl::string_view> pieces);
|
||||
|
||||
void STLStringAppendUninitializedAmortized(std::string* dest, size_t to_append);
|
||||
template <typename Integer>
|
||||
std::string IntegerToString(Integer i) {
|
||||
// Any integer (signed/unsigned) up to 64 bits can be formatted into a buffer
|
||||
// with 22 bytes (including NULL at the end).
|
||||
constexpr size_t kMaxDigits10 = 22;
|
||||
std::string result;
|
||||
strings_internal::STLStringResizeUninitialized(&result, kMaxDigits10);
|
||||
char* start = &result[0];
|
||||
// note: this can be optimized to not write last zero.
|
||||
char* end = numbers_internal::FastIntToBuffer(i, start);
|
||||
auto size = static_cast<size_t>(end - start);
|
||||
assert((size < result.size()) &&
|
||||
"StrCat(Integer) does not fit into kMaxDigits10");
|
||||
result.erase(size);
|
||||
return result;
|
||||
}
|
||||
template <typename Float>
|
||||
std::string FloatToString(Float f) {
|
||||
std::string result;
|
||||
strings_internal::STLStringResizeUninitialized(
|
||||
&result, numbers_internal::kSixDigitsToBufferSize);
|
||||
char* start = &result[0];
|
||||
result.erase(numbers_internal::SixDigitsToBuffer(f, start));
|
||||
return result;
|
||||
}
|
||||
|
||||
// `SingleArgStrCat` overloads take built-in `int`, `long` and `long long` types
|
||||
// (signed / unsigned) to avoid ambiguity on the call side. If we used int32_t
|
||||
// and int64_t, then at least one of the three (`int` / `long` / `long long`)
|
||||
// would have been ambiguous when passed to `SingleArgStrCat`.
|
||||
std::string SingleArgStrCat(int x);
|
||||
std::string SingleArgStrCat(unsigned int x);
|
||||
std::string SingleArgStrCat(long x); // NOLINT
|
||||
std::string SingleArgStrCat(unsigned long x); // NOLINT
|
||||
std::string SingleArgStrCat(long long x); // NOLINT
|
||||
std::string SingleArgStrCat(unsigned long long x); // NOLINT
|
||||
std::string SingleArgStrCat(float x);
|
||||
std::string SingleArgStrCat(double x);
|
||||
inline std::string SingleArgStrCat(int x) { return IntegerToString(x); }
|
||||
inline std::string SingleArgStrCat(unsigned int x) {
|
||||
return IntegerToString(x);
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
inline std::string SingleArgStrCat(long x) { return IntegerToString(x); }
|
||||
// NOLINTNEXTLINE
|
||||
inline std::string SingleArgStrCat(unsigned long x) {
|
||||
return IntegerToString(x);
|
||||
}
|
||||
// NOLINTNEXTLINE
|
||||
inline std::string SingleArgStrCat(long long x) { return IntegerToString(x); }
|
||||
// NOLINTNEXTLINE
|
||||
inline std::string SingleArgStrCat(unsigned long long x) {
|
||||
return IntegerToString(x);
|
||||
}
|
||||
inline std::string SingleArgStrCat(float x) { return FloatToString(x); }
|
||||
inline std::string SingleArgStrCat(double x) { return FloatToString(x); }
|
||||
|
||||
// `SingleArgStrAppend` overloads are defined here for the same reasons as with
|
||||
// `SingleArgStrCat` above.
|
||||
void SingleArgStrAppend(std::string& str, int x);
|
||||
void SingleArgStrAppend(std::string& str, unsigned int x);
|
||||
void SingleArgStrAppend(std::string& str, long x); // NOLINT
|
||||
void SingleArgStrAppend(std::string& str, unsigned long x); // NOLINT
|
||||
void SingleArgStrAppend(std::string& str, long long x); // NOLINT
|
||||
void SingleArgStrAppend(std::string& str, unsigned long long x); // NOLINT
|
||||
// As of September 2023, the SingleArgStrCat() optimization is only enabled for
|
||||
// libc++. The reasons for this are:
|
||||
// 1) The SSO size for libc++ is 23, while libstdc++ and MSSTL have an SSO size
|
||||
// of 15. Since IntegerToString unconditionally resizes the string to 22 bytes,
|
||||
// this causes both libstdc++ and MSSTL to allocate.
|
||||
// 2) strings_internal::STLStringResizeUninitialized() only has an
|
||||
// implementation that avoids initialization when using libc++. This isn't as
|
||||
// relevant as (1), and the cost should be benchmarked if (1) ever changes on
|
||||
// libstc++ or MSSTL.
|
||||
#ifdef _LIBCPP_VERSION
|
||||
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE true
|
||||
#else
|
||||
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE false
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
typename = std::enable_if_t<std::is_arithmetic<T>::value &&
|
||||
!std::is_same<T, char>::value &&
|
||||
!std::is_same<T, bool>::value>>
|
||||
template <typename T, typename = std::enable_if_t<
|
||||
ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE &&
|
||||
std::is_arithmetic<T>{} && !std::is_same<T, char>{}>>
|
||||
using EnableIfFastCase = T;
|
||||
|
||||
#undef ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE
|
||||
|
||||
} // namespace strings_internal
|
||||
|
||||
ABSL_MUST_USE_RESULT inline std::string StrCat() { return std::string(); }
|
||||
@@ -553,68 +600,6 @@ inline void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
|
||||
static_cast<const AlphaNum&>(args).Piece()...});
|
||||
}
|
||||
|
||||
template <class String, class T>
|
||||
std::enable_if_t<
|
||||
std::is_integral<absl::strings_internal::EnableIfFastCase<T>>::value, void>
|
||||
StrAppend(absl::Nonnull<String*> result, T i) {
|
||||
return absl::strings_internal::SingleArgStrAppend(*result, i);
|
||||
}
|
||||
|
||||
// This overload is only selected if all the parameters are numbers that can be
|
||||
// handled quickly.
|
||||
// Later we can look into how we can extend this to more general argument
|
||||
// mixtures without bloating codegen too much, or copying unnecessarily.
|
||||
template <typename String, typename... T>
|
||||
std::enable_if_t<
|
||||
(sizeof...(T) > 1),
|
||||
std::common_type_t<std::conditional_t<
|
||||
true, void, absl::strings_internal::EnableIfFastCase<T>>...>>
|
||||
StrAppend(absl::Nonnull<String*> str, T... args) {
|
||||
// Do not add unnecessary variables, logic, or even "free" lambdas here.
|
||||
// They can add overhead for the compiler and/or at run time.
|
||||
// Furthermore, assume this function will be inlined.
|
||||
// This function is carefully tailored to be able to be largely optimized away
|
||||
// so that it becomes near-equivalent to the caller handling each argument
|
||||
// individually while minimizing register pressure, so that the compiler
|
||||
// can inline it with minimal overhead.
|
||||
|
||||
// First, calculate the total length, so we can perform just a single resize.
|
||||
// Save all the lengths for later.
|
||||
size_t total_length = 0;
|
||||
const ptrdiff_t lengths[] = {
|
||||
absl::numbers_internal::GetNumDigitsOrNegativeIfNegative(args)...};
|
||||
for (const ptrdiff_t possibly_negative_length : lengths) {
|
||||
// Lengths are negative for negative numbers. Keep them for later use, but
|
||||
// take their absolute values for calculating total lengths;
|
||||
total_length += possibly_negative_length < 0
|
||||
? static_cast<size_t>(-possibly_negative_length)
|
||||
: static_cast<size_t>(possibly_negative_length);
|
||||
}
|
||||
|
||||
// Now reserve space for all the arguments.
|
||||
const size_t old_size = str->size();
|
||||
absl::strings_internal::STLStringAppendUninitializedAmortized(str,
|
||||
total_length);
|
||||
|
||||
// Finally, output each argument one-by-one, from left to right.
|
||||
size_t i = 0; // The current argument we're processing
|
||||
ptrdiff_t n; // The length of the current argument
|
||||
typename String::pointer pos = &(*str)[old_size];
|
||||
using SomeTrivialEmptyType = std::false_type;
|
||||
// Ugly code due to the lack of C++14 fold expression makes us.
|
||||
const SomeTrivialEmptyType dummy1;
|
||||
for (const SomeTrivialEmptyType& dummy2 :
|
||||
{(/* Comma expressions are poor man's C++17 fold expression for C++14 */
|
||||
(void)(n = lengths[i]),
|
||||
(void)(n < 0 ? (void)(*pos++ = '-'), (n = ~n) : 0),
|
||||
(void)absl::numbers_internal::FastIntToBufferBackward(
|
||||
absl::numbers_internal::UnsignedAbsoluteValue(std::move(args)),
|
||||
pos += n, static_cast<uint32_t>(n)),
|
||||
(void)++i, dummy1)...}) {
|
||||
(void)dummy2; // Remove & migrate to fold expressions in C++17
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for the future StrCat default floating-point format, %.6g
|
||||
// This is fast.
|
||||
inline strings_internal::AlphaNumBuffer<
|
||||
|
||||
Reference in New Issue
Block a user