diff options
Diffstat (limited to 'absl/container')
-rw-r--r-- | absl/container/BUILD.bazel | 3 | ||||
-rw-r--r-- | absl/container/fixed_array.h | 18 | ||||
-rw-r--r-- | absl/container/fixed_array_test.cc | 37 |
3 files changed, 51 insertions, 7 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 7d550cb16c5a..295f41250590 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -33,6 +33,7 @@ cc_library( "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:throw_delegate", + "//absl/memory", ], ) @@ -42,7 +43,6 @@ cc_test( copts = ABSL_TEST_COPTS + ["-fexceptions"], deps = [ ":fixed_array", - "//absl/base:core_headers", "//absl/base:exception_testing", "//absl/memory", "@com_google_googletest//:gtest_main", @@ -55,7 +55,6 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":fixed_array", - "//absl/base:core_headers", "//absl/base:exception_testing", "//absl/memory", "@com_google_googletest//:gtest_main", diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 58240b499a56..ec6fced16aba 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -47,6 +47,7 @@ #include "absl/base/macros.h" #include "absl/base/optimization.h" #include "absl/base/port.h" +#include "absl/memory/memory.h" namespace absl { @@ -107,6 +108,15 @@ class FixedArray { ? kInlineBytesDefault / sizeof(value_type) : inlined; + FixedArray(const FixedArray& other) : rep_(other.begin(), other.end()) {} + FixedArray(FixedArray&& other) noexcept( + // clang-format off + absl::allocator_is_nothrow<std::allocator<value_type>>::value && + // clang-format on + std::is_nothrow_move_constructible<value_type>::value) + : rep_(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end())) {} + // Creates an array object that can store `n` elements. // Note that trivially constructible elements will be uninitialized. explicit FixedArray(size_type n) : rep_(n) {} @@ -126,11 +136,9 @@ class FixedArray { ~FixedArray() {} - // Copy and move construction and assignment are deleted because (1) you can't - // copy or move an array, (2) assignment breaks the invariant that the size of - // a `FixedArray` never changes, and (3) there's no clear answer as to what - // should happen to a moved-from `FixedArray`. - FixedArray(const FixedArray&) = delete; + // Assignments are deleted because they break the invariant that the size of a + // `FixedArray` never changes. + void operator=(FixedArray&&) = delete; void operator=(const FixedArray&) = delete; // FixedArray::size() diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index 9e88eab0c696..b6782f517a6c 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -27,6 +27,8 @@ #include "absl/base/internal/exception_testing.h" #include "absl/memory/memory.h" +using ::testing::ElementsAreArray; + namespace { // Helper routine to determine if a absl::FixedArray used stack allocation. @@ -89,6 +91,41 @@ class ThreeInts { int ThreeInts::counter = 0; +TEST(FixedArrayTest, CopyCtor) { + absl::FixedArray<int, 10> on_stack(5); + std::iota(on_stack.begin(), on_stack.end(), 0); + absl::FixedArray<int, 10> stack_copy = on_stack; + EXPECT_THAT(stack_copy, ElementsAreArray(on_stack)); + EXPECT_TRUE(IsOnStack(stack_copy)); + + absl::FixedArray<int, 10> allocated(15); + std::iota(allocated.begin(), allocated.end(), 0); + absl::FixedArray<int, 10> alloced_copy = allocated; + EXPECT_THAT(alloced_copy, ElementsAreArray(allocated)); + EXPECT_FALSE(IsOnStack(alloced_copy)); +} + +TEST(FixedArrayTest, MoveCtor) { + absl::FixedArray<std::unique_ptr<int>, 10> on_stack(5); + for (int i = 0; i < 5; ++i) { + on_stack[i] = absl::make_unique<int>(i); + } + + absl::FixedArray<std::unique_ptr<int>, 10> stack_copy = std::move(on_stack); + for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i); + EXPECT_EQ(stack_copy.size(), on_stack.size()); + + absl::FixedArray<std::unique_ptr<int>, 10> allocated(15); + for (int i = 0; i < 15; ++i) { + allocated[i] = absl::make_unique<int>(i); + } + + absl::FixedArray<std::unique_ptr<int>, 10> alloced_copy = + std::move(allocated); + for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i); + EXPECT_EQ(allocated.size(), alloced_copy.size()); +} + TEST(FixedArrayTest, SmallObjects) { // Small object arrays { |