#include #include namespace mbgl { namespace style { namespace expression { Length::Length(std::unique_ptr input_) : Expression(type::Number), input(std::move(input_)) { } EvaluationResult Length::evaluate(const EvaluationContext& params) const { const EvaluationResult value = input->evaluate(params); if (!value) return value; return value->match( [] (const std::string& s) { return EvaluationResult { double(s.size()) }; }, [] (const std::vector& v) { return EvaluationResult { double(v.size()) }; }, [&] (const auto&) -> EvaluationResult { return EvaluationError { "Expected value to be of type string or array, but found " + toString(typeOf(*value)) + " instead." }; }); } void Length::eachChild(const std::function& visit) const { visit(*input); } bool Length::operator==(const Expression& e) const { if (auto eq = dynamic_cast(&e)) { return *eq->input == *input; } return false; } std::vector> Length::possibleOutputs() const { return { nullopt }; } using namespace mbgl::style::conversion; ParseResult Length::parse(const Convertible& value, ParsingContext& ctx) { std::size_t length = arrayLength(value); if (length != 2) { ctx.error("Expected one argument, but found " + util::toString(length) + " instead."); return ParseResult(); } ParseResult input = ctx.parse(arrayMember(value, 1), 1); if (!input) return ParseResult(); type::Type type = (*input)->getType(); if (!type.is() && !type.is() && !type.is()) { ctx.error("Expected argument of type string or array, but found " + toString(type) + " instead."); return ParseResult(); } return ParseResult(std::make_unique(std::move(*input))); } } // namespace expression } // namespace style } // namespace mbgl