#include #include #include #include #include #include namespace mbgl { namespace style { namespace expression { optional> findZoomCurve(const expression::Expression* e) { optional> result; if (auto let = dynamic_cast(e)) { result = findZoomCurve(let->getResult()); } else if (auto coalesce = dynamic_cast(e)) { std::size_t length = coalesce->getLength(); for (std::size_t i = 0; i < length; i++) { result = findZoomCurve(coalesce->getChild(i)); if (result) { break; } } } else if (auto curve = dynamic_cast(e)) { auto z = dynamic_cast(curve->getInput().get()); if (z && z->getName() == "zoom") { result = {curve}; } } else if (auto step = dynamic_cast(e)) { auto z = dynamic_cast(step->getInput().get()); if (z && z->getName() == "zoom") { result = {step}; } } if (result && result->is()) { return result; } e->eachChild([&](const Expression& child) { optional> childResult(findZoomCurve(&child)); if (childResult) { if (childResult->is()) { result = childResult; } else if (!result && childResult) { result = {ParsingError { R"("zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.)", "" }}; } else if (result && childResult && result != childResult) { result = {ParsingError { R"(Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.)", "" }}; } } }); return result; } variant findZoomCurveChecked(const expression::Expression* e) { return findZoomCurve(e)->match( [](const ParsingError&) -> variant { assert(false); return {}; }, [](auto zoomCurve) -> variant { return {std::move(zoomCurve)}; } ); } } // namespace expression } // namespace style } // namespace mbgl