diff options
author | Abseil Team <absl-team@google.com> | 2021-09-24 10:32:31 -0700 |
---|---|---|
committer | vslashg <gfalcon@google.com> | 2021-09-27 12:02:32 -0400 |
commit | b1b63f7aa8467ff5c2fc81231f6ec69fe93ca3b0 (patch) | |
tree | 8700c8b71de5d1e1beeb3a3a6415fd8253148f44 /absl/strings/internal/resize_uninitialized.h | |
parent | 1ce4ceca2b2931bc4d7e470228c2dbb2f3dfea0f (diff) | |
download | abseil-b1b63f7aa8467ff5c2fc81231f6ec69fe93ca3b0.tar.gz abseil-b1b63f7aa8467ff5c2fc81231f6ec69fe93ca3b0.tar.bz2 abseil-b1b63f7aa8467ff5c2fc81231f6ec69fe93ca3b0.zip |
Export of internal Abseil changes
--
d6f0dab708b123a5e24b98da1de0b11e36a7a86e by Evan Brown <ezb@google.com>:
In STLStringResizeUninitializedAmortized, use basic_string::__append_default_init for amortized growth rather than conditionally adding reserve in STLStringReserveAmortized. This way, we can avoid extra branches, e.g. in basic_string::__shrink_or_extend.
PiperOrigin-RevId: 398761382
GitOrigin-RevId: d6f0dab708b123a5e24b98da1de0b11e36a7a86e
Change-Id: Ib2d99411c95d61300519c32b885ce586b410c3bf
Diffstat (limited to 'absl/strings/internal/resize_uninitialized.h')
-rw-r--r-- | absl/strings/internal/resize_uninitialized.h | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h index 749c66e7..49859dcc 100644 --- a/absl/strings/internal/resize_uninitialized.h +++ b/absl/strings/internal/resize_uninitialized.h @@ -29,8 +29,9 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { -// Is a subclass of true_type or false_type, depending on whether or not -// T has a __resize_default_init member. +// In this type trait, we look for a __resize_default_init member function, and +// we use it if available, otherwise, we use resize. We provide HasMember to +// indicate whether __resize_default_init is present. template <typename string_type, typename = void> struct ResizeUninitializedTraits { using HasMember = std::false_type; @@ -79,14 +80,36 @@ void STLStringReserveAmortized(string_type* s, size_t new_size) { } } +// In this type trait, we look for an __append_default_init member function, and +// we use it if available, otherwise, we use append. +template <typename string_type, typename = void> +struct AppendUninitializedTraits { + static void Append(string_type* s, size_t n) { + s->append(n, typename string_type::value_type()); + } +}; + +template <typename string_type> +struct AppendUninitializedTraits< + string_type, absl::void_t<decltype(std::declval<string_type&>() + .__append_default_init(237))> > { + static void Append(string_type* s, size_t n) { + s->__append_default_init(n); + } +}; + // Like STLStringResizeUninitialized(str, new_size), except guaranteed to use // exponential growth so that the amortized complexity of increasing the string // size by a small amount is O(1), in contrast to O(str->size()) in the case of // precise growth. template <typename string_type> void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { - STLStringReserveAmortized(s, new_size); - STLStringResizeUninitialized(s, new_size); + const size_t size = s->size(); + if (new_size > size) { + AppendUninitializedTraits<string_type>::Append(s, new_size - size); + } else { + s->erase(new_size); + } } } // namespace strings_internal |