diff --git a/src/util.h b/src/util.h index 873a204f9cd794..3f04b562316852 100644 --- a/src/util.h +++ b/src/util.h @@ -390,6 +390,16 @@ constexpr size_t strsize(const T (&)[N]) { return N - 1; } +template +inline constexpr bool kMaybeStackBufferHasStringType = + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v; + +template +using MaybeStackBufferStringType = + std::conditional_t, char16_t, T>; + // Allocates an array of member type T. For up to kStackStorageSize items, // the stack is used, otherwise malloc(). template @@ -503,9 +513,28 @@ class MaybeStackBuffer { free(buf_); } - inline std::basic_string ToString() const { return {out(), length()}; } - inline std::basic_string_view ToStringView() const { - return {out(), length()}; + // Restrict string helpers to textual element types. libc++ deprecates + // `char_traits` for byte-oriented types like `unsigned char`. + template > + requires(kMaybeStackBufferHasStringType) + inline std::basic_string ToString() const { + if constexpr (std::is_same_v) { + return {out(), length()}; + } else { + return {reinterpret_cast(out()), length()}; + } + } + + template > + requires(kMaybeStackBufferHasStringType) + inline std::basic_string_view ToStringView() const { + if constexpr (std::is_same_v) { + return {out(), length()}; + } else { + return {reinterpret_cast(out()), length()}; + } } // This can only be used if the buffer contains path data in UTF8 inline std::filesystem::path ToPath() const;