1#pragma once
2
3#include <mbgl/style/expression/expression.hpp>
4#include <mbgl/style/conversion.hpp>
5#include <mbgl/style/expression/parsing_context.hpp>
6#include <mbgl/style/expression/type.hpp>
7#include <mbgl/style/expression/value.hpp>
8
9#include <mbgl/util/optional.hpp>
10#include <mbgl/util/variant.hpp>
11
12#include <memory>
13#include <vector>
14
15namespace mbgl {
16namespace style {
17namespace expression {
18
19/*
20 CompoundExpression provides a mechanism for implementing an expression
21 simply by providing a list of pure functions of the form
22 (const T0& arg0, const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are
23 member types of mbgl::style::expression::Value.
24
25 The majority of expressions specified in the style-spec are implemented in
26 this fashion (see compound_expression.cpp).
27*/
28
29
30/*
31 Represents the parameter list for an expression that takes an arbitrary
32 number of arguments (of a specific type).
33*/
34struct VarargsType { type::Type type; };
35template <typename T>
36struct Varargs : std::vector<T> {
37 template <class... Args>
38 Varargs(Args&&... args) : std::vector<T>(std::forward<Args>(args)...) {}
39};
40
41namespace detail {
42// Base class for the Signature<Fn> structs that are used to determine
43// each CompoundExpression definition's type::Type data from the type of its
44// "evaluate" function.
45struct SignatureBase {
46 SignatureBase(type::Type result_, variant<std::vector<type::Type>, VarargsType> params_, std::string name_) :
47 result(std::move(result_)),
48 params(std::move(params_)),
49 name(std::move(name_))
50 {}
51 virtual ~SignatureBase() = default;
52 virtual std::unique_ptr<Expression> makeExpression(std::vector<std::unique_ptr<Expression>>) const = 0;
53 type::Type result;
54 variant<std::vector<type::Type>, VarargsType> params;
55 std::string name;
56};
57} // namespace detail
58
59
60/*
61 Common base class for CompoundExpression<Signature> instances. Used to
62 allow downcasting (and access to things like name & parameter list) during
63 an Expression tree traversal.
64*/
65class CompoundExpressionBase : public Expression {
66public:
67 CompoundExpressionBase(std::string name_, const detail::SignatureBase& signature) :
68 Expression(Kind::CompoundExpression, signature.result),
69 name(std::move(name_)),
70 params(signature.params)
71 {}
72
73 std::string getName() const { return name; }
74 optional<std::size_t> getParameterCount() const {
75 return params.match(
76 fs: [&](const VarargsType&) { return optional<std::size_t>(); },
77 fs: [&](const std::vector<type::Type>& p) -> optional<std::size_t> { return p.size(); }
78 );
79 }
80
81 std::vector<optional<Value>> possibleOutputs() const override {
82 return { nullopt };
83 }
84
85private:
86 std::string name;
87 variant<std::vector<type::Type>, VarargsType> params;
88};
89
90template <typename Signature>
91class CompoundExpression : public CompoundExpressionBase {
92public:
93 using Args = typename Signature::Args;
94
95 CompoundExpression(const std::string& name_,
96 Signature signature_,
97 typename Signature::Args args_) :
98 CompoundExpressionBase(name_, signature_),
99 signature(signature_),
100 args(std::move(args_))
101 {}
102
103 EvaluationResult evaluate(const EvaluationContext& evaluationParams) const override {
104 return signature.apply(evaluationParams, args);
105 }
106
107 void eachChild(const std::function<void(const Expression&)>& visit) const override {
108 for (const std::unique_ptr<Expression>& e : args) {
109 visit(*e);
110 }
111 }
112
113 bool operator==(const Expression& e) const override {
114 if (e.getKind() == Kind::CompoundExpression) {
115 auto rhs = static_cast<const CompoundExpression*>(&e);
116 return getName() == rhs->getName() && Expression::childrenEqual(args, rhs->args);
117 }
118 return false;
119 }
120
121 std::string getOperator() const override {
122 return signature.name;
123 }
124
125private:
126 Signature signature;
127 typename Signature::Args args;
128};
129
130/*
131 Holds the map of expression name => implementation (which is just one or
132 more evaluation functions, each wrapped in a Signature struct).
133*/
134struct CompoundExpressionRegistry {
135 using Definition = std::vector<std::unique_ptr<detail::SignatureBase>>;
136 static std::unordered_map<std::string, Definition> definitions;
137};
138
139ParseResult parseCompoundExpression(const std::string name, const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
140
141ParseResult createCompoundExpression(const std::string& name,
142 std::vector<std::unique_ptr<Expression>> args,
143 ParsingContext& ctx);
144
145} // namespace expression
146} // namespace style
147} // namespace mbgl
148

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