1 #pragma once
2 
3 #include <mbgl/style/property_expression.hpp>
4 #include <mbgl/util/interpolate.hpp>
5 #include <mbgl/util/variant.hpp>
6 
7 namespace mbgl {
8 
9 template <class T>
10 class PossiblyEvaluatedPropertyValue {
11 private:
12     using Value = variant<
13         T,
14         style::PropertyExpression<T>>;
15 
16     Value value;
17 
18 public:
19     PossiblyEvaluatedPropertyValue() = default;
PossiblyEvaluatedPropertyValue(Value v,bool useIntegerZoom_=false)20     PossiblyEvaluatedPropertyValue(Value v, bool useIntegerZoom_ = false)
21         : value(std::move(v)),
22           useIntegerZoom(useIntegerZoom_) {}
23 
isConstant() const24     bool isConstant() const {
25         return value.template is<T>();
26     }
27 
constant() const28     optional<T> constant() const {
29         return value.match(
30             [&] (const T& t) { return optional<T>(t); },
31             [&] (const auto&) { return optional<T>(); });
32     }
33 
constantOr(const T & t) const34     T constantOr(const T& t) const {
35         return constant().value_or(t);
36     }
37 
38     template <class... Ts>
match(Ts &&...ts) const39     auto match(Ts&&... ts) const {
40         return value.match(std::forward<Ts>(ts)...);
41     }
42 
43     template <class Feature>
evaluate(const Feature & feature,float zoom,T defaultValue) const44     T evaluate(const Feature& feature, float zoom, T defaultValue) const {
45         return this->match(
46             [&] (const T& constant_) { return constant_; },
47             [&] (const style::PropertyExpression<T>& expression) {
48                 if (useIntegerZoom) {
49                     return expression.evaluate(floor(zoom), feature, defaultValue);
50                 } else {
51                     return expression.evaluate(zoom, feature, defaultValue);
52                 }
53             }
54         );
55     }
56 
57     bool useIntegerZoom;
58 };
59 
60 namespace util {
61 
62 template <typename T>
63 struct Interpolator<PossiblyEvaluatedPropertyValue<T>> {
operator ()mbgl::util::Interpolator64     PossiblyEvaluatedPropertyValue<T> operator()(const PossiblyEvaluatedPropertyValue<T>& a,
65                                                  const PossiblyEvaluatedPropertyValue<T>& b,
66                                                  const double t) const {
67         if (a.isConstant() && b.isConstant()) {
68             return { interpolate(*a.constant(), *b.constant(), t) };
69         } else {
70             return { a };
71         }
72     }
73 };
74 
75 } // namespace util
76 
77 } // namespace mbgl
78