summaryrefslogtreecommitdiff
path: root/absl/strings/internal/resize_uninitialized.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/internal/resize_uninitialized.h')
-rw-r--r--absl/strings/internal/resize_uninitialized.h47
1 files changed, 25 insertions, 22 deletions
diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h
index 2951bf84..ab1d8684 100644
--- a/absl/strings/internal/resize_uninitialized.h
+++ b/absl/strings/internal/resize_uninitialized.h
@@ -5,7 +5,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,54 +18,57 @@
#define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_
#include <string>
+#include <type_traits>
#include <utility>
#include "absl/base/port.h"
#include "absl/meta/type_traits.h" // for void_t
namespace absl {
-inline namespace lts_2018_12_18 {
+inline namespace lts_2019_08_08 {
namespace strings_internal {
// Is a subclass of true_type or false_type, depending on whether or not
-// T has a resize_uninitialized member.
-template <typename T, typename = void>
-struct HasResizeUninitialized : std::false_type {};
-template <typename T>
-struct HasResizeUninitialized<
- T, absl::void_t<decltype(std::declval<T>().resize_uninitialized(237))>>
- : std::true_type {};
+// T has a __resize_default_init member.
+template <typename string_type, typename = void>
+struct ResizeUninitializedTraits {
+ using HasMember = std::false_type;
+ static void Resize(string_type* s, size_t new_size) { s->resize(new_size); }
+};
+// __resize_default_init is provided by libc++ >= 8.0 and by Google's internal
+// ::string implementation.
template <typename string_type>
-void ResizeUninit(string_type* s, size_t new_size, std::true_type) {
- s->resize_uninitialized(new_size);
-}
-template <typename string_type>
-void ResizeUninit(string_type* s, size_t new_size, std::false_type) {
- s->resize(new_size);
-}
+struct ResizeUninitializedTraits<
+ string_type, absl::void_t<decltype(std::declval<string_type&>()
+ .__resize_default_init(237))> > {
+ using HasMember = std::true_type;
+ static void Resize(string_type* s, size_t new_size) {
+ s->__resize_default_init(new_size);
+ }
+};
-// Returns true if the string implementation supports a resize where
-// the new characters added to the string are left untouched.
+// Returns true if the std::string implementation supports a resize where
+// the new characters added to the std::string are left untouched.
//
// (A better name might be "STLStringSupportsUninitializedResize", alluding to
// the previous function.)
template <typename string_type>
inline constexpr bool STLStringSupportsNontrashingResize(string_type*) {
- return HasResizeUninitialized<string_type>();
+ return ResizeUninitializedTraits<string_type>::HasMember::value;
}
// Like str->resize(new_size), except any new characters added to "*str" as a
// result of resizing may be left uninitialized, rather than being filled with
// '0' bytes. Typically used when code is then going to overwrite the backing
-// store of the string with known data. Uses a Google extension to ::string.
+// store of the std::string with known data.
template <typename string_type, typename = void>
inline void STLStringResizeUninitialized(string_type* s, size_t new_size) {
- ResizeUninit(s, new_size, HasResizeUninitialized<string_type>());
+ ResizeUninitializedTraits<string_type>::Resize(s, new_size);
}
} // namespace strings_internal
-} // inline namespace lts_2018_12_18
+} // inline namespace lts_2019_08_08
} // namespace absl
#endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_