#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace style { namespace conversion { template void stringify(Writer& writer, NullValue) { writer.Null(); } template void stringify(Writer& writer, bool v) { writer.Bool(v); } template void stringify(Writer& writer, uint64_t v) { writer.Uint64(v); } template void stringify(Writer& writer, int64_t v) { writer.Int64(v); } template void stringify(Writer& writer, double v) { writer.Double(v); } template void stringify(Writer& writer, const std::string& v) { writer.String(v); } template ::value>> void stringify(Writer& writer, const T& v) { writer.String(Enum::toString(v)); } template void stringify(Writer& writer, const Color& v) { writer.String(v.stringify()); } template void stringify(Writer& writer, const std::array& v) { writer.StartArray(); writer.Double(v[0]); writer.Double(v[1]); writer.EndArray(); } template void stringify(Writer& writer, const std::array& v) { writer.StartArray(); writer.Double(v[0]); writer.Double(v[1]); writer.Double(v[2]); writer.Double(v[3]); writer.EndArray(); } template void stringify(Writer&, const Value&); template void stringify(Writer& writer, const std::vector& v) { writer.StartArray(); for (const auto& e : v) { stringify(writer, e); } writer.EndArray(); } template void stringify(Writer& writer, const std::unordered_map& m) { writer.StartObject(); for (const auto& p : m) { writer.Key(p.first.data(), static_cast(p.first.size())); stringify(writer, p.second); } writer.EndObject(); } template void stringify(Writer& writer, const Value& v) { Value::visit(v, [&] (const auto& v_) { stringify(writer, v_); }); } template class StringifyFilter { public: Writer& writer; void operator()(const NullFilter&) { writer.Null(); } void operator()(const EqualsFilter& f) { stringifyBinaryFilter(f, "=="); } void operator()(const NotEqualsFilter& f) { stringifyBinaryFilter(f, "!="); } void operator()(const LessThanFilter& f) { stringifyBinaryFilter(f, "<"); } void operator()(const LessThanEqualsFilter& f) { stringifyBinaryFilter(f, "<="); } void operator()(const GreaterThanFilter& f) { stringifyBinaryFilter(f, ">"); } void operator()(const GreaterThanEqualsFilter& f) { stringifyBinaryFilter(f, ">="); } void operator()(const InFilter& f) { stringifySetFilter(f, "in"); } void operator()(const NotInFilter& f) { stringifySetFilter(f, "!in"); } void operator()(const AllFilter& f) { stringifyCompoundFilter(f, "all"); } void operator()(const AnyFilter& f) { stringifyCompoundFilter(f, "any"); } void operator()(const NoneFilter& f) { stringifyCompoundFilter(f, "none"); } void operator()(const HasFilter& f) { stringifyUnaryFilter(f, "has"); } void operator()(const NotHasFilter& f) { stringifyUnaryFilter(f, "!has"); } private: template void stringifyBinaryFilter(const F& f, const char * op) { writer.StartArray(); writer.String(op); writer.String(f.key); stringify(writer, f.value); writer.EndArray(); } template void stringifySetFilter(const F& f, const char * op) { writer.StartArray(); writer.String(op); writer.String(f.key); for (const auto& value : f.values) { stringify(writer, value); } writer.EndArray(); } template void stringifyCompoundFilter(const F& f, const char * op) { writer.StartArray(); writer.String(op); for (const auto& filter : f.filters) { Filter::visit(filter, *this); } writer.EndArray(); } template void stringifyUnaryFilter(const F& f, const char * op) { writer.StartArray(); writer.String(op); writer.String(f.key); writer.EndArray(); } }; template void stringify(Writer& writer, const Filter& f) { Filter::visit(f, StringifyFilter { writer }); } template void stringify(Writer& writer, const Undefined&) { assert(false); // Should be omitted entirely instead. writer.Null(); } template void stringify(Writer& writer, const Function& f) { writer.StartObject(); writer.Key("base"); writer.Double(f.getBase()); writer.Key("stops"); writer.StartArray(); for (const auto& stop : f.getStops()) { writer.StartArray(); writer.Double(stop.first); stringify(writer, stop.second); writer.EndArray(); } writer.EndArray(); writer.EndObject(); } template void stringify(Writer& writer, const PropertyValue& v) { v.evaluate([&] (const auto& v_) { stringify(writer, v_); }); } template void stringify(Writer& writer, const PropertyValue& value) { if (value) { writer.Key(Property::key); stringify(writer, value); } } template void stringify(Writer& writer, const LayoutProperties& ps) { writer.StartObject(); util::ignore({ (stringify(writer, ps.unevaluated.template get()), 0)... }); writer.EndObject(); } } // namespace conversion } // namespace style } // namespace mbgl