#pragma once #include #include #include #include namespace mbgl { template class PossiblyEvaluatedPropertyValue { private: using Value = variant< T, style::SourceFunction, style::CompositeFunction>; Value value; public: PossiblyEvaluatedPropertyValue() = default; PossiblyEvaluatedPropertyValue(Value v, bool useIntegerZoom_ = false) : value(std::move(v)), useIntegerZoom(useIntegerZoom_) {} 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::SourceFunction& function) { return function.evaluate(feature, defaultValue); }, [&] (const style::CompositeFunction& function) { if (useIntegerZoom) { return function.evaluate(floor(zoom), feature, defaultValue); } else { return function.evaluate(zoom, feature, defaultValue); } } ); } bool useIntegerZoom; }; 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