summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2022-11-16 11:09:10 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2022-11-16 11:09:59 -0800
commitae52431653d1d2815820680d4539e749f53b7bc7 (patch)
treeb4f666ef21a8ab82fa2237a41f2cda98b2585fd6
parent4b48854949f8bf9afb871c293a9022331a0b77c7 (diff)
Update absl::make_unique to reflect the C++14 minimum
absl::make_unique is now std::make_unique in all configurations. Documentation has been updated to recommend using the std::make_unique spelling. PiperOrigin-RevId: 488988005 Change-Id: Iddb8b863e6301876713d78c3fbe6660d0f9a38cf
-rw-r--r--absl/memory/BUILD.bazel15
-rw-r--r--absl/memory/CMakeLists.txt14
-rw-r--r--absl/memory/memory.h102
-rw-r--r--absl/memory/memory_exception_safety_test.cc57
-rw-r--r--absl/memory/memory_test.cc98
5 files changed, 6 insertions, 280 deletions
diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel
index 389aedf3..a93f54a6 100644
--- a/absl/memory/BUILD.bazel
+++ b/absl/memory/BUILD.bazel
@@ -50,18 +50,3 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
-
-cc_test(
- name = "memory_exception_safety_test",
- srcs = [
- "memory_exception_safety_test.cc",
- ],
- copts = ABSL_TEST_COPTS,
- linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = [
- ":memory",
- "//absl/base:config",
- "//absl/base:exception_safety_testing",
- "@com_google_googletest//:gtest_main",
- ],
-)
diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt
index 9d50e1dc..c5ed4b42 100644
--- a/absl/memory/CMakeLists.txt
+++ b/absl/memory/CMakeLists.txt
@@ -39,17 +39,3 @@ absl_cc_test(
absl::core_headers
GTest::gmock_main
)
-
-absl_cc_test(
- NAME
- memory_exception_safety_test
- SRCS
- "memory_exception_safety_test.cc"
- COPTS
- ${ABSL_TEST_COPTS}
- DEPS
- absl::memory
- absl::config
- absl::exception_safety_testing
- GTest::gmock_main
-)
diff --git a/absl/memory/memory.h b/absl/memory/memory.h
index d6332606..e5ff0e65 100644
--- a/absl/memory/memory.h
+++ b/absl/memory/memory.h
@@ -75,32 +75,6 @@ std::unique_ptr<T> WrapUnique(T* ptr) {
return std::unique_ptr<T>(ptr);
}
-namespace memory_internal {
-
-// Traits to select proper overload and return type for `absl::make_unique<>`.
-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
-
-// gcc 4.8 has __cplusplus at 201301 but the libstdc++ shipped with it doesn't
-// define make_unique. Other supported compilers either just define __cplusplus
-// as 201103 but have make_unique (msvc), or have make_unique whenever
-// __cplusplus > 201103 (clang).
-#if (__cplusplus > 201103L || defined(_MSC_VER)) && \
- !(defined(__GLIBCXX__) && !defined(__cpp_lib_make_unique))
-using std::make_unique;
-#else
// -----------------------------------------------------------------------------
// Function Template: make_unique<T>()
// -----------------------------------------------------------------------------
@@ -109,82 +83,18 @@ using std::make_unique;
// during the construction process. `absl::make_unique<>` also avoids redundant
// type declarations, by avoiding the need to explicitly use the `new` operator.
//
-// This implementation of `absl::make_unique<>` is designed for C++11 code and
-// will be replaced in C++14 by the equivalent `std::make_unique<>` abstraction.
-// `absl::make_unique<>` is designed to be 100% compatible with
-// `std::make_unique<>` so that the eventual migration will involve a simple
-// rename operation.
+// https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
//
// For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic,
// see Herb Sutter's explanation on
// (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/].
// (In general, reviewers should treat `new T(a,b)` with scrutiny.)
//
-// Example usage:
-//
-// auto p = make_unique<X>(args...); // 'p' is a std::unique_ptr<X>
-// auto pa = make_unique<X[]>(5); // 'pa' is a std::unique_ptr<X[]>
-//
-// Three overloads of `absl::make_unique` are required:
-//
-// - For non-array T:
-//
-// Allocates a T with `new T(std::forward<Args> args...)`,
-// forwarding all `args` to T's constructor.
-// Returns a `std::unique_ptr<T>` owning that object.
-//
-// - For an array of unknown bounds T[]:
-//
-// `absl::make_unique<>` will allocate an array T of type U[] with
-// `new U[n]()` and return a `std::unique_ptr<U[]>` owning that array.
-//
-// Note that 'U[n]()' is different from 'U[n]', and elements will be
-// value-initialized. Note as well that `std::unique_ptr` will perform its
-// own destruction of the array elements upon leaving scope, even though
-// the array [] does not have a default destructor.
-//
-// NOTE: an array of unknown bounds T[] may still be (and often will be)
-// initialized to have a size, and will still use this overload. E.g:
-//
-// auto my_array = absl::make_unique<int[]>(10);
-//
-// - For an array of known bounds T[N]:
-//
-// `absl::make_unique<>` is deleted (like with `std::make_unique<>`) as
-// this overload is not useful.
-//
-// NOTE: an array of known bounds T[N] is not considered a useful
-// construction, and may cause undefined behavior in templates. E.g:
-//
-// auto my_array = absl::make_unique<int[10]>();
-//
-// In those cases, of course, you can still use the overload above and
-// simply initialize it to its desired size:
-//
-// auto my_array = absl::make_unique<int[]>(10);
-
-// `absl::make_unique` overload for non-array types.
-template <typename T, typename... Args>
-typename memory_internal::MakeUniqueResult<T>::scalar make_unique(
- Args&&... args) {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-
-// `absl::make_unique` 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(size_t n) {
- return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]());
-}
-
-// `absl::make_unique` 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(
- Args&&... /* args */) = delete;
-#endif
+// Historical note: Abseil once provided a C++11 compatible implementation of
+// the C++14's `std::make_unique`. Now that C++11 support has been sunsetted,
+// `absl::make_unique` simply uses the STL-provided implementation. New code
+// should use `std::make_unique`.
+using std::make_unique;
// -----------------------------------------------------------------------------
// Function Template: RawPtr()
diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc
deleted file mode 100644
index 1df72614..00000000
--- a/absl/memory/memory_exception_safety_test.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// 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,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/memory/memory.h"
-
-#include "absl/base/config.h"
-
-#ifdef ABSL_HAVE_EXCEPTIONS
-
-#include "gtest/gtest.h"
-#include "absl/base/internal/exception_safety_testing.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace {
-
-constexpr int kLength = 50;
-using Thrower = testing::ThrowingValue<testing::TypeSpec::kEverythingThrows>;
-
-TEST(MakeUnique, CheckForLeaks) {
- constexpr int kValue = 321;
- auto tester = testing::MakeExceptionSafetyTester()
- .WithInitialValue(Thrower(kValue))
- // Ensures make_unique does not modify the input. The real
- // test, though, is ConstructorTracker checking for leaks.
- .WithContracts(testing::strong_guarantee);
-
- EXPECT_TRUE(tester.Test([](Thrower* thrower) {
- static_cast<void>(absl::make_unique<Thrower>(*thrower));
- }));
-
- EXPECT_TRUE(tester.Test([](Thrower* thrower) {
- static_cast<void>(absl::make_unique<Thrower>(std::move(*thrower)));
- }));
-
- // Test T[n] overload
- EXPECT_TRUE(tester.Test([&](Thrower*) {
- static_cast<void>(absl::make_unique<Thrower[]>(kLength));
- }));
-}
-
-} // namespace
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_HAVE_EXCEPTIONS
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index 14b8b982..6f01cdff 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -64,13 +64,6 @@ TEST(WrapUniqueTest, WrapUnique) {
EXPECT_EQ(0, DestructorVerifier::instance_count());
}
-TEST(MakeUniqueTest, Basic) {
- std::unique_ptr<std::string> p = absl::make_unique<std::string>();
- EXPECT_EQ("", *p);
- p = absl::make_unique<std::string>("hi");
- EXPECT_EQ("hi", *p);
-}
-
// InitializationVerifier fills in a pattern when allocated so we can
// distinguish between its default and value initialized states (without
// accessing truly uninitialized memory).
@@ -94,65 +87,6 @@ struct InitializationVerifier {
int b;
};
-TEST(Initialization, MakeUnique) {
- auto p = absl::make_unique<InitializationVerifier>();
-
- EXPECT_EQ(0, p->a);
- EXPECT_EQ(0, p->b);
-}
-
-TEST(Initialization, MakeUniqueArray) {
- auto p = absl::make_unique<InitializationVerifier[]>(2);
-
- EXPECT_EQ(0, p[0].a);
- EXPECT_EQ(0, p[0].b);
- EXPECT_EQ(0, p[1].a);
- EXPECT_EQ(0, p[1].b);
-}
-
-struct MoveOnly {
- MoveOnly() = default;
- explicit MoveOnly(int i1) : ip1{new int{i1}} {}
- MoveOnly(int i1, int i2) : ip1{new int{i1}}, ip2{new int{i2}} {}
- std::unique_ptr<int> ip1;
- std::unique_ptr<int> ip2;
-};
-
-struct AcceptMoveOnly {
- explicit AcceptMoveOnly(MoveOnly m) : m_(std::move(m)) {}
- MoveOnly m_;
-};
-
-TEST(MakeUniqueTest, MoveOnlyTypeAndValue) {
- using ExpectedType = std::unique_ptr<MoveOnly>;
- {
- auto p = absl::make_unique<MoveOnly>();
- static_assert(std::is_same<decltype(p), ExpectedType>::value,
- "unexpected return type");
- EXPECT_TRUE(!p->ip1);
- EXPECT_TRUE(!p->ip2);
- }
- {
- auto p = absl::make_unique<MoveOnly>(1);
- static_assert(std::is_same<decltype(p), ExpectedType>::value,
- "unexpected return type");
- EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
- EXPECT_TRUE(!p->ip2);
- }
- {
- auto p = absl::make_unique<MoveOnly>(1, 2);
- static_assert(std::is_same<decltype(p), ExpectedType>::value,
- "unexpected return type");
- EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
- EXPECT_TRUE(p->ip2 && *p->ip2 == 2);
- }
-}
-
-TEST(MakeUniqueTest, AcceptMoveOnly) {
- auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly());
- p = std::unique_ptr<AcceptMoveOnly>(new AcceptMoveOnly(MoveOnly()));
-}
-
struct ArrayWatch {
void* operator new[](size_t n) {
allocs().push_back(n);
@@ -165,38 +99,6 @@ struct ArrayWatch {
}
};
-TEST(MakeUniqueTest, Array) {
- // Ensure state is clean before we start so that these tests
- // are order-agnostic.
- ArrayWatch::allocs().clear();
-
- auto p = absl::make_unique<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(MakeUniqueTest, NotAmbiguousWithStdMakeUnique) {
- // Ensure that absl::make_unique is not ambiguous with std::make_unique.
- // In C++14 mode, the below call to make_unique has both types as candidates.
- struct TakesStdType {
- explicit TakesStdType(const std::vector<int>& vec) {}
- };
- using absl::make_unique;
- (void)make_unique<TakesStdType>(std::vector<int>());
-}
-
-#if 0
-// These tests shouldn't compile.
-TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
- auto m = MoveOnly();
- auto p = absl::make_unique<AcceptMoveOnly>(m);
-}
-TEST(MakeUniqueTestNC, KnownBoundArray) {
- auto p = absl::make_unique<ArrayWatch[5]>();
-}
-#endif
-
TEST(RawPtrTest, RawPointer) {
int i = 5;
EXPECT_EQ(&i, absl::RawPtr(&i));