1#pragma once
2
3#include <mbgl/util/optional.hpp>
4#include <mbgl/util/variant.hpp>
5#include <mbgl/util/color.hpp>
6#include <mbgl/style/expression/type.hpp>
7#include <mbgl/style/expression/value.hpp>
8#include <mbgl/style/expression/parsing_context.hpp>
9
10#include <array>
11#include <vector>
12#include <memory>
13
14namespace mbgl {
15
16class GeometryTileFeature;
17
18namespace style {
19namespace expression {
20
21class EvaluationError {
22public:
23 std::string message;
24};
25
26class EvaluationContext {
27public:
28 EvaluationContext(float zoom_) : zoom(zoom_), feature(nullptr) {}
29 EvaluationContext(GeometryTileFeature const * feature_) : zoom(optional<float>()), feature(feature_) {}
30 EvaluationContext(float zoom_, GeometryTileFeature const * feature_) :
31 zoom(zoom_), feature(feature_)
32 {}
33 EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> heatmapDensity_) :
34 zoom(std::move(zoom_)), feature(feature_), heatmapDensity(std::move(heatmapDensity_))
35 {}
36
37 optional<float> zoom;
38 GeometryTileFeature const * feature;
39 optional<double> heatmapDensity;
40};
41
42template <typename T>
43class Result : private variant<EvaluationError, T> {
44public:
45 using variant<EvaluationError, T>::variant;
46 using Value = T;
47
48 Result() = default;
49
50 explicit operator bool () const {
51 return this->template is<T>();
52 }
53
54 // optional does some type trait magic for this one, so this might
55 // be problematic as is.
56 const T* operator->() const {
57 assert(this->template is<T>());
58 return std::addressof(this->template get<T>());
59 }
60
61 T* operator->() {
62 assert(this->template is<T>());
63 return std::addressof(this->template get<T>());
64 }
65
66 T& operator*() {
67 assert(this->template is<T>());
68 return this->template get<T>();
69 }
70
71 const T& operator*() const {
72 assert(this->template is<T>());
73 return this->template get<T>();
74 }
75
76 const EvaluationError& error() const {
77 assert(this->template is<EvaluationError>());
78 return this->template get<EvaluationError>();
79 }
80};
81
82class EvaluationResult : public Result<Value> {
83public:
84 using Result::Result; // NOLINT
85
86 EvaluationResult() = default;
87
88 EvaluationResult(const std::array<double, 4>& arr) :
89 Result(toExpressionValue(value: arr))
90 {}
91
92 // used only for the special (private) "error" expression
93 EvaluationResult(const type::ErrorType&) {
94 assert(false);
95 }
96};
97
98/*
99 Expression is an abstract class that serves as an interface and base class
100 for particular expression implementations.
101
102 CompoundExpression implements the majority of expressions in the spec by
103 inferring the argument and output from a simple function (const T0& arg0,
104 const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are member types of
105 mbgl::style::expression::Value.
106
107 The other Expression subclasses (Let, Curve, Match, etc.) exist in order to
108 implement expressions that need specialized parsing, type checking, or
109 evaluation logic that can't be handled by CompoundExpression's inference
110 mechanism.
111
112 Each Expression subclass also provides a static
113 ParseResult ExpressionClass::parse(const V&, ParsingContext),
114 which handles parsing a style-spec JSON representation of the expression.
115*/
116
117enum class Kind : int32_t {
118 Coalesce,
119 CompoundExpression,
120 Literal,
121 ArrayAssertion,
122 At,
123 Interpolate,
124 Assertion,
125 Length,
126 Step,
127 Let,
128 Var,
129 CollatorExpression,
130 Coercion,
131 Match,
132 Error,
133 Case,
134 Any,
135 All,
136 Equals,
137};
138
139class Expression {
140public:
141 Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {}
142 virtual ~Expression() = default;
143
144 virtual EvaluationResult evaluate(const EvaluationContext& params) const = 0;
145 virtual void eachChild(const std::function<void(const Expression&)>&) const = 0;
146 virtual bool operator==(const Expression&) const = 0;
147 bool operator!=(const Expression& rhs) const {
148 return !operator==(rhs);
149 }
150
151 Kind getKind() const { return kind; };
152 type::Type getType() const { return type; };
153
154 EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> heatmapDensity) const;
155
156 /**
157 * Statically analyze the expression, attempting to enumerate possible outputs. Returns
158 * an array of values plus the sentinel null optional value, used to indicate that the
159 * complete set of outputs is statically undecidable.
160 */
161 virtual std::vector<optional<Value>> possibleOutputs() const = 0;
162
163 virtual mbgl::Value serialize() const {
164 std::vector<mbgl::Value> serialized;
165 serialized.emplace_back(args: getOperator());
166 eachChild([&](const Expression &child) {
167 serialized.emplace_back(args: child.serialize());
168 });
169 return serialized;
170 };
171
172 virtual std::string getOperator() const = 0;
173
174protected:
175 template <typename T>
176 static bool childrenEqual(const T& lhs, const T& rhs) {
177 if (lhs.size() != rhs.size()) return false;
178 for (auto leftChild = lhs.begin(), rightChild = rhs.begin();
179 leftChild != lhs.end();
180 leftChild++, rightChild++)
181 {
182 if (!Expression::childEqual(*leftChild, *rightChild)) return false;
183 }
184 return true;
185 }
186
187 static bool childEqual(const std::unique_ptr<Expression>& lhs, const std::unique_ptr<Expression>& rhs) {
188 return *lhs == *rhs;
189 }
190
191 template <typename T>
192 static bool childEqual(const std::pair<T, std::unique_ptr<Expression>>& lhs,
193 const std::pair<T, std::unique_ptr<Expression>>& rhs) {
194 return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
195 }
196
197 template <typename T>
198 static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs,
199 const std::pair<T, std::shared_ptr<Expression>>& rhs) {
200 return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
201 }
202
203 static bool childEqual(const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& lhs,
204 const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& rhs) {
205 return *(lhs.first) == *(rhs.first) && *(lhs.second) == *(rhs.second);
206 }
207
208private:
209 Kind kind;
210 type::Type type;
211};
212
213} // namespace expression
214} // namespace style
215} // namespace mbgl
216

source code of qtlocation/src/3rdparty/mapbox-gl-native/include/mbgl/style/expression/expression.hpp