diff options
-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 | ||||
-rw-r--r-- | absl/strings/str_cat.h | 3 | ||||
-rw-r--r-- | absl/strings/substitute.h | 14 |
5 files changed, 53 insertions, 22 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 7d550cb1..295f4125 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 58240b49..ec6fced1 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 9e88eab0..b6782f51 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 { diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 5b4c9baa..1cf7b11f 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -46,8 +46,7 @@ // You can convert to hexadecimal output rather than decimal output using the // `Hex` type contained here. To do so, pass `Hex(my_int)` as a parameter to // `StrCat()` or `StrAppend()`. You may specify a minimum hex field width using -// a `PadSpec` enum, so the equivalent of `StringPrintf("%04x", my_int)` is -// `absl::StrCat(absl::Hex(my_int, absl::kZeroPad4))`. +// a `PadSpec` enum. // // ----------------------------------------------------------------------------- diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index 76d6d8e9..5596a5db 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -45,17 +45,6 @@ // SubstituteAndAppend(&s, "My name is $0 and I am $1 years old.", "Bob", 5); // EXPECT_EQ("Hi. My name is Bob and I am 5 years old.", s); // -// Differences from `StringPrintf()`: -// * The format std::string does not identify the types of arguments. Instead, the -// arguments are implicitly converted to strings. See below for a list of -// accepted types. -// * Substitutions in the format std::string are identified by a '$' followed by a -// single digit. You can use arguments out-of-order and use the same -// argument multiple times. -// * A '$$' sequence in the format std::string means output a literal '$' -// character. -// * `Substitute()` is significantly faster than `StringPrintf()`. For very -// large strings, it may be orders of magnitude faster. // // Supported types: // * absl::string_view, std::string, const char* (null is equivalent to "") @@ -157,8 +146,7 @@ class Arg { Arg(bool value) // NOLINT(runtime/explicit) : piece_(value ? "true" : "false") {} // `void*` values, with the exception of `char*`, are printed as - // `StringPrintf()` with format "%p": e.g. ("0x<hex value>"). - // However, in the case of `nullptr`, "NULL" is printed. + // "0x<hex value>". However, in the case of `nullptr`, "NULL" is printed. Arg(const void* value); // NOLINT(runtime/explicit) Arg(const Arg&) = delete; |