summaryrefslogtreecommitdiff
path: root/absl/strings/internal/resize_uninitialized.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-09-24 10:32:31 -0700
committerGravatar vslashg <gfalcon@google.com>2021-09-27 12:02:32 -0400
commitb1b63f7aa8467ff5c2fc81231f6ec69fe93ca3b0 (patch)
tree8700c8b71de5d1e1beeb3a3a6415fd8253148f44 /absl/strings/internal/resize_uninitialized.h
parent1ce4ceca2b2931bc4d7e470228c2dbb2f3dfea0f (diff)
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.h31
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