Add absl::make_unique_for_overwrite

This is a polyfill for C++20's `std::make_unique_for_overwrite`.

https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique

PiperOrigin-RevId: 875171828
Change-Id: I270264c258ba6629ccb7b93030ae3b298b2a8b23
diff --git a/absl/memory/memory.h b/absl/memory/memory.h
index 3508135..f0f7aea 100644
--- a/absl/memory/memory.h
+++ b/absl/memory/memory.h
@@ -96,6 +96,53 @@
 // should use `std::make_unique`.
 using std::make_unique;
 
+namespace memory_internal {
+
+// Traits to select proper overload and return type for
+// `absl::make_unique_for_overwrite<>`.
+template <typename T>
+struct MakeUniqueResult {
+  using scalar = std::unique_ptr<T>;
+};
+template <typename T>
+struct MakeUniqueResult<T[]> {
+  using array = std::unique_ptr<T[]>;
+};
+template <typename T, size_t N>
+struct MakeUniqueResult<T[N]> {
+  using invalid = void;
+};
+
+}  // namespace memory_internal
+
+// These are make_unique_for_overwrite variants modeled after
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1973r1.pdf
+// Unlike absl::make_unique, values are default initialized rather than value
+// initialized.
+//
+// `absl::make_unique_for_overwrite` overload for non-array types.
+template <typename T>
+typename memory_internal::MakeUniqueResult<T>::scalar
+    make_unique_for_overwrite() {
+  return std::unique_ptr<T>(new T);
+}
+
+// `absl::make_unique_for_overwrite` overload for an array T[] of unknown
+// bounds. The array allocation needs to use the `new T[size]` form and cannot
+// take element constructor arguments. The `std::unique_ptr` will manage
+// destructing these array elements.
+template <typename T>
+typename memory_internal::MakeUniqueResult<T>::array
+    make_unique_for_overwrite(size_t n) {
+  return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]);
+}
+
+// `absl::make_unique_for_overwrite` overload for an array T[N] of known bounds.
+// This construction will be rejected.
+template <typename T, typename... Args>
+typename memory_internal::MakeUniqueResult<T>::invalid
+    make_unique_for_overwrite(Args&&... /* args */) = delete;
+
 // -----------------------------------------------------------------------------
 // Function Template: RawPtr()
 // -----------------------------------------------------------------------------
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index fafd3a4..aeb6001 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -64,6 +64,11 @@
   EXPECT_EQ(0, DestructorVerifier::instance_count());
 }
 
+TEST(MakeUniqueForOverwriteTest, Basic) {
+  std::unique_ptr<int> p = absl::make_unique_for_overwrite<int>();
+  p = absl::make_unique_for_overwrite<int>();
+}
+
 // InitializationVerifier fills in a pattern when allocated so we can
 // distinguish between its default and value initialized states (without
 // accessing truly uninitialized memory).
@@ -87,6 +92,28 @@
   int b;
 };
 
+TEST(Initialization, MakeUniqueForOverwrite) {
+  auto p = absl::make_unique_for_overwrite<InitializationVerifier>();
+
+  int pattern;
+  memset(&pattern, InitializationVerifier::kDefaultScalar, sizeof(pattern));
+
+  EXPECT_EQ(pattern, p->a);
+  EXPECT_EQ(pattern, p->b);
+}
+
+TEST(Initialization, MakeUniqueForOverwriteArray) {
+  auto p = absl::make_unique_for_overwrite<InitializationVerifier[]>(2);
+
+  int pattern;
+  memset(&pattern, InitializationVerifier::kDefaultArray, sizeof(pattern));
+
+  EXPECT_EQ(pattern, p[0].a);
+  EXPECT_EQ(pattern, p[0].b);
+  EXPECT_EQ(pattern, p[1].a);
+  EXPECT_EQ(pattern, p[1].b);
+}
+
 struct ArrayWatch {
   void* operator new[](size_t n) {
     allocs().push_back(n);
@@ -99,6 +126,17 @@
   }
 };
 
+TEST(MakeUniqueForOverwriteTest, Array) {
+  // Ensure state is clean before we start so that these tests
+  // are order-agnostic.
+  ArrayWatch::allocs().clear();
+
+  auto p = absl::make_unique_for_overwrite<ArrayWatch[]>(5);
+  static_assert(std::is_same<decltype(p), std::unique_ptr<ArrayWatch[]>>::value,
+                "unexpected return type");
+  EXPECT_THAT(ArrayWatch::allocs(), ElementsAre(5 * sizeof(ArrayWatch)));
+}
+
 TEST(RawPtrTest, RawPointer) {
   int i = 5;
   EXPECT_EQ(&i, absl::RawPtr(&i));