diff options
-rw-r--r-- | absl/container/btree_test.cc | 26 | ||||
-rw-r--r-- | absl/container/internal/btree_container.h | 8 | ||||
-rw-r--r-- | absl/flags/BUILD.bazel | 1 | ||||
-rw-r--r-- | absl/status/internal/statusor_internal.h | 2 | ||||
-rw-r--r-- | absl/status/statusor_test.cc | 11 | ||||
-rw-r--r-- | absl/time/duration.cc | 3 |
6 files changed, 44 insertions, 7 deletions
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index 1bfa0c20..b6c11ea1 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -55,6 +55,7 @@ using ::testing::ElementsAreArray; using ::testing::IsEmpty; using ::testing::IsNull; using ::testing::Pair; +using ::testing::SizeIs; template <typename T, typename U> void CheckPairEquals(const T &x, const U &y) { @@ -2109,6 +2110,31 @@ TEST(Btree, MergeIntoMultiMapsWithDifferentComparators) { Pair(4, 1), Pair(4, 4), Pair(5, 5))); } +TEST(Btree, MergeIntoSetMovableOnly) { + absl::btree_set<MovableOnlyInstance> src; + src.insert(MovableOnlyInstance(1)); + absl::btree_multiset<MovableOnlyInstance> dst1; + dst1.insert(MovableOnlyInstance(2)); + absl::btree_set<MovableOnlyInstance> dst2; + + // Test merge into multiset. + dst1.merge(src); + + EXPECT_TRUE(src.empty()); + // ElementsAre/ElementsAreArray don't work with move-only types. + ASSERT_THAT(dst1, SizeIs(2)); + EXPECT_EQ(*dst1.begin(), MovableOnlyInstance(1)); + EXPECT_EQ(*std::next(dst1.begin()), MovableOnlyInstance(2)); + + // Test merge into set. + dst2.merge(dst1); + + EXPECT_TRUE(dst1.empty()); + ASSERT_THAT(dst2, SizeIs(2)); + EXPECT_EQ(*dst2.begin(), MovableOnlyInstance(1)); + EXPECT_EQ(*std::next(dst2.begin()), MovableOnlyInstance(2)); +} + struct KeyCompareToWeakOrdering { template <typename T> absl::weak_ordering operator()(const T &a, const T &b) const { diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 137614f8..279024d3 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -151,7 +151,6 @@ class btree_container { return extract(iterator(position)); } - public: // Utility routines. void clear() { tree_.clear(); } void swap(btree_container &other) { tree_.swap(other.tree_); } @@ -344,7 +343,7 @@ class btree_set_container : public btree_container<Tree> { int> = 0> void merge(btree_container<T> &src) { // NOLINT for (auto src_it = src.begin(); src_it != src.end();) { - if (insert(std::move(*src_it)).second) { + if (insert(std::move(params_type::element(src_it.slot()))).second) { src_it = src.erase(src_it); } else { ++src_it; @@ -627,8 +626,9 @@ class btree_multiset_container : public btree_container<Tree> { typename T::params_type::is_map_container>>::value, int> = 0> void merge(btree_container<T> &src) { // NOLINT - insert(std::make_move_iterator(src.begin()), - std::make_move_iterator(src.end())); + for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it) { + insert(std::move(params_type::element(src_it.slot()))); + } src.clear(); } diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 62fb9a8b..9de9e223 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -114,7 +114,6 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, - visibility = ["//visibility:private"], deps = [ "//absl/base:config", "//absl/base:fast_type_id", diff --git a/absl/status/internal/statusor_internal.h b/absl/status/internal/statusor_internal.h index 96e41da5..7cc76256 100644 --- a/absl/status/internal/statusor_internal.h +++ b/absl/status/internal/statusor_internal.h @@ -215,7 +215,7 @@ class StatusOrData { template <typename U, absl::enable_if_t<std::is_constructible<absl::Status, U&&>::value, int> = 0> - explicit StatusOrData(U&& v) : status_(v) { + explicit StatusOrData(U&& v) : status_(std::forward<U>(v)) { EnsureNotOk(); } diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc index 5e4b2687..c2e8fb7e 100644 --- a/absl/status/statusor_test.cc +++ b/absl/status/statusor_test.cc @@ -292,6 +292,17 @@ TEST(StatusOr, TestDefaultCtor) { EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); } +TEST(StatusOr, StatusCtorForwards) { + absl::Status status(absl::StatusCode::kInternal, "Some error"); + + EXPECT_EQ(absl::StatusOr<int>(status).status().message(), "Some error"); + EXPECT_EQ(status.message(), "Some error"); + + EXPECT_EQ(absl::StatusOr<int>(std::move(status)).status().message(), + "Some error"); + EXPECT_NE(status.message(), "Some error"); +} + // Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`, // which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether // exceptions are enabled. diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 952cc093..eca1a6d9 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -763,7 +763,8 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit // (milli-, micro-, or nanoseconds) to ensure that the leading digit -// is non-zero. The zero duration formats as 0, with no unit. +// is non-zero. +// Unlike Go, we format the zero duration as 0, with no unit. std::string FormatDuration(Duration d) { const Duration min_duration = Seconds(kint64min); if (d == min_duration) { |