#pragma once #include #include #include #include #include namespace mbgl { namespace style { class PropertyEvaluationParameters; template class LayoutProperty { public: using UnevaluatedType = PropertyValue; using EvaluatorType = PropertyEvaluator; using PossiblyEvaluatedType = T; using Type = T; }; template class DataDrivenLayoutProperty { public: using UnevaluatedType = DataDrivenPropertyValue; using EvaluatorType = DataDrivenPropertyEvaluator; using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue; using Type = T; }; template class LayoutProperties { public: using Properties = TypeList; template using Tuple = IndexedTuple; /* For layout properties we implement a two step evaluation process: if you have a zoom level, you can evaluate a set of unevaluated property values, producing a set of possibly evaluated values, where undefined, constant, or camera function values have been fully evaluated, and source or composite function values have not. Once you also have a particular feature, you can evaluate that set of possibly evaluated values fully, producing a set of fully evaluated values. This is in theory maximally efficient in terms of avoiding repeated evaluation of camera functions, though it's more of a historical accident than a purposeful optimization. */ using UnevaluatedTypes = TypeList; using PossiblyEvaluatedTypes = TypeList; using EvaluatedTypes = TypeList; class Evaluated : public Tuple { public: using Tuple::Tuple; }; class PossiblyEvaluated : public Tuple { public: using Tuple::Tuple; template static T evaluate(float, const GeometryTileFeature&, const T& t, const T&) { return t; } template static T evaluate(float z, const GeometryTileFeature& feature, const PossiblyEvaluatedPropertyValue& v, const T& defaultValue) { return v.match( [&] (const T& t) { return t; }, [&] (const SourceFunction& t) { return t.evaluate(feature, defaultValue); }, [&] (const CompositeFunction& t) { return t.evaluate(z, feature, defaultValue); }); } template auto evaluate(float z, const GeometryTileFeature& feature) const { return evaluate(z, feature, this->template get

(), P::defaultValue()); } Evaluated evaluate(float z, const GeometryTileFeature& feature) const { return Evaluated { evaluate(z, feature)... }; } }; class Unevaluated : public Tuple { public: using Tuple::Tuple; }; template auto evaluate(const PropertyEvaluationParameters& parameters) const { using Evaluator = typename P::EvaluatorType; return unevaluated.template get

() .evaluate(Evaluator(parameters, P::defaultValue())); } PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters) const { return PossiblyEvaluated { evaluate(parameters)... }; } Unevaluated unevaluated; }; } // namespace style } // namespace mbgl