#include #include #include namespace mbgl { namespace style { template struct Comparator { const Op& op; template bool operator()(const T& lhs, const T& rhs) const { return op(lhs, rhs); } template auto operator()(const T0& lhs, const T1& rhs) const -> typename std::enable_if_t::value && !std::is_same::value && std::is_arithmetic::value && !std::is_same::value, bool> { return op(double(lhs), double(rhs)); } template auto operator()(const T0&, const T1&) const -> typename std::enable_if_t::value || std::is_same::value || !std::is_arithmetic::value || std::is_same::value, bool> { return false; } bool operator()(const NullValue&, const NullValue&) const { // Should be unreachable; null is not currently allowed by the style specification. assert(false); return false; } bool operator()(const std::vector&, const std::vector&) const { // Should be unreachable; nested values are not currently allowed by the style specification. assert(false); return false; } bool operator()(const PropertyMap&, const PropertyMap&) const { // Should be unreachable; nested values are not currently allowed by the style specification. assert(false); return false; } }; template bool compare(const Value& lhs, const Value& rhs, const Op& op) { return Value::binary_visit(lhs, rhs, Comparator { op }); } bool equal(const Value& lhs, const Value& rhs) { return compare(lhs, rhs, [] (const auto& lhs_, const auto& rhs_) { return lhs_ == rhs_; }); } bool FilterEvaluator::operator()(const NullFilter&) const { return true; } bool FilterEvaluator::operator()(const EqualsFilter& filter) const { optional actual = context.feature->getValue(filter.key); return actual && equal(*actual, filter.value); } bool FilterEvaluator::operator()(const NotEqualsFilter& filter) const { optional actual = context.feature->getValue(filter.key); return !actual || !equal(*actual, filter.value); } bool FilterEvaluator::operator()(const LessThanFilter& filter) const { optional actual = context.feature->getValue(filter.key); return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; }); } bool FilterEvaluator::operator()(const LessThanEqualsFilter& filter) const { optional actual = context.feature->getValue(filter.key); return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; }); } bool FilterEvaluator::operator()(const GreaterThanFilter& filter) const { optional actual = context.feature->getValue(filter.key); return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; }); } bool FilterEvaluator::operator()(const GreaterThanEqualsFilter& filter) const { optional actual = context.feature->getValue(filter.key); return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; }); } bool FilterEvaluator::operator()(const InFilter& filter) const { optional actual = context.feature->getValue(filter.key); if (!actual) return false; for (const auto& v: filter.values) { if (equal(*actual, v)) { return true; } } return false; } bool FilterEvaluator::operator()(const NotInFilter& filter) const { optional actual = context.feature->getValue(filter.key); if (!actual) return true; for (const auto& v: filter.values) { if (equal(*actual, v)) { return false; } } return true; } bool FilterEvaluator::operator()(const AnyFilter& filter) const { for (const auto& f: filter.filters) { if (Filter::visit(f, *this)) { return true; } } return false; } bool FilterEvaluator::operator()(const AllFilter& filter) const { for (const auto& f: filter.filters) { if (!Filter::visit(f, *this)) { return false; } } return true; } bool FilterEvaluator::operator()(const NoneFilter& filter) const { for (const auto& f: filter.filters) { if (Filter::visit(f, *this)) { return false; } } return true; } bool FilterEvaluator::operator()(const HasFilter& filter) const { return bool(context.feature->getValue(filter.key)); } bool FilterEvaluator::operator()(const NotHasFilter& filter) const { return !context.feature->getValue(filter.key); } bool FilterEvaluator::operator()(const TypeEqualsFilter& filter) const { return context.feature->getType() == filter.value; } bool FilterEvaluator::operator()(const TypeNotEqualsFilter& filter) const { return context.feature->getType() != filter.value; } bool FilterEvaluator::operator()(const TypeInFilter& filter) const { for (const auto& v: filter.values) { if (context.feature->getType() == v) { return true; } } return false; } bool FilterEvaluator::operator()(const TypeNotInFilter& filter) const { for (const auto& v: filter.values) { if (context.feature->getType() == v) { return false; } } return true; } bool FilterEvaluator::operator()(const IdentifierEqualsFilter& filter) const { return context.feature->getID() == filter.value; } bool FilterEvaluator::operator()(const IdentifierNotEqualsFilter& filter) const { return context.feature->getID() != filter.value; } bool FilterEvaluator::operator()(const IdentifierInFilter& filter) const { for (const auto& v: filter.values) { if (context.feature->getID() == v) { return true; } } return false; } bool FilterEvaluator::operator()(const IdentifierNotInFilter& filter) const { for (const auto& v: filter.values) { if (context.feature->getID() == v) { return false; } } return true; } bool FilterEvaluator::operator()(const HasIdentifierFilter&) const { return bool(context.feature->getID()); } bool FilterEvaluator::operator()(const NotHasIdentifierFilter&) const { return !context.feature->getID(); } bool FilterEvaluator::operator()(const ExpressionFilter& filter) const { const expression::EvaluationResult result = filter.expression->evaluate(context); if (result) { const optional typed = expression::fromExpressionValue(*result); return typed ? *typed : false; } return false; } } // namespace style } // namespace mbgl