[core] Prepare Filter for public API (#4900)

This commit is contained in:
John Firebaugh
2016-04-28 16:33:09 -07:00
parent 10528091db
commit da78422c5c
21 changed files with 438 additions and 1034 deletions

View File

@@ -1,4 +1,5 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/sprite/sprite_image.hpp>
@@ -26,6 +27,7 @@
#include <mbgl/util/std.hpp>
#include <mbgl/util/get_geometries.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
namespace mbgl {
@@ -99,8 +101,7 @@ bool SymbolBucket::needsClipping() const {
return mode == MapMode::Still;
}
void SymbolBucket::parseFeatures(const GeometryTileLayer& layer,
const FilterExpression& filter) {
void SymbolBucket::parseFeatures(const GeometryTileLayer& layer, const Filter& filter) {
const bool has_text = !layout.textField.value.empty() && !layout.textFont.value.empty();
const bool has_icon = !layout.iconImage.value.empty();
@@ -113,15 +114,27 @@ void SymbolBucket::parseFeatures(const GeometryTileLayer& layer,
for (GLsizei i = 0; i < featureCount; i++) {
auto feature = layer.getFeature(i);
GeometryTileFeatureExtractor extractor(*feature);
if (!evaluate(filter, extractor))
FilterEvaluator<GeometryTileFeatureExtractor> evaluator(*feature);
if (!Filter::visit(filter, evaluator))
continue;
SymbolFeature ft;
auto getValue = [&feature](const std::string& key) -> std::string {
auto value = feature->getValue(key);
return value ? toString(*value) : std::string();
if (!value)
return std::string();
if (value->is<std::string>())
return value->get<std::string>();
if (value->is<bool>())
return value->get<bool>() ? "true" : "false";
if (value->is<int64_t>())
return util::toString(value->get<int64_t>());
if (value->is<uint64_t>())
return util::toString(value->get<uint64_t>());
if (value->is<double>())
return util::toString(value->get<double>());
return "null";
};
if (has_text) {

View File

@@ -13,7 +13,7 @@
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/text/shaping.hpp>
#include <mbgl/text/quads.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/layer/symbol_layer.hpp>
#include <memory>
@@ -88,8 +88,7 @@ public:
void drawIcons(IconShader&, gl::GLObjectStore&);
void drawCollisionBoxes(CollisionBoxShader&, gl::GLObjectStore&);
void parseFeatures(const GeometryTileLayer&,
const FilterExpression&);
void parseFeatures(const GeometryTileLayer&, const Filter&);
bool needsDependencies(GlyphStore&, SpriteStore&);
void placeFeatures(CollisionTile&) override;

91
src/mbgl/style/filter.hpp Normal file
View File

@@ -0,0 +1,91 @@
#pragma once
#include <mbgl/util/variant.hpp>
#include <mbgl/util/value.hpp>
#include <string>
#include <vector>
namespace mbgl {
typedef variant<
class NullFilter,
class EqualsFilter,
class NotEqualsFilter,
class LessThanFilter,
class LessThanEqualsFilter,
class GreaterThanFilter,
class GreaterThanEqualsFilter,
class InFilter,
class NotInFilter,
class AnyFilter,
class AllFilter,
class NoneFilter
> Filter;
class NullFilter {};
class EqualsFilter {
public:
std::string key;
Value value;
};
class NotEqualsFilter {
public:
std::string key;
Value value;
};
class LessThanFilter {
public:
std::string key;
Value value;
};
class LessThanEqualsFilter {
public:
std::string key;
Value value;
};
class GreaterThanFilter {
public:
std::string key;
Value value;
};
class GreaterThanEqualsFilter {
public:
std::string key;
Value value;
};
class InFilter {
public:
std::string key;
std::vector<Value> values;
};
class NotInFilter {
public:
std::string key;
std::vector<Value> values;
};
class AnyFilter {
public:
std::vector<Filter> filters;
};
class AllFilter {
public:
std::vector<Filter> filters;
};
class NoneFilter {
public:
std::vector<Filter> filters;
};
} // namespace mbgl

View File

@@ -0,0 +1,138 @@
#pragma once
#include <mbgl/style/filter.hpp>
#include <mbgl/util/optional.hpp>
#include <type_traits>
namespace mbgl {
template <class Extractor>
class FilterEvaluator {
public:
FilterEvaluator(const Extractor& extractor_)
: extractor(extractor_) {}
bool operator()(const NullFilter&) const {
return true;
}
bool operator()(const EqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return actual && equal(*actual, filter.value);
}
bool operator()(const NotEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return !actual || !equal(*actual, filter.value);
}
bool operator()(const LessThanFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; });
}
bool operator()(const LessThanEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; });
}
bool operator()(const GreaterThanFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; });
}
bool operator()(const GreaterThanEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; });
}
bool operator()(const InFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
if (!actual)
return false;
for (const auto& v: filter.values) {
if (equal(*actual, v)) {
return true;
}
}
return false;
}
bool operator()(const NotInFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
if (!actual)
return true;
for (const auto& v: filter.values) {
if (equal(*actual, v)) {
return false;
}
}
return true;
}
bool operator()(const AnyFilter& filter) const {
for (const auto& f: filter.filters) {
if (Filter::visit(f, *this)) {
return true;
}
}
return false;
}
bool operator()(const AllFilter& filter) const {
for (const auto& f: filter.filters) {
if (!Filter::visit(f, *this)) {
return false;
}
}
return true;
}
bool operator()(const NoneFilter& filter) const {
for (const auto& f: filter.filters) {
if (Filter::visit(f, *this)) {
return false;
}
}
return true;
}
private:
template <class Op>
struct Comparator {
const Op& op;
template <class T>
bool operator()(const T& lhs, const T& rhs) const {
return op(lhs, rhs);
}
template <class T0, class T1>
auto operator()(const T0& lhs, const T1& rhs) const
-> typename std::enable_if_t<std::is_arithmetic<T0>::value && !std::is_same<T0, bool>::value &&
std::is_arithmetic<T1>::value && !std::is_same<T1, bool>::value, bool> {
return op(double(lhs), double(rhs));
}
template <class T0, class T1>
auto operator()(const T0&, const T1&) const
-> typename std::enable_if_t<!std::is_arithmetic<T0>::value || std::is_same<T0, bool>::value ||
!std::is_arithmetic<T1>::value || std::is_same<T1, bool>::value, bool> {
return false;
}
};
template <class Op>
bool compare(const Value& lhs, const Value& rhs, const Op& op) const {
return Value::binary_visit(lhs, rhs, Comparator<Op> { op });
}
bool equal(const Value& lhs, const Value& rhs) const {
return compare(lhs, rhs, [] (const auto& lhs_, const auto& rhs_) { return lhs_ == rhs_; });
}
const Extractor& extractor;
};
} // namespace mbgl

View File

@@ -1,128 +0,0 @@
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/platform/log.hpp>
namespace mbgl {
Value parseFeatureType(const Value& value) {
if (value == std::string("Point")) {
return Value(uint64_t(FeatureType::Point));
} else if (value == std::string("LineString")) {
return Value(uint64_t(FeatureType::LineString));
} else if (value == std::string("Polygon")) {
return Value(uint64_t(FeatureType::Polygon));
} else {
Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon");
return Value(uint64_t(FeatureType::Unknown));
}
}
template <class Expression>
FilterExpression parseBinaryFilter(const JSValue& value) {
FilterExpression empty;
if (value.Size() < 3) {
Log::Warning(Event::ParseStyle, "filter expression must have 3 elements");
return empty;
}
if (!value[1u].IsString()) {
Log::Warning(Event::ParseStyle, "filter expression key must be a string");
return empty;
}
Expression expression;
expression.key = { value[1u].GetString(), value[1u].GetStringLength() };
expression.value = parseValue(value[2u]);
if (expression.key == "$type") {
expression.value = parseFeatureType(expression.value);
}
return expression;
}
template <class Expression>
FilterExpression parseSetFilter(const JSValue& value) {
FilterExpression empty;
if (value.Size() < 2) {
Log::Warning(Event::ParseStyle, "filter expression must at least 2 elements");
return empty;
}
if (!value[1u].IsString()) {
Log::Warning(Event::ParseStyle, "filter expression key must be a string");
return empty;
}
Expression expression;
expression.key = { value[1u].GetString(), value[1u].GetStringLength() };
for (rapidjson::SizeType i = 2; i < value.Size(); ++i) {
Value parsedValue = parseValue(value[i]);
if (expression.key == "$type") {
parsedValue = parseFeatureType(parsedValue);
}
expression.values.push_back(parsedValue);
}
return expression;
}
template <class Expression>
FilterExpression parseCompoundFilter(const JSValue& value) {
Expression expression;
for (rapidjson::SizeType i = 1; i < value.Size(); ++i) {
expression.expressions.push_back(parseFilterExpression(value[i]));
}
return expression;
}
FilterExpression parseFilterExpression(const JSValue& value) {
FilterExpression empty;
if (!value.IsArray()) {
Log::Warning(Event::ParseStyle, "filter expression must be an array");
return empty;
}
if (value.Size() < 1) {
Log::Warning(Event::ParseStyle, "filter expression must have at least 1 element");
return empty;
}
if (!value[0u].IsString()) {
Log::Warning(Event::ParseStyle, "filter operator must be a string");
return empty;
}
std::string op = { value[0u].GetString(), value[0u].GetStringLength() };
if (op == "==") {
return parseBinaryFilter<EqualsExpression>(value);
} else if (op == "!=") {
return parseBinaryFilter<NotEqualsExpression>(value);
} else if (op == ">") {
return parseBinaryFilter<GreaterThanExpression>(value);
} else if (op == ">=") {
return parseBinaryFilter<GreaterThanEqualsExpression>(value);
} else if (op == "<") {
return parseBinaryFilter<LessThanExpression>(value);
} else if (op == "<=") {
return parseBinaryFilter<LessThanEqualsExpression>(value);
} else if (op == "in") {
return parseSetFilter<InExpression>(value);
} else if (op == "!in") {
return parseSetFilter<NotInExpression>(value);
} else if (op == "all") {
return parseCompoundFilter<AllExpression>(value);
} else if (op == "any") {
return parseCompoundFilter<AnyExpression>(value);
} else if (op == "none") {
return parseCompoundFilter<NoneExpression>(value);
} else {
Log::Warning(Event::ParseStyle, "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\"");
return empty;
}
}
} // namespace mbgl

View File

@@ -1,124 +0,0 @@
#ifndef MBGL_STYLE_FILTER_EXPRESSION
#define MBGL_STYLE_FILTER_EXPRESSION
#include <mbgl/style/value.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <string>
#include <vector>
namespace mbgl {
typedef variant<
struct NullExpression,
struct EqualsExpression,
struct NotEqualsExpression,
struct LessThanExpression,
struct LessThanEqualsExpression,
struct GreaterThanExpression,
struct GreaterThanEqualsExpression,
struct InExpression,
struct NotInExpression,
struct AnyExpression,
struct AllExpression,
struct NoneExpression
> FilterExpression;
FilterExpression parseFilterExpression(const JSValue&);
template <class Extractor>
bool evaluate(const FilterExpression&, const Extractor&);
struct NullExpression {
template <class Extractor>
bool evaluate(const Extractor&) const { return true; }
};
struct EqualsExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct NotEqualsExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct LessThanExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct LessThanEqualsExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct GreaterThanExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct GreaterThanEqualsExpression {
std::string key;
Value value;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct InExpression {
std::string key;
std::vector<Value> values;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct NotInExpression {
std::string key;
std::vector<Value> values;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct AnyExpression {
std::vector<FilterExpression> expressions;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct AllExpression {
std::vector<FilterExpression> expressions;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
struct NoneExpression {
std::vector<FilterExpression> expressions;
template <class Extractor>
bool evaluate(const Extractor&) const;
};
} // namespace mbgl
#endif

View File

@@ -1,119 +0,0 @@
#include <mbgl/util/optional.hpp>
#include <mbgl/style/value_comparison.hpp>
namespace mbgl {
template <class Extractor>
struct Evaluator : public mapbox::util::static_visitor<bool>
{
const Extractor& extractor;
Evaluator(const Extractor& extractor_)
: extractor(extractor_) {}
template <class E>
bool operator()(const E& e) const { return e.evaluate(extractor); }
};
template <class Extractor>
bool evaluate(const FilterExpression& expression, const Extractor& extractor) {
return mapbox::util::apply_visitor(Evaluator<Extractor>(extractor), expression);
};
template <class Extractor>
bool EqualsExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return actual && util::relaxed_equal(*actual, value);
}
template <class Extractor>
bool NotEqualsExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return !actual || util::relaxed_not_equal(*actual, value);
}
template <class Extractor>
bool LessThanExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return actual && util::relaxed_less(*actual, value);
}
template <class Extractor>
bool LessThanEqualsExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return actual && util::relaxed_less_equal(*actual, value);
}
template <class Extractor>
bool GreaterThanExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return actual && util::relaxed_greater(*actual, value);
}
template <class Extractor>
bool GreaterThanEqualsExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
return actual && util::relaxed_greater_equal(*actual, value);
}
template <class Extractor>
bool InExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
if (!actual)
return false;
for (const auto& v: values) {
if (util::relaxed_equal(*actual, v)) {
return true;
}
}
return false;
}
template <class Extractor>
bool NotInExpression::evaluate(const Extractor& extractor) const {
optional<Value> actual = extractor.getValue(key);
if (!actual)
return true;
for (const auto& v: values) {
if (util::relaxed_equal(*actual, v)) {
return false;
}
}
return true;
}
template <class Extractor>
bool AnyExpression::evaluate(const Extractor& extractor) const {
Evaluator<Extractor> evaluator(extractor);
for (const auto& e: expressions) {
if (mapbox::util::apply_visitor(evaluator, e)) {
return true;
}
}
return false;
}
template <class Extractor>
bool AllExpression::evaluate(const Extractor& extractor) const {
Evaluator<Extractor> evaluator(extractor);
for (const auto& e: expressions) {
if (!mapbox::util::apply_visitor(evaluator, e)) {
return false;
}
}
return true;
}
template <class Extractor>
bool NoneExpression::evaluate(const Extractor& extractor) const {
Evaluator<Extractor> evaluator(extractor);
for (const auto& e: expressions) {
if (mapbox::util::apply_visitor(evaluator, e)) {
return false;
}
}
return true;
}
} // namespace mbgl

View File

@@ -1,15 +1,16 @@
#include <mbgl/style/style_bucket_parameters.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/tile/geometry_tile.hpp>
namespace mbgl {
void StyleBucketParameters::eachFilteredFeature(const FilterExpression& filter,
void StyleBucketParameters::eachFilteredFeature(const Filter& filter,
std::function<void (const GeometryTileFeature&)> function) {
for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) {
auto feature = layer.getFeature(i);
GeometryTileFeatureExtractor extractor(*feature);
if (!evaluate(filter, extractor))
FilterEvaluator<GeometryTileFeatureExtractor> evaluator(*feature);
if (!Filter::visit(filter, evaluator))
continue;
function(*feature);

View File

@@ -2,7 +2,7 @@
#define STYLE_BUCKET_PARAMETERS
#include <mbgl/map/mode.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/tile/tile_data.hpp>
#include <functional>
@@ -42,7 +42,7 @@ public:
return state == TileData::State::obsolete;
}
void eachFilteredFeature(const FilterExpression&, std::function<void (const GeometryTileFeature&)>);
void eachFilteredFeature(const Filter&, std::function<void (const GeometryTileFeature&)>);
const TileID& tileID;
const GeometryTileLayer& layer;

View File

@@ -2,7 +2,7 @@
#define MBGL_STYLE_STYLE_LAYER
#include <mbgl/style/types.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/rapidjson.hpp>
@@ -65,7 +65,7 @@ public:
std::string ref;
std::string source;
std::string sourceLayer;
FilterExpression filter;
Filter filter;
float minZoom = -std::numeric_limits<float>::infinity();
float maxZoom = std::numeric_limits<float>::infinity();
VisibilityType visibility = VisibilityType::Visible;

View File

@@ -11,6 +11,7 @@
#include <mapbox/geojsonvt.hpp>
#include <mapbox/geojsonvt/convert.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/util/mapbox.hpp>
#include <rapidjson/document.h>
@@ -451,7 +452,7 @@ void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::u
}
if (value.HasMember("filter")) {
layer->filter = parseFilterExpression(value["filter"]);
layer->filter = parseFilter(value["filter"]);
}
if (value.HasMember("minzoom")) {
@@ -497,6 +498,149 @@ void StyleParser::parseVisibility(StyleLayer& layer, const JSValue& value) {
layer.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
}
Value parseFeatureType(const Value& value) {
if (value == std::string("Point")) {
return Value(uint64_t(FeatureType::Point));
} else if (value == std::string("LineString")) {
return Value(uint64_t(FeatureType::LineString));
} else if (value == std::string("Polygon")) {
return Value(uint64_t(FeatureType::Polygon));
} else {
Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon");
return Value(uint64_t(FeatureType::Unknown));
}
}
Value parseValue(const JSValue& value) {
switch (value.GetType()) {
case rapidjson::kNullType:
case rapidjson::kFalseType:
return false;
case rapidjson::kTrueType:
return true;
case rapidjson::kStringType:
return std::string { value.GetString(), value.GetStringLength() };
case rapidjson::kNumberType:
if (value.IsUint64()) return value.GetUint64();
if (value.IsInt64()) return value.GetInt64();
return value.GetDouble();
default:
return false;
}
}
template <class Expression>
Filter parseBinaryFilter(const JSValue& value) {
Filter empty;
if (value.Size() < 3) {
Log::Warning(Event::ParseStyle, "filter expression must have 3 elements");
return empty;
}
if (!value[1u].IsString()) {
Log::Warning(Event::ParseStyle, "filter expression key must be a string");
return empty;
}
Expression expression;
expression.key = { value[1u].GetString(), value[1u].GetStringLength() };
expression.value = parseValue(value[2u]);
if (expression.key == "$type") {
expression.value = parseFeatureType(expression.value);
}
return expression;
}
template <class Expression>
Filter parseSetFilter(const JSValue& value) {
Filter empty;
if (value.Size() < 2) {
Log::Warning(Event::ParseStyle, "filter expression must at least 2 elements");
return empty;
}
if (!value[1u].IsString()) {
Log::Warning(Event::ParseStyle, "filter expression key must be a string");
return empty;
}
Expression expression;
expression.key = { value[1u].GetString(), value[1u].GetStringLength() };
for (rapidjson::SizeType i = 2; i < value.Size(); ++i) {
Value parsedValue = parseValue(value[i]);
if (expression.key == "$type") {
parsedValue = parseFeatureType(parsedValue);
}
expression.values.push_back(parsedValue);
}
return expression;
}
template <class Expression>
Filter parseCompoundFilter(const JSValue& value) {
Expression expression;
for (rapidjson::SizeType i = 1; i < value.Size(); ++i) {
expression.filters.push_back(parseFilter(value[i]));
}
return expression;
}
Filter parseFilter(const JSValue& value) {
Filter empty;
if (!value.IsArray()) {
Log::Warning(Event::ParseStyle, "filter expression must be an array");
return empty;
}
if (value.Size() < 1) {
Log::Warning(Event::ParseStyle, "filter expression must have at least 1 element");
return empty;
}
if (!value[0u].IsString()) {
Log::Warning(Event::ParseStyle, "filter operator must be a string");
return empty;
}
std::string op = { value[0u].GetString(), value[0u].GetStringLength() };
if (op == "==") {
return parseBinaryFilter<EqualsFilter>(value);
} else if (op == "!=") {
return parseBinaryFilter<NotEqualsFilter>(value);
} else if (op == ">") {
return parseBinaryFilter<GreaterThanFilter>(value);
} else if (op == ">=") {
return parseBinaryFilter<GreaterThanEqualsFilter>(value);
} else if (op == "<") {
return parseBinaryFilter<LessThanFilter>(value);
} else if (op == "<=") {
return parseBinaryFilter<LessThanEqualsFilter>(value);
} else if (op == "in") {
return parseSetFilter<InFilter>(value);
} else if (op == "!in") {
return parseSetFilter<NotInFilter>(value);
} else if (op == "all") {
return parseCompoundFilter<AllFilter>(value);
} else if (op == "any") {
return parseCompoundFilter<AnyFilter>(value);
} else if (op == "none") {
return parseCompoundFilter<NoneFilter>(value);
} else {
Log::Warning(Event::ParseStyle, "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\"");
return empty;
}
}
std::vector<FontStack> StyleParser::fontStacks() const {
std::set<FontStack> result;

View File

@@ -4,6 +4,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/source/source.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <vector>
@@ -17,6 +18,8 @@ namespace mbgl {
class StyleLayer;
class Source;
Filter parseFilter(const JSValue&);
class StyleParser {
public:
~StyleParser();

View File

@@ -1,33 +0,0 @@
#include <mbgl/style/value.hpp>
#include <mbgl/util/string.hpp>
std::string mbgl::toString(const mbgl::Value& value) {
if (value.is<std::string>()) return value.get<std::string>();
else if (value.is<bool>()) return value.get<bool>() ? "true" : "false";
else if (value.is<int64_t>()) return util::toString(value.get<int64_t>());
else if (value.is<uint64_t>()) return util::toString(value.get<uint64_t>());
else if (value.is<double>()) return util::toString(value.get<double>());
else return "null";
}
mbgl::Value mbgl::parseValue(const JSValue& value) {
switch (value.GetType()) {
case rapidjson::kNullType:
case rapidjson::kFalseType:
return false;
case rapidjson::kTrueType:
return true;
case rapidjson::kStringType:
return std::string { value.GetString(), value.GetStringLength() };
case rapidjson::kNumberType:
if (value.IsUint64()) return value.GetUint64();
if (value.IsInt64()) return value.GetInt64();
return value.GetDouble();
default:
return false;
}
}

View File

@@ -1,20 +0,0 @@
#ifndef MBGL_STYLE_VALUE
#define MBGL_STYLE_VALUE
#include <mbgl/util/variant.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <cstdlib>
#include <cerrno>
namespace mbgl {
typedef variant<bool, int64_t, uint64_t, double, std::string> Value;
std::string toString(const Value &value);
Value parseValue(const JSValue&);
} // namespace mbgl
#endif

View File

@@ -1,109 +0,0 @@
#ifndef MBGL_STYLE_VALUE_COMPARISON
#define MBGL_STYLE_VALUE_COMPARISON
#include <mbgl/style/value.hpp>
#include <cstdlib>
#include <cerrno>
namespace mbgl {
namespace util {
namespace detail {
template <typename Operator>
struct relaxed_operator_visitor {
typedef bool result_type;
template <typename T0, typename T1>
inline bool operator()(T0, T1) const { return false; }
template <typename T>
inline bool operator()(T lhs, T rhs) const { return Operator()(lhs, rhs); }
inline bool operator()(int64_t lhs, uint64_t rhs) const {
return Operator()(double(lhs), double(rhs));
}
inline bool operator()(int64_t lhs, double rhs) const {
return Operator()(double(lhs), rhs);
}
inline bool operator()(uint64_t lhs, int64_t rhs) const {
return Operator()(double(lhs), double(rhs));
}
inline bool operator()(uint64_t lhs, double rhs) const {
return Operator()(double(lhs), rhs);
}
inline bool operator()(double lhs, uint64_t rhs) const {
return Operator()(lhs, double(rhs));
}
inline bool operator()(double lhs, int64_t rhs) const {
return Operator()(lhs, double(rhs));
}
};
struct relaxed_equal_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs == rhs; }
};
struct relaxed_not_equal_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs != rhs; }
};
struct relaxed_greater_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs > rhs; }
};
struct relaxed_greater_equal_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs >= rhs; }
};
struct relaxed_less_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs < rhs; }
};
struct relaxed_less_equal_operator {
template <typename T0, typename T1>
inline bool operator()(T0 lhs, T1 rhs) const { return lhs <= rhs; }
};
} // end namespace detail
inline bool relaxed_equal(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_equal_operator>(), lhs, rhs);
}
inline bool relaxed_not_equal(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_not_equal_operator>(), lhs, rhs);
}
inline bool relaxed_greater(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_greater_operator>(), lhs, rhs);
}
inline bool relaxed_greater_equal(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_greater_equal_operator>(), lhs, rhs);
}
inline bool relaxed_less(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_less_operator>(), lhs, rhs);
}
inline bool relaxed_less_equal(Value const &lhs, Value const &rhs) {
return apply_visitor(detail::relaxed_operator_visitor<detail::relaxed_less_equal_operator>(), lhs, rhs);
}
} // namespace util
} // namespace mbgl
#endif

View File

@@ -1,6 +1,4 @@
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter_expression_private.hpp>
namespace mbgl {
@@ -12,6 +10,4 @@ optional<Value> GeometryTileFeatureExtractor::getValue(const std::string& key) c
return feature.getValue(key);
}
template bool evaluate(const FilterExpression&, const GeometryTileFeatureExtractor&);
} // namespace mbgl

View File

@@ -1,7 +1,7 @@
#ifndef MBGL_MAP_GEOMETRY_TILE
#define MBGL_MAP_GEOMETRY_TILE
#include <mbgl/style/value.hpp>
#include <mbgl/util/value.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/vec.hpp>

9
src/mbgl/util/value.hpp Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <mbgl/util/variant.hpp>
namespace mbgl {
typedef variant<bool, int64_t, uint64_t, double, std::string> Value;
} // namespace mbgl

View File

@@ -1,9 +1,11 @@
#include <iostream>
#include <mbgl/test/util.hpp>
#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter_expression_private.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <rapidjson/document.h>
#include <map>
@@ -36,24 +38,25 @@ private:
FeatureType type;
};
FilterExpression parse(const char * expression) {
Filter parse(const char * expression) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
doc.Parse<0>(expression);
return parseFilterExpression(doc);
return parseFilter(doc);
}
bool evaluate(const FilterExpression& expression, const Properties& properties, FeatureType type = FeatureType::Unknown) {
return mbgl::evaluate(expression, Extractor(properties, type));
bool evaluate(const Filter& filter, const Properties& properties, FeatureType type = FeatureType::Unknown) {
FilterEvaluator<Extractor> evaluator({properties, type});
return Filter::visit(filter, evaluator);
}
TEST(FilterComparison, EqualsString) {
FilterExpression f = parse("[\"==\", \"foo\", \"bar\"]");
TEST(Filter, EqualsString) {
Filter f = parse("[\"==\", \"foo\", \"bar\"]");
ASSERT_TRUE(evaluate(f, {{ "foo", std::string("bar") }}));
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("baz") }}));
};
TEST(FilterComparison, EqualsNumber) {
FilterExpression f = parse("[\"==\", \"foo\", 0]");
TEST(Filter, EqualsNumber) {
Filter f = parse("[\"==\", \"foo\", 0]");
ASSERT_TRUE(evaluate(f, {{ "foo", int64_t(0) }}));
ASSERT_TRUE(evaluate(f, {{ "foo", uint64_t(0) }}));
ASSERT_TRUE(evaluate(f, {{ "foo", double(0) }}));
@@ -66,20 +69,20 @@ TEST(FilterComparison, EqualsNumber) {
ASSERT_FALSE(evaluate(f, {{}}));
}
TEST(FilterComparison, EqualsType) {
FilterExpression f = parse("[\"==\", \"$type\", \"LineString\"]");
TEST(Filter, EqualsType) {
Filter f = parse("[\"==\", \"$type\", \"LineString\"]");
ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
}
TEST(FilterComparison, InType) {
FilterExpression f = parse("[\"in\", \"$type\", \"LineString\", \"Polygon\"]");
TEST(Filter, InType) {
Filter f = parse("[\"in\", \"$type\", \"LineString\", \"Polygon\"]");
ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
ASSERT_TRUE(evaluate(f, {{}}, FeatureType::Polygon));
}
TEST(FilterComparison, Any) {
TEST(Filter, Any) {
ASSERT_FALSE(evaluate(parse("[\"any\"]"), {{}}));
ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
@@ -89,7 +92,7 @@ TEST(FilterComparison, Any) {
{{ std::string("foo"), int64_t(1) }}));
}
TEST(FilterComparison, All) {
TEST(Filter, All) {
ASSERT_TRUE(evaluate(parse("[\"all\"]"), {{}}));
ASSERT_TRUE(evaluate(parse("[\"all\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
@@ -99,7 +102,7 @@ TEST(FilterComparison, All) {
{{ std::string("foo"), int64_t(1) }}));
}
TEST(FilterComparison, None) {
TEST(Filter, None) {
ASSERT_TRUE(evaluate(parse("[\"none\"]"), {{}}));
ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));

View File

@@ -1,459 +0,0 @@
#include <iostream>
#include <mbgl/test/util.hpp>
#include <mbgl/style/value.hpp>
#include <mbgl/style/value_comparison.hpp>
using namespace mbgl;
TEST(Variant, toString) {
// Force the default locale so we don't
// get results like "3,14" instead of "3.14".
std::locale::global(std::locale::classic());
EXPECT_EQ("lord", toString( (std::string)"lord" ));
EXPECT_EQ("36", toString( (uint64_t)36 ));
EXPECT_EQ("-239", toString( (int64_t)-239 ));
EXPECT_EQ("0", toString( (int64_t)0 ));
EXPECT_EQ("3.14159268", toString( (double)3.14159268 ));
EXPECT_EQ("3.1415926535897931", toString( (double)3.1415926535897931 ));
EXPECT_EQ("true", toString( true ));
EXPECT_EQ("false", toString( false ));
}
TEST(Variant, RelaxedEquality) {
// Compare to bool
EXPECT_TRUE(util::relaxed_equal(bool(false), bool(false)));
EXPECT_TRUE(util::relaxed_equal(bool(true), bool(true)));
EXPECT_FALSE(util::relaxed_equal(bool(false), bool(true)));
EXPECT_FALSE(util::relaxed_equal(bool(false), int64_t(0)));
EXPECT_FALSE(util::relaxed_equal(bool(false), uint64_t(0)));
EXPECT_FALSE(util::relaxed_equal(bool(false), double(0)));
EXPECT_FALSE(util::relaxed_equal(bool(false), std::string("0")));
EXPECT_FALSE(util::relaxed_equal(bool(false), std::string("")));
EXPECT_FALSE(util::relaxed_equal(bool(false), int64_t(386)));
EXPECT_FALSE(util::relaxed_equal(bool(false), int64_t(-7042)));
EXPECT_FALSE(util::relaxed_equal(bool(false), uint64_t(386)));
EXPECT_FALSE(util::relaxed_equal(bool(false), double(3.145)));
EXPECT_FALSE(util::relaxed_equal(bool(false), std::string("386")));
EXPECT_FALSE(util::relaxed_equal(bool(false), std::string("test")));
EXPECT_FALSE(util::relaxed_equal(bool(true), int64_t(1)));
EXPECT_FALSE(util::relaxed_equal(bool(true), uint64_t(1)));
EXPECT_FALSE(util::relaxed_equal(bool(true), double(1)));
EXPECT_FALSE(util::relaxed_equal(bool(true), std::string("1")));
EXPECT_FALSE(util::relaxed_equal(bool(true), bool(false)));
EXPECT_FALSE(util::relaxed_equal(bool(true), int64_t(386)));
EXPECT_FALSE(util::relaxed_equal(bool(true), int64_t(-7042)));
EXPECT_FALSE(util::relaxed_equal(bool(true), uint64_t(386)));
EXPECT_FALSE(util::relaxed_equal(bool(true), double(3.145)));
EXPECT_FALSE(util::relaxed_equal(bool(true), std::string("386")));
EXPECT_FALSE(util::relaxed_equal(bool(true), std::string("test")));
EXPECT_FALSE(util::relaxed_equal(bool(true), std::string("")));
// Compare to int64_t
EXPECT_TRUE(util::relaxed_equal(int64_t(386), int64_t(386)));
EXPECT_TRUE(util::relaxed_equal(int64_t(-7042), int64_t(-7042)));
EXPECT_TRUE(util::relaxed_equal(int64_t(386), uint64_t(386)));
EXPECT_TRUE(util::relaxed_equal(int64_t(386), double(386)));
EXPECT_FALSE(util::relaxed_equal(int64_t(386), std::string("386")));
EXPECT_FALSE(util::relaxed_equal(int64_t(1), bool(true)));
EXPECT_FALSE(util::relaxed_equal(int64_t(0), bool(false)));
EXPECT_FALSE(util::relaxed_equal(int64_t(386), int64_t(387)));
EXPECT_FALSE(util::relaxed_equal(int64_t(-7042), int64_t(-7043)));
EXPECT_FALSE(util::relaxed_equal(int64_t(386), uint64_t(387)));
EXPECT_FALSE(util::relaxed_equal(int64_t(386), double(387)));
EXPECT_FALSE(util::relaxed_equal(int64_t(386), std::string("387")));
EXPECT_FALSE(util::relaxed_equal(int64_t(1), bool(false)));
EXPECT_FALSE(util::relaxed_equal(int64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_equal(int64_t(1), std::string("true")));
EXPECT_FALSE(util::relaxed_equal(int64_t(0), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(int64_t(1), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(int64_t(0), std::string("true")));
// Compare to uint64_t
EXPECT_TRUE(util::relaxed_equal(uint64_t(386), int64_t(386)));
EXPECT_TRUE(util::relaxed_equal(uint64_t(386), uint64_t(386)));
EXPECT_TRUE(util::relaxed_equal(uint64_t(0), uint64_t(0)));
EXPECT_TRUE(util::relaxed_equal(uint64_t(386), double(386)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(386), std::string("386")));
EXPECT_FALSE(util::relaxed_equal(uint64_t(1), bool(true)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(0), bool(false)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(386), int64_t(387)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(386), uint64_t(387)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(0), uint64_t(1)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(386), double(387)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(386), std::string("387")));
EXPECT_FALSE(util::relaxed_equal(uint64_t(1), bool(false)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_equal(uint64_t(1), std::string("true")));
EXPECT_FALSE(util::relaxed_equal(uint64_t(0), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(uint64_t(1), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(uint64_t(0), std::string("true")));
// Compare to double
EXPECT_TRUE(util::relaxed_equal(double(3.159385), double(3.159385)));
EXPECT_TRUE(util::relaxed_equal(double(386), int64_t(386)));
EXPECT_TRUE(util::relaxed_equal(double(386), uint64_t(386)));
EXPECT_TRUE(util::relaxed_equal(double(0), uint64_t(0)));
EXPECT_TRUE(util::relaxed_equal(double(386), double(386)));
EXPECT_FALSE(util::relaxed_equal(double(386), std::string("386")));
EXPECT_FALSE(util::relaxed_equal(double(1), bool(true)));
EXPECT_FALSE(util::relaxed_equal(double(0), bool(false)));
EXPECT_FALSE(util::relaxed_equal(double(3.159385), double(3.159383)));
EXPECT_FALSE(util::relaxed_equal(double(386), int64_t(387)));
EXPECT_FALSE(util::relaxed_equal(double(386), uint64_t(387)));
EXPECT_FALSE(util::relaxed_equal(double(0), uint64_t(1)));
EXPECT_FALSE(util::relaxed_equal(double(386), double(387)));
EXPECT_FALSE(util::relaxed_equal(double(386), std::string("387")));
EXPECT_FALSE(util::relaxed_equal(double(1), bool(false)));
EXPECT_FALSE(util::relaxed_equal(double(0), bool(true)));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("true")));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("TRue")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("FALSe")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("null")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("Null")));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("false")));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("False")));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("null")));
EXPECT_FALSE(util::relaxed_equal(double(1), std::string("NULL")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("true")));
EXPECT_FALSE(util::relaxed_equal(double(0), std::string("TRUE")));
// Compare to string
EXPECT_TRUE(util::relaxed_equal(std::string("lord"), std::string("lord")));
EXPECT_FALSE(util::relaxed_equal(std::string("386"), int64_t(386)));
EXPECT_FALSE(util::relaxed_equal(std::string("-386"), int64_t(-386)));
EXPECT_FALSE(util::relaxed_equal(std::string("386"), uint64_t(386)));
EXPECT_FALSE(util::relaxed_equal(std::string("386.36"), double(386.36)));
EXPECT_FALSE(util::relaxed_equal(std::string(""), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("1"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("lord"), std::string("baron")));
EXPECT_FALSE(util::relaxed_equal(std::string("386"), int64_t(387)));
EXPECT_FALSE(util::relaxed_equal(std::string("-386"), int64_t(-387)));
EXPECT_FALSE(util::relaxed_equal(std::string("386"), uint64_t(387)));
EXPECT_FALSE(util::relaxed_equal(std::string("386.36"), double(386.37)));
EXPECT_FALSE(util::relaxed_equal(std::string("some string"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("true"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("True"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("false"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("fAlse"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("null"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("NULl"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("true"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("TRUE"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("some string"), bool(false)));
EXPECT_FALSE(util::relaxed_equal(std::string("false"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("FALSE"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("null"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string("NULl"), bool(true)));
EXPECT_FALSE(util::relaxed_equal(std::string(""), bool(true)));
}
TEST(Variant, RelaxedGreater) {
EXPECT_TRUE(util::relaxed_greater(std::string("387"), std::string("386")));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater(double(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater(bool(true), std::string("0")));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater(uint64_t(387), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater(int64_t(387), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater(double(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_greater(bool(true), uint64_t(0)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater(uint64_t(387), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater(int64_t(387), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater(double(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_greater(bool(true), int64_t(0)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), double(386.7)));
EXPECT_TRUE(util::relaxed_greater(uint64_t(387), double(386.7)));
EXPECT_TRUE(util::relaxed_greater(int64_t(387), double(386.7)));
EXPECT_TRUE(util::relaxed_greater(double(387), double(386.7)));
EXPECT_FALSE(util::relaxed_greater(bool(true), double(0)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), bool(true)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), bool(false)));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater(double(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater(double(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater(double(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater(double(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater(bool(true), double(0)));
EXPECT_FALSE(util::relaxed_greater(bool(true), double(0.5)));
EXPECT_TRUE(util::relaxed_greater(bool(true), bool(false)));
EXPECT_FALSE(util::relaxed_greater(bool(true), bool(true)));
EXPECT_FALSE(util::relaxed_greater(bool(true), int64_t(0)));
EXPECT_FALSE(util::relaxed_greater(bool(true), uint64_t(0)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), std::string("388")));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater(double(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater(bool(true), std::string("388")));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater(double(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater(bool(true), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater(double(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater(bool(true), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater(std::string("387"), double(388.7)));
EXPECT_FALSE(util::relaxed_greater(uint64_t(387), double(388.7)));
EXPECT_FALSE(util::relaxed_greater(int64_t(387), double(388.7)));
EXPECT_FALSE(util::relaxed_greater(double(387), double(388.7)));
EXPECT_FALSE(util::relaxed_greater(bool(true), double(388)));
EXPECT_FALSE(util::relaxed_greater(bool(true), bool(true)));
EXPECT_FALSE(util::relaxed_greater(bool(false), bool(false)));
}
TEST(Variant, RelaxedGreaterEqual) {
EXPECT_TRUE(util::relaxed_greater_equal(std::string("387"), std::string("386")));
EXPECT_TRUE(util::relaxed_greater_equal(std::string("387"), std::string("387")));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), std::string("387")));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), std::string("387")));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), std::string("386")));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), std::string("387")));
EXPECT_FALSE(util::relaxed_greater_equal(bool(true), std::string("0")));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), uint64_t(386)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), uint64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), uint64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), uint64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), uint64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), uint64_t(387)));
EXPECT_FALSE(util::relaxed_greater_equal(bool(true), uint64_t(0)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), int64_t(386)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), int64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), int64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), int64_t(387)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), int64_t(386)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), int64_t(387)));
EXPECT_FALSE(util::relaxed_greater_equal(bool(true), int64_t(0)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), double(386.7)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), double(387)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), double(386.7)));
EXPECT_TRUE(util::relaxed_greater_equal(uint64_t(387), double(387)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), double(386.7)));
EXPECT_TRUE(util::relaxed_greater_equal(int64_t(387), double(387)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), double(386.7)));
EXPECT_TRUE(util::relaxed_greater_equal(double(387), double(387)));
EXPECT_FALSE(util::relaxed_greater_equal(bool(true), double(0)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), bool(false)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), bool(true)));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), bool(false)));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), bool(true)));
EXPECT_TRUE(util::relaxed_greater_equal(bool(true), bool(false)));
EXPECT_TRUE(util::relaxed_greater_equal(bool(true), bool(true)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), std::string("388")));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), std::string("388")));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_greater_equal(std::string("387"), double(388.7)));
EXPECT_FALSE(util::relaxed_greater_equal(uint64_t(387), double(388.7)));
EXPECT_FALSE(util::relaxed_greater_equal(int64_t(387), double(388.7)));
EXPECT_FALSE(util::relaxed_greater_equal(double(387), double(388.7)));
}
TEST(Variant, RelaxedLess) {
EXPECT_TRUE(util::relaxed_less(std::string("387"), std::string("388")));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less(int64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less(double(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less(bool(false), std::string("388")));
EXPECT_FALSE(util::relaxed_less(bool(false), std::string("1")));
EXPECT_FALSE(util::relaxed_less(std::string("387"), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less(uint64_t(387), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less(int64_t(387), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less(double(387), uint64_t(388)));
EXPECT_FALSE(util::relaxed_less(bool(false), uint64_t(388)));
EXPECT_FALSE(util::relaxed_less(bool(false), uint64_t(1)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), int64_t(388)));
EXPECT_TRUE(util::relaxed_less(uint64_t(387), int64_t(388)));
EXPECT_TRUE(util::relaxed_less(int64_t(387), int64_t(388)));
EXPECT_TRUE(util::relaxed_less(double(387), int64_t(388)));
EXPECT_FALSE(util::relaxed_less(bool(false), int64_t(388)));
EXPECT_FALSE(util::relaxed_less(bool(false), int64_t(1)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), double(387.7)));
EXPECT_TRUE(util::relaxed_less(uint64_t(387), double(387.7)));
EXPECT_TRUE(util::relaxed_less(int64_t(387), double(387.7)));
EXPECT_TRUE(util::relaxed_less(double(387), double(387.7)));
EXPECT_FALSE(util::relaxed_less(bool(false), double(387)));
EXPECT_FALSE(util::relaxed_less(bool(false), double(1)));
EXPECT_FALSE(util::relaxed_less(std::string("0"), bool(true)));
EXPECT_FALSE(util::relaxed_less(uint64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_less(int64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_less(double(0), bool(true)));
EXPECT_TRUE(util::relaxed_less(bool(false), bool(true)));
EXPECT_FALSE(util::relaxed_less(bool(true), std::string("386")));
EXPECT_FALSE(util::relaxed_less(bool(true), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less(bool(true), int64_t(386)));
EXPECT_FALSE(util::relaxed_less(bool(true), double(386)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), std::string("386")));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less(int64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less(double(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less(std::string("387"), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less(int64_t(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less(double(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), int64_t(386)));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less(int64_t(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less(double(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), double(386.7)));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), double(386.7)));
EXPECT_FALSE(util::relaxed_less(int64_t(387), double(386.7)));
EXPECT_FALSE(util::relaxed_less(double(387), double(386.7)));
EXPECT_FALSE(util::relaxed_less(std::string("387"), bool(true)));
EXPECT_FALSE(util::relaxed_less(uint64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_less(int64_t(387), bool(true)));
EXPECT_FALSE(util::relaxed_less(double(387), bool(true)));
EXPECT_FALSE(util::relaxed_less(bool(true), bool(true)));
EXPECT_FALSE(util::relaxed_less(bool(false), bool(false)));
}
TEST(Variant, RelaxedLessEqual) {
EXPECT_TRUE(util::relaxed_less_equal(std::string("387"), std::string("388")));
EXPECT_TRUE(util::relaxed_less_equal(std::string("387"), std::string("387")));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), std::string("387")));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), std::string("387")));
EXPECT_FALSE(util::relaxed_less_equal(double(387), std::string("388")));
EXPECT_FALSE(util::relaxed_less_equal(double(387), std::string("387")));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), std::string("388")));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), std::string("1")));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), std::string("0")));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), uint64_t(388)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), uint64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), uint64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), uint64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), uint64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), uint64_t(387)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), uint64_t(388)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), uint64_t(1)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), uint64_t(0)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), int64_t(388)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), int64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), int64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), int64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), int64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), int64_t(387)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), int64_t(388)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), int64_t(387)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), int64_t(388)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), int64_t(1)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), int64_t(0)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), double(387.7)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), double(387)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), double(387.7)));
EXPECT_TRUE(util::relaxed_less_equal(uint64_t(387), double(387)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), double(387.7)));
EXPECT_TRUE(util::relaxed_less_equal(int64_t(387), double(387)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), double(387.7)));
EXPECT_TRUE(util::relaxed_less_equal(double(387), double(387)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), double(387)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), double(1)));
EXPECT_FALSE(util::relaxed_less_equal(bool(false), double(0)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("0"), bool(true)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("0"), bool(false)));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(0), bool(false)));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(0), bool(true)));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(0), bool(false)));
EXPECT_FALSE(util::relaxed_less_equal(double(0), bool(true)));
EXPECT_FALSE(util::relaxed_less_equal(double(0), bool(false)));
EXPECT_TRUE(util::relaxed_less_equal(bool(false), bool(true)));
EXPECT_TRUE(util::relaxed_less_equal(bool(false), bool(false)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), std::string("386")));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less_equal(double(387), std::string("386")));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(double(387), uint64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), int64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(double(387), int64_t(386)));
EXPECT_FALSE(util::relaxed_less_equal(std::string("387"), double(386.7)));
EXPECT_FALSE(util::relaxed_less_equal(uint64_t(387), double(386.7)));
EXPECT_FALSE(util::relaxed_less_equal(int64_t(387), double(386.7)));
EXPECT_FALSE(util::relaxed_less_equal(double(387), double(386.7)));
}

View File

@@ -59,10 +59,9 @@
'style/source.cpp',
'style/style.cpp',
'style/style_layer.cpp',
'style/comparisons.cpp',
'style/filter.cpp',
'style/functions.cpp',
'style/style_parser.cpp',
'style/variant.cpp',
'sprite/sprite_atlas.cpp',
'sprite/sprite_image.cpp',