tint/utils: Add Vector::Any(), Vector::All() and predicates

Can be used to write simple whole-vector comparision checks.

Change-Id: I441a7e8d6b626a5a32ef3db9043e771f792900d3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131746
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2023-05-09 15:10:05 +00:00 committed by Dawn LUCI CQ
parent 2fb010f909
commit 567a53e87c
6 changed files with 213 additions and 6 deletions

View File

@ -251,6 +251,7 @@ libtint_source_set("libtint_utils_src") {
"utils/hashset.h", "utils/hashset.h",
"utils/map.h", "utils/map.h",
"utils/math.h", "utils/math.h",
"utils/predicates.h",
"utils/scoped_assignment.h", "utils/scoped_assignment.h",
"utils/slice.h", "utils/slice.h",
"utils/string.cc", "utils/string.cc",
@ -1725,6 +1726,7 @@ if (tint_build_unittests) {
"utils/io/tmpfile_test.cc", "utils/io/tmpfile_test.cc",
"utils/map_test.cc", "utils/map_test.cc",
"utils/math_test.cc", "utils/math_test.cc",
"utils/predicates_test.cc",
"utils/result_test.cc", "utils/result_test.cc",
"utils/reverse_test.cc", "utils/reverse_test.cc",
"utils/scoped_assignment_test.cc", "utils/scoped_assignment_test.cc",

View File

@ -532,6 +532,7 @@ list(APPEND TINT_LIB_SRCS
utils/hashset.h utils/hashset.h
utils/map.h utils/map.h
utils/math.h utils/math.h
utils/predicates.h
utils/scoped_assignment.h utils/scoped_assignment.h
utils/slice.h utils/slice.h
utils/string.cc utils/string.cc
@ -1030,6 +1031,7 @@ if(TINT_BUILD_TESTS)
utils/hashset_test.cc utils/hashset_test.cc
utils/map_test.cc utils/map_test.cc
utils/math_test.cc utils/math_test.cc
utils/predicates_test.cc
utils/result_test.cc utils/result_test.cc
utils/reverse_test.cc utils/reverse_test.cc
utils/scoped_assignment_test.cc utils/scoped_assignment_test.cc

View File

@ -0,0 +1,78 @@
// Copyright 2023 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TINT_UTILS_PREDICATES_H_
#define SRC_TINT_UTILS_PREDICATES_H_
namespace tint::utils {
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is
/// equal to
/// @p value
template <typename T>
auto Eq(const T& value) {
return [value](const T& v) { return v == value; };
}
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is not
/// equal to @p value
template <typename T>
auto Ne(const T& value) {
return [value](const T& v) { return v != value; };
}
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is
/// greater than @p value
template <typename T>
auto Gt(const T& value) {
return [value](const T& v) { return v > value; };
}
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is
/// less than
/// @p value
template <typename T>
auto Lt(const T& value) {
return [value](const T& v) { return v < value; };
}
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is
/// greater or equal to @p value
template <typename T>
auto Ge(const T& value) {
return [value](const T& v) { return v >= value; };
}
/// @param value the value to compare against
/// @return a function with the signature `bool(const T&)` which returns true if the argument is
/// less than or equal to @p value
template <typename T>
auto Le(const T& value) {
return [value](const T& v) { return v <= value; };
}
/// @param ptr the pointer
/// @return true if the pointer argument is null.
static inline bool IsNull(const void* ptr) {
return ptr == nullptr;
}
} // namespace tint::utils
#endif // SRC_TINT_UTILS_PREDICATES_H_

View File

@ -0,0 +1,83 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/utils/predicates.h"
#include "gtest/gtest.h"
namespace tint::utils {
namespace {
TEST(PredicatesTest, Eq) {
auto pred = Eq(3);
EXPECT_FALSE(pred(1));
EXPECT_FALSE(pred(2));
EXPECT_TRUE(pred(3));
EXPECT_FALSE(pred(4));
EXPECT_FALSE(pred(5));
}
TEST(PredicatesTest, Ne) {
auto pred = Ne(3);
EXPECT_TRUE(pred(1));
EXPECT_TRUE(pred(2));
EXPECT_FALSE(pred(3));
EXPECT_TRUE(pred(4));
EXPECT_TRUE(pred(5));
}
TEST(PredicatesTest, Gt) {
auto pred = Gt(3);
EXPECT_FALSE(pred(1));
EXPECT_FALSE(pred(2));
EXPECT_FALSE(pred(3));
EXPECT_TRUE(pred(4));
EXPECT_TRUE(pred(5));
}
TEST(PredicatesTest, Lt) {
auto pred = Lt(3);
EXPECT_TRUE(pred(1));
EXPECT_TRUE(pred(2));
EXPECT_FALSE(pred(3));
EXPECT_FALSE(pred(4));
EXPECT_FALSE(pred(5));
}
TEST(PredicatesTest, Ge) {
auto pred = Ge(3);
EXPECT_FALSE(pred(1));
EXPECT_FALSE(pred(2));
EXPECT_TRUE(pred(3));
EXPECT_TRUE(pred(4));
EXPECT_TRUE(pred(5));
}
TEST(PredicatesTest, Le) {
auto pred = Le(3);
EXPECT_TRUE(pred(1));
EXPECT_TRUE(pred(2));
EXPECT_TRUE(pred(3));
EXPECT_FALSE(pred(4));
EXPECT_FALSE(pred(5));
}
TEST(PredicatesTest, IsNull) {
int i = 1;
EXPECT_TRUE(IsNull(nullptr));
EXPECT_FALSE(IsNull(&i));
}
} // namespace
} // namespace tint::utils

View File

@ -322,6 +322,20 @@ class Vector {
Sort([](auto& a, auto& b) { return a < b; }); Sort([](auto& a, auto& b) { return a < b; });
} }
/// @returns true if the predicate function returns true for any of the elements of the vector
/// @param pred a function-like with the signature `bool(T)`
template <typename PREDICATE>
bool Any(PREDICATE&& pred) const {
return std::any_of(begin(), end(), std::forward<PREDICATE>(pred));
}
/// @returns false if the predicate function returns false for any of the elements of the vector
/// @param pred a function-like with the signature `bool(T)`
template <typename PREDICATE>
bool All(PREDICATE&& pred) const {
return std::all_of(begin(), end(), std::forward<PREDICATE>(pred));
}
/// @returns true if the vector is empty. /// @returns true if the vector is empty.
bool IsEmpty() const { return impl_.slice.len == 0; } bool IsEmpty() const { return impl_.slice.len == 0; }

View File

@ -20,6 +20,7 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "src/tint/utils/bitcast.h" #include "src/tint/utils/bitcast.h"
#include "src/tint/utils/predicates.h"
#include "src/tint/utils/string_stream.h" #include "src/tint/utils/string_stream.h"
namespace tint::utils { namespace tint::utils {
@ -1788,6 +1789,38 @@ TEST(TintVectorTest, Equality) {
EXPECT_NE((Vector{2, 1}), (Vector{1, 2})); EXPECT_NE((Vector{2, 1}), (Vector{1, 2}));
} }
TEST(TintVectorTest, Sort) {
Vector vec{1, 5, 3, 4, 2};
vec.Sort();
EXPECT_THAT(vec, testing::ElementsAre(1, 2, 3, 4, 5));
}
TEST(TintVectorTest, Any) {
Vector vec{1, 7, 5, 9};
EXPECT_TRUE(vec.Any(Eq(1)));
EXPECT_FALSE(vec.Any(Eq(2)));
EXPECT_FALSE(vec.Any(Eq(3)));
EXPECT_FALSE(vec.Any(Eq(4)));
EXPECT_TRUE(vec.Any(Eq(5)));
EXPECT_FALSE(vec.Any(Eq(6)));
EXPECT_TRUE(vec.Any(Eq(7)));
EXPECT_FALSE(vec.Any(Eq(8)));
EXPECT_TRUE(vec.Any(Eq(9)));
}
TEST(TintVectorTest, All) {
Vector vec{1, 7, 5, 9};
EXPECT_FALSE(vec.All(Ne(1)));
EXPECT_TRUE(vec.All(Ne(2)));
EXPECT_TRUE(vec.All(Ne(3)));
EXPECT_TRUE(vec.All(Ne(4)));
EXPECT_FALSE(vec.All(Ne(5)));
EXPECT_TRUE(vec.All(Ne(6)));
EXPECT_FALSE(vec.All(Ne(7)));
EXPECT_TRUE(vec.All(Ne(8)));
EXPECT_FALSE(vec.All(Ne(9)));
}
TEST(TintVectorTest, ostream) { TEST(TintVectorTest, ostream) {
utils::StringStream ss; utils::StringStream ss;
ss << Vector{1, 2, 3}; ss << Vector{1, 2, 3};
@ -2005,12 +2038,6 @@ TEST(TintVectorRefTest, Index) {
EXPECT_EQ(vec_ref[1], "two"); EXPECT_EQ(vec_ref[1], "two");
} }
TEST(TintVectorRefTest, Sort) {
Vector vec{1, 5, 3, 4, 2};
vec.Sort();
EXPECT_THAT(vec, testing::ElementsAre(1, 2, 3, 4, 5));
}
TEST(TintVectorRefTest, SortPredicate) { TEST(TintVectorRefTest, SortPredicate) {
Vector vec{1, 5, 3, 4, 2}; Vector vec{1, 5, 3, 4, 2};
vec.Sort([](int a, int b) { return b < a; }); vec.Sort([](int a, int b) { return b < a; });
@ -2072,6 +2099,7 @@ TEST(TintVectorRefTest, ostream) {
ss << vec_ref; ss << vec_ref;
EXPECT_EQ(ss.str(), "[1, 2, 3]"); EXPECT_EQ(ss.str(), "[1, 2, 3]");
} }
} // namespace } // namespace
} // namespace tint::utils } // namespace tint::utils