#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace style { namespace expression { struct Value; using ValueBase = variant< NullValue, bool, double, std::string, Color, Collator, Formatted, mapbox::util::recursive_wrapper>, mapbox::util::recursive_wrapper>>; struct Value : ValueBase { using ValueBase::ValueBase; // Javascript's Number.MAX_SAFE_INTEGER static uint64_t maxSafeInteger() { return 9007199254740991ULL; } static bool isSafeInteger(uint64_t x) { return x <= maxSafeInteger(); }; static bool isSafeInteger(int64_t x) { return static_cast(x > 0 ? x : -x) <= maxSafeInteger(); } static bool isSafeInteger(double x) { return static_cast(x > 0 ? x : -x) <= maxSafeInteger(); } }; constexpr NullValue Null = NullValue(); type::Type typeOf(const Value& value); std::string toString(const Value& value); std::string stringify(const Value& value); /* Returns a Type object representing the expression type that corresponds to the value type T. (Specialized for primitives and specific array types in the .cpp.) */ template type::Type valueTypeToExpressionType(); /* Conversions between style value types and expression::Value */ template struct ValueConverter { static Value toExpressionValue(const T& value) { return Value(value); } static optional fromExpressionValue(const Value& value) { return value.template is() ? value.template get() : optional(); } }; template <> struct ValueConverter { static type::Type expressionType() { return type::Value; } static Value toExpressionValue(const Value& value) { return value; } static optional fromExpressionValue(const Value& value) { return value; } }; template <> struct ValueConverter { static Value toExpressionValue(const mbgl::Value& value); static mbgl::Value fromExpressionValue(const Value& value); }; template <> struct ValueConverter { static type::Type expressionType() { return type::Number; } static Value toExpressionValue(const float value); static optional fromExpressionValue(const Value& value); }; template struct ValueConverter> { static type::Type expressionType() { return type::Array(valueTypeToExpressionType(), N); } static Value toExpressionValue(const std::array& value); static optional> fromExpressionValue(const Value& value); }; template struct ValueConverter> { static type::Type expressionType() { return type::Array(valueTypeToExpressionType()); } static Value toExpressionValue(const std::vector& value); static optional> fromExpressionValue(const Value& value); }; template <> struct ValueConverter { static type::Type expressionType() { return type::Array(type::Number, 3); } static Value toExpressionValue(const mbgl::style::Position& value); static optional fromExpressionValue(const Value& v); }; template struct ValueConverter::value >> { static type::Type expressionType() { return type::String; } static Value toExpressionValue(const T& value); static optional fromExpressionValue(const Value& value); }; template Value toExpressionValue(const T& value) { return ValueConverter::toExpressionValue(value); } template optional fromExpressionValue(const Value& value) { return ValueConverter::fromExpressionValue(value); } template std::vector> fromExpressionValues(const std::vector>& values) { std::vector> result; for (const auto& value : values) { result.push_back(value ? fromExpressionValue(*value) : nullopt); } return result; } } // namespace expression } // namespace style } // namespace mbgl