diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2018-01-08 13:18:40 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2018-01-09 16:10:51 -0800 |
commit | a13027c1b6e2aa9a213628acf9124cd6c872f204 (patch) | |
tree | c0c86f052025c3637c9af0922551492f4398860b /src/mbgl | |
parent | 43a9bd3fbab666f21583ff264d6b6ba1d7069374 (diff) | |
download | qtlocation-mapboxgl-a13027c1b6e2aa9a213628acf9124cd6c872f204.tar.gz |
[core] Improve typing for !=, == expressions
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/style/expression/compound_expression.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/style/expression/equals.cpp | 83 | ||||
-rw-r--r-- | src/mbgl/style/expression/parsing_context.cpp | 3 |
3 files changed, 86 insertions, 16 deletions
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 70bc6dfd95..ff21157faa 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -175,12 +175,6 @@ struct Signature<Lambda, std::enable_if_t<std::is_class<Lambda>::value>> using Definition = CompoundExpressionRegistry::Definition; -template <typename T> -Result<bool> equal(const T& lhs, const T& rhs) { return lhs == rhs; } - -template <typename T> -Result<bool> notEqual(const T& lhs, const T& rhs) { return lhs != rhs; } - template <typename Fn> static std::unique_ptr<detail::SignatureBase> makeSignature(Fn evaluateFunction) { return std::make_unique<detail::Signature<Fn>>(evaluateFunction); @@ -376,16 +370,6 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali return result; }); - define("==", equal<double>); - define("==", equal<const std::string&>); - define("==", equal<bool>); - define("==", equal<NullValue>); - - define("!=", notEqual<double>); - define("!=", notEqual<const std::string&>); - define("!=", notEqual<bool>); - define("!=", notEqual<NullValue>); - define(">", [](double lhs, double rhs) -> Result<bool> { return lhs > rhs; }); define(">", [](const std::string& lhs, const std::string& rhs) -> Result<bool> { return lhs > rhs; }); define(">=", [](double lhs, double rhs) -> Result<bool> { return lhs >= rhs; }); diff --git a/src/mbgl/style/expression/equals.cpp b/src/mbgl/style/expression/equals.cpp new file mode 100644 index 0000000000..08ef85e92b --- /dev/null +++ b/src/mbgl/style/expression/equals.cpp @@ -0,0 +1,83 @@ +#include <mbgl/style/expression/equals.hpp> + +namespace mbgl { +namespace style { +namespace expression { + +Equals::Equals(std::unique_ptr<Expression> lhs_, std::unique_ptr<Expression> rhs_, bool negate_) + : Expression(type::Boolean), + lhs(std::move(lhs_)), + rhs(std::move(rhs_)), + negate(negate_) { +} + +EvaluationResult Equals::evaluate(const EvaluationContext& params) const { + EvaluationResult lhsResult = lhs->evaluate(params); + if (!lhsResult) return lhsResult; + + EvaluationResult rhsResult = rhs->evaluate(params); + if (!rhsResult) return lhsResult; + + bool result = *lhsResult == *rhsResult; + if (negate) { + result = !result; + } + return result; +} + +void Equals::eachChild(const std::function<void(const Expression&)>& visit) const { + visit(*lhs); + visit(*rhs); +} + +bool Equals::operator==(const Expression& e) const { + if (auto eq = dynamic_cast<const Equals*>(&e)) { + return eq->negate == negate && *eq->lhs == *lhs && *eq->rhs == *rhs; + } + return false; +} + +static bool isComparableType(const type::Type& type) { + return type == type::String || + type == type::Number || + type == type::Boolean || + type == type::Null; +} + +using namespace mbgl::style::conversion; +ParseResult Equals::parse(const Convertible& value, ParsingContext& ctx) { + std::size_t length = arrayLength(value); + + if (length != 3) { + ctx.error("Expected two arguments."); + return ParseResult(); + } + + bool negate = toString(arrayMember(value, 0)) == std::string("!="); + + ParseResult lhs = ctx.parse(arrayMember(value, 1), 1, {type::Value}); + if (!lhs) return ParseResult(); + + ParseResult rhs = ctx.parse(arrayMember(value, 2), 2, {type::Value}); + if (!rhs) return ParseResult(); + + type::Type lhsType = (*lhs)->getType(); + type::Type rhsType = (*rhs)->getType(); + + if (!isComparableType(lhsType) && !isComparableType(rhsType)) { + ctx.error("Expected at least one argument to be a string, number, boolean, or null, but found (" + + toString(lhsType) + ", " + toString(rhsType) + ") instead."); + return ParseResult(); + } + + if (lhsType != rhsType && lhsType != type::Value && rhsType != type::Value) { + ctx.error("Cannot compare " + toString(lhsType) + " and " + toString(rhsType) + "."); + return ParseResult(); + } + + return ParseResult(std::make_unique<Equals>(std::move(*lhs), std::move(*rhs), negate)); +} + +} // namespace expression +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp index 501ba2749f..8dd99dd8d0 100644 --- a/src/mbgl/style/expression/parsing_context.cpp +++ b/src/mbgl/style/expression/parsing_context.cpp @@ -13,6 +13,7 @@ #include <mbgl/style/expression/coalesce.hpp> #include <mbgl/style/expression/coercion.hpp> #include <mbgl/style/expression/compound_expression.hpp> +#include <mbgl/style/expression/equals.hpp> #include <mbgl/style/expression/interpolate.hpp> #include <mbgl/style/expression/let.hpp> #include <mbgl/style/expression/literal.hpp> @@ -75,6 +76,8 @@ ParseResult ParsingContext::parse(const Convertible& value, std::size_t index_, const ExpressionRegistry& getExpressionRegistry() { static ExpressionRegistry registry {{ + {"==", Equals::parse}, + {"!=", Equals::parse}, {"all", All::parse}, {"any", Any::parse}, {"array", ArrayAssertion::parse}, |