summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2018-01-08 13:18:40 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2018-01-09 16:10:51 -0800
commita13027c1b6e2aa9a213628acf9124cd6c872f204 (patch)
treec0c86f052025c3637c9af0922551492f4398860b /src
parent43a9bd3fbab666f21583ff264d6b6ba1d7069374 (diff)
downloadqtlocation-mapboxgl-a13027c1b6e2aa9a213628acf9124cd6c872f204.tar.gz
[core] Improve typing for !=, == expressions
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/style/expression/compound_expression.cpp16
-rw-r--r--src/mbgl/style/expression/equals.cpp83
-rw-r--r--src/mbgl/style/expression/parsing_context.cpp3
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},