mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
AK+Everywhere: Make Variant::visit() respect the Variant's constness
...and fix all the instances of visit() taking non-const arguments.
This commit is contained in:
parent
d55c130df5
commit
9de33629da
Notes:
sideshowbarker
2024-07-17 20:55:23 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/9de33629daa Pull-request: https://github.com/SerenityOS/serenity/pull/11866
12
AK/Variant.h
12
AK/Variant.h
@ -80,16 +80,16 @@ struct Variant<IndexType, InitialIndex> {
|
|||||||
|
|
||||||
template<typename IndexType, typename... Ts>
|
template<typename IndexType, typename... Ts>
|
||||||
struct VisitImpl {
|
struct VisitImpl {
|
||||||
template<typename Visitor, IndexType CurrentIndex = 0>
|
template<typename Self, typename Visitor, IndexType CurrentIndex = 0>
|
||||||
ALWAYS_INLINE static constexpr decltype(auto) visit(IndexType id, const void* data, Visitor&& visitor) requires(CurrentIndex < sizeof...(Ts))
|
ALWAYS_INLINE static constexpr decltype(auto) visit(Self& self, IndexType id, const void* data, Visitor&& visitor) requires(CurrentIndex < sizeof...(Ts))
|
||||||
{
|
{
|
||||||
using T = typename TypeList<Ts...>::template Type<CurrentIndex>;
|
using T = typename TypeList<Ts...>::template Type<CurrentIndex>;
|
||||||
|
|
||||||
if (id == CurrentIndex)
|
if (id == CurrentIndex)
|
||||||
return visitor(*bit_cast<T*>(data));
|
return visitor(*bit_cast<CopyConst<Self, T>*>(data));
|
||||||
|
|
||||||
if constexpr ((CurrentIndex + 1) < sizeof...(Ts))
|
if constexpr ((CurrentIndex + 1) < sizeof...(Ts))
|
||||||
return visit<Visitor, CurrentIndex + 1>(id, data, forward<Visitor>(visitor));
|
return visit<Self, Visitor, CurrentIndex + 1>(self, id, data, forward<Visitor>(visitor));
|
||||||
else
|
else
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
@ -367,14 +367,14 @@ public:
|
|||||||
ALWAYS_INLINE decltype(auto) visit(Fs&&... functions)
|
ALWAYS_INLINE decltype(auto) visit(Fs&&... functions)
|
||||||
{
|
{
|
||||||
Visitor<Fs...> visitor { forward<Fs>(functions)... };
|
Visitor<Fs...> visitor { forward<Fs>(functions)... };
|
||||||
return VisitHelper::visit(m_index, m_data, move(visitor));
|
return VisitHelper::visit(*this, m_index, m_data, move(visitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Fs>
|
template<typename... Fs>
|
||||||
ALWAYS_INLINE decltype(auto) visit(Fs&&... functions) const
|
ALWAYS_INLINE decltype(auto) visit(Fs&&... functions) const
|
||||||
{
|
{
|
||||||
Visitor<Fs...> visitor { forward<Fs>(functions)... };
|
Visitor<Fs...> visitor { forward<Fs>(functions)... };
|
||||||
return VisitHelper::visit(m_index, m_data, move(visitor));
|
return VisitHelper::visit(*this, m_index, m_data, move(visitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... NewTs>
|
template<typename... NewTs>
|
||||||
|
@ -31,9 +31,22 @@ TEST_CASE(visit)
|
|||||||
bool correct = false;
|
bool correct = false;
|
||||||
Variant<int, String, float> the_value { 42.0f };
|
Variant<int, String, float> the_value { 42.0f };
|
||||||
the_value.visit(
|
the_value.visit(
|
||||||
[&](const int&) { correct = false; },
|
[&](int const&) { correct = false; },
|
||||||
[&](const String&) { correct = false; },
|
[&](String const&) { correct = false; },
|
||||||
[&](const float&) { correct = true; });
|
[&](float const&) { correct = true; });
|
||||||
|
EXPECT(correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE(visit_const)
|
||||||
|
{
|
||||||
|
bool correct = false;
|
||||||
|
Variant<int, String> const the_value { "42"sv };
|
||||||
|
|
||||||
|
the_value.visit(
|
||||||
|
[&](String const&) { correct = true; },
|
||||||
|
[&](auto&) {},
|
||||||
|
[&](auto const&) {});
|
||||||
|
|
||||||
EXPECT(correct);
|
EXPECT(correct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +152,9 @@ TEST_CASE(return_values)
|
|||||||
MyVariant the_value { 42.0f };
|
MyVariant the_value { 42.0f };
|
||||||
|
|
||||||
float value = the_value.visit(
|
float value = the_value.visit(
|
||||||
[&](const int&) { return 1.0f; },
|
[&](int const&) { return 1.0f; },
|
||||||
[&](const String&) { return 2.0f; },
|
[&](String const&) { return 2.0f; },
|
||||||
[&](const float& f) { return f; });
|
[&](float const& f) { return f; });
|
||||||
EXPECT_EQ(value, 42.0f);
|
EXPECT_EQ(value, 42.0f);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -157,9 +170,9 @@ TEST_CASE(return_values)
|
|||||||
const MyVariant the_value { "str" };
|
const MyVariant the_value { "str" };
|
||||||
|
|
||||||
String value = the_value.visit(
|
String value = the_value.visit(
|
||||||
[&](const int&) { return String { "wrong" }; },
|
[&](int const&) { return String { "wrong" }; },
|
||||||
[&](const String& s) { return s; },
|
[&](String const& s) { return s; },
|
||||||
[&](const float&) { return String { "wrong" }; });
|
[&](float const&) { return String { "wrong" }; });
|
||||||
EXPECT_EQ(value, "str");
|
EXPECT_EQ(value, "str");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,9 +183,9 @@ TEST_CASE(return_values_by_reference)
|
|||||||
Variant<int, String, float> the_value { 42.0f };
|
Variant<int, String, float> the_value { 42.0f };
|
||||||
|
|
||||||
auto& value = the_value.visit(
|
auto& value = the_value.visit(
|
||||||
[&](const int&) -> RefPtr<Object>& { return ref; },
|
[&](int const&) -> RefPtr<Object>& { return ref; },
|
||||||
[&](const String&) -> RefPtr<Object>& { return ref; },
|
[&](String const&) -> RefPtr<Object>& { return ref; },
|
||||||
[&](const float&) -> RefPtr<Object>& { return ref; });
|
[&](float const&) -> RefPtr<Object>& { return ref; });
|
||||||
|
|
||||||
EXPECT_EQ(ref, value);
|
EXPECT_EQ(ref, value);
|
||||||
EXPECT_EQ(ref->ref_count(), 1u);
|
EXPECT_EQ(ref->ref_count(), 1u);
|
||||||
|
@ -2507,7 +2507,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
|
|||||||
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression
|
// AssignmentExpression : LeftHandSideExpression = AssignmentExpression
|
||||||
return m_lhs.visit(
|
return m_lhs.visit(
|
||||||
// 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
|
// 1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
|
||||||
[&](NonnullRefPtr<Expression>& lhs) -> ThrowCompletionOr<Value> {
|
[&](NonnullRefPtr<Expression> const& lhs) -> ThrowCompletionOr<Value> {
|
||||||
// a. Let lref be the result of evaluating LeftHandSideExpression.
|
// a. Let lref be the result of evaluating LeftHandSideExpression.
|
||||||
// b. ReturnIfAbrupt(lref).
|
// b. ReturnIfAbrupt(lref).
|
||||||
auto reference = TRY(lhs->to_reference(interpreter, global_object));
|
auto reference = TRY(lhs->to_reference(interpreter, global_object));
|
||||||
@ -2534,7 +2534,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
|
|||||||
return rhs_result;
|
return rhs_result;
|
||||||
},
|
},
|
||||||
// 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
|
// 2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
|
||||||
[&](NonnullRefPtr<BindingPattern>& pattern) -> ThrowCompletionOr<Value> {
|
[&](NonnullRefPtr<BindingPattern> const& pattern) -> ThrowCompletionOr<Value> {
|
||||||
// 3. Let rref be the result of evaluating AssignmentExpression.
|
// 3. Let rref be the result of evaluating AssignmentExpression.
|
||||||
// 4. Let rval be ? GetValue(rref).
|
// 4. Let rval be ? GetValue(rref).
|
||||||
auto rhs_result = TRY(m_rhs->execute(interpreter, global_object)).release_value();
|
auto rhs_result = TRY(m_rhs->execute(interpreter, global_object)).release_value();
|
||||||
|
@ -201,7 +201,7 @@ public:
|
|||||||
views.empend(view);
|
views.empend(view);
|
||||||
return views;
|
return views;
|
||||||
},
|
},
|
||||||
[](Utf8View& view) {
|
[](Utf8View const& view) {
|
||||||
Vector<RegexStringView> views;
|
Vector<RegexStringView> views;
|
||||||
auto it = view.begin();
|
auto it = view.begin();
|
||||||
auto previous_newline_position_it = it;
|
auto previous_newline_position_it = it;
|
||||||
|
@ -123,10 +123,10 @@ static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_valu
|
|||||||
{
|
{
|
||||||
return calc_value.visit(
|
return calc_value.visit(
|
||||||
[](float value) { return value; },
|
[](float value) { return value; },
|
||||||
[&](Length length) {
|
[&](Length const& length) {
|
||||||
return length.resolved_or_zero(layout_node, reference_for_percent).to_px(layout_node);
|
return length.resolved_or_zero(layout_node, reference_for_percent).to_px(layout_node);
|
||||||
},
|
},
|
||||||
[&](NonnullOwnPtr<CalculatedStyleValue::CalcSum>& calc_sum) {
|
[&](NonnullOwnPtr<CalculatedStyleValue::CalcSum> const& calc_sum) {
|
||||||
return resolve_calc_sum(calc_sum, layout_node, reference_for_percent);
|
return resolve_calc_sum(calc_sum, layout_node, reference_for_percent);
|
||||||
},
|
},
|
||||||
[](auto&) {
|
[](auto&) {
|
||||||
@ -173,7 +173,7 @@ static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue con
|
|||||||
{
|
{
|
||||||
return number_value.visit(
|
return number_value.visit(
|
||||||
[](float number) { return number; },
|
[](float number) { return number; },
|
||||||
[](NonnullOwnPtr<CalculatedStyleValue::CalcNumberSum>& calc_number_sum) {
|
[](NonnullOwnPtr<CalculatedStyleValue::CalcNumberSum> const& calc_number_sum) {
|
||||||
return resolve_calc_number_sum(calc_number_sum);
|
return resolve_calc_number_sum(calc_number_sum);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,16 @@ NonnullRefPtr<MediaQuery> MediaQuery::create_not_all()
|
|||||||
String MediaFeatureValue::to_string() const
|
String MediaFeatureValue::to_string() const
|
||||||
{
|
{
|
||||||
return m_value.visit(
|
return m_value.visit(
|
||||||
[](String& ident) { return serialize_an_identifier(ident); },
|
[](String const& ident) { return serialize_an_identifier(ident); },
|
||||||
[](Length& length) { return length.to_string(); },
|
[](Length const& length) { return length.to_string(); },
|
||||||
[](double number) { return String::number(number); });
|
[](double number) { return String::number(number); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaFeatureValue::is_same_type(MediaFeatureValue const& other) const
|
bool MediaFeatureValue::is_same_type(MediaFeatureValue const& other) const
|
||||||
{
|
{
|
||||||
return m_value.visit(
|
return m_value.visit(
|
||||||
[&](String&) { return other.is_ident(); },
|
[&](String const&) { return other.is_ident(); },
|
||||||
[&](Length&) { return other.is_length(); },
|
[&](Length const&) { return other.is_length(); },
|
||||||
[&](double) { return other.is_number(); });
|
[&](double) { return other.is_number(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,13 +35,13 @@ MatchResult Supports::Condition::evaluate() const
|
|||||||
MatchResult Supports::InParens::evaluate() const
|
MatchResult Supports::InParens::evaluate() const
|
||||||
{
|
{
|
||||||
return value.visit(
|
return value.visit(
|
||||||
[&](NonnullOwnPtr<Condition>& condition) {
|
[&](NonnullOwnPtr<Condition> const& condition) {
|
||||||
return condition->evaluate();
|
return condition->evaluate();
|
||||||
},
|
},
|
||||||
[&](Feature& feature) {
|
[&](Feature const& feature) {
|
||||||
return feature.evaluate();
|
return feature.evaluate();
|
||||||
},
|
},
|
||||||
[&](GeneralEnclosed& general_enclosed) {
|
[&](GeneralEnclosed const& general_enclosed) {
|
||||||
return general_enclosed.evaluate();
|
return general_enclosed.evaluate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user