#pragma once #include #include #include #include #include namespace mbgl { template class PossiblyEvaluatedPropertyValue { private: using Value = variant< T, style::PropertyExpression>; Value value; public: PossiblyEvaluatedPropertyValue() = default; PossiblyEvaluatedPropertyValue(Value v) : value(std::move(v)) {} bool isConstant() const { return value.template is(); } optional constant() const { return value.match( [&] (const T& t) { return optional(t); }, [&] (const auto&) { return optional(); }); } T constantOr(const T& t) const { return constant().value_or(t); } template auto match(Ts&&... ts) const { return value.match(std::forward(ts)...); } template T evaluate(const Feature& feature, float zoom, T defaultValue) const { return this->match( [&] (const T& constant_) { return constant_; }, [&] (const style::PropertyExpression& expression) { return expression.evaluate(zoom, feature, defaultValue); } ); } template T evaluate(const Feature& feature, float zoom, const CanonicalTileID& canonical, T defaultValue) const { return this->match([&](const T& constant_) { return constant_; }, [&](const style::PropertyExpression& expression) { return expression.evaluate(zoom, feature, canonical, defaultValue); }); } template T evaluate(const Feature& feature, float zoom, const FeatureState& featureState, T defaultValue) const { return this->match([&](const T& constant_) { return constant_; }, [&](const style::PropertyExpression& expression) { return expression.evaluate(zoom, feature, featureState, defaultValue); }); } }; template class PossiblyEvaluatedPropertyValue> { private: using Value = variant< Faded, style::PropertyExpression>; Value value; public: PossiblyEvaluatedPropertyValue() = default; PossiblyEvaluatedPropertyValue(Value v) : value(std::move(v)) {} bool isConstant() const { return value.template is>(); } optional> constant() const { return value.match( [&] (const Faded& t) { return optional>(t); }, [&] (const auto&) { return optional>(); }); } Faded constantOr(const Faded& t) const { return constant().value_or(t); } template auto match(Ts&&... ts) const { return value.match(std::forward(ts)...); } template Faded evaluate(const Feature& feature, float zoom, const std::set& availableImages, const CanonicalTileID& canonical, T defaultValue) const { return this->match( [&] (const Faded& constant_) { return constant_; }, [&] (const style::PropertyExpression& expression) { if (!expression.isZoomConstant()) { const T min = expression.evaluate(std::floor(zoom), feature, availableImages, canonical, defaultValue); const T max = expression.evaluate(std::floor(zoom) + 1, feature, availableImages, canonical, defaultValue); return Faded {min, max}; } else { const T evaluated = expression.evaluate(feature, availableImages, defaultValue); return Faded {evaluated, evaluated}; } } ); } }; namespace util { template struct Interpolator> { PossiblyEvaluatedPropertyValue operator()(const PossiblyEvaluatedPropertyValue& a, const PossiblyEvaluatedPropertyValue& b, const double t) const { if (a.isConstant() && b.isConstant()) { return { interpolate(*a.constant(), *b.constant(), t) }; } else { return { a }; } } }; } // namespace util } // namespace mbgl