summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/container/btree_test.cc26
-rw-r--r--absl/container/internal/btree_container.h8
-rw-r--r--absl/flags/BUILD.bazel1
-rw-r--r--absl/status/internal/statusor_internal.h2
-rw-r--r--absl/status/statusor_test.cc11
-rw-r--r--absl/time/duration.cc3
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) {