This is an automated email from the ASF dual-hosted git repository.
westonpace pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 79563cf2f7 GH-15098: [C++] fix util::EqualityComparable to compile on
clang 15 (#33940)
79563cf2f7 is described below
commit 79563cf2f798f071e45c3154738388e821b2b02e
Author: Weston Pace <[email protected]>
AuthorDate: Thu Feb 16 20:16:27 2023 -0800
GH-15098: [C++] fix util::EqualityComparable to compile on clang 15 (#33940)
If you have an equality operator then C++20 then clang 15 expects it to be
symmetric. The util::EqualityComparable operator== was defined as:
`bool operator==(util::EqualityComparable<T>, T)`
and there is no equivalent:
`bool operator==(T, util::EqualityComparable<T>)`
This was later determined to be unintentional strictness and the [standard
was
clarified](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html).
This error was relaxed in clang 16. Equality only needs to be symmetric if
you want the compiler to provide `!=` for you (which we don't rely on).
However, it seems like a worthwhile fix, and it doesn't appear that Clang will
be backporting the fix to clang 15 (that is my interpretation of the fact that
clang lists the def [...]
Furthermore, the old definition allowed for
`Scalar::operator==(std::shared_ptr<Scalar> other)` (i.e. comparing with a
shared_ptr) and it isn't clear to me that should be allowed (it's generally
inconsistent with the rest of the code base). This change seems to have undone
that and I made no change to restore it (and instead fixed the references to
that odd equality operation).
BREAKING CHANGE: The functions `bool Scalar::Equals(const
std::shared_ptr<Scalar>&) const` and `bool Scalar::Equals(const
std::shared_ptr<Scalar>&, const EqualOptions&) const` have been removed.
Instead `bool Scalar::Equals(const Scalar&) const` and `bool
Scalar::Equals(const Scalar&, const EqualOptions&) const` should be used.
BREAKING CHANGE: `FileInfo::ToString` now includes the size and mtime.
* Closes: #15098
Authored-by: Weston Pace <[email protected]>
Signed-off-by: Weston Pace <[email protected]>
---
c_glib/arrow-glib/scalar.cpp | 4 +-
c_glib/test/test-file-info.rb | 2 +-
cpp/src/arrow/compute/api_vector.h | 3 --
cpp/src/arrow/compute/exec/expression.cc | 4 +-
cpp/src/arrow/compute/exec/source_node.cc | 2 +-
cpp/src/arrow/compute/function.h | 3 --
cpp/src/arrow/compute/kernels/test_util.cc | 2 +-
cpp/src/arrow/dataset/file_parquet.cc | 2 +-
cpp/src/arrow/filesystem/filesystem.cc | 3 +-
cpp/src/arrow/filesystem/gcsfs_test.cc | 8 +---
cpp/src/arrow/scalar.h | 2 -
cpp/src/arrow/scalar_test.cc | 76 +++++++++++++++---------------
cpp/src/arrow/testing/json_integration.cc | 2 +-
cpp/src/arrow/testing/matchers.h | 4 +-
cpp/src/arrow/util/compare.h | 6 +--
r/src/scalar.cpp | 2 +-
16 files changed, 58 insertions(+), 67 deletions(-)
diff --git a/c_glib/arrow-glib/scalar.cpp b/c_glib/arrow-glib/scalar.cpp
index 24f9b2caad..401d0b6dfb 100644
--- a/c_glib/arrow-glib/scalar.cpp
+++ b/c_glib/arrow-glib/scalar.cpp
@@ -340,10 +340,10 @@ garrow_scalar_equal_options(GArrowScalar *scalar,
if (is_approx) {
return arrow_scalar->ApproxEquals(*arrow_other_scalar, *arrow_options);
} else {
- return arrow_scalar->Equals(arrow_other_scalar, *arrow_options);
+ return arrow_scalar->Equals(*arrow_other_scalar, *arrow_options);
}
} else {
- return arrow_scalar->Equals(arrow_other_scalar);
+ return arrow_scalar->Equals(*arrow_other_scalar);
}
}
diff --git a/c_glib/test/test-file-info.rb b/c_glib/test/test-file-info.rb
index e6a3a0d62a..64633e2e67 100644
--- a/c_glib/test/test-file-info.rb
+++ b/c_glib/test/test-file-info.rb
@@ -164,7 +164,7 @@ class TestFileInfo < Test::Unit::TestCase
end
test("#to_s") do
- assert_equal("FileInfo(FileType::Unknown, )",
+ assert_equal("FileInfo(FileType::Unknown, , -1, -1)",
@file_info.to_s)
end
end
diff --git a/cpp/src/arrow/compute/api_vector.h
b/cpp/src/arrow/compute/api_vector.h
index 88331b6e59..365ca0a684 100644
--- a/cpp/src/arrow/compute/api_vector.h
+++ b/cpp/src/arrow/compute/api_vector.h
@@ -101,9 +101,6 @@ class ARROW_EXPORT SortKey : public
util::EqualityComparable<SortKey> {
explicit SortKey(FieldRef target, SortOrder order = SortOrder::Ascending)
: target(std::move(target)), order(order) {}
- using util::EqualityComparable<SortKey>::Equals;
- using util::EqualityComparable<SortKey>::operator==;
- using util::EqualityComparable<SortKey>::operator!=;
bool Equals(const SortKey& other) const;
std::string ToString() const;
diff --git a/cpp/src/arrow/compute/exec/expression.cc
b/cpp/src/arrow/compute/exec/expression.cc
index 4d060f34e3..b5e5bf6038 100644
--- a/cpp/src/arrow/compute/exec/expression.cc
+++ b/cpp/src/arrow/compute/exec/expression.cc
@@ -225,7 +225,7 @@ bool Expression::Equals(const Expression& other) const {
// is equal to the literal NaN (e.g. the expressions are equal even if
// the values are not)
EqualOptions equal_options = EqualOptions::Defaults().nans_equal(true);
- return lit->scalar()->Equals(other.literal()->scalar(), equal_options);
+ return lit->scalar()->Equals(*other.literal()->scalar(), equal_options);
}
if (auto ref = field_ref()) {
@@ -248,7 +248,7 @@ bool Expression::Equals(const Expression& other) const {
if (call->options == other_call->options) return true;
if (call->options && other_call->options) {
- return call->options->Equals(other_call->options);
+ return call->options->Equals(*other_call->options);
}
return false;
}
diff --git a/cpp/src/arrow/compute/exec/source_node.cc
b/cpp/src/arrow/compute/exec/source_node.cc
index 426063a3c1..5be35f3360 100644
--- a/cpp/src/arrow/compute/exec/source_node.cc
+++ b/cpp/src/arrow/compute/exec/source_node.cc
@@ -86,7 +86,7 @@ struct SourceNode : ExecNode, public TracedNode {
batch_count_ += num_batches;
}
plan_->query_context()->ScheduleTask(
- [=]() {
+ [this, morsel_length, use_legacy_batching, morsel]() {
int64_t offset = 0;
do {
int64_t batch_size =
diff --git a/cpp/src/arrow/compute/function.h b/cpp/src/arrow/compute/function.h
index 8a1b0da424..333c9a65c5 100644
--- a/cpp/src/arrow/compute/function.h
+++ b/cpp/src/arrow/compute/function.h
@@ -65,9 +65,6 @@ class ARROW_EXPORT FunctionOptions : public
util::EqualityComparable<FunctionOpt
const char* type_name() const { return options_type()->type_name(); }
bool Equals(const FunctionOptions& other) const;
- using util::EqualityComparable<FunctionOptions>::Equals;
- using util::EqualityComparable<FunctionOptions>::operator==;
- using util::EqualityComparable<FunctionOptions>::operator!=;
std::string ToString() const;
std::unique_ptr<FunctionOptions> Copy() const;
/// \brief Serialize an options struct to a buffer.
diff --git a/cpp/src/arrow/compute/kernels/test_util.cc
b/cpp/src/arrow/compute/kernels/test_util.cc
index 9341c35b1a..23d0fd18d5 100644
--- a/cpp/src/arrow/compute/kernels/test_util.cc
+++ b/cpp/src/arrow/compute/kernels/test_util.cc
@@ -85,7 +85,7 @@ void CheckScalar(std::string func_name, const ScalarVector&
inputs,
std::shared_ptr<Scalar> expected, const FunctionOptions*
options) {
ASSERT_OK_AND_ASSIGN(Datum out, CallFunction(func_name, GetDatums(inputs),
options));
ValidateOutput(out);
- if (!out.scalar()->Equals(expected)) {
+ if (!out.scalar()->Equals(*expected)) {
std::string summary = func_name + "(";
for (const auto& input : inputs) {
summary += input->ToString() + ",";
diff --git a/cpp/src/arrow/dataset/file_parquet.cc
b/cpp/src/arrow/dataset/file_parquet.cc
index 2ea6f76784..3a9931cf2a 100644
--- a/cpp/src/arrow/dataset/file_parquet.cc
+++ b/cpp/src/arrow/dataset/file_parquet.cc
@@ -303,7 +303,7 @@ std::optional<compute::Expression>
ParquetFileFragment::EvaluateStatisticsAsExpr
min = maybe_min.MoveValueUnsafe();
max = maybe_max.MoveValueUnsafe();
- if (min->Equals(max)) {
+ if (min->Equals(*max)) {
auto single_value = compute::equal(field_expr,
compute::literal(std::move(min)));
if (statistics.null_count() == 0) {
diff --git a/cpp/src/arrow/filesystem/filesystem.cc
b/cpp/src/arrow/filesystem/filesystem.cc
index c8fa4d1c37..73b94d3828 100644
--- a/cpp/src/arrow/filesystem/filesystem.cc
+++ b/cpp/src/arrow/filesystem/filesystem.cc
@@ -116,7 +116,8 @@ std::string FileInfo::ToString() const {
}
std::ostream& operator<<(std::ostream& os, const FileInfo& info) {
- return os << "FileInfo(" << info.type() << ", " << info.path() << ")";
+ return os << "FileInfo(" << info.type() << ", " << info.path() << ", " <<
info.size()
+ << ", " << info.mtime().time_since_epoch().count() << ")";
}
std::string FileInfo::extension() const {
diff --git a/cpp/src/arrow/filesystem/gcsfs_test.cc
b/cpp/src/arrow/filesystem/gcsfs_test.cc
index af22087530..15d596dc0b 100644
--- a/cpp/src/arrow/filesystem/gcsfs_test.cc
+++ b/cpp/src/arrow/filesystem/gcsfs_test.cc
@@ -46,7 +46,6 @@
#include <gtest/gtest.h>
#include <array>
-#include <iostream>
#include <random>
#include <string>
#include <thread>
@@ -61,10 +60,6 @@
namespace arrow {
namespace fs {
-/// Custom comparison for FileInfo, we need this to use complex googletest
matchers.
-inline bool operator==(const FileInfo& a, const FileInfo& b) {
- return a.path() == b.path() && a.type() == b.type();
-}
namespace {
@@ -268,7 +263,8 @@ class GcsIntegrationTest : public ::testing::Test {
const auto filename =
internal::ConcatAbstractPath(folder, "test-file-" +
std::to_string(i));
CreateFile(fs.get(), filename, filename);
- result.contents.push_back(arrow::fs::File(filename));
+ ARROW_ASSIGN_OR_RAISE(auto file_info, fs->GetFileInfo(filename));
+ result.contents.push_back(std::move(file_info));
}
}
return result;
diff --git a/cpp/src/arrow/scalar.h b/cpp/src/arrow/scalar.h
index cf852dff36..a6c959c4d9 100644
--- a/cpp/src/arrow/scalar.h
+++ b/cpp/src/arrow/scalar.h
@@ -60,8 +60,6 @@ struct ARROW_EXPORT Scalar : public
std::enable_shared_from_this<Scalar>,
/// \brief Whether the value is valid (not null) or not
bool is_valid = false;
- using util::EqualityComparable<Scalar>::operator==;
- using util::EqualityComparable<Scalar>::Equals;
bool Equals(const Scalar& other,
const EqualOptions& options = EqualOptions::Defaults()) const;
diff --git a/cpp/src/arrow/scalar_test.cc b/cpp/src/arrow/scalar_test.cc
index 404bbc84c5..5c2f1f1e3b 100644
--- a/cpp/src/arrow/scalar_test.cc
+++ b/cpp/src/arrow/scalar_test.cc
@@ -437,10 +437,10 @@ class TestDecimalScalar : public ::testing::Test {
ASSERT_OK(first->ValidateFull());
ASSERT_OK(second->ValidateFull());
- ASSERT_TRUE(first->Equals(null));
+ ASSERT_TRUE(first->Equals(*null));
ASSERT_FALSE(first->Equals(pi));
ASSERT_TRUE(second->Equals(pi));
- ASSERT_FALSE(second->Equals(null));
+ ASSERT_FALSE(second->Equals(*null));
auto invalid = ScalarType(ValueType::GetMaxValue(6),
std::make_shared<T>(5, 2));
EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid,
@@ -556,7 +556,7 @@ class TestStringScalar : public ::testing::Test {
ASSERT_OK(one->ValidateFull());
ASSERT_OK(two->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(type_)));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(type_)));
ASSERT_TRUE(one->Equals(ScalarType("one")));
ASSERT_TRUE(two->Equals(ScalarType("two")));
ASSERT_FALSE(two->Equals(Int64Scalar(1)));
@@ -632,7 +632,7 @@ TEST(TestFixedSizeBinaryScalar, Basics) {
ASSERT_OK(one->ValidateFull());
ASSERT_OK(two->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(ty)));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(ty)));
ASSERT_TRUE(one->Equals(FixedSizeBinaryScalar(Buffer::FromString("one"),
ty)));
ASSERT_TRUE(two->Equals(FixedSizeBinaryScalar(Buffer::FromString("two"),
ty)));
}
@@ -695,10 +695,10 @@ TEST(TestDateScalars, Basics) {
ASSERT_OK(null->ValidateFull());
ASSERT_OK(last->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(ty)));
- ASSERT_TRUE(first->Equals(MakeScalar(ty, 5).ValueOrDie()));
- ASSERT_TRUE(last->Equals(MakeScalar(ty, 42).ValueOrDie()));
- ASSERT_FALSE(last->Equals(MakeScalar("string")));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(ty)));
+ ASSERT_TRUE(first->Equals(*MakeScalar(ty, 5).ValueOrDie()));
+ ASSERT_TRUE(last->Equals(*MakeScalar(ty, 42).ValueOrDie()));
+ ASSERT_FALSE(last->Equals(*MakeScalar("string")));
}
}
@@ -751,10 +751,10 @@ TEST(TestTimeScalars, Basics) {
ASSERT_OK(null->ValidateFull());
ASSERT_OK(last->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(ty)));
- ASSERT_TRUE(first->Equals(MakeScalar(ty, 5).ValueOrDie()));
- ASSERT_TRUE(last->Equals(MakeScalar(ty, 42).ValueOrDie()));
- ASSERT_FALSE(last->Equals(MakeScalar("string")));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(ty)));
+ ASSERT_TRUE(first->Equals(*MakeScalar(ty, 5).ValueOrDie()));
+ ASSERT_TRUE(last->Equals(*MakeScalar(ty, 42).ValueOrDie()));
+ ASSERT_FALSE(last->Equals(*MakeScalar("string")));
}
}
@@ -819,10 +819,10 @@ TEST(TestTimestampScalars, Basics) {
ASSERT_OK(null->ValidateFull());
ASSERT_OK(last->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(ty)));
- ASSERT_TRUE(first->Equals(MakeScalar(ty, 5).ValueOrDie()));
- ASSERT_TRUE(last->Equals(MakeScalar(ty, 42).ValueOrDie()));
- ASSERT_FALSE(last->Equals(MakeScalar(int64(), 42).ValueOrDie()));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(ty)));
+ ASSERT_TRUE(first->Equals(*MakeScalar(ty, 5).ValueOrDie()));
+ ASSERT_TRUE(last->Equals(*MakeScalar(ty, 42).ValueOrDie()));
+ ASSERT_FALSE(last->Equals(*MakeScalar(int64(), 42).ValueOrDie()));
}
}
@@ -909,9 +909,9 @@ TEST(TestDurationScalars, Basics) {
ASSERT_OK(null->ValidateFull());
ASSERT_OK(last->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(ty)));
- ASSERT_TRUE(first->Equals(MakeScalar(ty, 5).ValueOrDie()));
- ASSERT_TRUE(last->Equals(MakeScalar(ty, 42).ValueOrDie()));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(ty)));
+ ASSERT_TRUE(first->Equals(*MakeScalar(ty, 5).ValueOrDie()));
+ ASSERT_TRUE(last->Equals(*MakeScalar(ty, 42).ValueOrDie()));
}
EXPECT_EQ(DurationScalar{std::chrono::nanoseconds{1235}},
@@ -972,9 +972,9 @@ TEST(TestMonthIntervalScalars, Basics) {
ASSERT_OK(null->ValidateFull());
ASSERT_OK(last->ValidateFull());
- ASSERT_TRUE(null->Equals(CheckMakeNullScalar(type)));
- ASSERT_TRUE(first->Equals(MakeScalar(type, 5).ValueOrDie()));
- ASSERT_TRUE(last->Equals(MakeScalar(type, 42).ValueOrDie()));
+ ASSERT_TRUE(null->Equals(*CheckMakeNullScalar(type)));
+ ASSERT_TRUE(first->Equals(*MakeScalar(type, 5).ValueOrDie()));
+ ASSERT_TRUE(last->Equals(*MakeScalar(type, 42).ValueOrDie()));
}
TEST(TestDayTimeIntervalScalars, Basics) {
@@ -1164,8 +1164,8 @@ TEST(TestStructScalar, FieldAccess) {
ASSERT_RAISES(Invalid, abc.field("c").status());
ASSERT_OK_AND_ASSIGN(auto d, abc.field("d"));
- ASSERT_TRUE(d->Equals(MakeNullScalar(int64())));
- ASSERT_FALSE(d->Equals(MakeScalar(int64(), 12).ValueOrDie()));
+ ASSERT_TRUE(d->Equals(*MakeNullScalar(int64())));
+ ASSERT_FALSE(d->Equals(*MakeScalar(int64(), 12).ValueOrDie()));
}
TEST(TestStructScalar, NullScalar) {
@@ -1269,25 +1269,25 @@ TEST(TestDictionaryScalar, Basics) {
auto encoded_null,
checked_cast<const DictionaryScalar&>(*scalar_null).GetEncodedValue());
ASSERT_OK(encoded_null->ValidateFull());
- ASSERT_TRUE(encoded_null->Equals(MakeNullScalar(utf8())));
+ ASSERT_TRUE(encoded_null->Equals(*MakeNullScalar(utf8())));
ASSERT_OK_AND_ASSIGN(
auto encoded_null_value,
checked_cast<const
DictionaryScalar&>(scalar_null_value).GetEncodedValue());
ASSERT_OK(encoded_null_value->ValidateFull());
- ASSERT_TRUE(encoded_null_value->Equals(MakeNullScalar(utf8())));
+ ASSERT_TRUE(encoded_null_value->Equals(*MakeNullScalar(utf8())));
ASSERT_OK_AND_ASSIGN(
auto encoded_alpha,
checked_cast<const DictionaryScalar&>(scalar_alpha).GetEncodedValue());
ASSERT_OK(encoded_alpha->ValidateFull());
- ASSERT_TRUE(encoded_alpha->Equals(MakeScalar("alpha")));
+ ASSERT_TRUE(encoded_alpha->Equals(*MakeScalar("alpha")));
ASSERT_OK_AND_ASSIGN(
auto encoded_gamma,
checked_cast<const DictionaryScalar&>(scalar_gamma).GetEncodedValue());
ASSERT_OK(encoded_gamma->ValidateFull());
- ASSERT_TRUE(encoded_gamma->Equals(MakeScalar("gamma")));
+ ASSERT_TRUE(encoded_gamma->Equals(*MakeScalar("gamma")));
// test Array.GetScalar
DictionaryArray arr(ty, ArrayFromJSON(index_ty, "[2, 0, 1, null]"), dict);
@@ -1306,7 +1306,7 @@ TEST(TestDictionaryScalar, Basics) {
ASSERT_TRUE(first->Equals(scalar_gamma));
ASSERT_TRUE(second->Equals(scalar_alpha));
- ASSERT_TRUE(last->Equals(scalar_null));
+ ASSERT_TRUE(last->Equals(*scalar_null));
auto first_dict_scalar = checked_cast<const DictionaryScalar&>(*first);
ASSERT_TRUE(first_dict_scalar.value.dictionary->Equals(arr.dictionary()));
@@ -1397,7 +1397,7 @@ TEST(TestDictionaryScalar, Cast) {
AssertScalarsEqual(*encoded_alpha, *roundtripped_alpha);
// dictionaries differ, though encoded values are identical
- ASSERT_FALSE(alpha_dict.Equals(cast_alpha));
+ ASSERT_FALSE(alpha_dict.Equals(*cast_alpha));
}
}
}
@@ -1415,7 +1415,7 @@ void CheckGetValidUnionScalar(const Array& arr, int64_t
index, const Scalar& exp
void CheckGetNullUnionScalar(const Array& arr, int64_t index) {
ASSERT_OK_AND_ASSIGN(auto scalar, arr.GetScalar(index));
- ASSERT_TRUE(scalar->Equals(MakeNullScalar(arr.type())));
+ ASSERT_TRUE(scalar->Equals(*MakeNullScalar(arr.type())));
ASSERT_FALSE(scalar->is_valid);
ASSERT_FALSE(checked_cast<const
UnionScalar&>(*scalar).child_value()->is_valid);
@@ -1535,17 +1535,17 @@ class TestUnionScalar : public ::testing::Test {
void TestEquals() {
// Differing values
- ASSERT_FALSE(union_alpha_->Equals(union_beta_));
- ASSERT_FALSE(union_two_->Equals(union_three_));
+ ASSERT_FALSE(union_alpha_->Equals(*union_beta_));
+ ASSERT_FALSE(union_two_->Equals(*union_three_));
// Differing validities
- ASSERT_FALSE(union_alpha_->Equals(union_string_null_));
+ ASSERT_FALSE(union_alpha_->Equals(*union_string_null_));
// Differing types
- ASSERT_FALSE(union_alpha_->Equals(union_two_));
- ASSERT_FALSE(union_alpha_->Equals(union_other_two_));
+ ASSERT_FALSE(union_alpha_->Equals(*union_two_));
+ ASSERT_FALSE(union_alpha_->Equals(*union_other_two_));
// Type codes don't count when comparing union scalars: the underlying
values
// are identical even though their provenance is different.
- ASSERT_TRUE(union_two_->Equals(union_other_two_));
- ASSERT_TRUE(union_string_null_->Equals(union_number_null_));
+ ASSERT_TRUE(union_two_->Equals(*union_other_two_));
+ ASSERT_TRUE(union_string_null_->Equals(*union_number_null_));
}
void TestMakeNullScalar() {
diff --git a/cpp/src/arrow/testing/json_integration.cc
b/cpp/src/arrow/testing/json_integration.cc
index 2af094a781..a6bed8ca19 100644
--- a/cpp/src/arrow/testing/json_integration.cc
+++ b/cpp/src/arrow/testing/json_integration.cc
@@ -146,7 +146,7 @@ class IntegrationJsonReader::Impl {
RETURN_NOT_OK(json::ReadSchema(doc_, pool_, &dictionary_memo_, &schema_));
- auto it = doc_.FindMember("batches");
+ auto it = std::as_const(doc_).FindMember("batches");
RETURN_NOT_ARRAY("batches", it, doc_);
record_batches_ = &it->value;
diff --git a/cpp/src/arrow/testing/matchers.h b/cpp/src/arrow/testing/matchers.h
index 34792525a7..b4625b3922 100644
--- a/cpp/src/arrow/testing/matchers.h
+++ b/cpp/src/arrow/testing/matchers.h
@@ -71,6 +71,8 @@ class AnyOfJSONMatcher {
template <typename arg_type>
operator testing::Matcher<arg_type>() const { // NOLINT runtime/explicit
struct Impl : testing::MatcherInterface<const arg_type&> {
+ static_assert(std::is_same<arg_type, std::shared_ptr<Scalar>>(),
+ "AnyOfJSON only supported for std::shared_ptr<Scalar>");
Impl(std::shared_ptr<DataType> type, std::string array_json)
: type_(std::move(type)), array_json_(std::move(array_json)) {
array = ArrayFromJSON(type_, array_json_);
@@ -98,7 +100,7 @@ class AnyOfJSONMatcher {
return false;
}
- if (scalar->Equals(arg)) return true;
+ if (scalar->Equals(*arg)) return true;
}
*result_listener << "Argument scalar: '" << arg->ToString()
<< "' matches no scalar from " << array->ToString();
diff --git a/cpp/src/arrow/util/compare.h b/cpp/src/arrow/util/compare.h
index 6477bf139f..0594b6002f 100644
--- a/cpp/src/arrow/util/compare.h
+++ b/cpp/src/arrow/util/compare.h
@@ -47,12 +47,12 @@ class EqualityComparable {
struct PtrsEqual {
bool operator()(const std::shared_ptr<T>& l, const std::shared_ptr<T>& r)
const {
- return l->Equals(r);
+ return l->Equals(*r);
}
};
- bool operator==(const T& other) const { return cast().Equals(other); }
- bool operator!=(const T& other) const { return !(cast() == other); }
+ friend bool operator==(T const& a, T const& b) { return a.Equals(b); }
+ friend bool operator!=(T const& a, T const& b) { return !(a == b); }
private:
const T& cast() const { return static_cast<const T&>(*this); }
diff --git a/r/src/scalar.cpp b/r/src/scalar.cpp
index 0fdf5bddbb..c78b5c1405 100644
--- a/r/src/scalar.cpp
+++ b/r/src/scalar.cpp
@@ -83,7 +83,7 @@ std::shared_ptr<arrow::DataType> Scalar__type(const
std::shared_ptr<arrow::Scala
// [[arrow::export]]
bool Scalar__Equals(const std::shared_ptr<arrow::Scalar>& lhs,
const std::shared_ptr<arrow::Scalar>& rhs) {
- return lhs->Equals(rhs);
+ return lhs->Equals(*rhs);
}
// [[arrow::export]]