From 8c60bd522c9f6af50f2678748fe526b9ff8628e8 Mon Sep 17 00:00:00 2001 From: Weston Pace Date: Thu, 2 Jun 2022 10:26:03 -1000 Subject: [PATCH] ARROW-16743: Added the && operator to arrow::Status --- cpp/src/arrow/scalar.cc | 9 +++++---- cpp/src/arrow/status.h | 18 ++++++++++++++++++ cpp/src/arrow/status_test.cc | 19 ++++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/cpp/src/arrow/scalar.cc b/cpp/src/arrow/scalar.cc index 15304c012859..851d4aa334b0 100644 --- a/cpp/src/arrow/scalar.cc +++ b/cpp/src/arrow/scalar.cc @@ -75,15 +75,16 @@ struct ScalarHashImpl { } Status Visit(const DayTimeIntervalScalar& s) { - return StdHash(s.value.days) & StdHash(s.value.milliseconds); + return StdHash(s.value.days) && StdHash(s.value.milliseconds); } Status Visit(const MonthDayNanoIntervalScalar& s) { - return StdHash(s.value.days) & StdHash(s.value.months) & StdHash(s.value.nanoseconds); + return StdHash(s.value.days) && StdHash(s.value.months) && + StdHash(s.value.nanoseconds); } Status Visit(const Decimal128Scalar& s) { - return StdHash(s.value.low_bits()) & StdHash(s.value.high_bits()); + return StdHash(s.value.low_bits()) && StdHash(s.value.high_bits()); } Status Visit(const Decimal256Scalar& s) { @@ -140,7 +141,7 @@ struct ScalarHashImpl { Status ArrayHash(const Array& a) { return ArrayHash(*a.data()); } Status ArrayHash(const ArrayData& a) { - RETURN_NOT_OK(StdHash(a.length) & StdHash(a.GetNullCount())); + RETURN_NOT_OK(StdHash(a.length) && StdHash(a.GetNullCount())); if (a.buffers[0] != nullptr) { // We can't visit values without unboxing the whole array, so only hash // the null bitmap for now. diff --git a/cpp/src/arrow/status.h b/cpp/src/arrow/status.h index 056d60d6f327..cfb5e73060ec 100644 --- a/cpp/src/arrow/status.h +++ b/cpp/src/arrow/status.h @@ -150,6 +150,8 @@ class ARROW_MUST_USE_TYPE ARROW_EXPORT Status : public util::EqualityComparable< // AND the statuses. inline Status operator&(const Status& s) const noexcept; inline Status operator&(Status&& s) const noexcept; + inline Status operator&&(const Status& s) const noexcept; + inline Status operator&&(Status&& s) const noexcept; inline Status& operator&=(const Status& s) noexcept; inline Status& operator&=(Status&& s) noexcept; @@ -424,6 +426,22 @@ Status Status::operator&(Status&& s) const noexcept { } } +Status Status::operator&&(const Status& s) const noexcept { + if (ok()) { + return s; + } else { + return *this; + } +} + +Status Status::operator&&(Status&& s) const noexcept { + if (ok()) { + return std::move(s); + } else { + return *this; + } +} + Status& Status::operator&=(const Status& s) noexcept { if (ok() && !s.ok()) { CopyFrom(s); diff --git a/cpp/src/arrow/status_test.cc b/cpp/src/arrow/status_test.cc index a8e1d1ca9a84..4d8fd7fa3e81 100644 --- a/cpp/src/arrow/status_test.cc +++ b/cpp/src/arrow/status_test.cc @@ -93,11 +93,11 @@ TEST(StatusTest, AndStatus) { ASSERT_TRUE(res.IsInvalid()); // With rvalues - res = Status::OK() & Status::Invalid("foo"); + res = Status::OK() && Status::Invalid("foo"); ASSERT_TRUE(res.IsInvalid()); - res = Status::Invalid("foo") & Status::OK(); + res = Status::Invalid("foo") && Status::OK(); ASSERT_TRUE(res.IsInvalid()); - res = Status::Invalid("foo") & Status::IOError("bar"); + res = Status::Invalid("foo") && Status::IOError("bar"); ASSERT_TRUE(res.IsInvalid()); res = Status::OK(); @@ -109,6 +109,19 @@ TEST(StatusTest, AndStatus) { ASSERT_TRUE(res.IsInvalid()); } +Status PassingTaskWithSideEffect(bool* hit_side_effect) { + *hit_side_effect = true; + return Status::OK(); +} + +Status FailingTask() { return Status::Invalid("err"); } + +TEST(StatusTest, SortCircuitAndStatus) { + bool hit_side_effect = false; + Status res = PassingTaskWithSideEffect(&hit_side_effect) && FailingTask(); + ASSERT_TRUE(hit_side_effect); +} + TEST(StatusTest, TestEquality) { ASSERT_EQ(Status(), Status::OK()); ASSERT_EQ(Status::Invalid("error"), Status::Invalid("error"));