Commit 9f128f4e authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[base] Remove base::fold and base::all

They can be replaced by std::conjunction and c++17 folding expressions.

R=tebbi@chromium.org

Bug: v8:12425
Change-Id: I109ac904245aab431f11752eff5129fd4361de8a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3570428Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79843}
parent 16b5fc3c
...@@ -60,19 +60,6 @@ struct has_output_operator< ...@@ -60,19 +60,6 @@ struct has_output_operator<
T, TStream, decltype(void(std::declval<TStream&>() << std::declval<T>()))> T, TStream, decltype(void(std::declval<TStream&>() << std::declval<T>()))>
: std::true_type {}; : std::true_type {};
// Fold all arguments from left to right with a given function.
template <typename Func, typename T>
constexpr auto fold(Func func, T&& t) {
return std::forward<T>(t);
}
template <typename Func, typename T1, typename T2, typename... Ts>
constexpr auto fold(Func func, T1&& first, T2&& second, Ts&&... more) {
auto&& folded = func(std::forward<T1>(first), std::forward<T2>(second));
return fold(std::move(func), std::forward<decltype(folded)>(folded),
std::forward<Ts>(more)...);
}
// {is_same<Ts...>::value} is true if all Ts are the same, false otherwise. // {is_same<Ts...>::value} is true if all Ts are the same, false otherwise.
template <typename... Ts> template <typename... Ts>
struct is_same : public std::false_type {}; struct is_same : public std::false_type {};
...@@ -83,12 +70,6 @@ struct is_same<T> : public std::true_type {}; ...@@ -83,12 +70,6 @@ struct is_same<T> : public std::true_type {};
template <typename T, typename... Ts> template <typename T, typename... Ts>
struct is_same<T, T, Ts...> : public is_same<T, Ts...> {}; struct is_same<T, T, Ts...> : public is_same<T, Ts...> {};
// Returns true, iff all values (implicitly converted to bool) are trueish.
template <typename... Args>
constexpr bool all(Args... rest) {
return fold(std::logical_and<>{}, true, rest...);
}
} // namespace base } // namespace base
} // namespace v8 } // namespace v8
......
...@@ -26,12 +26,8 @@ class V8_EXPORT_PRIVATE CPURegList { ...@@ -26,12 +26,8 @@ class V8_EXPORT_PRIVATE CPURegList {
public: public:
template <typename... CPURegisters> template <typename... CPURegisters>
explicit CPURegList(CPURegister reg0, CPURegisters... regs) explicit CPURegList(CPURegister reg0, CPURegisters... regs)
: list_(base::fold( : list_(((uint64_t{1} << reg0.code()) | ... |
[](uint64_t acc, CPURegister v) { (regs.is_valid() ? uint64_t{1} << regs.code() : 0))),
if (!v.is_valid()) return acc;
return acc | (uint64_t{1} << v.code());
},
0, reg0, regs...)),
size_(reg0.SizeInBits()), size_(reg0.SizeInBits()),
type_(reg0.type()) { type_(reg0.type()) {
DCHECK(AreSameSizeAndType(reg0, regs...)); DCHECK(AreSameSizeAndType(reg0, regs...));
......
...@@ -20,22 +20,14 @@ constexpr bool ShouldPadArguments(int argument_count) { ...@@ -20,22 +20,14 @@ constexpr bool ShouldPadArguments(int argument_count) {
} }
#ifdef DEBUG #ifdef DEBUG
struct CountIfValidRegisterFunctor { template <typename... RegTypes,
template <typename RegType>
constexpr int operator()(int count, RegType reg) const {
return count + (reg.is_valid() ? 1 : 0);
}
};
template <typename RegType, typename... RegTypes,
// All arguments must be either Register or DoubleRegister. // All arguments must be either Register or DoubleRegister.
typename = typename std::enable_if< typename = typename std::enable_if<
base::is_same<Register, RegType, RegTypes...>::value || base::is_same<Register, RegTypes...>::value ||
base::is_same<DoubleRegister, RegType, RegTypes...>::value>::type> base::is_same<DoubleRegister, RegTypes...>::value>::type>
inline constexpr bool AreAliased(RegType first_reg, RegTypes... regs) { inline constexpr bool AreAliased(RegTypes... regs) {
int num_different_regs = RegListBase<RegType>{first_reg, regs...}.Count(); int num_different_regs = RegListBase{regs...}.Count();
int num_given_regs = int num_given_regs = (... + (regs.is_valid() ? 1 : 0));
base::fold(CountIfValidRegisterFunctor{}, 0, first_reg, regs...);
return num_different_regs < num_given_regs; return num_different_regs < num_given_regs;
} }
#endif #endif
......
...@@ -70,7 +70,7 @@ class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -70,7 +70,7 @@ class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
// for argument types convertible to Node* during overload resolution. // for argument types convertible to Node* during overload resolution.
template <typename... Nodes, template <typename... Nodes,
typename = typename std::enable_if_t< typename = typename std::enable_if_t<
base::all(std::is_convertible<Nodes, Node*>::value...)>> std::conjunction_v<std::is_convertible<Nodes, Node*>...>>>
Node* NewNode(const Operator* op, Nodes... nodes) { Node* NewNode(const Operator* op, Nodes... nodes) {
std::array<Node*, sizeof...(nodes)> nodes_arr{ std::array<Node*, sizeof...(nodes)> nodes_arr{
{static_cast<Node*>(nodes)...}}; {static_cast<Node*>(nodes)...}};
......
...@@ -107,63 +107,6 @@ static_assert(has_output_operator<TestClass3>::value, ...@@ -107,63 +107,6 @@ static_assert(has_output_operator<TestClass3>::value,
static_assert(has_output_operator<const TestClass3>::value, static_assert(has_output_operator<const TestClass3>::value,
"const TestClass3 can be output"); "const TestClass3 can be output");
//////////////////////////////
// Test fold.
//////////////////////////////
struct FoldAllSameType {
constexpr uint32_t operator()(uint32_t a, uint32_t b) const { return a | b; }
};
static_assert(base::fold(FoldAllSameType{}, 3, 6) == 7, "check fold");
// Test that it works if implicit conversion is needed for one of the
// parameters.
static_assert(base::fold(FoldAllSameType{}, uint8_t{1}, 256) == 257,
"check correct type inference");
// Test a single parameter.
static_assert(base::fold(FoldAllSameType{}, 25) == 25,
"check folding a single argument");
TEST(TemplateUtilsTest, FoldDifferentType) {
auto fn = [](std::string str, char c) {
str.push_back(c);
return str;
};
CHECK_EQ(base::fold(fn, std::string("foo"), 'b', 'a', 'r'), "foobar");
}
TEST(TemplateUtilsTest, FoldMoveOnlyType) {
auto fn = [](std::unique_ptr<std::string> str, char c) {
str->push_back(c);
return str;
};
std::unique_ptr<std::string> str = std::make_unique<std::string>("foo");
std::unique_ptr<std::string> folded =
base::fold(fn, std::move(str), 'b', 'a', 'r');
CHECK_NULL(str);
CHECK_NOT_NULL(folded);
CHECK_EQ(*folded, "foobar");
}
struct TemplatizedFoldFunctor {
template <typename T, typename... Tup>
std::tuple<Tup..., typename std::decay<T>::type> operator()(
std::tuple<Tup...> tup, T&& val) {
return std::tuple_cat(std::move(tup),
std::make_tuple(std::forward<T>(val)));
}
};
TEST(TemplateUtilsTest, FoldToTuple) {
auto input = std::make_tuple(char{'x'}, int{4}, double{3.2},
std::unique_ptr<uint8_t>{}, std::string{"foo"});
auto result =
base::fold(TemplatizedFoldFunctor{}, std::make_tuple(),
std::get<0>(input), std::get<1>(input), std::get<2>(input),
std::unique_ptr<uint8_t>{}, std::get<4>(input));
static_assert(std::is_same<decltype(result), decltype(input)>::value,
"the resulting tuple should have the same type as the input");
DCHECK_EQ(input, result);
}
} // namespace template_utils_unittest } // namespace template_utils_unittest
} // namespace base } // namespace base
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment