add noexcepts (#2119)

Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
Tim Sylvester
2024-04-08 08:39:18 -07:00
committed by GitHub
parent f868e0806f
commit 705bdfb3de
128 changed files with 1135 additions and 990 deletions

View File

@@ -389,7 +389,11 @@ public:
protected:
template <typename DataDrivenPaintProperty, typename Evaluated>
static bool isConstant(const Evaluated& evaluated) {
static bool isConstant(const Evaluated& evaluated) noexcept {
using PropType = decltype(evaluated.template get<DataDrivenPaintProperty>());
using MethodType = decltype(&std::remove_reference_t<PropType>::isConstant);
static_assert(std::is_nothrow_invocable_v<MethodType, PropType>, "isConstant() must be noexcept");
return evaluated.template get<DataDrivenPaintProperty>().isConstant();
}

View File

@@ -139,21 +139,21 @@ struct FreeCameraOptions {
std::optional<vec4> orientation = std::nullopt;
/** Helper function for setting the mercator position as Lat&Lng and altitude in meters */
void setLocation(const LatLngAltitude& location);
void setLocation(const LatLngAltitude& location) noexcept;
/** Helper function for converting mercator position into Lat&Lng and
altitude in meters. This function fails to return a value if `position`
is invalid or is not set */
std::optional<LatLngAltitude> getLocation() const;
std::optional<LatLngAltitude> getLocation() const noexcept;
/** Helper function for setting orientation of the camera by defining a
focus point on the map. Up vector is required in certain scenarios where
bearing can't be deduced from the viewing direction */
void lookAtPoint(const LatLng& location, const std::optional<vec3>& upVector = std::nullopt);
void lookAtPoint(const LatLng& location, const std::optional<vec3>& upVector = std::nullopt) noexcept;
/** Helper function for setting the orientation of the camera as a pitch and
a bearing. Both values are in degrees */
void setPitchBearing(double pitch, double bearing);
void setPitchBearing(double pitch, double bearing) noexcept;
};
} // namespace mbgl

View File

@@ -2,11 +2,13 @@
#include <mbgl/math/minmax.hpp>
#include <type_traits>
namespace mbgl {
namespace util {
template <typename T>
T clamp(T value, T min_, T max_) {
auto clamp(std::enable_if_t<std::is_scalar_v<T>, T> value, T min_, T max_) noexcept {
return max(min_, min(max_, value));
}

View File

@@ -15,24 +15,24 @@ class ColorRampPropertyValue {
private:
std::shared_ptr<expression::Expression> value;
friend bool operator==(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
friend bool operator==(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) noexcept {
return (lhs.isUndefined() && rhs.isUndefined()) || (lhs.value && rhs.value && *(lhs.value) == *(rhs.value));
}
friend bool operator!=(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
friend bool operator!=(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) noexcept {
return !(lhs == rhs);
}
public:
ColorRampPropertyValue() noexcept = default;
ColorRampPropertyValue(std::shared_ptr<expression::Expression> value_)
ColorRampPropertyValue(std::shared_ptr<expression::Expression> value_) noexcept
: value(std::move(value_)) {}
bool isUndefined() const { return value == nullptr; }
bool isUndefined() const noexcept { return value == nullptr; }
// noop, needed for batch evaluation of paint property values to compile
template <typename Evaluator>
Color evaluate(const Evaluator&, TimePoint = {}) const {
Color evaluate(const Evaluator&, TimePoint = {}) const noexcept {
return {};
}
@@ -41,10 +41,10 @@ public:
return *expression::fromExpressionValue<Color>(*result);
}
bool isDataDriven() const { return false; }
bool hasDataDrivenPropertyDifference(const ColorRampPropertyValue&) const { return false; }
bool isDataDriven() const noexcept { return false; }
bool hasDataDrivenPropertyDifference(const ColorRampPropertyValue&) const noexcept { return false; }
const expression::Expression& getExpression() const { return *value; }
const expression::Expression& getExpression() const noexcept { return *value; }
using Dependency = style::expression::Dependency;
Dependency getDependencies() const noexcept { return value ? value->dependencies : Dependency::None; }

View File

@@ -20,7 +20,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;

View File

@@ -20,7 +20,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
bool operator==(const Expression& e) const noexcept override {
if (e.getKind() == Kind::At) {
auto rhs = static_cast<const At*>(&e);
return *index == *(rhs->index) && *input == *(rhs->input);

View File

@@ -19,7 +19,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override { return "any"; }
@@ -38,7 +38,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override { return "all"; }

View File

@@ -26,7 +26,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;

View File

@@ -14,8 +14,8 @@ namespace expression {
class Coalesce : public Expression {
public:
using Args = std::vector<std::unique_ptr<Expression>>;
Coalesce(const type::Type& type_, Args args_)
: Expression(Kind::Coalesce, type_, collectDependencies(args_)),
Coalesce(type::Type type_, Args args_)
: Expression(Kind::Coalesce, std::move(type_), collectDependencies(args_)),
args(std::move(args_)) {}
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
@@ -24,11 +24,11 @@ public:
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::size_t getLength() const { return args.size(); }
std::size_t getLength() const noexcept { return args.size(); }
Expression* getChild(std::size_t i) const { return args.at(i).get(); }

View File

@@ -21,7 +21,7 @@ public:
mbgl::Value serialize() const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;

View File

@@ -21,7 +21,7 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression&) const override;
bool operator==(const Expression&) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override {
// Technically the set of possible outputs is the combinatoric set of

View File

@@ -20,10 +20,10 @@ public:
BasicComparison(std::string op, std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs);
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression&) const override;
bool operator==(const Expression&) const noexcept override;
EvaluationResult evaluate(const EvaluationContext&) const override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override;
std::string getOperator() const override { return op; }
private:
std::string op;
@@ -43,10 +43,10 @@ public:
std::unique_ptr<Expression> collator);
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression&) const override;
bool operator==(const Expression&) const noexcept override;
EvaluationResult evaluate(const EvaluationContext&) const override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override;
std::string getOperator() const override { return op; }
private:
std::string op;

View File

@@ -33,13 +33,13 @@ public:
std::string getOperator() const override;
EvaluationResult evaluate(const EvaluationContext& evaluationParams) const override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::vector<std::optional<Value>> possibleOutputs() const override { return {std::nullopt}; }
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::optional<std::size_t> getParameterCount() const;
std::optional<std::size_t> getParameterCount() const noexcept;
static bool exists(const std::string& name);
static bool exists(const std::string& name) noexcept;
protected:
const detail::SignatureBase& signature;

View File

@@ -22,21 +22,20 @@ namespace expression {
class Distance final : public Expression {
public:
Distance(GeoJSON geoJSONSource_, Feature::geometry_type geometries_);
~Distance() override;
EvaluationResult evaluate(const EvaluationContext&) const override;
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
void eachChild(const std::function<void(const Expression&)>&) const override {}
void eachChild(const std::function<void(const Expression&)>&) const noexcept override {}
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::vector<std::optional<Value>> possibleOutputs() const override { return {std::nullopt}; }
mbgl::Value serialize() const override;
std::string getOperator() const override;
std::string getOperator() const override { return "distance"; }
private:
GeoJSON geoJSONSource;

View File

@@ -29,11 +29,12 @@ std::unique_ptr<Expression> createExpression(const mbgl::style::conversion::Conv
std::unique_ptr<Expression> error(std::string);
std::unique_ptr<Expression> literal(const char* value);
std::unique_ptr<Expression> literal(Value&& value);
std::unique_ptr<Expression> literal(const Value& value);
std::unique_ptr<Expression> literal(std::initializer_list<double> value);
std::unique_ptr<Expression> literal(std::initializer_list<const char*> value);
std::unique_ptr<Expression> assertion(const type::Type&,
std::unique_ptr<Expression> assertion(type::Type,
std::unique_ptr<Expression>,
std::unique_ptr<Expression> def = nullptr);
std::unique_ptr<Expression> number(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr);
@@ -61,9 +62,9 @@ std::unique_ptr<Expression> step(std::unique_ptr<Expression> input,
double input1,
std::unique_ptr<Expression> output1);
Interpolator linear();
Interpolator exponential(double base);
Interpolator cubicBezier(double x1, double y1, double x2, double y2);
Interpolator linear() noexcept;
Interpolator exponential(double base) noexcept;
Interpolator cubicBezier(double x1, double y1, double x2, double y2) noexcept;
std::unique_ptr<Expression> interpolate(Interpolator interpolator,
std::unique_ptr<Expression> input,

View File

@@ -16,11 +16,11 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override {}
bool operator==(const Expression& e) const override { return e.getKind() == Kind::Error; }
bool operator==(const Expression& e) const noexcept override { return e.getKind() == Kind::Error; }
EvaluationResult evaluate(const EvaluationContext&) const override { return EvaluationError{message}; }
std::vector<std::optional<Value>> possibleOutputs() const override { return {}; }
std::vector<std::optional<Value>> possibleOutputs() const noexcept override { return {}; }
std::string getOperator() const override { return "error"; }

View File

@@ -29,23 +29,23 @@ public:
class EvaluationContext {
public:
EvaluationContext() = default;
explicit EvaluationContext(float zoom_)
explicit EvaluationContext(float zoom_) noexcept
: zoom(zoom_) {}
explicit EvaluationContext(GeometryTileFeature const* feature_)
explicit EvaluationContext(GeometryTileFeature const* feature_) noexcept
: feature(feature_) {}
EvaluationContext(float zoom_, GeometryTileFeature const* feature_)
EvaluationContext(float zoom_, GeometryTileFeature const* feature_) noexcept
: zoom(zoom_),
feature(feature_) {}
EvaluationContext(std::optional<mbgl::Value> accumulated_, GeometryTileFeature const* feature_)
EvaluationContext(std::optional<mbgl::Value> accumulated_, GeometryTileFeature const* feature_) noexcept(false)
: accumulated(std::move(accumulated_)),
feature(feature_) {}
EvaluationContext(float zoom_, GeometryTileFeature const* feature_, const FeatureState* state_)
EvaluationContext(float zoom_, GeometryTileFeature const* feature_, const FeatureState* state_) noexcept
: zoom(zoom_),
feature(feature_),
featureState(state_) {}
EvaluationContext(std::optional<float> zoom_,
GeometryTileFeature const* feature_,
std::optional<double> colorRampParameter_)
std::optional<double> colorRampParameter_) noexcept
: zoom(std::move(zoom_)),
feature(feature_),
colorRampParameter(std::move(colorRampParameter_)) {}
@@ -86,38 +86,45 @@ class Result : private variant<EvaluationError, T> {
public:
using variant<EvaluationError, T>::variant;
using Value = T;
using Variant = variant<EvaluationError, T>;
Result() = default;
static_assert(std::is_nothrow_constructible_v<Variant>);
template <typename U>
VARIANT_INLINE Result(U&& val)
: variant<EvaluationError, T>(val) {}
: Variant(std::forward<U>(val)) {}
explicit operator bool() const { return this->template is<T>(); }
template <typename U>
VARIANT_INLINE Result(const U& val)
: Variant(val) {}
explicit operator bool() const noexcept { return this->template is<T>(); }
// optional does some type trait magic for this one, so this might
// be problematic as is.
const T* operator->() const {
const T* operator->() const noexcept {
assert(this->template is<T>());
return std::addressof(this->template get<T>());
}
T* operator->() {
T* operator->() noexcept {
assert(this->template is<T>());
return std::addressof(this->template get<T>());
}
T& operator*() {
T& operator*() noexcept {
assert(this->template is<T>());
return this->template get<T>();
}
const T& operator*() const {
const T& operator*() const noexcept {
assert(this->template is<T>());
return this->template get<T>();
}
const EvaluationError& error() const {
const EvaluationError& error() const noexcept {
assert(this->template is<EvaluationError>());
return this->template get<EvaluationError>();
}
@@ -133,7 +140,7 @@ public:
: Result(toExpressionValue(arr)) {}
// used only for the special (private) "error" expression
EvaluationResult(const type::ErrorType&) { assert(false); }
EvaluationResult(const type::ErrorType&) noexcept { assert(false); }
};
/**
@@ -217,11 +224,12 @@ public:
virtual EvaluationResult evaluate(const EvaluationContext& params) const = 0;
virtual void eachChild(const std::function<void(const Expression&)>&) const = 0;
virtual bool operator==(const Expression&) const = 0;
bool operator!=(const Expression& rhs) const { return !operator==(rhs); }
Kind getKind() const { return kind; }
const type::Type& getType() const { return type; }
virtual bool operator==(const Expression&) const = 0;
bool operator!=(const Expression& rhs) const noexcept { return !operator==(rhs); }
Kind getKind() const noexcept { return kind; };
const type::Type& getType() const noexcept { return type; };
EvaluationResult evaluate(std::optional<float> zoom,
const Feature& feature,
@@ -258,33 +266,47 @@ public:
protected:
template <typename T>
static bool childrenEqual(const T& lhs, const T& rhs) {
static bool childrenEqual(const T& lhs, const T& rhs) noexcept {
if (lhs.size() != rhs.size()) return false;
for (auto leftChild = lhs.begin(), rightChild = rhs.begin(); leftChild != lhs.end();
leftChild++, rightChild++) {
if (!Expression::childEqual(*leftChild, *rightChild)) return false;
if (!Expression::childEqual(*leftChild, *rightChild)) {
return false;
}
}
return true;
}
static bool childEqual(const std::unique_ptr<Expression>& lhs, const std::unique_ptr<Expression>& rhs) {
static bool childEqual(const std::unique_ptr<Expression>& lhs, const std::unique_ptr<Expression>& rhs) noexcept {
return *lhs == *rhs;
}
template <typename T>
template <typename T, typename = std::enable_if_t<std::is_scalar_v<T>>>
static bool childEqual(const std::pair<T, std::unique_ptr<Expression>>& lhs,
const std::pair<T, std::unique_ptr<Expression>>& rhs) {
const std::pair<T, std::unique_ptr<Expression>>& rhs) noexcept {
return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
}
template <typename T>
template <typename T, typename = std::enable_if_t<std::is_scalar_v<T>>, typename = void>
static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs,
const std::pair<T, std::shared_ptr<Expression>>& rhs) {
const std::pair<T, std::shared_ptr<Expression>>& rhs) noexcept {
return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
}
template <typename T, typename = std::enable_if_t<!std::is_scalar_v<T>>>
static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs,
const std::pair<T, std::shared_ptr<Expression>>& rhs) noexcept {
#if __clang_major__ > 16
// On older compilers, this assignment doesn't do overload resolution
// in the same way that `lhs==rhs` does and produces ambiguity errors.
bool (*equality_method)(const T&, const T&) noexcept = &std::operator==;
static_assert(std::is_nothrow_invocable_v<decltype(equality_method), const T&, const T&>);
#endif
return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
}
static bool childEqual(const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& lhs,
const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& rhs) {
const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& rhs) noexcept {
return *(lhs.first) == *(rhs.first) && *(lhs.second) == *(rhs.second);
}

View File

@@ -32,15 +32,15 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override {
std::vector<std::optional<Value>> possibleOutputs() const noexcept override {
// Technically the combinatoric set of all children
// Usually, this.text will be undefined anyway
return {std::nullopt};
}
const std::vector<FormatExpressionSection>& getSections() const { return sections; }
const std::vector<FormatExpressionSection>& getSections() const noexcept { return sections; }
mbgl::Value serialize() const override;
std::string getOperator() const override { return "format"; }

View File

@@ -10,11 +10,9 @@ namespace expression {
template <class T>
class FormatSectionOverride final : public Expression {
public:
FormatSectionOverride(const type::Type& type_,
PossiblyEvaluatedPropertyValue<T> defaultValue_,
std::string propertyName_)
FormatSectionOverride(type::Type type_, PossiblyEvaluatedPropertyValue<T> defaultValue_, std::string propertyName_)
: Expression(Kind::FormatSectionOverride,
type_,
std::move(type_),
defaultValue_.getDependencies() | Dependency::Override | Dependency::Feature),
defaultValue(std::move(defaultValue_)),
propertyName(std::move(propertyName_)) {}

View File

@@ -10,7 +10,9 @@ namespace style {
namespace expression {
/// Return the smallest range of stops that covers the interval [lower, upper]
Range<float> getCoveringStops(const std::map<double, std::unique_ptr<Expression>>& stops, double lower, double upper);
Range<float> getCoveringStops(const std::map<double, std::unique_ptr<Expression>>& stops,
double lower,
double upper) noexcept;
} // namespace expression
} // namespace style

View File

@@ -17,7 +17,7 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override { return {std::nullopt}; }

View File

@@ -17,11 +17,11 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override;
std::string getOperator() const override { return "in"; }
private:
std::unique_ptr<Expression> needle;

View File

@@ -19,10 +19,10 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override;
std::string getOperator() const override { return "index-of"; }
private:
EvaluationResult evaluateForArrayInput(const std::vector<Value>& array,

View File

@@ -24,8 +24,8 @@ public:
std::unique_ptr<Expression> input_,
std::map<double, std::unique_ptr<Expression>> stops_);
const std::unique_ptr<Expression>& getInput() const { return input; }
const Interpolator& getInterpolator() const { return interpolator; }
const std::unique_ptr<Expression>& getInput() const noexcept { return input; }
const Interpolator& getInterpolator() const noexcept { return interpolator; }
void eachChild(const std::function<void(const Expression&)>& visit) const override {
visit(*input);
@@ -41,7 +41,7 @@ public:
}
// Return the smallest range of stops that covers the interval [lower, upper]
Range<float> getCoveringStops(const double lower, const double upper) const {
Range<float> getCoveringStops(const double lower, const double upper) const noexcept {
return ::mbgl::style::expression::getCoveringStops(stops, lower, upper);
}
@@ -50,9 +50,9 @@ public:
[&](const auto& interp) { return interp.interpolationFactor(inputLevels, inputValue); });
}
bool operator==(const Expression& e) const override {
bool operator==(const Expression& e) const noexcept override {
if (e.getKind() == Kind::Interpolate) {
auto rhs = static_cast<const Interpolate*>(&e);
const auto* rhs = static_cast<const Interpolate*>(&e);
if (interpolator != rhs->interpolator || *input != *(rhs->input) || stops.size() != rhs->stops.size()) {
return false;
}

View File

@@ -10,27 +10,27 @@ namespace expression {
class ExponentialInterpolator {
public:
ExponentialInterpolator(double base_)
ExponentialInterpolator(double base_) noexcept
: base(base_) {}
double base;
double interpolationFactor(const Range<double>& inputLevels, const double input) const {
double interpolationFactor(const Range<double>& inputLevels, const double input) const noexcept {
return util::interpolationFactor(
static_cast<float>(base),
Range<float>{static_cast<float>(inputLevels.min), static_cast<float>(inputLevels.max)},
static_cast<float>(input));
}
bool operator==(const ExponentialInterpolator& rhs) const { return base == rhs.base; }
bool operator==(const ExponentialInterpolator& rhs) const noexcept { return base == rhs.base; }
};
class CubicBezierInterpolator {
public:
CubicBezierInterpolator(double x1_, double y1_, double x2_, double y2_)
CubicBezierInterpolator(double x1_, double y1_, double x2_, double y2_) noexcept
: ub(x1_, y1_, x2_, y2_) {}
double interpolationFactor(const Range<double>& inputLevels, const double input) const {
double interpolationFactor(const Range<double>& inputLevels, const double input) const noexcept {
return ub.solve(util::interpolationFactor(
1.0f,
Range<float>{static_cast<float>(inputLevels.min), static_cast<float>(inputLevels.max)},
@@ -38,7 +38,7 @@ public:
1e-6);
}
bool operator==(const CubicBezierInterpolator& rhs) const { return ub == rhs.ub; }
bool operator==(const CubicBezierInterpolator& rhs) const noexcept { return ub == rhs.ub; }
util::UnitBezier ub;
};

View File

@@ -10,8 +10,8 @@ namespace expression {
template <typename T>
bool isGlobalPropertyConstant(const Expression& expression, const T& properties) {
if (expression.getKind() == Kind::CompoundExpression) {
auto e = static_cast<const CompoundExpression*>(&expression);
for (const std::string& property : properties) {
const auto* e = static_cast<const CompoundExpression*>(&expression);
for (const auto& property : properties) {
if (e->getOperator() == property) {
return false;
}

View File

@@ -19,7 +19,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override { return "length"; }

View File

@@ -26,9 +26,9 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
bool operator==(const Expression& e) const noexcept override {
if (e.getKind() == Kind::Let) {
auto rhs = static_cast<const Let*>(&e);
const auto* rhs = static_cast<const Let*>(&e);
return *result == *(rhs->result);
}
return false;
@@ -36,7 +36,7 @@ public:
std::vector<std::optional<Value>> possibleOutputs() const override;
Expression* getResult() const { return result.get(); }
Expression* getResult() const noexcept { return result.get(); }
mbgl::Value serialize() const override;
std::string getOperator() const override { return "let"; }
@@ -58,7 +58,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
bool operator==(const Expression& e) const noexcept override {
if (e.getKind() == Kind::Var) {
auto rhs = static_cast<const Var*>(&e);
return *value == *(rhs->value);
@@ -71,7 +71,7 @@ public:
mbgl::Value serialize() const override;
std::string getOperator() const override { return "var"; }
const std::shared_ptr<Expression>& getBoundExpression() const { return value; }
const std::shared_ptr<Expression>& getBoundExpression() const noexcept { return value; }
private:
std::string name;

View File

@@ -16,19 +16,23 @@ public:
: Expression(Kind::Literal, typeOf(value_), Dependency::None),
value(value_) {}
Literal(const type::Array& type_, std::vector<Value> value_)
: Expression(Kind::Literal, type_, Dependency::None),
Literal(Value&& value_)
: Expression(Kind::Literal, typeOf(value_), Dependency::None),
value(std::move(value_)) {}
Literal(type::Array type_, std::vector<Value> value_)
: Expression(Kind::Literal, std::move(type_), Dependency::None),
value(std::move(value_)) {}
EvaluationResult evaluate(const EvaluationContext&) const override { return value; }
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
void eachChild(const std::function<void(const Expression&)>&) const override {}
void eachChild(const std::function<void(const Expression&)>&) const noexcept override {}
bool operator==(const Expression& e) const override {
bool operator==(const Expression& e) const noexcept override {
if (e.getKind() == Kind::Literal) {
auto rhs = static_cast<const Literal*>(&e);
const auto* rhs = static_cast<const Literal*>(&e);
return value == rhs->value;
}
return false;
@@ -36,7 +40,7 @@ public:
std::vector<std::optional<Value>> possibleOutputs() const override { return {{value}}; }
Value getValue() const { return value; }
const Value& getValue() const noexcept { return value; }
mbgl::Value serialize() const override;
std::string getOperator() const override { return "literal"; }

View File

@@ -15,11 +15,12 @@ class Match : public Expression {
public:
using Branches = std::unordered_map<T, std::shared_ptr<Expression>>;
Match(const type::Type& type_,
Match(type::Type type_,
std::unique_ptr<Expression> input_,
Branches branches_,
std::unique_ptr<Expression> otherwise_)
: Expression(Kind::Match, type_, depsOf(input_) | depsOf(otherwise_) | collectDependencies(branches_)),
: Expression(
Kind::Match, std::move(type_), depsOf(input_) | depsOf(otherwise_) | collectDependencies(branches_)),
input(std::move(input_)),
branches(std::move(branches_)),
otherwise(std::move(otherwise_)) {}
@@ -28,7 +29,7 @@ public:
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;

View File

@@ -21,7 +21,7 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
mbgl::Value serialize() const override;

View File

@@ -91,7 +91,7 @@ public:
std::string getKey() const { return key; }
std::optional<type::Type> getExpected() const { return expected; }
const std::vector<ParsingError>& getErrors() const { return *errors; }
const std::vector<ParsingError>& getErrors() const noexcept { return *errors; }
std::string getCombinedErrors() const;
/**
@@ -150,7 +150,7 @@ public:
ctx.errors->clear();
}
void clearErrors() { errors->clear(); }
void clearErrors() noexcept { errors->clear(); }
private:
ParsingContext(std::string key_,
@@ -177,7 +177,7 @@ private:
std::shared_ptr<std::vector<ParsingError>> errors;
};
bool isExpression(const std::string&);
bool isExpression(const std::string&) noexcept;
} // namespace expression
} // namespace style

View File

@@ -19,10 +19,10 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
std::string getOperator() const override;
std::string getOperator() const override { return "slice"; }
private:
EvaluationResult evaluateForStringInput(const std::string& input, int fromIndexValue, int toIndexValue) const;

View File

@@ -16,18 +16,16 @@ namespace expression {
class Step : public Expression {
public:
Step(const type::Type& type_,
std::unique_ptr<Expression> input_,
std::map<double, std::unique_ptr<Expression>> stops_);
Step(type::Type type_, std::unique_ptr<Expression> input_, std::map<double, std::unique_ptr<Expression>> stops_);
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
void eachStop(const std::function<void(double, const Expression&)>& visit) const;
const std::unique_ptr<Expression>& getInput() const { return input; }
Range<float> getCoveringStops(double lower, double upper) const;
const std::unique_ptr<Expression>& getInput() const noexcept { return input; }
Range<float> getCoveringStops(double lower, double upper) const noexcept;
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;

View File

@@ -33,21 +33,26 @@ using ValueBase = variant<NullValue,
mapbox::util::recursive_wrapper<std::vector<Value>>,
mapbox::util::recursive_wrapper<std::unordered_map<std::string, Value>>>;
struct Value : ValueBase {
using ValueBase::ValueBase;
VARIANT_INLINE Value()
: ValueBase() {}
VARIANT_INLINE Value() noexcept {}
template <typename T>
VARIANT_INLINE Value(T&& val)
: ValueBase(std::forward<T>(val)) {}
template <typename T>
VARIANT_INLINE Value(const T& val)
: ValueBase(val) {}
// Javascript's Number.MAX_SAFE_INTEGER
static uint64_t maxSafeInteger() { return 9007199254740991ULL; }
static constexpr uint64_t maxSafeInteger() noexcept { return 9007199254740991ULL; }
static bool isSafeInteger(uint64_t x) { return x <= maxSafeInteger(); };
static bool isSafeInteger(int64_t x) { return static_cast<uint64_t>(x > 0 ? x : -x) <= maxSafeInteger(); }
static bool isSafeInteger(double x) { return static_cast<uint64_t>(x > 0 ? x : -x) <= maxSafeInteger(); }
static constexpr bool isSafeInteger(uint64_t x) noexcept { return x <= maxSafeInteger(); };
static constexpr bool isSafeInteger(int64_t x) noexcept {
return static_cast<uint64_t>(x > 0 ? x : -x) <= maxSafeInteger();
}
static constexpr bool isSafeInteger(double x) noexcept {
return static_cast<uint64_t>(x > 0 ? x : -x) <= maxSafeInteger();
}
};
constexpr NullValue Null = NullValue();

View File

@@ -19,14 +19,14 @@ public:
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
void eachChild(const std::function<void(const Expression&)>&) const override {}
void eachChild(const std::function<void(const Expression&)>&) const noexcept override {}
bool operator==(const Expression& e) const override;
bool operator==(const Expression& e) const noexcept override;
std::vector<std::optional<Value>> possibleOutputs() const override;
mbgl::Value serialize() const override;
std::string getOperator() const override;
std::string getOperator() const override { return "within"; }
private:
GeoJSON geoJSONSource;

View File

@@ -16,6 +16,7 @@ public:
virtual ~LayerProperties() = default;
/// Returns constants mask for the data-driven properties.
virtual unsigned long constantsMask() const { return 0u; }
Immutable<Layer::Impl> baseImpl;
/// Contains render passes used by the renderer, see `mbgl::RenderPass`.
uint8_t renderPasses = 0u;
@@ -23,7 +24,7 @@ public:
virtual expression::Dependency getDependencies() const noexcept = 0;
protected:
LayerProperties(Immutable<Layer::Impl> impl)
LayerProperties(Immutable<Layer::Impl> impl) noexcept
: baseImpl(std::move(impl)) {}
};

View File

@@ -14,7 +14,7 @@ namespace style {
class PropertyExpressionBase {
public:
explicit PropertyExpressionBase(std::unique_ptr<expression::Expression>);
explicit PropertyExpressionBase(std::unique_ptr<expression::Expression>) noexcept;
bool isZoomConstant() const noexcept { return isZoomConstant_; }
bool isFeatureConstant() const noexcept { return isFeatureConstant_; }
@@ -48,10 +48,12 @@ protected:
template <class T>
class PropertyExpression final : public PropertyExpressionBase {
static_assert(std::is_nothrow_move_constructible_v<T>);
public:
// Second parameter to be used only for conversions from legacy functions.
PropertyExpression(std::unique_ptr<expression::Expression> expression_,
std::optional<T> defaultValue_ = std::nullopt)
std::optional<T> defaultValue_ = std::nullopt) noexcept
: PropertyExpressionBase(std::move(expression_)),
defaultValue(std::move(defaultValue_)) {}
@@ -137,6 +139,8 @@ public:
return expression::fromExpressionValues<T>(expression->possibleOutputs());
}
using Expression = expression::Expression;
friend bool operator==(const PropertyExpression& lhs, const PropertyExpression& rhs) {
return *lhs.expression == *rhs.expression;
}

View File

@@ -14,40 +14,42 @@ private:
Value value;
friend bool operator==(const PropertyValue& lhs, const PropertyValue& rhs) { return lhs.value == rhs.value; }
friend bool operator==(const PropertyValue& lhs, const PropertyValue& rhs) noexcept {
return lhs.value == rhs.value;
}
friend bool operator!=(const PropertyValue& lhs, const PropertyValue& rhs) { return !(lhs == rhs); }
friend bool operator!=(const PropertyValue& lhs, const PropertyValue& rhs) noexcept { return !(lhs == rhs); }
public:
PropertyValue() = default;
PropertyValue(T constant)
: value(std::move(constant)) {}
: value(std::forward<T>(constant)) {}
PropertyValue(PropertyExpression<T> expression)
PropertyValue(PropertyExpression<T> expression) noexcept
: value(std::move(expression)) {}
bool isUndefined() const { return value.template is<Undefined>(); }
bool isUndefined() const noexcept { return value.template is<Undefined>(); }
bool isConstant() const { return value.template is<T>(); }
bool isConstant() const noexcept { return value.template is<T>(); }
bool isExpression() const { return value.template is<PropertyExpression<T>>(); }
bool isExpression() const noexcept { return value.template is<PropertyExpression<T>>(); }
bool isDataDriven() const {
bool isDataDriven() const noexcept {
return value.match([](const Undefined&) { return false; },
[](const T&) { return false; },
[](const PropertyExpression<T>& fn) { return !fn.isFeatureConstant(); });
}
bool isZoomConstant() const {
bool isZoomConstant() const noexcept {
return value.match([](const Undefined&) { return true; },
[](const T&) { return true; },
[](const PropertyExpression<T>& fn) { return fn.isZoomConstant(); });
}
const T& asConstant() const { return value.template get<T>(); }
const T& asConstant() const noexcept { return value.template get<T>(); }
const PropertyExpression<T>& asExpression() const { return value.template get<PropertyExpression<T>>(); }
const PropertyExpression<T>& asExpression() const noexcept { return value.template get<PropertyExpression<T>>(); }
template <class... Ts>
auto match(Ts&&... ts) const {
@@ -59,15 +61,15 @@ public:
return Value::visit(value, evaluator);
}
bool hasDataDrivenPropertyDifference(const PropertyValue<T>& other) const {
bool hasDataDrivenPropertyDifference(const PropertyValue<T>& other) const noexcept {
return *this != other && (isDataDriven() || other.isDataDriven());
}
using Dependency = style::expression::Dependency;
Dependency getDependencies() const noexcept {
return value.match([](const Undefined&) noexcept { return Dependency::None; },
[](const T&) noexcept { return Dependency::None; },
[](const PropertyExpression<T>& ex) noexcept { return ex.getDependencies(); });
return value.match([](const Undefined&) { return Dependency::None; },
[](const T&) { return Dependency::None; },
[](const PropertyExpression<T>& ex) { return ex.getDependencies(); });
}
};

View File

@@ -16,7 +16,7 @@ enum CompressionFormat {
std::string compress(const std::string& raw, int windowBits = CompressionFormat::ZLIB);
std::string decompress(const std::string& raw, int windowBits = CompressionFormat::DETECT);
std::uint32_t crc32(const void* raw, size_t size);
std::uint32_t crc32(const void* raw, size_t size) noexcept;
} // namespace util
} // namespace mbgl

View File

@@ -52,16 +52,16 @@ public:
}
}
double latitude() const { return lat; }
double longitude() const { return lon; }
double latitude() const noexcept { return lat; }
double longitude() const noexcept { return lon; }
LatLng wrapped() const { return {lat, lon, Wrapped}; }
LatLng wrapped() const noexcept { return {lat, lon, Wrapped}; }
void wrap() { lon = util::wrap(lon, -util::LONGITUDE_MAX, util::LONGITUDE_MAX); }
void wrap() noexcept { lon = util::wrap(lon, -util::LONGITUDE_MAX, util::LONGITUDE_MAX); }
// If the distance from start to end longitudes is between half and full
// world, unwrap the start longitude to ensure the shortest path is taken.
void unwrapForShortestPath(const LatLng& end) {
void unwrapForShortestPath(const LatLng& end) noexcept {
const double delta = std::abs(end.lon - lon);
if (delta <= util::LONGITUDE_MAX || delta >= util::DEGREES_MAX) return;
if (lon > 0 && end.lon < 0)
@@ -71,31 +71,31 @@ public:
}
// Constructs a LatLng object with the top left position of the specified tile.
LatLng(const CanonicalTileID& id);
LatLng(const UnwrappedTileID& id);
LatLng(const CanonicalTileID& id) noexcept;
LatLng(const UnwrappedTileID& id) noexcept;
friend bool operator==(const LatLng& a, const LatLng& b) { return a.lat == b.lat && a.lon == b.lon; }
friend bool operator==(const LatLng& a, const LatLng& b) noexcept { return a.lat == b.lat && a.lon == b.lon; }
friend bool operator!=(const LatLng& a, const LatLng& b) { return !(a == b); }
friend bool operator!=(const LatLng& a, const LatLng& b) noexcept { return !(a == b); }
};
class LatLngBounds {
public:
// Return a bounds covering the entire (unwrapped) world.
static LatLngBounds world() { return {{-90, -180}, {90, 180}}; }
static LatLngBounds world() noexcept { return {{-90, -180}, {90, 180}}; }
// Return the bounds consisting of the single point.
static LatLngBounds singleton(const LatLng& a) { return {a, a}; }
// Return the convex hull of two points; the smallest bounds that contains both.
static LatLngBounds hull(const LatLng& a, const LatLng& b) {
static LatLngBounds hull(const LatLng& a, const LatLng& b) noexcept {
LatLngBounds bounds(a, a);
bounds.extend(b);
return bounds;
}
// Return a bounds that may serve as the identity element for the extend operation.
static LatLngBounds empty() {
static LatLngBounds empty() noexcept {
LatLngBounds bounds = world();
std::swap(bounds.sw, bounds.ne);
return bounds;
@@ -106,61 +106,63 @@ public:
///
/// Note: this is different than LatLngBounds::world() since arbitrary
/// unwrapped coordinates are also inside the bounds.
LatLngBounds()
LatLngBounds() noexcept
: sw({-90, -180}),
ne({90, 180}),
bounded(false) {}
// Constructs a LatLngBounds object with the tile's exact boundaries.
LatLngBounds(const CanonicalTileID&);
LatLngBounds(const CanonicalTileID&) noexcept;
bool valid() const { return (sw.latitude() <= ne.latitude()) && (sw.longitude() <= ne.longitude()); }
bool valid() const noexcept { return (sw.latitude() <= ne.latitude()) && (sw.longitude() <= ne.longitude()); }
double south() const { return sw.latitude(); }
double west() const { return sw.longitude(); }
double north() const { return ne.latitude(); }
double east() const { return ne.longitude(); }
double south() const noexcept { return sw.latitude(); }
double west() const noexcept { return sw.longitude(); }
double north() const noexcept { return ne.latitude(); }
double east() const noexcept { return ne.longitude(); }
LatLng southwest() const { return sw; }
LatLng northeast() const { return ne; }
LatLng southeast() const { return {south(), east()}; }
LatLng northwest() const { return {north(), west()}; }
LatLng southwest() const noexcept { return sw; }
LatLng northeast() const noexcept { return ne; }
LatLng southeast() const noexcept { return {south(), east()}; }
LatLng northwest() const noexcept { return {north(), west()}; }
LatLng center() const { return {(sw.latitude() + ne.latitude()) / 2, (sw.longitude() + ne.longitude()) / 2}; }
LatLng center() const noexcept {
return {(sw.latitude() + ne.latitude()) / 2, (sw.longitude() + ne.longitude()) / 2};
}
LatLng constrain(const LatLng& p) const;
LatLng constrain(const LatLng& p) const noexcept;
void extend(const LatLng& point) {
void extend(const LatLng& point) noexcept {
sw = LatLng(std::min(point.latitude(), sw.latitude()), std::min(point.longitude(), sw.longitude()));
ne = LatLng(std::max(point.latitude(), ne.latitude()), std::max(point.longitude(), ne.longitude()));
}
void extend(const LatLngBounds& bounds) {
void extend(const LatLngBounds& bounds) noexcept {
extend(bounds.sw);
extend(bounds.ne);
}
bool isEmpty() const { return sw.latitude() > ne.latitude() || sw.longitude() > ne.longitude(); }
bool isEmpty() const noexcept { return sw.latitude() > ne.latitude() || sw.longitude() > ne.longitude(); }
bool crossesAntimeridian() const { return (sw.wrapped().longitude() > ne.wrapped().longitude()); }
bool crossesAntimeridian() const noexcept { return (sw.wrapped().longitude() > ne.wrapped().longitude()); }
bool contains(const CanonicalTileID& tileID) const;
bool contains(const LatLng& point, LatLng::WrapMode wrap = LatLng::Unwrapped) const;
bool contains(const LatLngBounds& area, LatLng::WrapMode wrap = LatLng::Unwrapped) const;
bool contains(const CanonicalTileID& tileID) const noexcept;
bool contains(const LatLng& point, LatLng::WrapMode wrap = LatLng::Unwrapped) const noexcept;
bool contains(const LatLngBounds& area, LatLng::WrapMode wrap = LatLng::Unwrapped) const noexcept;
bool intersects(LatLngBounds area, LatLng::WrapMode wrap = LatLng::Unwrapped) const;
bool intersects(LatLngBounds area, LatLng::WrapMode wrap = LatLng::Unwrapped) const noexcept;
private:
LatLng sw;
LatLng ne;
bool bounded = true;
LatLngBounds(LatLng sw_, LatLng ne_)
LatLngBounds(LatLng sw_, LatLng ne_) noexcept
: sw(sw_),
ne(ne_) {}
bool containsLatitude(double latitude) const;
bool containsLongitude(double longitude, LatLng::WrapMode wrap) const;
bool containsLatitude(double latitude) const noexcept;
bool containsLongitude(double longitude, LatLng::WrapMode wrap) const noexcept;
friend bool operator==(const LatLngBounds& a, const LatLngBounds& b) {
return (!a.bounded && !b.bounded) || (a.bounded && b.bounded && a.sw == b.sw && a.ne == b.ne);
@@ -205,12 +207,12 @@ public:
}
}
double top() const { return _top; }
double left() const { return _left; }
double bottom() const { return _bottom; }
double right() const { return _right; }
double top() const noexcept { return _top; }
double left() const noexcept { return _left; }
double bottom() const noexcept { return _bottom; }
double right() const noexcept { return _right; }
bool isFlush() const { return _top == 0 && _left == 0 && _bottom == 0 && _right == 0; }
bool isFlush() const noexcept { return _top == 0 && _left == 0 && _bottom == 0 && _right == 0; }
void operator+=(const EdgeInsets& o) {
_top += o._top;
@@ -219,7 +221,7 @@ public:
_right += o._right;
}
EdgeInsets operator+(const EdgeInsets& o) const {
EdgeInsets operator+(const EdgeInsets& o) const noexcept {
return {
_top + o._top,
_left + o._left,
@@ -228,13 +230,13 @@ public:
};
}
ScreenCoordinate getCenter(uint16_t width, uint16_t height) const;
ScreenCoordinate getCenter(uint16_t width, uint16_t height) const noexcept;
friend bool operator==(const EdgeInsets& a, const EdgeInsets& b) {
friend bool operator==(const EdgeInsets& a, const EdgeInsets& b) noexcept {
return a._top == b._top && a._left == b._left && a._bottom == b._bottom && a._right == b._right;
}
friend bool operator!=(const EdgeInsets& a, const EdgeInsets& b) { return !(a == b); }
friend bool operator!=(const EdgeInsets& a, const EdgeInsets& b) noexcept { return !(a == b); }
};
struct LatLngAltitude {

View File

@@ -12,25 +12,25 @@ namespace util {
*/
class SimpleIdentity final {
private:
constexpr SimpleIdentity(std::int64_t id)
constexpr SimpleIdentity(std::int64_t id) noexcept
: uniqueID(id) {}
public:
SimpleIdentity();
SimpleIdentity() noexcept;
SimpleIdentity(const SimpleIdentity&) = default;
~SimpleIdentity() = default;
static const SimpleIdentity Empty;
bool operator<(const SimpleIdentity& other) const { return uniqueID < other.uniqueID; }
bool operator==(const SimpleIdentity& other) const { return uniqueID == other.uniqueID; }
bool operator!=(const SimpleIdentity& other) const { return uniqueID != other.uniqueID; }
bool operator<(const SimpleIdentity& other) const noexcept { return uniqueID < other.uniqueID; }
bool operator==(const SimpleIdentity& other) const noexcept { return uniqueID == other.uniqueID; }
bool operator!=(const SimpleIdentity& other) const noexcept { return uniqueID != other.uniqueID; }
std::int64_t id() const { return uniqueID; }
bool isEmpty() const { return uniqueID != emptyID; }
std::int64_t id() const noexcept { return uniqueID; }
bool isEmpty() const noexcept { return uniqueID != emptyID; }
operator bool() const { return isEmpty(); }
bool operator!() const { return !isEmpty(); }
operator bool() const noexcept { return isEmpty(); }
bool operator!() const noexcept { return !isEmpty(); }
private:
static constexpr std::int64_t emptyID = 0;
@@ -46,7 +46,7 @@ protected:
SimpleIdentifiable(const SimpleIdentifiable&) = default;
virtual ~SimpleIdentifiable() = default;
const util::SimpleIdentity& getId() const { return uniqueID; }
const util::SimpleIdentity& getId() const noexcept { return uniqueID; }
protected:
util::SimpleIdentity uniqueID;

View File

@@ -13,15 +13,15 @@ namespace util {
/// https://github.com/mapbox/cpp/blob/1bb519ef25edd6169f1d6d8a65414044616590a9/docs/structural-metaprogramming.md
/// for more details.
template <class... Ts>
void ignore(Ts&&...) {}
void ignore(Ts&&...) noexcept {}
// std::initializer_list overload, for situations where you need sequenced
// modifications.
template <class T>
void ignore(const std::initializer_list<T>&) {}
void ignore(const std::initializer_list<T>&) noexcept {}
// Handle the zero-argument case.
inline void ignore(const std::initializer_list<int>&) {}
inline void ignore(const std::initializer_list<int>&) noexcept {}
} // namespace util
} // namespace mbgl

View File

@@ -28,12 +28,12 @@ public:
Mutable(const Mutable&) = delete;
Mutable& operator=(const Mutable&) = delete;
T* get() { return ptr.get(); }
T* operator->() { return ptr.get(); }
T& operator*() { return *ptr; }
T* get() noexcept { return ptr.get(); }
T* operator->() noexcept { return ptr.get(); }
T& operator*() noexcept { return *ptr; }
private:
Mutable(std::shared_ptr<T>&& s)
Mutable(std::shared_ptr<T>&& s) noexcept
: ptr(std::move(s)) {}
std::shared_ptr<T> ptr;
@@ -45,7 +45,7 @@ private:
friend Mutable<S> makeMutable(Args&&...);
// NOLINTNEXTLINE(readability-redundant-declaration)
template <class S, class U>
friend Mutable<S> staticMutableCast(const Mutable<U>&);
friend Mutable<S> staticMutableCast(const Mutable<U>&) noexcept;
};
template <class T, class... Args>
@@ -54,7 +54,7 @@ Mutable<T> makeMutable(Args&&... args) {
}
template <class S, class U>
Mutable<S> staticMutableCast(const Mutable<U>& u) {
Mutable<S> staticMutableCast(const Mutable<U>& u) noexcept {
return Mutable<S>(std::static_pointer_cast<S>(u.ptr));
}
@@ -73,18 +73,18 @@ template <class T>
class Immutable {
public:
template <class S>
Immutable(Mutable<S>&& s)
Immutable(Mutable<S>&& s) noexcept
: ptr(std::const_pointer_cast<const S>(std::move(s.ptr))) {}
template <class S>
Immutable(Immutable<S> s)
Immutable(Immutable<S> s) noexcept
: ptr(std::move(s.ptr)) {}
Immutable(Immutable&&) noexcept = default;
Immutable(const Immutable&) = default;
template <class S>
Immutable& operator=(Mutable<S>&& s) {
Immutable& operator=(Mutable<S>&& s) noexcept {
ptr = std::const_pointer_cast<const S>(std::move(s.ptr));
return *this;
}
@@ -92,16 +92,16 @@ public:
Immutable& operator=(Immutable&&) noexcept = default;
Immutable& operator=(const Immutable&) = default;
const T* get() const { return ptr.get(); }
const T* operator->() const { return ptr.get(); }
const T& operator*() const { return *ptr; }
const T* get() const noexcept { return ptr.get(); }
const T* operator->() const noexcept { return ptr.get(); }
const T& operator*() const noexcept { return *ptr; }
friend bool operator==(const Immutable<T>& lhs, const Immutable<T>& rhs) { return lhs.ptr == rhs.ptr; }
friend bool operator==(const Immutable<T>& lhs, const Immutable<T>& rhs) noexcept { return lhs.ptr == rhs.ptr; }
friend bool operator!=(const Immutable<T>& lhs, const Immutable<T>& rhs) { return lhs.ptr != rhs.ptr; }
friend bool operator!=(const Immutable<T>& lhs, const Immutable<T>& rhs) noexcept { return lhs.ptr != rhs.ptr; }
private:
Immutable(std::shared_ptr<const T>&& s)
Immutable(std::shared_ptr<const T>&& s) noexcept
: ptr(std::move(s)) {}
std::shared_ptr<const T> ptr;
@@ -111,11 +111,11 @@ private:
// NOLINTNEXTLINE(readability-redundant-declaration)
template <class S, class U>
friend Immutable<S> staticImmutableCast(const Immutable<U>&);
friend Immutable<S> staticImmutableCast(const Immutable<U>&) noexcept;
};
template <class S, class U>
Immutable<S> staticImmutableCast(const Immutable<U>& u) {
Immutable<S> staticImmutableCast(const Immutable<U>& u) noexcept {
return Immutable<S>(std::static_pointer_cast<const S>(u.ptr));
}

View File

@@ -41,7 +41,7 @@ public:
template <class... Us>
IndexedTuple(Us&&... other)
: std::tuple<Ts...>(std::forward<Us>(other)...){};
: std::tuple<Ts...>(std::forward<Us>(other)...) {}
template <class... Js, class... Us>
IndexedTuple<TypeList<Is..., Js...>, TypeList<Ts..., Us...>> concat(
@@ -54,7 +54,9 @@ public:
return static_cast<const std::tuple<Ts...>&>(*this) == static_cast<const std::tuple<Ts...>&>(other);
}
bool operator!=(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const { return !(*this == other); }
bool operator!=(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& other) const noexcept {
return !(*this == other);
}
};
template <class, class T>

View File

@@ -15,7 +15,7 @@
namespace mbgl {
namespace util {
float interpolationFactor(float base, Range<float> range, float z);
float interpolationFactor(float base, Range<float> range, float z) noexcept;
template <class T, class Enabled = void>
struct Interpolator;
@@ -37,9 +37,9 @@ struct Interpolator {
template <>
struct Interpolator<float> {
float operator()(const float& a, const float& b, const float t) const { return a * (1.0f - t) + b * t; }
float operator()(const float& a, const float& b, const float t) const noexcept { return a * (1.0f - t) + b * t; }
float operator()(const float& a, const float& b, const double t) const {
float operator()(const float& a, const float& b, const double t) const noexcept {
return static_cast<float>(a * (1.0 - t) + b * t);
}
};
@@ -50,12 +50,12 @@ private:
using Array = std::array<T, N>;
template <std::size_t... I>
Array operator()(const Array& a, const Array& b, const double t, std::index_sequence<I...>) {
Array operator()(const Array& a, const Array& b, const double t, std::index_sequence<I...>) noexcept {
return {{interpolate(a[I], b[I], t)...}};
}
public:
Array operator()(const Array& a, const Array& b, const double t) {
Array operator()(const Array& a, const Array& b, const double t) noexcept {
return operator()(a, b, t, std::make_index_sequence<N>());
}
};
@@ -66,12 +66,12 @@ private:
using Array = std::array<float, N>;
template <std::size_t... I>
Array operator()(const Array& a, const Array& b, const float t, std::index_sequence<I...>) {
Array operator()(const Array& a, const Array& b, const float t, std::index_sequence<I...>) noexcept {
return {{interpolate(a[I], b[I], t)...}};
}
public:
Array operator()(const Array& a, const Array& b, const float t) {
Array operator()(const Array& a, const Array& b, const float t) noexcept {
return operator()(a, b, t, std::make_index_sequence<N>());
}
};
@@ -105,7 +105,7 @@ struct Interpolator<std::vector<style::expression::Value>> {
template <>
struct Interpolator<style::Position> {
public:
style::Position operator()(const style::Position& a, const style::Position& b, const float t) {
style::Position operator()(const style::Position& a, const style::Position& b, const float t) noexcept {
auto pos = style::Position();
auto interpolated = interpolate(a.getCartesian(), b.getCartesian(), t);
pos.setCartesian(interpolated);
@@ -116,11 +116,11 @@ public:
template <>
struct Interpolator<Color> {
public:
Color operator()(const Color& a, const Color& b, const float t) {
Color operator()(const Color& a, const Color& b, const float t) noexcept {
return {interpolate(a.r, b.r, t), interpolate(a.g, b.g, t), interpolate(a.b, b.b, t), interpolate(a.a, b.a, t)};
}
Color operator()(const Color& a, const Color& b, const double t) {
Color operator()(const Color& a, const Color& b, const double t) noexcept {
return {interpolate(a.r, b.r, t), interpolate(a.g, b.g, t), interpolate(a.b, b.b, t), interpolate(a.a, b.a, t)};
}
};
@@ -128,7 +128,7 @@ public:
template <>
struct Interpolator<style::Rotation> {
public:
style::Rotation operator()(const style::Rotation& a, const style::Rotation& b, const double t) {
style::Rotation operator()(const style::Rotation& a, const style::Rotation& b, const double t) noexcept {
assert(a.period() == b.period());
auto period = a.period();
auto aAngle = std::fmod(a.getAngle(), period);

View File

@@ -38,30 +38,30 @@ public:
Log();
~Log();
static void useLogThread(bool enable);
static void useLogThread(bool enable) noexcept;
template <typename... Args>
static void Debug(Event event, Args&&... args) {
static void Debug(Event event, Args&&... args) noexcept {
Record(EventSeverity::Debug, event, ::std::forward<Args>(args)...);
}
template <typename... Args>
static void Info(Event event, Args&&... args) {
static void Info(Event event, Args&&... args) noexcept {
Record(EventSeverity::Info, event, ::std::forward<Args>(args)...);
}
template <typename... Args>
static void Warning(Event event, Args&&... args) {
static void Warning(Event event, Args&&... args) noexcept {
Record(EventSeverity::Warning, event, ::std::forward<Args>(args)...);
}
template <typename... Args>
static void Error(Event event, Args&&... args) {
static void Error(Event event, Args&&... args) noexcept {
Record(EventSeverity::Error, event, ::std::forward<Args>(args)...);
}
template <typename... Args>
static void Record(EventSeverity severity, Event event, Args&&... args) {
static void Record(EventSeverity severity, Event event, Args&&... args) noexcept {
if (!includes(severity, disabledEventSeverities) && !includes(event, disabledEvents) &&
!includes({severity, event}, disabledEventPermutations)) {
record(severity, event, ::std::forward<Args>(args)...);
@@ -71,8 +71,8 @@ public:
private:
static Log* get() noexcept;
static void record(EventSeverity severity, Event event, const std::string& msg);
static void record(EventSeverity severity, Event event, int64_t code, const std::string& msg);
static void record(EventSeverity severity, Event event, const std::string& msg) noexcept;
static void record(EventSeverity severity, Event event, int64_t code, const std::string& msg) noexcept;
static void record(EventSeverity severity,
Event event,
int64_t code,

View File

@@ -40,9 +40,9 @@ public:
class Projection {
public:
// Map pixel width at given scale.
static double worldSize(double scale) { return scale * util::tileSize_D; }
static double worldSize(double scale) noexcept { return scale * util::tileSize_D; }
static double getMetersPerPixelAtLatitude(double lat, double zoom) {
static double getMetersPerPixelAtLatitude(double lat, double zoom) noexcept {
const double constrainedZoom = util::clamp(zoom, util::MIN_ZOOM, util::MAX_ZOOM);
const double constrainedScale = std::pow(2.0, constrainedZoom);
const double constrainedLatitude = util::clamp(lat, -util::LATITUDE_MAX, util::LATITUDE_MAX);
@@ -50,7 +50,7 @@ public:
worldSize(constrainedScale);
}
static ProjectedMeters projectedMetersForLatLng(const LatLng& latLng) {
static ProjectedMeters projectedMetersForLatLng(const LatLng& latLng) noexcept {
const double constrainedLatitude = util::clamp(latLng.latitude(), -util::LATITUDE_MAX, util::LATITUDE_MAX);
const double constrainedLongitude = util::clamp(latLng.longitude(), -util::LONGITUDE_MAX, util::LONGITUDE_MAX);
@@ -74,10 +74,12 @@ public:
return {latitude, longitude};
}
static Point<double> project(const LatLng& latLng, double scale) { return project_(latLng, worldSize(scale)); }
static Point<double> project(const LatLng& latLng, double scale) noexcept {
return project_(latLng, worldSize(scale));
}
/// Returns point on tile
static Point<double> project(const LatLng& latLng, int32_t zoom) { return project_(latLng, 1 << zoom); }
static Point<double> project(const LatLng& latLng, int32_t zoom) noexcept { return project_(latLng, 1 << zoom); }
static LatLng unproject(const Point<double>& p, double scale, LatLng::WrapMode wrapMode = LatLng::Unwrapped) {
auto p2 = p * util::DEGREES_MAX / worldSize(scale);
@@ -87,7 +89,7 @@ public:
}
private:
static Point<double> project_(const LatLng& latLng, double worldSize) {
static Point<double> project_(const LatLng& latLng, double worldSize) noexcept {
const double latitude = util::clamp(latLng.latitude(), -util::LATITUDE_MAX, util::LATITUDE_MAX);
return Point<double>{util::LONGITUDE_MAX + latLng.longitude(),
util::LONGITUDE_MAX -

View File

@@ -16,12 +16,12 @@ public:
};
template <class T>
bool operator==(const Range<T>& a, const Range<T>& b) {
constexpr bool operator==(const Range<T>& a, const Range<T>& b) {
return a.min == b.min && a.max == b.max;
}
template <class T>
bool operator!=(const Range<T>& a, const Range<T>& b) {
constexpr bool operator!=(const Range<T>& a, const Range<T>& b) {
return !(a == b);
}

View File

@@ -8,25 +8,25 @@ class Size {
public:
constexpr Size() = default;
constexpr Size(const uint32_t width_, const uint32_t height_)
constexpr Size(const uint32_t width_, const uint32_t height_) noexcept
: width(width_),
height(height_) {}
constexpr uint32_t area() const { return width * height; }
constexpr uint32_t area() const noexcept { return width * height; }
constexpr float aspectRatio() const { return static_cast<float>(width) / static_cast<float>(height); }
constexpr float aspectRatio() const noexcept { return static_cast<float>(width) / static_cast<float>(height); }
constexpr bool isEmpty() const { return width == 0 || height == 0; }
constexpr bool isEmpty() const noexcept { return width == 0 || height == 0; }
uint32_t width = 0;
uint32_t height = 0;
};
constexpr inline bool operator==(const Size& a, const Size& b) {
constexpr inline bool operator==(const Size& a, const Size& b) noexcept {
return a.width == b.width && a.height == b.height;
}
constexpr inline bool operator!=(const Size& a, const Size& b) {
constexpr inline bool operator!=(const Size& a, const Size& b) noexcept {
return !(a == b);
}

View File

@@ -8,15 +8,15 @@ namespace util {
template <typename T>
struct SuppressCopies {
SuppressCopies() = default;
SuppressCopies(SuppressCopies const&) {}
SuppressCopies(SuppressCopies const&) noexcept {}
SuppressCopies(SuppressCopies&& other)
: value(std::forward<T>(other.value)) {}
SuppressCopies& operator=(SuppressCopies o) {
: value(std::forward<T>(other.value)) noexcept {}
SuppressCopies& operator=(SuppressCopies o) noexcept {
std::swap(value, o.value);
return *this;
}
operator T&() { return value; }
T& get() { return value; }
operator T&() noexcept { return value; }
T& get() noexcept { return value; }
private:
T value;

View File

@@ -44,12 +44,12 @@ public:
// TileJSON also includes center and zoom but they are not used by mbgl.
friend bool operator==(const Tileset& lhs, const Tileset& rhs) {
friend bool operator==(const Tileset& lhs, const Tileset& rhs) noexcept {
return std::tie(lhs.tiles, lhs.zoomRange, lhs.attribution, lhs.scheme, lhs.bounds) ==
std::tie(rhs.tiles, rhs.zoomRange, rhs.attribution, rhs.scheme, rhs.bounds);
}
friend bool operator!=(const Tileset& lhs, const Tileset& rhs) { return !(lhs == rhs); }
friend bool operator!=(const Tileset& lhs, const Tileset& rhs) noexcept { return !(lhs == rhs); }
};
} // namespace mbgl

View File

@@ -77,7 +77,7 @@ public:
: TinyUnorderedMap(values_.begin(), values_.end()) {}
/// Move constructor
TinyUnorderedMap(TinyUnorderedMap&& rhs)
TinyUnorderedMap(TinyUnorderedMap&& rhs) noexcept
: linearSize(rhs.linearSize),
keys(std::move(rhs.keys)),
values(std::move(rhs.values)) {
@@ -127,7 +127,7 @@ public:
}
/// Swap all contents with another instance
TinyUnorderedMap& swap(TinyUnorderedMap& other) {
TinyUnorderedMap& swap(TinyUnorderedMap& other) noexcept {
this->Super::swap(other);
std::swap(keys, other.keys);
std::swap(values, other.values);
@@ -154,7 +154,7 @@ public:
std::size_t count(const Key& key) const noexcept { return find(key) ? 1 : 0; }
void clear() {
void clear() noexcept {
linearSize = 0;
this->Super::clear();
}

View File

@@ -33,7 +33,7 @@ namespace util {
struct UnitBezier {
/// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
constexpr UnitBezier(double p1x, double p1y, double p2x, double p2y)
constexpr UnitBezier(double p1x, double p1y, double p2x, double p2y) noexcept
: cx(3.0 * p1x),
bx(3.0 * (p2x - p1x) - (3.0 * p1x)),
ax(1.0 - (3.0 * p1x) - (3.0 * (p2x - p1x) - (3.0 * p1x))),
@@ -41,26 +41,26 @@ struct UnitBezier {
by(3.0 * (p2y - p1y) - (3.0 * p1y)),
ay(1.0 - (3.0 * p1y) - (3.0 * (p2y - p1y) - (3.0 * p1y))) {}
std::pair<double, double> getP1() const { return {cx / 3.0, cy / 3.0}; }
std::pair<double, double> getP1() const noexcept { return {cx / 3.0, cy / 3.0}; }
std::pair<double, double> getP2() const {
std::pair<double, double> getP2() const noexcept {
return {
(bx + (3.0 * cx / 3.0) + cx) / 3.0,
(by + (3.0 * cy / 3.0) + cy) / 3.0,
};
}
double sampleCurveX(double t) const {
double sampleCurveX(double t) const noexcept {
// `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
return ((ax * t + bx) * t + cx) * t;
}
double sampleCurveY(double t) const { return ((ay * t + by) * t + cy) * t; }
double sampleCurveY(double t) const noexcept { return ((ay * t + by) * t + cy) * t; }
double sampleCurveDerivativeX(double t) const { return (3.0 * ax * t + 2.0 * bx) * t + cx; }
double sampleCurveDerivativeX(double t) const noexcept { return (3.0 * ax * t + 2.0 * bx) * t + cx; }
/// Given an x value, find a parametric value it came from.
double solveCurveX(double x, double epsilon) const {
double solveCurveX(double x, double epsilon) const noexcept {
double t0;
double t1;
double t2;
@@ -99,9 +99,9 @@ struct UnitBezier {
return t2;
}
double solve(double x, double epsilon) const { return sampleCurveY(solveCurveX(x, epsilon)); }
double solve(double x, double epsilon) const noexcept { return sampleCurveY(solveCurveX(x, epsilon)); }
bool operator==(const UnitBezier& rhs) const {
bool operator==(const UnitBezier& rhs) const noexcept {
return std::tie(cx, bx, ax, cy, by, ay) == std::tie(rhs.cx, rhs.bx, rhs.ax, rhs.cy, rhs.by, rhs.ay);
}

View File

@@ -101,7 +101,7 @@ std::string decompress(const std::string &raw, int windowBits) {
return result;
}
std::uint32_t crc32(const void *raw, size_t size) {
std::uint32_t crc32(const void *raw, size_t size) noexcept {
auto hash = ::crc32(0L, Z_NULL, 0);
if (raw) {
const auto *p = static_cast<const Bytef *>(raw);

View File

@@ -94,10 +94,10 @@ public:
class ConstantSymbolSizeBinder final : public SymbolSizeBinder {
public:
ConstantSymbolSizeBinder(const float /*tileZoom*/, const float& size, const float /*defaultValue*/)
ConstantSymbolSizeBinder(const float /*tileZoom*/, const float& size, const float /*defaultValue*/) noexcept
: layoutSize(size) {}
ConstantSymbolSizeBinder(const float /*tileZoom*/, const style::Undefined&, const float defaultValue)
ConstantSymbolSizeBinder(const float /*tileZoom*/, const style::Undefined&, const float defaultValue) noexcept
: layoutSize(defaultValue) {}
ConstantSymbolSizeBinder(const float tileZoom,
@@ -111,7 +111,7 @@ public:
zoomLevels, Range<float>{expression_.evaluate(zoomLevels.min), expression_.evaluate(zoomLevels.max)});
}
Range<float> getVertexSizeData(const GeometryTileFeature&) override { return {0.0f, 0.0f}; };
Range<float> getVertexSizeData(const GeometryTileFeature&) noexcept override { return {0.0f, 0.0f}; };
ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override {
float size = layoutSize;
@@ -143,7 +143,7 @@ class SourceFunctionSymbolSizeBinder final : public SymbolSizeBinder {
public:
SourceFunctionSymbolSizeBinder(const float /*tileZoom*/,
style::PropertyExpression<float> expression_,
const float defaultValue_)
const float defaultValue_) noexcept
: expression(std::move(expression_)),
defaultValue(defaultValue_) {}
@@ -152,7 +152,7 @@ public:
return {size, size};
};
ZoomEvaluatedSize evaluateForZoom(float) const override {
ZoomEvaluatedSize evaluateForZoom(float) const noexcept override {
const float unused = 0.0f;
return {true, false, unused, unused, unused};
}
@@ -165,7 +165,7 @@ class CompositeFunctionSymbolSizeBinder final : public SymbolSizeBinder {
public:
CompositeFunctionSymbolSizeBinder(const float tileZoom,
style::PropertyExpression<float> expression_,
const float defaultValue_)
const float defaultValue_) noexcept
: expression(std::move(expression_)),
defaultValue(defaultValue_),
layoutZoom(tileZoom + 1),

View File

@@ -18,16 +18,16 @@ private:
public:
PossiblyEvaluatedPropertyValue() = default;
PossiblyEvaluatedPropertyValue(Value v)
PossiblyEvaluatedPropertyValue(Value v) noexcept
: value(std::move(v)) {}
bool isConstant() const { return value.template is<T>(); }
bool isConstant() const noexcept { return value.template is<T>(); }
std::optional<T> constant() const {
return value.match([&](const T& t) { return std::optional<T>(t); }, [&](const auto&) { return std::nullopt; });
}
T constantOr(const T& t) const { return constant().value_or(t); }
T constantOr(const T& t) const noexcept { return constant().value_or(t); }
template <class... Ts>
auto match(Ts&&... ts) const {
@@ -60,9 +60,8 @@ public:
using Dependency = style::expression::Dependency;
Dependency getDependencies() const noexcept {
return value.match(
[](const T&) noexcept { return Dependency::None; },
[](const style::PropertyExpression<T>& expression) noexcept { return expression.getDependencies(); });
return value.match([](const T&) { return Dependency::None; },
[](const style::PropertyExpression<T>& expression) { return expression.getDependencies(); });
}
};
@@ -75,10 +74,10 @@ private:
public:
PossiblyEvaluatedPropertyValue() = default;
PossiblyEvaluatedPropertyValue(Value v)
PossiblyEvaluatedPropertyValue(Value v) noexcept
: value(std::move(v)) {}
bool isConstant() const { return value.template is<Faded<T>>(); }
bool isConstant() const noexcept { return value.template is<Faded<T>>(); }
std::optional<Faded<T>> constant() const {
return value.match([&](const Faded<T>& t) { return std::optional<Faded<T>>(t); },
@@ -115,9 +114,8 @@ public:
using Dependency = style::expression::Dependency;
Dependency getDependencies() const noexcept {
return value.match(
[](const Faded<T>&) noexcept { return Dependency::None; },
[](const style::PropertyExpression<T>& expression) noexcept { return expression.getDependencies(); });
return value.match([](const Faded<T>&) { return Dependency::None; },
[](const style::PropertyExpression<T>& expression) { return expression.getDependencies(); });
}
};
@@ -127,7 +125,7 @@ template <typename T>
struct Interpolator<PossiblyEvaluatedPropertyValue<T>> {
PossiblyEvaluatedPropertyValue<T> operator()(const PossiblyEvaluatedPropertyValue<T>& a,
const PossiblyEvaluatedPropertyValue<T>& b,
const double t) const {
const double t) const noexcept {
if (a.isConstant() && b.isConstant()) {
return {interpolate(*a.constant(), *b.constant(), t)};
} else {
@@ -137,7 +135,7 @@ struct Interpolator<PossiblyEvaluatedPropertyValue<T>> {
PossiblyEvaluatedPropertyValue<T> operator()(const PossiblyEvaluatedPropertyValue<T>& a,
const PossiblyEvaluatedPropertyValue<T>& b,
const float t) const {
const float t) const noexcept {
if (a.isConstant() && b.isConstant()) {
return {interpolate(*a.constant(), *b.constant(), t)};
} else {

View File

@@ -167,7 +167,7 @@ ParseResult convertLegacyHasFilter(const Convertible& values, Error& error) {
} else if (*property == "$id") {
return createExpression("filter-has-id", std::vector<std::unique_ptr<Expression>>(), error);
} else {
return createExpression("filter-has", {std::make_unique<Literal>(*property)}, error);
return createExpression("filter-has", {std::make_unique<Literal>(std::move(*property))}, error);
}
}

View File

@@ -22,7 +22,9 @@ namespace conversion {
using namespace expression;
using namespace expression::dsl;
const static std::string tokenReservedChars = "{}";
namespace {
const std::string_view tokenReservedChars = "{}";
}
bool hasTokens(const std::string& source) {
auto pos = source.begin();
@@ -194,6 +196,8 @@ struct Converter<int64_t> {
}
};
namespace {
enum class FunctionType {
Interval,
Exponential,
@@ -202,17 +206,17 @@ enum class FunctionType {
Invalid
};
static bool interpolatable(type::Type type) {
bool interpolatable(type::Type type) noexcept {
return type.match([&](const type::NumberType&) { return true; },
[&](const type::ColorType&) { return true; },
[&](const type::Array& array) { return array.N && array.itemType == type::Number; },
[&](const auto&) { return false; });
}
static std::optional<std::unique_ptr<Expression>> convertLiteral(type::Type type,
const Convertible& value,
Error& error,
bool convertTokens = false) {
std::optional<std::unique_ptr<Expression>> convertLiteral(type::Type type,
const Convertible& value,
Error& error,
bool convertTokens = false) {
return type.match(
[&](const type::NumberType&) -> std::optional<std::unique_ptr<Expression>> {
auto result = convert<float>(value, error);
@@ -320,10 +324,10 @@ static std::optional<std::unique_ptr<Expression>> convertLiteral(type::Type type
});
}
static std::optional<std::map<double, std::unique_ptr<Expression>>> convertStops(const type::Type& type,
const Convertible& value,
Error& error,
bool convertTokens) {
std::optional<std::map<double, std::unique_ptr<Expression>>> convertStops(const type::Type& type,
const Convertible& value,
Error& error,
bool convertTokens) {
auto stopsValue = objectMember(value, "stops");
if (!stopsValue) {
error.message = "function value must specify stops";
@@ -371,7 +375,7 @@ static std::optional<std::map<double, std::unique_ptr<Expression>>> convertStops
return {std::move(stops)};
}
static void omitFirstStop(std::map<double, std::unique_ptr<Expression>>& stops) {
void omitFirstStop(std::map<double, std::unique_ptr<Expression>>& stops) {
double min = std::numeric_limits<double>::max();
for (auto& s : stops) {
if (s.first < min) {
@@ -432,7 +436,7 @@ std::optional<std::map<T, std::unique_ptr<Expression>>> convertBranches(const ty
return {std::move(stops)};
}
static std::optional<double> convertBase(const Convertible& value, Error& error) {
std::optional<double> convertBase(const Convertible& value, Error& error) {
auto baseValue = objectMember(value, "base");
if (!baseValue) {
@@ -448,16 +452,16 @@ static std::optional<double> convertBase(const Convertible& value, Error& error)
return *base;
}
static std::unique_ptr<Expression> step(const type::Type& type,
std::unique_ptr<Expression> input,
std::map<double, std::unique_ptr<Expression>> stops) {
return std::make_unique<Step>(type, std::move(input), std::move(stops));
std::unique_ptr<Expression> step(type::Type type,
std::unique_ptr<Expression> input,
std::map<double, std::unique_ptr<Expression>> stops) {
return std::make_unique<Step>(std::move(type), std::move(input), std::move(stops));
}
static std::unique_ptr<Expression> interpolate(type::Type type,
Interpolator interpolator,
std::unique_ptr<Expression> input,
std::map<double, std::unique_ptr<Expression>> stops) {
std::unique_ptr<Expression> interpolate(type::Type type,
Interpolator interpolator,
std::unique_ptr<Expression> input,
std::map<double, std::unique_ptr<Expression>> stops) {
ParsingContext ctx;
auto result = createInterpolate(std::move(type), std::move(interpolator), std::move(input), std::move(stops), ctx);
if (!result) {
@@ -468,22 +472,23 @@ static std::unique_ptr<Expression> interpolate(type::Type type,
}
template <class T>
std::unique_ptr<Expression> categorical(const type::Type& type,
std::unique_ptr<Expression> categorical(type::Type type,
const std::string& property,
std::map<T, std::unique_ptr<Expression>> branches,
std::unique_ptr<Expression> def) {
std::unordered_map<T, std::shared_ptr<Expression>> convertedBranches;
convertedBranches.reserve(branches.size());
for (auto& b : branches) {
convertedBranches[b.first] = std::move(b.second);
}
return std::make_unique<Match<T>>(type,
return std::make_unique<Match<T>>(std::move(type),
get(literal(property)),
std::move(convertedBranches),
def ? std::move(def) : error("replaced with default"));
}
template <>
std::unique_ptr<Expression> categorical<bool>(const type::Type& type,
std::unique_ptr<Expression> categorical<bool>(type::Type type,
const std::string& property,
std::map<bool, std::unique_ptr<Expression>> branches,
std::unique_ptr<Expression> def) {
@@ -496,28 +501,29 @@ std::unique_ptr<Expression> categorical<bool>(const type::Type& type,
: std::move(it->second);
std::vector<typename Case::Branch> convertedBranches;
convertedBranches.reserve(2);
convertedBranches.emplace_back(eq(get(literal(property)), literal(Value(true))), std::move(trueCase));
convertedBranches.emplace_back(eq(get(literal(property)), literal(Value(false))), std::move(falseCase));
return std::make_unique<Case>(
type, std::move(convertedBranches), def ? std::move(def) : error("replaced with default"));
std::move(type), std::move(convertedBranches), def ? std::move(def) : error("replaced with default"));
}
static std::unique_ptr<Expression> numberOrDefault(const type::Type& type,
std::unique_ptr<Expression> get,
std::unique_ptr<Expression> expr,
std::unique_ptr<Expression> def) {
std::unique_ptr<Expression> numberOrDefault(type::Type type,
std::unique_ptr<Expression> get,
std::unique_ptr<Expression> expr,
std::unique_ptr<Expression> def) {
if (!def) {
return expr;
}
std::vector<Case::Branch> branches;
branches.emplace_back(eq(compound("typeof", std::move(get)), literal("number")), std::move(expr));
return std::make_unique<Case>(type, std::move(branches), std::move(def));
return std::make_unique<Case>(std::move(type), std::move(branches), std::move(def));
}
static std::optional<std::unique_ptr<Expression>> convertIntervalFunction(
const type::Type& type,
std::optional<std::unique_ptr<Expression>> convertIntervalFunction(
type::Type type,
const Convertible& value,
Error& error,
const std::function<std::unique_ptr<Expression>(bool)>& makeInput,
@@ -529,11 +535,12 @@ static std::optional<std::unique_ptr<Expression>> convertIntervalFunction(
}
omitFirstStop(*stops);
return numberOrDefault(type, makeInput(false), step(type, makeInput(true), std::move(*stops)), std::move(def));
auto expr = step(type, makeInput(true), std::move(*stops));
return numberOrDefault(std::move(type), makeInput(false), std::move(expr), std::move(def));
}
static std::optional<std::unique_ptr<Expression>> convertExponentialFunction(
const type::Type& type,
std::optional<std::unique_ptr<Expression>> convertExponentialFunction(
type::Type type,
const Convertible& value,
Error& error,
const std::function<std::unique_ptr<Expression>(bool)>& makeInput,
@@ -548,17 +555,15 @@ static std::optional<std::unique_ptr<Expression>> convertExponentialFunction(
return std::nullopt;
}
return numberOrDefault(type,
makeInput(false),
interpolate(type, exponential(*base), makeInput(true), std::move(*stops)),
std::move(def));
auto expr = interpolate(type, exponential(*base), makeInput(true), std::move(*stops));
return numberOrDefault(std::move(type), makeInput(false), std::move(expr), std::move(def));
}
static std::optional<std::unique_ptr<Expression>> convertCategoricalFunction(const type::Type& type,
const Convertible& value,
Error& err,
const std::string& property,
std::unique_ptr<Expression> def) {
std::optional<std::unique_ptr<Expression>> convertCategoricalFunction(type::Type type,
const Convertible& value,
Error& err,
const std::string& property,
std::unique_ptr<Expression> def) {
auto stopsValue = objectMember(value, "stops");
if (!stopsValue) {
err.message = "function value must specify stops";
@@ -592,7 +597,7 @@ static std::optional<std::unique_ptr<Expression>> convertCategoricalFunction(con
if (!branches) {
return std::nullopt;
}
return categorical(type, property, std::move(*branches), std::move(def));
return categorical(std::move(type), property, std::move(*branches), std::move(def));
}
if (toNumber(arrayMember(first, 0))) {
@@ -600,7 +605,7 @@ static std::optional<std::unique_ptr<Expression>> convertCategoricalFunction(con
if (!branches) {
return std::nullopt;
}
return categorical(type, property, std::move(*branches), std::move(def));
return categorical(std::move(type), property, std::move(*branches), std::move(def));
}
if (toString(arrayMember(first, 0))) {
@@ -608,7 +613,7 @@ static std::optional<std::unique_ptr<Expression>> convertCategoricalFunction(con
if (!branches) {
return std::nullopt;
}
return categorical(type, property, std::move(*branches), std::move(def));
return categorical(std::move(type), property, std::move(*branches), std::move(def));
}
err.message = "stop domain value must be a number, string, or boolean";
@@ -690,12 +695,14 @@ std::optional<std::unique_ptr<Expression>> composite(type::Type type,
}
if (interpolatable(type)) {
return interpolate(type, linear(), zoom(), std::move(stops));
return interpolate(std::move(type), linear(), zoom(), std::move(stops));
} else {
return step(type, zoom(), std::move(stops));
return step(std::move(type), zoom(), std::move(stops));
}
}
} // namespace
std::optional<std::unique_ptr<Expression>> convertFunctionToExpression(type::Type type,
const Convertible& value,
Error& err,

View File

@@ -76,7 +76,7 @@ ParseResult Assertion::parse(const Convertible& value, ParsingContext& ctx) {
parsed.push_back(std::move(*input));
}
return ParseResult(std::make_unique<Assertion>(type, std::move(parsed)));
return ParseResult(std::make_unique<Assertion>(std::move(type), std::move(parsed)));
}
std::string Assertion::getOperator() const {
@@ -105,7 +105,7 @@ void Assertion::eachChild(const std::function<void(const Expression&)>& visit) c
}
};
bool Assertion::operator==(const Expression& e) const {
bool Assertion::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Assertion) {
auto rhs = static_cast<const Assertion*>(&e);
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);

View File

@@ -20,9 +20,9 @@ void Any::eachChild(const std::function<void(const Expression&)>& visit) const {
}
}
bool Any::operator==(const Expression& e) const {
bool Any::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Any) {
auto rhs = static_cast<const Any*>(&e);
const auto* rhs = static_cast<const Any*>(&e);
return Expression::childrenEqual(inputs, rhs->inputs);
}
return false;
@@ -47,9 +47,9 @@ void All::eachChild(const std::function<void(const Expression&)>& visit) const {
}
}
bool All::operator==(const Expression& e) const {
bool All::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::All) {
auto rhs = static_cast<const All*>(&e);
const auto* rhs = static_cast<const All*>(&e);
return Expression::childrenEqual(inputs, rhs->inputs);
}
return false;

View File

@@ -28,9 +28,9 @@ void Case::eachChild(const std::function<void(const Expression&)>& visit) const
visit(*otherwise);
}
bool Case::operator==(const Expression& e) const {
bool Case::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Case) {
auto rhs = static_cast<const Case*>(&e);
const auto* rhs = static_cast<const Case*>(&e);
return *otherwise == *(rhs->otherwise) && Expression::childrenEqual(branches, rhs->branches);
}
return false;

View File

@@ -35,9 +35,9 @@ void Coalesce::eachChild(const std::function<void(const Expression&)>& visit) co
}
}
bool Coalesce::operator==(const Expression& e) const {
bool Coalesce::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Coalesce) {
auto rhs = static_cast<const Coalesce*>(&e);
const auto* rhs = static_cast<const Coalesce*>(&e);
return Expression::childrenEqual(args, rhs->args);
}
return false;
@@ -91,7 +91,8 @@ ParseResult Coalesce::parse(const Convertible& value, ParsingContext& ctx) {
return type::checkSubtype(*expectedType, arg->getType());
});
return ParseResult(std::make_unique<Coalesce>(needsAnnotation ? type::Value : *outputType, std::move(args)));
return ParseResult(
std::make_unique<Coalesce>(needsAnnotation ? type::Value : std::move(*outputType), std::move(args)));
}
} // namespace expression

View File

@@ -12,7 +12,7 @@ using CoerceFunction = EvaluationResult (*)(const Value&);
namespace {
EvaluationResult toBoolean(const Value& v) {
EvaluationResult toBoolean(const Value& v) noexcept {
return v.match([&](double f) { return static_cast<bool>(f); },
[&](const std::string& s) { return s.length() > 0; },
[&](bool b) { return b; },
@@ -50,7 +50,7 @@ EvaluationResult toColor(const Value& colorValue) {
}
},
[&colorValue](const std::vector<Value>& components) -> EvaluationResult {
std::size_t len = components.size();
const std::size_t len = components.size();
bool isNumeric = std::all_of(components.begin(), components.end(), [](const Value& item) -> bool {
return item.template is<double>();
});
@@ -132,14 +132,15 @@ mbgl::Value Coercion::serialize() const {
};
std::string Coercion::getOperator() const {
return getType().match([](const type::BooleanType&) { return "to-boolean"; },
[](const type::ColorType&) { return "to-color"; },
[](const type::NumberType&) { return "to-number"; },
[](const type::StringType&) { return "to-string"; },
[](const auto&) {
assert(false);
return "";
});
auto s = getType().match([](const type::BooleanType&) -> std::string_view { return "to-boolean"; },
[](const type::ColorType&) -> std::string_view { return "to-color"; },
[](const type::NumberType&) -> std::string_view { return "to-number"; },
[](const type::StringType&) -> std::string_view { return "to-string"; },
[](const auto&) noexcept -> std::string_view {
assert(false);
return "";
});
return std::string(s);
}
using namespace mbgl::style::conversion;
@@ -203,9 +204,9 @@ void Coercion::eachChild(const std::function<void(const Expression&)>& visit) co
}
};
bool Coercion::operator==(const Expression& e) const {
bool Coercion::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Coercion) {
auto rhs = static_cast<const Coercion*>(&e);
const auto* rhs = static_cast<const Coercion*>(&e);
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);
}
return false;

View File

@@ -75,7 +75,7 @@ void CollatorExpression::eachChild(const std::function<void(const Expression&)>&
}
}
bool CollatorExpression::operator==(const Expression& e) const {
bool CollatorExpression::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::CollatorExpression) {
const auto* rhs = static_cast<const CollatorExpression*>(&e);
const bool lLocSet = locale && *locale;
@@ -108,7 +108,7 @@ EvaluationResult CollatorExpression::evaluate(const EvaluationContext& params) c
return diacriticSensitiveResult.error();
}
if (locale) {
if (locale && *locale) {
if (auto localeResult = (*locale)->evaluate(params)) {
return Collator(caseSensitiveResult->get<bool>(),
diacriticSensitiveResult->get<bool>(),

View File

@@ -8,7 +8,7 @@ namespace mbgl {
namespace style {
namespace expression {
static bool isComparableType(const std::string& op, const type::Type& type) {
static bool isComparableType(const std::string& op, const type::Type& type) noexcept {
if (op == "==" || op == "!=") {
return type == type::String || type == type::Number || type == type::Boolean || type == type::Null ||
type == type::Value;
@@ -17,13 +17,13 @@ static bool isComparableType(const std::string& op, const type::Type& type) {
}
}
bool eq(const Value& a, const Value& b) {
bool eq(const Value& a, const Value& b) noexcept {
return a == b;
}
bool neq(const Value& a, const Value& b) {
bool neq(const Value& a, const Value& b) noexcept {
return a != b;
}
bool lt(const Value& lhs, const Value& rhs) {
bool lt(const Value& lhs, const Value& rhs) noexcept {
return lhs.match([&](const std::string& a) { return a < rhs.get<std::string>(); },
[&](double a) { return a < rhs.get<double>(); },
[&](const auto&) {
@@ -31,7 +31,7 @@ bool lt(const Value& lhs, const Value& rhs) {
return false;
});
}
bool gt(const Value& lhs, const Value& rhs) {
bool gt(const Value& lhs, const Value& rhs) noexcept {
return lhs.match([&](const std::string& a) { return a > rhs.get<std::string>(); },
[&](double a) { return a > rhs.get<double>(); },
[&](const auto&) {
@@ -39,7 +39,7 @@ bool gt(const Value& lhs, const Value& rhs) {
return false;
});
}
bool lteq(const Value& lhs, const Value& rhs) {
bool lteq(const Value& lhs, const Value& rhs) noexcept {
return lhs.match([&](const std::string& a) { return a <= rhs.get<std::string>(); },
[&](double a) { return a <= rhs.get<double>(); },
[&](const auto&) {
@@ -47,7 +47,7 @@ bool lteq(const Value& lhs, const Value& rhs) {
return false;
});
}
bool gteq(const Value& lhs, const Value& rhs) {
bool gteq(const Value& lhs, const Value& rhs) noexcept {
return lhs.match([&](const std::string& a) { return a >= rhs.get<std::string>(); },
[&](double a) { return a >= rhs.get<double>(); },
[&](const auto&) {
@@ -56,26 +56,26 @@ bool gteq(const Value& lhs, const Value& rhs) {
});
}
bool eqCollate(const std::string& a, const std::string& b, const Collator& c) {
bool eqCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return c.compare(a, b) == 0;
}
bool neqCollate(const std::string& a, const std::string& b, const Collator& c) {
bool neqCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return !eqCollate(a, b, c);
}
bool ltCollate(const std::string& a, const std::string& b, const Collator& c) {
bool ltCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return c.compare(a, b) < 0;
}
bool gtCollate(const std::string& a, const std::string& b, const Collator& c) {
bool gtCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return c.compare(a, b) > 0;
}
bool lteqCollate(const std::string& a, const std::string& b, const Collator& c) {
bool lteqCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return c.compare(a, b) <= 0;
}
bool gteqCollate(const std::string& a, const std::string& b, const Collator& c) {
bool gteqCollate(const std::string& a, const std::string& b, const Collator& c) noexcept {
return c.compare(a, b) >= 0;
}
static BasicComparison::CompareFunctionType getBasicCompareFunction(const std::string& op) {
static BasicComparison::CompareFunctionType getBasicCompareFunction(const std::string& op) noexcept {
if (op == "==")
return eq;
else if (op == "!=")
@@ -92,7 +92,7 @@ static BasicComparison::CompareFunctionType getBasicCompareFunction(const std::s
return nullptr;
}
static CollatorComparison::CompareFunctionType getCollatorComparisonFunction(const std::string& op) {
static CollatorComparison::CompareFunctionType getCollatorComparisonFunction(const std::string& op) noexcept {
if (op == "==")
return eqCollate;
else if (op == "!=")
@@ -148,13 +148,9 @@ void BasicComparison::eachChild(const std::function<void(const Expression&)>& vi
visit(*rhs);
}
std::string BasicComparison::getOperator() const {
return op;
}
bool BasicComparison::operator==(const Expression& e) const {
bool BasicComparison::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Comparison) {
auto comp = static_cast<const BasicComparison*>(&e);
const auto* comp = static_cast<const BasicComparison*>(&e);
return comp->op == op && *comp->lhs == *lhs && *comp->rhs == *rhs;
}
return false;
@@ -207,13 +203,9 @@ void CollatorComparison::eachChild(const std::function<void(const Expression&)>&
visit(*collator);
}
std::string CollatorComparison::getOperator() const {
return op;
}
bool CollatorComparison::operator==(const Expression& e) const {
bool CollatorComparison::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Comparison) {
auto comp = static_cast<const CollatorComparison*>(&e);
const auto* comp = static_cast<const CollatorComparison*>(&e);
return comp->op == op && *comp->collator == *collator && *comp->lhs == *lhs && *comp->rhs == *rhs;
}
return false;

View File

@@ -1247,14 +1247,10 @@ EvaluationResult CompoundExpression::evaluate(const EvaluationContext& evaluatio
return signature.apply(evaluationParams, args);
}
std::optional<std::size_t> CompoundExpression::getParameterCount() const {
std::optional<std::size_t> CompoundExpression::getParameterCount() const noexcept {
return signature.params.match(
[&](const VarargsType&) -> std::optional<std::size_t> { return std::nullopt; },
[&](const std::vector<type::Type>& p) -> std::optional<std::size_t> { return p.size(); });
}
std::vector<std::optional<Value>> CompoundExpression::possibleOutputs() const {
return {std::nullopt};
[&](const VarargsType&) noexcept -> std::optional<std::size_t> { return std::nullopt; },
[&](const std::vector<type::Type>& p) noexcept -> std::optional<std::size_t> { return p.size(); });
}
void CompoundExpression::eachChild(const std::function<void(const Expression&)>& visit) const {
@@ -1263,7 +1259,7 @@ void CompoundExpression::eachChild(const std::function<void(const Expression&)>&
}
}
bool CompoundExpression::operator==(const Expression& e) const {
bool CompoundExpression::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::CompoundExpression) {
auto rhs = static_cast<const CompoundExpression*>(&e);
return signature.name == rhs->signature.name && signature.result == rhs->signature.result &&
@@ -1272,7 +1268,7 @@ bool CompoundExpression::operator==(const Expression& e) const {
return false;
}
bool CompoundExpression::exists(const std::string& name) {
bool CompoundExpression::exists(const std::string& name) noexcept {
return compoundExpressionRegistry.contains(name.c_str());
}

View File

@@ -20,20 +20,20 @@
namespace mbgl {
namespace {
const std::size_t MinPointsSize = 100;
const std::size_t MinLinePointsSize = 50;
const double InvalidDistance = std::numeric_limits<double>::quiet_NaN();
const double InfiniteDistance = std::numeric_limits<double>::infinity();
const mapbox::cheap_ruler::CheapRuler::Unit UnitInMeters = mapbox::cheap_ruler::CheapRuler::Unit::Meters;
constexpr std::size_t MinPointsSize = 100;
constexpr std::size_t MinLinePointsSize = 50;
constexpr double InvalidDistance = std::numeric_limits<double>::quiet_NaN();
constexpr double InfiniteDistance = std::numeric_limits<double>::infinity();
constexpr mapbox::cheap_ruler::CheapRuler::Unit UnitInMeters = mapbox::cheap_ruler::CheapRuler::Unit::Meters;
// Inclusive index range for multipoint or linestring container
using IndexRange = std::pair<std::size_t, std::size_t>;
std::size_t getRangeSize(const IndexRange& range) {
inline std::size_t getRangeSize(const IndexRange& range) noexcept {
return range.second - range.first + 1;
}
bool isRangeSafe(const IndexRange& range, const std::size_t threshold) {
bool isRangeSafe(const IndexRange& range, const std::size_t threshold) noexcept {
auto ret = (range.second >= range.first && range.second < threshold);
if (!ret) {
mbgl::Log::Error(mbgl::Event::Style, "Index is out of range");
@@ -42,31 +42,33 @@ bool isRangeSafe(const IndexRange& range, const std::size_t threshold) {
}
std::pair<std::optional<IndexRange>, std::optional<IndexRange>> splitRange(const IndexRange& range, bool isLine) {
if (range.first > range.second) return std::make_pair(std::nullopt, std::nullopt);
auto size = getRangeSize(range);
if (range.first > range.second) {
return std::make_pair(std::nullopt, std::nullopt);
}
const auto size = getRangeSize(range);
if (isLine) {
if (size == 2) {
return std::make_pair(range, std::nullopt);
}
auto size1 = size / 2;
IndexRange range1(range.first, range.first + size1);
IndexRange range2(range.first + size1, range.second);
return std::make_pair(std::move(range1), std::move(range2));
const auto size1 = size / 2;
return std::make_pair(IndexRange{range.first, range.first + size1},
IndexRange{range.first + size1, range.second});
} else {
if (size == 1) {
return std::make_pair(range, std::nullopt);
}
auto size1 = size / 2 - 1;
IndexRange range1(range.first, range.first + size1);
IndexRange range2(range.first + size1 + 1, range.second);
return std::make_pair(std::move(range1), std::move(range2));
const auto size1 = size / 2 - 1;
return std::make_pair(IndexRange{range.first, range.first + size1},
IndexRange{range.first + size1 + 1, range.second});
}
}
using DistanceBBox = GeometryBBox<double>;
DistanceBBox getBBox(const mapbox::geometry::multi_point<double>& points, const IndexRange& range) {
if (!isRangeSafe(range, points.size())) return DefaultDistanceBBox;
DistanceBBox getBBox(const mapbox::geometry::multi_point<double>& points, const IndexRange& range) noexcept {
if (!isRangeSafe(range, points.size())) {
return DefaultDistanceBBox;
}
DistanceBBox bbox = DefaultDistanceBBox;
for (std::size_t i = range.first; i <= range.second; ++i) {
@@ -75,8 +77,11 @@ DistanceBBox getBBox(const mapbox::geometry::multi_point<double>& points, const
return bbox;
}
DistanceBBox getBBox(const mapbox::geometry::line_string<double>& line, const IndexRange& range) {
if (!isRangeSafe(range, line.size())) return DefaultDistanceBBox;
DistanceBBox getBBox(const mapbox::geometry::line_string<double>& line, const IndexRange& range) noexcept {
if (!isRangeSafe(range, line.size())) {
return DefaultDistanceBBox;
}
DistanceBBox bbox = DefaultDistanceBBox;
for (std::size_t i = range.first; i <= range.second; ++i) {
updateBBox(bbox, line[i]);
@@ -84,7 +89,7 @@ DistanceBBox getBBox(const mapbox::geometry::line_string<double>& line, const In
return bbox;
}
DistanceBBox getBBox(const mapbox::geometry::polygon<double>& polygon) {
DistanceBBox getBBox(const mapbox::geometry::polygon<double>& polygon) noexcept {
DistanceBBox bbox = DefaultDistanceBBox;
for (const auto& ring : polygon) {
for (const auto& p : ring) {
@@ -94,7 +99,7 @@ DistanceBBox getBBox(const mapbox::geometry::polygon<double>& polygon) {
return bbox;
}
bool isMultiPointValid(const mapbox::geometry::multi_point<double>& points) {
bool isMultiPointValid(const mapbox::geometry::multi_point<double>& points) noexcept {
if (points.empty()) {
mbgl::Log::Error(mbgl::Event::Style, "Invalid MultiPoint with empty geometry points");
return false;
@@ -102,7 +107,7 @@ bool isMultiPointValid(const mapbox::geometry::multi_point<double>& points) {
return true;
}
bool isLineStringValid(const mapbox::geometry::line_string<double>& line) {
bool isLineStringValid(const mapbox::geometry::line_string<double>& line) noexcept {
if (line.size() < 2) {
mbgl::Log::Error(mbgl::Event::Style, "Invalid LineString with fewer than 2 geometry points");
return false;
@@ -110,7 +115,7 @@ bool isLineStringValid(const mapbox::geometry::line_string<double>& line) {
return true;
}
bool isPolygonValid(const mapbox::geometry::polygon<double>& polygon) {
bool isPolygonValid(const mapbox::geometry::polygon<double>& polygon) noexcept {
if (polygon.empty()) {
mbgl::Log::Error(mbgl::Event::Style, "Invalid Polygon with empty rings");
return false;
@@ -131,7 +136,7 @@ bool isPolygonValid(const mapbox::geometry::polygon<double>& polygon) {
// and {dx, dy} to calculate the distance. Distance will be 0.0 if bounding box are overlapping.
double bboxToBBoxDistance(const DistanceBBox& bbox1,
const DistanceBBox& bbox2,
mapbox::cheap_ruler::CheapRuler& ruler) {
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
if (bbox1 == DefaultDistanceBBox || bbox2 == DefaultDistanceBBox) {
return InvalidDistance;
}
@@ -158,7 +163,7 @@ double bboxToBBoxDistance(const DistanceBBox& bbox1,
double pointToLineDistance(const mapbox::geometry::point<double>& point,
const mapbox::geometry::line_string<double>& line,
mapbox::cheap_ruler::CheapRuler& ruler) {
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
const auto nearestPoint = std::get<0>(ruler.pointOnLine(line, point));
return ruler.distance(point, nearestPoint);
}
@@ -168,21 +173,24 @@ double segmentToSegmentDistance(const mapbox::geometry::point<double>& p1,
const mapbox::geometry::point<double>& p2,
const mapbox::geometry::point<double>& q1,
const mapbox::geometry::point<double>& q2,
mapbox::cheap_ruler::CheapRuler& ruler) {
auto dist1 = std::min(pointToLineDistance(p1, mapbox::geometry::line_string<double>{q1, q2}, ruler),
pointToLineDistance(p2, mapbox::geometry::line_string<double>{q1, q2}, ruler));
auto dist2 = std::min(pointToLineDistance(q1, mapbox::geometry::line_string<double>{p1, p2}, ruler),
pointToLineDistance(q2, mapbox::geometry::line_string<double>{p1, p2}, ruler));
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
const auto dist1 = std::min(pointToLineDistance(p1, mapbox::geometry::line_string<double>{q1, q2}, ruler),
pointToLineDistance(p2, mapbox::geometry::line_string<double>{q1, q2}, ruler));
const auto dist2 = std::min(pointToLineDistance(q1, mapbox::geometry::line_string<double>{p1, p2}, ruler),
pointToLineDistance(q2, mapbox::geometry::line_string<double>{p1, p2}, ruler));
return std::min(dist1, dist2);
}
double lineToLineDistance(const mapbox::geometry::line_string<double>& line1,
IndexRange& range1,
const IndexRange& range1,
const mapbox::geometry::line_string<double>& line2,
IndexRange& range2,
mapbox::cheap_ruler::CheapRuler& ruler) {
bool rangeSafe = isRangeSafe(range1, line1.size()) && isRangeSafe(range2, line2.size());
if (!rangeSafe) return InvalidDistance;
const IndexRange& range2,
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
const bool rangeSafe = isRangeSafe(range1, line1.size()) && isRangeSafe(range2, line2.size());
if (!rangeSafe) {
return InvalidDistance;
}
double dist = InfiniteDistance;
for (std::size_t i = range1.first; i < range1.second; ++i) {
const auto& p1 = line1[i];
@@ -190,7 +198,9 @@ double lineToLineDistance(const mapbox::geometry::line_string<double>& line1,
for (std::size_t j = range2.first; j < range2.second; ++j) {
const auto& q1 = line2[j];
const auto& q2 = line2[j + 1];
if (segmentIntersectSegment(p1, p2, q1, q2)) return 0.0;
if (segmentIntersectSegment(p1, p2, q1, q2)) {
return 0.0;
}
dist = std::min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));
}
}
@@ -198,17 +208,22 @@ double lineToLineDistance(const mapbox::geometry::line_string<double>& line1,
}
double pointsToPointsDistance(const mapbox::geometry::multi_point<double>& points1,
IndexRange& range1,
const IndexRange& range1,
const mapbox::geometry::multi_point<double>& points2,
IndexRange& range2,
mapbox::cheap_ruler::CheapRuler& ruler) {
bool rangeSafe = isRangeSafe(range1, points1.size()) && isRangeSafe(range2, points2.size());
if (!rangeSafe) return InvalidDistance;
const IndexRange& range2,
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
const bool rangeSafe = isRangeSafe(range1, points1.size()) && isRangeSafe(range2, points2.size());
if (!rangeSafe) {
return InvalidDistance;
}
double dist = InfiniteDistance;
for (std::size_t i = range1.first; i <= range1.second; ++i) {
for (std::size_t j = range2.first; j <= range2.second; ++j) {
dist = std::min(dist, ruler.distance(points1[i], points2[j]));
if (dist == 0.0) return dist;
if (dist == 0.0) {
return dist;
}
}
}
return dist;
@@ -216,19 +231,25 @@ double pointsToPointsDistance(const mapbox::geometry::multi_point<double>& point
double pointToPolygonDistance(const mapbox::geometry::point<double>& point,
const mapbox::geometry::polygon<double>& polygon,
mapbox::cheap_ruler::CheapRuler& ruler) {
if (pointWithinPolygon(point, polygon, true /*trueOnBoundary*/)) return 0.0;
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
if (pointWithinPolygon(point, polygon, true /*trueOnBoundary*/)) {
return 0.0;
}
double dist = InfiniteDistance;
for (const auto& ring : polygon) {
if (ring.front() != ring.back()) {
dist = std::min(
dist,
pointToLineDistance(point, mapbox::geometry::line_string<double>{ring.back(), ring.front()}, ruler));
if (dist == 0.0) return dist;
if (dist == 0.0) {
return dist;
}
}
const auto nearestPoint = std::get<0>(ruler.pointOnLine(ring, point));
dist = std::min(dist, ruler.distance(point, nearestPoint));
if (dist == 0.0) return dist;
if (dist == 0.0) {
return dist;
}
}
return dist;
}
@@ -236,10 +257,15 @@ double pointToPolygonDistance(const mapbox::geometry::point<double>& point,
double lineToPolygonDistance(const mapbox::geometry::line_string<double>& line,
const IndexRange& range,
const mapbox::geometry::polygon<double>& polygon,
mapbox::cheap_ruler::CheapRuler& ruler) {
if (!isRangeSafe(range, line.size())) return InvalidDistance;
const mapbox::cheap_ruler::CheapRuler& ruler) noexcept {
if (!isRangeSafe(range, line.size())) {
return InvalidDistance;
}
for (std::size_t i = range.first; i <= range.second; ++i) {
if (pointWithinPolygon(line[i], polygon, true /*trueOnBoundary*/)) return 0.0;
if (pointWithinPolygon(line[i], polygon, true /*trueOnBoundary*/)) {
return 0.0;
}
}
double dist = InfiniteDistance;
@@ -250,7 +276,9 @@ double lineToPolygonDistance(const mapbox::geometry::line_string<double>& line,
for (std::size_t j = 0, len = ring.size(), k = len - 1; j < len; k = j++) {
const auto& q1 = ring[k];
const auto& q2 = ring[j];
if (segmentIntersectSegment(p1, p2, q1, q2)) return 0.0;
if (segmentIntersectSegment(p1, p2, q1, q2)) {
return 0.0;
}
dist = std::min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));
}
}
@@ -262,7 +290,7 @@ double lineToPolygonDistance(const mapbox::geometry::line_string<double>& line,
// quadratic, performance improvement is needed.
double polygonToPolygonDistance(const mapbox::geometry::polygon<double>& polygon1,
const mapbox::geometry::polygon<double>& polygon2,
mapbox::cheap_ruler::CheapRuler& ruler,
const mapbox::cheap_ruler::CheapRuler& ruler,
double currentMiniDist = InfiniteDistance) {
const auto bbox1 = getBBox(polygon1);
const auto bbox2 = getBBox(polygon2);
@@ -270,16 +298,20 @@ double polygonToPolygonDistance(const mapbox::geometry::polygon<double>& polygon
return currentMiniDist;
}
const auto polygonIntersect = [](const mapbox::geometry::polygon<double>& poly1,
const mapbox::geometry::polygon<double>& poly2) {
const mapbox::geometry::polygon<double>& poly2) noexcept {
for (const auto& ring : poly1) {
for (std::size_t i = 0; i <= ring.size() - 1; ++i) {
if (pointWithinPolygon(ring[i], poly2, true /*trueOnBoundary*/)) return true;
if (pointWithinPolygon(ring[i], poly2, true /*trueOnBoundary*/)) {
return true;
}
}
}
return false;
};
if (boxWithinBox(bbox1, bbox2)) {
if (polygonIntersect(polygon1, polygon2)) return 0.0;
if (polygonIntersect(polygon1, polygon2)) {
return 0.0;
}
} else if (polygonIntersect(polygon2, polygon1)) {
return 0.0;
}
@@ -293,7 +325,9 @@ double polygonToPolygonDistance(const mapbox::geometry::polygon<double>& polygon
for (std::size_t j = 0, len2 = ring2.size(), k = len2 - 1; j < len2; k = j++) {
const auto& q1 = ring2[k];
const auto& q2 = ring2[j];
if (segmentIntersectSegment(p1, p2, q1, q2)) return 0.0;
if (segmentIntersectSegment(p1, p2, q1, q2)) {
return 0.0;
}
dist = std::min(dist, segmentToSegmentDistance(p1, p2, q1, q2, ruler));
}
}
@@ -305,7 +339,7 @@ double polygonToPolygonDistance(const mapbox::geometry::polygon<double>& polygon
// <distance, range1, range2>
using DistPair = std::tuple<double, IndexRange, IndexRange>;
struct Comparator {
bool operator()(DistPair& left, DistPair& right) { return std::get<0>(left) < std::get<0>(right); }
bool operator()(DistPair& left, DistPair& right) noexcept { return std::get<0>(left) < std::get<0>(right); }
};
// The priority queue will ensure the top element would always be the pair that has the biggest distance
using DistQueue = std::priority_queue<DistPair, std::deque<DistPair>, Comparator>;
@@ -315,19 +349,25 @@ using DistQueue = std::priority_queue<DistPair, std::deque<DistPair>, Comparator
double pointsToPolygonDistance(const mapbox::geometry::multi_point<double>& points,
const mapbox::geometry::polygon<double>& polygon,
mapbox::cheap_ruler::CheapRuler& ruler,
const mapbox::cheap_ruler::CheapRuler& ruler,
double currentMiniDist = InfiniteDistance) {
auto miniDist = std::min(ruler.distance(points[0], polygon[0][0]), currentMiniDist);
if (miniDist == 0.0) return miniDist;
if (miniDist == 0.0) {
return miniDist;
}
DistQueue distQueue;
distQueue.push(std::forward_as_tuple(0, IndexRange(0, points.size() - 1), IndexRange(0, 0)));
const auto polyBBox = getBBox(polygon);
while (!distQueue.empty()) {
auto distPair = distQueue.top();
const auto distPair = distQueue.top();
distQueue.pop();
if (std::get<0>(distPair) >= miniDist) continue;
auto& range = std::get<1>(distPair);
if (std::get<0>(distPair) >= miniDist) {
continue;
}
const auto& range = std::get<1>(distPair);
// In case the set size are relatively small, we could use brute-force directly
if (getRangeSize(range) <= MinLinePointsSize) {
@@ -336,21 +376,25 @@ double pointsToPolygonDistance(const mapbox::geometry::multi_point<double>& poin
return InvalidDistance;
}
for (std::size_t i = range.first; i <= range.second; ++i) {
auto tempDist = pointToPolygonDistance(points[i], polygon, ruler);
const auto tempDist = pointToPolygonDistance(points[i], polygon, ruler);
miniDist = std::min(miniDist, tempDist);
if (miniDist == 0.0) return 0.0;
if (miniDist == 0.0) {
return 0.0;
}
}
} else {
auto newRangesA = splitRange(range, false /*isLine*/);
const auto newRangesA = splitRange(range, false /*isLine*/);
const auto updateQueue =
[&distQueue, &miniDist, &ruler, &points, &polyBBox](std::optional<IndexRange>& rangeA) {
if (!rangeA) return;
auto tempDist = bboxToBBoxDistance(getBBox(points, *rangeA), polyBBox, ruler);
// Insert new pair to the queue if the bbox distance is less
// than miniDist, The pair with biggest distance will be at
// the top
if (tempDist < miniDist)
[&distQueue, &miniDist, &ruler, &points, &polyBBox](const std::optional<IndexRange>& rangeA) {
if (!rangeA) {
return;
}
const auto tempDist = bboxToBBoxDistance(getBBox(points, *rangeA), polyBBox, ruler);
// Insert new pair to the queue if the bbox distance is less than
// miniDist, The pair with biggest distance will be at the top
if (tempDist < miniDist) {
distQueue.push(std::make_tuple(tempDist, std::move(*rangeA), IndexRange(0, 0)));
}
};
updateQueue(newRangesA.first);
updateQueue(newRangesA.second);
@@ -361,37 +405,46 @@ double pointsToPolygonDistance(const mapbox::geometry::multi_point<double>& poin
double lineToPolygonDistance(const mapbox::geometry::line_string<double>& line,
const mapbox::geometry::polygon<double>& polygon,
mapbox::cheap_ruler::CheapRuler& ruler,
const mapbox::cheap_ruler::CheapRuler& ruler,
double currentMiniDist = InfiniteDistance) {
auto miniDist = std::min(ruler.distance(line[0], polygon[0][0]), currentMiniDist);
if (miniDist == 0.0) return miniDist;
if (miniDist == 0.0) {
return miniDist;
}
DistQueue distQueue;
distQueue.push(std::forward_as_tuple(0, IndexRange(0, line.size() - 1), IndexRange(0, 0)));
const auto polyBBox = getBBox(polygon);
while (!distQueue.empty()) {
auto distPair = distQueue.top();
const auto distPair = distQueue.top();
distQueue.pop();
if (std::get<0>(distPair) >= miniDist) continue;
auto& range = std::get<1>(distPair);
if (std::get<0>(distPair) >= miniDist) {
continue;
}
const auto& range = std::get<1>(distPair);
// In case the set size are relatively small, we could use brute-force directly
if (getRangeSize(range) <= MinLinePointsSize) {
auto tempDist = lineToPolygonDistance(line, range, polygon, ruler);
if (std::isnan(tempDist)) return tempDist;
const auto tempDist = lineToPolygonDistance(line, range, polygon, ruler);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
miniDist = std::min(miniDist, tempDist);
if (miniDist == 0.0) return 0.0;
} else {
auto newRangesA = splitRange(range, true /*isLine*/);
const auto newRangesA = splitRange(range, true /*isLine*/);
const auto updateQueue =
[&distQueue, &miniDist, &ruler, &line, &polyBBox](std::optional<IndexRange>& rangeA) {
if (!rangeA) return;
auto tempDist = bboxToBBoxDistance(getBBox(line, *rangeA), polyBBox, ruler);
// Insert new pair to the queue if the bbox distance is less
// than miniDist, The pair with biggest distance will be at
// the top
if (tempDist < miniDist)
[&distQueue, &miniDist, &ruler, &line, &polyBBox](const std::optional<IndexRange>& rangeA) {
if (!rangeA) {
return;
}
const auto tempDist = bboxToBBoxDistance(getBBox(line, *rangeA), polyBBox, ruler);
// Insert new pair to the queue if the bbox distance is less than
// miniDist, The pair with biggest distance will be at the top
if (tempDist < miniDist) {
distQueue.push(std::make_tuple(tempDist, std::move(*rangeA), IndexRange(0, 0)));
}
};
updateQueue(newRangesA.first);
updateQueue(newRangesA.second);
@@ -402,38 +455,48 @@ double lineToPolygonDistance(const mapbox::geometry::line_string<double>& line,
double lineToLineDistance(const mapbox::geometry::line_string<double>& line1,
const mapbox::geometry::line_string<double>& line2,
mapbox::cheap_ruler::CheapRuler& ruler,
const mapbox::cheap_ruler::CheapRuler& ruler,
double currentMiniDist = InfiniteDistance) {
auto miniDist = std::min(ruler.distance(line1[0], line2[0]), currentMiniDist);
if (miniDist == 0.0) return miniDist;
if (miniDist == 0.0) {
return miniDist;
}
DistQueue distQueue;
distQueue.push(std::forward_as_tuple(0, IndexRange(0, line1.size() - 1), IndexRange(0, line2.size() - 1)));
while (!distQueue.empty()) {
auto distPair = distQueue.top();
const auto distPair = distQueue.top();
distQueue.pop();
if (std::get<0>(distPair) >= miniDist) continue;
auto& rangeA = std::get<1>(distPair);
auto& rangeB = std::get<2>(distPair);
if (std::get<0>(distPair) >= miniDist) {
continue;
}
const auto& rangeA = std::get<1>(distPair);
const auto& rangeB = std::get<2>(distPair);
// In case the set size are relatively small, we could use brute-force directly
if (getRangeSize(rangeA) <= MinLinePointsSize && getRangeSize(rangeB) <= MinLinePointsSize) {
auto tempDist = lineToLineDistance(line1, rangeA, line2, rangeB, ruler);
if (std::isnan(tempDist)) return tempDist;
const auto tempDist = lineToLineDistance(line1, rangeA, line2, rangeB, ruler);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
miniDist = std::min(miniDist, tempDist);
if (miniDist == 0.0) return 0.0;
} else {
auto newRangesA = splitRange(rangeA, true /*isLine*/);
auto newRangesB = splitRange(rangeB, true /*isLine*/);
const auto newRangesA = splitRange(rangeA, true /*isLine*/);
const auto newRangesB = splitRange(rangeB, true /*isLine*/);
const auto updateQueue = [&distQueue, &miniDist, &ruler, &line1, &line2](
std::optional<IndexRange>& range1, std::optional<IndexRange>& range2) {
if (!range1 || !range2) return;
auto tempDist = bboxToBBoxDistance(getBBox(line1, *range1), getBBox(line2, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less
// than miniDist, The pair with biggest distance will be at
// the top
if (tempDist < miniDist)
const std::optional<IndexRange>& range1,
const std::optional<IndexRange>& range2) {
if (!range1 || !range2) {
return;
}
const auto tempDist = bboxToBBoxDistance(getBBox(line1, *range1), getBBox(line2, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less than
// miniDist, The pair with biggest distance will be at the top
if (tempDist < miniDist) {
distQueue.push(std::make_tuple(tempDist, std::move(*range1), std::move(*range2)));
}
};
updateQueue(newRangesA.first, newRangesB.first);
updateQueue(newRangesA.first, newRangesB.second);
@@ -446,39 +509,48 @@ double lineToLineDistance(const mapbox::geometry::line_string<double>& line1,
double pointsToPointsDistance(const mapbox::geometry::multi_point<double>& pointSet1,
const mapbox::geometry::multi_point<double>& pointSet2,
mapbox::cheap_ruler::CheapRuler& ruler) {
const mapbox::cheap_ruler::CheapRuler& ruler) {
auto miniDist = ruler.distance(pointSet1[0], pointSet2[0]);
if (miniDist == 0.0) return miniDist;
if (miniDist == 0.0) {
return miniDist;
}
DistQueue distQueue;
distQueue.push(std::forward_as_tuple(0, IndexRange(0, pointSet1.size() - 1), IndexRange(0, pointSet2.size() - 1)));
while (!distQueue.empty()) {
auto distPair = distQueue.top();
const auto distPair = distQueue.top();
distQueue.pop();
if (std::get<0>(distPair) >= miniDist) {
continue;
}
auto& rangeA = std::get<1>(distPair);
auto& rangeB = std::get<2>(distPair);
const auto& rangeA = std::get<1>(distPair);
const auto& rangeB = std::get<2>(distPair);
// In case the set size are relatively small, we could use brute-force directly
if (getRangeSize(rangeA) <= MinPointsSize && getRangeSize(rangeB) <= MinPointsSize) {
auto tempDist = pointsToPointsDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);
if (std::isnan(tempDist)) return tempDist;
const auto tempDist = pointsToPointsDistance(pointSet1, rangeA, pointSet2, rangeB, ruler);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
miniDist = std::min(miniDist, tempDist);
if (miniDist == 0.0) return 0.0;
} else {
auto newRangesA = splitRange(rangeA, false /*isLine*/);
auto newRangesB = splitRange(rangeB, false /*isLine*/);
const auto newRangesA = splitRange(rangeA, false /*isLine*/);
const auto newRangesB = splitRange(rangeB, false /*isLine*/);
const auto updateQueue = [&distQueue, &miniDist, &ruler, &pointSet1, &pointSet2](
std::optional<IndexRange>& range1, std::optional<IndexRange>& range2) {
if (!range1 || !range2) return;
auto tempDist = bboxToBBoxDistance(getBBox(pointSet1, *range1), getBBox(pointSet2, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less
// than miniDist, The pair with biggest distance will be at
// the top
if (tempDist < miniDist)
const std::optional<IndexRange>& range1,
const std::optional<IndexRange>& range2) {
if (!range1 || !range2) {
return;
}
const auto tempDist = bboxToBBoxDistance(
getBBox(pointSet1, *range1), getBBox(pointSet2, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less than
// miniDist, The pair with biggest distance will be at the top
if (tempDist < miniDist) {
distQueue.push(std::make_tuple(tempDist, std::move(*range1), std::move(*range2)));
}
};
updateQueue(newRangesA.first, newRangesB.first);
updateQueue(newRangesA.first, newRangesB.second);
@@ -491,45 +563,55 @@ double pointsToPointsDistance(const mapbox::geometry::multi_point<double>& point
double pointsToLineDistance(const mapbox::geometry::multi_point<double>& points,
const mapbox::geometry::line_string<double>& line,
mapbox::cheap_ruler::CheapRuler& ruler,
const mapbox::cheap_ruler::CheapRuler& ruler,
double currentMiniDist = InfiniteDistance) {
auto miniDist = std::min(currentMiniDist, ruler.distance(points[0], line[0]));
if (miniDist == 0.0) return miniDist;
if (miniDist == 0.0) {
return miniDist;
}
DistQueue distQueue;
distQueue.push(std::forward_as_tuple(0, IndexRange(0, points.size() - 1), IndexRange(0, line.size() - 1)));
while (!distQueue.empty()) {
auto distPair = distQueue.top();
const auto distPair = distQueue.top();
distQueue.pop();
if (std::get<0>(distPair) >= miniDist) continue;
auto& rangeA = std::get<1>(distPair);
auto& rangeB = std::get<2>(distPair);
if (std::get<0>(distPair) >= miniDist) {
continue;
}
const auto& rangeA = std::get<1>(distPair);
const auto& rangeB = std::get<2>(distPair);
// In case the set size are relatively small, we could use brute-force directly
if (getRangeSize(rangeA) <= MinPointsSize && getRangeSize(rangeB) <= MinLinePointsSize) {
bool rangeSafe = isRangeSafe(rangeA, points.size()) && isRangeSafe(rangeB, line.size());
if (!rangeSafe) {
if (!isRangeSafe(rangeA, points.size()) && isRangeSafe(rangeB, line.size())) {
mbgl::Log::Error(mbgl::Event::Style, "Index is out of range");
return InvalidDistance;
}
auto subLine = mapbox::geometry::multi_point<double>(line.begin() + rangeB.first,
line.begin() + rangeB.second + 1);
const auto subLine = mapbox::geometry::multi_point<double>(line.begin() + rangeB.first,
line.begin() + rangeB.second + 1);
for (std::size_t i = rangeA.first; i <= rangeA.second; ++i) {
miniDist = std::min(miniDist, pointToLineDistance(points[i], subLine, ruler));
if (miniDist == 0.0) return 0.0;
if (miniDist == 0.0) {
return 0.0;
}
}
} else {
auto newRangesA = splitRange(rangeA, false /*isLine*/);
auto newRangesB = splitRange(rangeB, true /*isLine*/);
const auto newRangesA = splitRange(rangeA, false /*isLine*/);
const auto newRangesB = splitRange(rangeB, true /*isLine*/);
const auto updateQueue = [&distQueue, &miniDist, &ruler, &points, &line](
std::optional<IndexRange>& range1, std::optional<IndexRange>& range2) {
if (!range1 || !range2) return;
auto tempDist = bboxToBBoxDistance(getBBox(points, *range1), getBBox(line, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less
// than miniDist, The pair with biggest distance will be at
// the top
if (tempDist < miniDist)
const std::optional<IndexRange>& range1,
const std::optional<IndexRange>& range2) {
if (!range1 || !range2) {
return;
}
const auto tempDist = bboxToBBoxDistance(getBBox(points, *range1), getBBox(line, *range2), ruler);
// Insert new pair to the queue if the bbox distance is less than
// miniDist, The pair with biggest distance will be at the top
if (tempDist < miniDist) {
distQueue.push(std::make_tuple(tempDist, std::move(*range1), std::move(*range2)));
}
};
updateQueue(newRangesA.first, newRangesB.first);
updateQueue(newRangesA.first, newRangesB.second);
@@ -542,29 +624,35 @@ double pointsToLineDistance(const mapbox::geometry::multi_point<double>& points,
double pointsToLinesDistance(const mapbox::geometry::multi_point<double>& points,
const mapbox::geometry::multi_line_string<double>& lines,
mapbox::cheap_ruler::CheapRuler& ruler) {
const mapbox::cheap_ruler::CheapRuler& ruler) {
double dist = InfiniteDistance;
for (const auto& line : lines) {
dist = std::min(dist, pointsToLineDistance(points, line, ruler, dist));
if (dist == 0.0) return dist;
if (dist == 0.0) {
return dist;
}
}
return dist;
}
double lineToLinesDistance(const mapbox::geometry::line_string<double>& line,
const mapbox::geometry::multi_line_string<double>& lines,
mapbox::cheap_ruler::CheapRuler& ruler) {
const mapbox::cheap_ruler::CheapRuler& ruler) {
double dist = InfiniteDistance;
for (const auto& l : lines) {
dist = std::min(dist, lineToLineDistance(line, l, ruler, dist));
if (dist == 0.0) return dist;
if (dist == 0.0) {
return dist;
}
}
return dist;
}
double pointsToGeometryDistance(const mapbox::geometry::multi_point<double>& points,
const Feature::geometry_type& geoSet) {
if (!isMultiPointValid(points)) return InvalidDistance;
if (!isMultiPointValid(points)) {
return InvalidDistance;
}
mapbox::cheap_ruler::CheapRuler ruler(points.front().y, UnitInMeters);
return geoSet.match(
[&points, &ruler](const mapbox::geometry::point<double>& p) {
@@ -603,7 +691,9 @@ double pointsToGeometryDistance(const mapbox::geometry::multi_point<double>& poi
}
double lineToGeometryDistance(const mapbox::geometry::line_string<double>& line, const Feature::geometry_type& geoSet) {
if (!isLineStringValid(line)) return InvalidDistance;
if (!isLineStringValid(line)) {
return InvalidDistance;
}
mapbox::cheap_ruler::CheapRuler ruler(line.front().y, UnitInMeters);
return geoSet.match(
[&line, &ruler](const mapbox::geometry::point<double>& p) {
@@ -643,43 +733,48 @@ double lineToGeometryDistance(const mapbox::geometry::line_string<double>& line,
double polygonToGeometryDistance(const mapbox::geometry::polygon<double>& polygon,
const Feature::geometry_type& geoSet) {
if (!isPolygonValid(polygon)) return InvalidDistance;
if (!isPolygonValid(polygon)) {
return InvalidDistance;
}
mapbox::cheap_ruler::CheapRuler ruler(polygon.front().front().y, UnitInMeters);
return geoSet.match(
[&polygon, &ruler](const mapbox::geometry::point<double>& p) {
return pointToPolygonDistance(p, polygon, ruler);
},
[&polygon, &ruler](const mapbox::geometry::multi_point<double>& points) {
if (!isMultiPointValid(points)) return InvalidDistance;
return pointsToPolygonDistance(points, polygon, ruler);
return isMultiPointValid(points) ? pointsToPolygonDistance(points, polygon, ruler) : InvalidDistance;
},
[&polygon, &ruler](const mapbox::geometry::line_string<double>& line) {
if (!isLineStringValid(line)) return InvalidDistance;
return lineToPolygonDistance(line, polygon, ruler);
return isLineStringValid(line) ? lineToPolygonDistance(line, polygon, ruler) : InvalidDistance;
},
[&polygon, &ruler](const mapbox::geometry::multi_line_string<double>& lines) {
double dist = InfiniteDistance;
for (const auto& line : lines) {
if (!isLineStringValid(line)) return InvalidDistance;
auto tempDist = lineToPolygonDistance(line, polygon, ruler, dist);
if (std::isnan(tempDist)) return tempDist;
if (!isLineStringValid(line)) {
return InvalidDistance;
}
const auto tempDist = lineToPolygonDistance(line, polygon, ruler, dist);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
dist = std::min(dist, tempDist);
if (dist == 0.0) return dist;
}
return dist;
},
[&polygon, &ruler](const mapbox::geometry::polygon<double>& polygon1) {
if (!isPolygonValid(polygon1)) return InvalidDistance;
return polygonToPolygonDistance(polygon, polygon1, ruler);
return isPolygonValid(polygon1) ? polygonToPolygonDistance(polygon, polygon1, ruler) : InvalidDistance;
},
[&polygon, &ruler](const mapbox::geometry::multi_polygon<double>& polygons) {
double dist = InfiniteDistance;
for (const auto& polygon1 : polygons) {
if (!isPolygonValid(polygon1)) return InvalidDistance;
auto tempDist = polygonToPolygonDistance(polygon, polygon1, ruler, dist);
if (std::isnan(tempDist)) return tempDist;
if (!isPolygonValid(polygon1)) {
return InvalidDistance;
}
const auto tempDist = polygonToPolygonDistance(polygon, polygon1, ruler, dist);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
dist = std::min(dist, tempDist);
if (dist == 0.0) return dist;
}
return dist;
},
@@ -703,10 +798,11 @@ double calculateDistance(const GeometryTileFeature& feature,
[&geoSet](const mapbox::geometry::multi_line_string<double>& lines) -> double {
double dist = InfiniteDistance;
for (const auto& line : lines) {
auto tempDist = lineToGeometryDistance(line, geoSet);
if (std::isnan(tempDist)) return tempDist;
const auto tempDist = lineToGeometryDistance(line, geoSet);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
dist = std::min(dist, tempDist);
if (dist == 0.0) return dist;
}
return dist;
},
@@ -716,20 +812,21 @@ double calculateDistance(const GeometryTileFeature& feature,
[&geoSet](const mapbox::geometry::multi_polygon<double>& polygons) -> double {
double dist = InfiniteDistance;
for (const auto& polygon : polygons) {
auto tempDist = polygonToGeometryDistance(polygon, geoSet);
if (std::isnan(tempDist)) return tempDist;
const auto tempDist = polygonToGeometryDistance(polygon, geoSet);
if (std::isnan(tempDist) || tempDist == 0.0) {
return tempDist;
}
dist = std::min(dist, tempDist);
if (dist == 0.0) return dist;
}
return dist;
},
[](const auto&) -> double { return InvalidDistance; });
[](const auto&) { return InvalidDistance; });
}
std::optional<GeoJSON> parseValue(const style::conversion::Convertible& value, style::expression::ParsingContext& ctx) {
if (isArray(value)) {
// object value, quoted with ["distance", GeoJSONObj]
auto length = arrayLength(value);
const auto length = arrayLength(value);
if (length != 2) {
ctx.error("'distance' expression requires one argument, but found " +
util::toString(arrayLength(value) - 1) + " instead.");
@@ -799,7 +896,7 @@ EvaluationResult Distance::evaluate(const EvaluationContext& params) const {
}
ParseResult Distance::parse(const Convertible& value, ParsingContext& ctx) {
auto parsedValue = parseValue(value, ctx);
const auto parsedValue = parseValue(value, ctx);
if (!parsedValue) {
return ParseResult();
}
@@ -882,7 +979,7 @@ mbgl::Value Distance::serialize() const {
return std::vector<mbgl::Value>{{getOperator(), serialized}};
}
bool Distance::operator==(const Expression& e) const {
bool Distance::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Distance) {
auto rhs = static_cast<const Distance*>(&e);
return geoJSONSource == rhs->geoJSONSource && geometries == rhs->geometries;
@@ -890,14 +987,6 @@ bool Distance::operator==(const Expression& e) const {
return false;
}
std::vector<std::optional<Value>> Distance::possibleOutputs() const {
return {std::nullopt};
}
std::string Distance::getOperator() const {
return "distance";
}
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -58,12 +58,17 @@ std::unique_ptr<Expression> literal(const Value& value) {
return std::make_unique<Literal>(value);
}
std::unique_ptr<Expression> literal(Value&& value) {
return std::make_unique<Literal>(std::move(value));
}
std::unique_ptr<Expression> literal(std::initializer_list<double> value) {
std::vector<Value> values;
values.reserve(value.size());
for (auto i : value) {
values.emplace_back(i);
}
return literal(values);
return literal(std::move(values));
}
std::unique_ptr<Expression> literal(std::initializer_list<const char*> value) {
@@ -74,14 +79,14 @@ std::unique_ptr<Expression> literal(std::initializer_list<const char*> value) {
return literal(values);
}
std::unique_ptr<Expression> assertion(const type::Type& type,
std::unique_ptr<Expression> assertion(type::Type type,
std::unique_ptr<Expression> value,
std::unique_ptr<Expression> def) {
std::vector<std::unique_ptr<Expression>> v = vec(std::move(value));
if (def) {
v.push_back(std::move(def));
}
return std::make_unique<Assertion>(type, std::move(v));
return std::make_unique<Assertion>(std::move(type), std::move(v));
}
std::unique_ptr<Expression> number(std::unique_ptr<Expression> value, std::unique_ptr<Expression> def) {
@@ -96,15 +101,17 @@ std::unique_ptr<Expression> boolean(std::unique_ptr<Expression> value, std::uniq
return assertion(type::Boolean, std::move(value), std::move(def));
}
std::unique_ptr<Expression> coercion(const type::Type& type,
namespace {
std::unique_ptr<Expression> coercion(type::Type type,
std::unique_ptr<Expression> value,
std::unique_ptr<Expression> def) {
std::vector<std::unique_ptr<Expression>> v = vec(std::move(value));
if (def) {
v.push_back(std::move(def));
}
return std::make_unique<Coercion>(type, std::move(v));
return std::make_unique<Coercion>(std::move(type), std::move(v));
}
} // namespace
std::unique_ptr<Expression> toColor(std::unique_ptr<Expression> value, std::unique_ptr<Expression> def) {
return coercion(type::Color, std::move(value), std::move(def));
@@ -162,18 +169,18 @@ std::unique_ptr<Expression> step(std::unique_ptr<Expression> input,
std::map<double, std::unique_ptr<Expression>> stops;
stops[-std::numeric_limits<double>::infinity()] = std::move(output0);
stops[input1] = std::move(output1);
return std::make_unique<Step>(type, std::move(input), std::move(stops));
return std::make_unique<Step>(std::move(type), std::move(input), std::move(stops));
}
Interpolator linear() {
Interpolator linear() noexcept {
return ExponentialInterpolator(1.0);
}
Interpolator exponential(double base) {
Interpolator exponential(double base) noexcept {
return ExponentialInterpolator(base);
}
Interpolator cubicBezier(double x1, double y1, double x2, double y2) {
Interpolator cubicBezier(double x1, double y1, double x2, double y2) noexcept {
return CubicBezierInterpolator(x1, y1, x2, y2);
}

View File

@@ -110,9 +110,9 @@ void FormatExpression::eachChild(const std::function<void(const Expression&)>& f
}
}
bool FormatExpression::operator==(const Expression& e) const {
bool FormatExpression::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::FormatExpression) {
auto rhs = static_cast<const FormatExpression*>(&e);
const auto* rhs = static_cast<const FormatExpression*>(&e);
if (sections.size() != rhs->sections.size()) {
return false;
}

View File

@@ -1,15 +1,21 @@
#include <mbgl/style/expression/get_covering_stops.hpp>
#include <cmath>
namespace mbgl {
namespace style {
namespace expression {
Range<float> getCoveringStops(const std::map<double, std::unique_ptr<Expression>>& stops,
const double lower,
const double upper) {
const double upper) noexcept {
assert(!stops.empty());
if (stops.empty()) {
return {std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN()};
}
auto minIt = stops.lower_bound(lower);
auto maxIt = stops.lower_bound(upper);
const auto maxIt = stops.lower_bound(upper);
// lower_bound yields first element >= lowerZoom, but we want the *last*
// element <= lowerZoom, so if we found a stop > lowerZoom, back up by one.

View File

@@ -35,9 +35,9 @@ void ImageExpression::eachChild(const std::function<void(const Expression&)>& fn
fn(*imageID);
}
bool ImageExpression::operator==(const Expression& e) const {
bool ImageExpression::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::ImageExpression) {
auto rhs = static_cast<const ImageExpression*>(&e);
const auto* rhs = static_cast<const ImageExpression*>(&e);
return *imageID == *rhs->imageID;
}
return false;

View File

@@ -10,20 +10,20 @@ namespace style {
namespace expression {
namespace {
bool isComparableType(const type::Type& type) {
bool isComparableType(const type::Type& type) noexcept {
return type == type::Boolean || type == type::String || type == type::Number || type == type::Null ||
type == type::Value;
}
bool isComparableRuntimeType(const type::Type& type) {
bool isComparableRuntimeType(const type::Type& type) noexcept {
return type == type::Boolean || type == type::String || type == type::Number || type == type::Null;
}
bool isSearchableType(const type::Type& type) {
bool isSearchableType(const type::Type& type) noexcept {
return type == type::String || type.is<type::Array>() || type == type::Null || type == type::Value;
}
bool isSearchableRuntimeType(const type::Type& type) {
bool isSearchableRuntimeType(const type::Type& type) noexcept {
return type == type::String || type.is<type::Array>() || type == type::Null;
}
} // namespace
@@ -87,7 +87,7 @@ using namespace mbgl::style::conversion;
ParseResult In::parse(const Convertible& value, ParsingContext& ctx) {
assert(isArray(value));
std::size_t length = arrayLength(value);
const std::size_t length = arrayLength(value);
if (length != 3) {
ctx.error("Expected 2 arguments, but found " + util::toString(length - 1) + " instead.");
return ParseResult();
@@ -99,8 +99,8 @@ ParseResult In::parse(const Convertible& value, ParsingContext& ctx) {
ParseResult haystack = ctx.parse(arrayMember(value, 2), 2, {type::Value});
if (!haystack) return ParseResult();
type::Type needleType = (*needle)->getType();
type::Type haystackType = (*haystack)->getType();
const type::Type needleType = (*needle)->getType();
const type::Type haystackType = (*haystack)->getType();
if (!isComparableType(needleType)) {
ctx.error(
@@ -120,7 +120,7 @@ ParseResult In::parse(const Convertible& value, ParsingContext& ctx) {
return ParseResult(std::make_unique<In>(std::move(*needle), std::move(*haystack)));
}
bool In::operator==(const Expression& e) const {
bool In::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::In) {
auto rhs = static_cast<const In*>(&e);
return *needle == *(rhs->needle) && *haystack == *(rhs->haystack);
@@ -132,10 +132,6 @@ std::vector<std::optional<Value>> In::possibleOutputs() const {
return {{true}, {false}};
}
std::string In::getOperator() const {
return "in";
}
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -115,7 +115,7 @@ ParseResult IndexOf::parse(const Convertible &value, ParsingContext &ctx) {
std::make_unique<IndexOf>(std::move(*keyword), std::move(*input), fromIndex ? std::move(*fromIndex) : nullptr));
}
bool IndexOf::operator==(const Expression &e) const {
bool IndexOf::operator==(const Expression &e) const noexcept {
if (e.getKind() == Kind::IndexOf) {
auto rhs = static_cast<const IndexOf *>(&e);
const auto fromIndexEqual = (fromIndex && rhs->fromIndex && *fromIndex == *(rhs->fromIndex)) ||
@@ -129,10 +129,6 @@ std::vector<std::optional<Value>> IndexOf::possibleOutputs() const {
return {std::nullopt};
}
std::string IndexOf::getOperator() const {
return "index-of";
}
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -52,8 +52,11 @@ bool isFeatureConstant(const Expression& expression) {
return featureConstant;
}
namespace {
const auto zoomProperty = std::array<std::string_view, 1>{"zoom"};
}
bool isZoomConstant(const Expression& e) {
return isGlobalPropertyConstant(e, std::array<std::string, 1>{{"zoom"}});
return isGlobalPropertyConstant(e, zoomProperty);
}
bool isRuntimeConstant(const Expression& expression) {

View File

@@ -25,7 +25,7 @@ void Length::eachChild(const std::function<void(const Expression&)>& visit) cons
visit(*input);
}
bool Length::operator==(const Expression& e) const {
bool Length::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Length) {
auto eq = static_cast<const Length*>(&e);
return *eq->input == *input;

View File

@@ -107,7 +107,7 @@ ParseResult Var::parse(const Convertible& value_, ParsingContext& ctx) {
return ParseResult();
}
return ParseResult(std::make_unique<Var>(name_, std::move(*bindingValue)));
return ParseResult(std::make_unique<Var>(std::move(name_), std::move(*bindingValue)));
}
mbgl::Value Var::serialize() const {

View File

@@ -75,7 +75,7 @@ ParseResult Literal::parse(const Convertible& value, ParsingContext& ctx) {
util::toString(arrayLength(value) - 1) + " instead.");
return ParseResult();
}
const std::optional<Value> parsedValue = parseValue(arrayMember(value, 1), ctx);
std::optional<Value> parsedValue = parseValue(arrayMember(value, 1), ctx);
if (!parsedValue) {
return ParseResult();
}
@@ -87,15 +87,15 @@ ParseResult Literal::parse(const Convertible& value, ParsingContext& ctx) {
auto expected = ctx.getExpected()->template get<type::Array>();
if (type.N && (*type.N == 0) && (!expected.N || (*expected.N == 0))) {
return ParseResult(
std::make_unique<Literal>(expected, parsedValue->template get<std::vector<Value>>()));
std::make_unique<Literal>(std::move(expected), parsedValue->template get<std::vector<Value>>()));
}
}
return ParseResult(std::make_unique<Literal>(*parsedValue));
return ParseResult(std::make_unique<Literal>(std::move(*parsedValue)));
} else {
// bare primitive value (string, number, boolean, null)
const std::optional<Value> parsedValue = parseValue(value, ctx);
return ParseResult(std::make_unique<Literal>(*parsedValue));
return ParseResult(std::make_unique<Literal>(std::move(*parsedValue)));
}
}

View File

@@ -18,9 +18,9 @@ void Match<T>::eachChild(const std::function<void(const Expression&)>& visit) co
}
template <typename T>
bool Match<T>::operator==(const Expression& e) const {
bool Match<T>::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Match) {
auto rhs = static_cast<const Match*>(&e);
const auto* rhs = static_cast<const Match*>(&e);
return (*input == *(rhs->input) && *otherwise == *(rhs->otherwise) &&
Expression::childrenEqual(branches, rhs->branches));
}
@@ -220,8 +220,8 @@ static ParseResult create(type::Type outputType,
index += 2;
}
return ParseResult(
std::make_unique<Match<T>>(outputType, std::move(input), std::move(typedBranches), std::move(otherwise)));
return ParseResult(std::make_unique<Match<T>>(
std::move(outputType), std::move(input), std::move(typedBranches), std::move(otherwise)));
}
ParseResult parseMatch(const Convertible& value, ParsingContext& ctx) {
@@ -309,10 +309,12 @@ ParseResult parseMatch(const Convertible& value, ParsingContext& ctx) {
return inputType->match(
[&](const type::NumberType&) {
return create<int64_t>(*outputType, std::move(*input), std::move(branches), std::move(*otherwise), ctx);
return create<int64_t>(
std::move(*outputType), std::move(*input), std::move(branches), std::move(*otherwise), ctx);
},
[&](const type::StringType&) {
return create<std::string>(*outputType, std::move(*input), std::move(branches), std::move(*otherwise), ctx);
return create<std::string>(
std::move(*outputType), std::move(*input), std::move(branches), std::move(*otherwise), ctx);
},
[&](const auto&) {
// unreachable: inputType is set by parseInputValue(), which only

View File

@@ -85,7 +85,7 @@ void NumberFormat::eachChild(const std::function<void(const Expression&)>& visit
if (maxFractionDigits) visit(*maxFractionDigits);
}
bool NumberFormat::operator==(const Expression& e) const {
bool NumberFormat::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::NumberFormat) {
auto rhs = static_cast<const NumberFormat*>(&e);
if ((locale && (!rhs->locale || *locale != *rhs->locale)) || (!locale && rhs->locale)) {

View File

@@ -43,20 +43,23 @@ namespace mbgl {
namespace style {
namespace expression {
bool isConstant(const Expression& expression) {
if (expression.getKind() == Kind::Var) {
auto varExpression = static_cast<const Var*>(&expression);
return isConstant(*varExpression->getBoundExpression());
}
namespace {
const auto requiredProps = std::array<std::string_view, 4>{"zoom", "heatmap-density", "line-progress", "accumulated"};
if (expression.getKind() == Kind::CompoundExpression) {
auto compound = static_cast<const CompoundExpression*>(&expression);
bool isConstant(const Expression& expression) {
const auto kind = expression.getKind();
if (kind == Kind::Var) {
const auto* varExpression = static_cast<const Var*>(&expression);
return isConstant(*varExpression->getBoundExpression());
} else if (kind == Kind::CompoundExpression) {
const auto* compound = static_cast<const CompoundExpression*>(&expression);
if (compound->getOperator() == "error") {
return false;
}
}
bool isTypeAnnotation = expression.getKind() == Kind::Coercion || expression.getKind() == Kind::Assertion;
const bool isTypeAnnotation = kind == Kind::Coercion || kind == Kind::Assertion;
bool childrenConstant = true;
expression.eachChild([&](const Expression& child) {
@@ -73,15 +76,10 @@ bool isConstant(const Expression& expression) {
childrenConstant = childrenConstant && child.getKind() == Kind::Literal;
}
});
if (!childrenConstant) {
return false;
}
return isFeatureConstant(expression) &&
isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "heatmap-density"}}) &&
isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "line-progress"}}) &&
isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "accumulated"}});
return childrenConstant && isFeatureConstant(expression) && isGlobalPropertyConstant(expression, requiredProps);
}
} // namespace
using namespace mbgl::style::conversion;
@@ -143,7 +141,7 @@ MAPBOX_ETERNAL_CONSTEXPR const auto expressionRegistry =
{"index-of", IndexOf::parse},
{"slice", Slice::parse}});
bool isExpression(const std::string& name) {
bool isExpression(const std::string& name) noexcept {
return expressionRegistry.contains(name.c_str());
}
@@ -182,14 +180,14 @@ ParseResult ParsingContext::parse(const Convertible& value,
return parsed;
}
auto annotate = [](std::unique_ptr<Expression> expression,
const type::Type& type,
TypeAnnotationOption typeAnnotation) -> std::unique_ptr<Expression> {
const auto annotate = [](std::unique_ptr<Expression> expression,
type::Type type,
TypeAnnotationOption typeAnnotation) -> std::unique_ptr<Expression> {
switch (typeAnnotation) {
case TypeAnnotationOption::assert:
return std::make_unique<Assertion>(type, dsl::vec(std::move(expression)));
return std::make_unique<Assertion>(std::move(type), dsl::vec(std::move(expression)));
case TypeAnnotationOption::coerce:
return std::make_unique<Coercion>(type, dsl::vec(std::move(expression)));
return std::make_unique<Coercion>(std::move(type), dsl::vec(std::move(expression)));
case TypeAnnotationOption::omit:
return expression;
}
@@ -204,12 +202,12 @@ ParseResult ParsingContext::parse(const Convertible& value,
if ((*expected == type::String || *expected == type::Number || *expected == type::Boolean ||
*expected == type::Object || expected->is<type::Array>()) &&
actual == type::Value) {
parsed = {
annotate(std::move(*parsed), *expected, typeAnnotationOption.value_or(TypeAnnotationOption::assert))};
parsed = {annotate(
std::move(*parsed), std::move(*expected), typeAnnotationOption.value_or(TypeAnnotationOption::assert))};
} else if ((*expected == type::Color || *expected == type::Formatted || *expected == type::Image) &&
(actual == type::Value || actual == type::String)) {
parsed = {
annotate(std::move(*parsed), *expected, typeAnnotationOption.value_or(TypeAnnotationOption::coerce))};
parsed = {annotate(
std::move(*parsed), std::move(*expected), typeAnnotationOption.value_or(TypeAnnotationOption::coerce))};
} else {
checkType((*parsed)->getType());
if (!errors->empty()) {
@@ -237,7 +235,7 @@ ParseResult ParsingContext::parse(const Convertible& value,
return ParseResult(
std::make_unique<Literal>(type.get<type::Array>(), evaluated->get<std::vector<Value>>()));
} else {
return ParseResult(std::make_unique<Literal>(*evaluated));
return ParseResult(std::make_unique<Literal>(std::move(*evaluated)));
}
}

View File

@@ -10,7 +10,7 @@ namespace expression {
namespace {
int normalizeIndex(int index, int length) {
int normalizeIndex(int index, int length) noexcept {
if (index < 0) {
index += length;
}
@@ -133,7 +133,7 @@ ParseResult Slice::parse(const Convertible &value, ParsingContext &ctx) {
std::make_unique<Slice>(std::move(*input), std::move(*fromIndex), toIndex ? std::move(*toIndex) : nullptr));
}
bool Slice::operator==(const Expression &e) const {
bool Slice::operator==(const Expression &e) const noexcept {
if (e.getKind() == Kind::Slice) {
auto rhs = static_cast<const Slice *>(&e);
const auto toIndexEqual = (toIndex && rhs->toIndex && *toIndex == *(rhs->toIndex)) ||
@@ -147,10 +147,6 @@ std::vector<std::optional<Value>> Slice::possibleOutputs() const {
return {std::nullopt};
}
std::string Slice::getOperator() const {
return "slice";
}
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -9,10 +9,8 @@ namespace mbgl {
namespace style {
namespace expression {
Step::Step(const type::Type& type_,
std::unique_ptr<Expression> input_,
std::map<double, std::unique_ptr<Expression>> stops_)
: Expression(Kind::Step, type_, depsOf(input_) | collectDependencies(stops_)),
Step::Step(type::Type type_, std::unique_ptr<Expression> input_, std::map<double, std::unique_ptr<Expression>> stops_)
: Expression(Kind::Step, std::move(type_), depsOf(input_) | collectDependencies(stops_)),
input(std::move(input_)),
stops(std::move(stops_)) {
assert(input->getType() == type::Number);
@@ -56,7 +54,7 @@ void Step::eachStop(const std::function<void(double, const Expression&)>& visit)
}
}
bool Step::operator==(const Expression& e) const {
bool Step::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Step) {
auto rhs = static_cast<const Step*>(&e);
return *input == *(rhs->input) && Expression::childrenEqual(stops, rhs->stops);
@@ -74,7 +72,7 @@ std::vector<std::optional<Value>> Step::possibleOutputs() const {
return result;
}
Range<float> Step::getCoveringStops(const double lower, const double upper) const {
Range<float> Step::getCoveringStops(const double lower, const double upper) const noexcept {
return ::mbgl::style::expression::getCoveringStops(stops, lower, upper);
}
@@ -174,7 +172,7 @@ ParseResult Step::parse(const mbgl::style::conversion::Convertible& value, Parsi
assert(outputType);
return ParseResult(std::make_unique<Step>(*outputType, std::move(*input), std::move(stops)));
return ParseResult(std::make_unique<Step>(std::move(*outputType), std::move(*input), std::move(stops)));
}
mbgl::Value Step::serialize() const {

View File

@@ -108,12 +108,12 @@ struct FromMBGLValue {
return result;
}
Value operator()(const std::string& s) { return s; }
Value operator()(const bool b) { return b; }
Value operator()(const NullValue) { return Null; }
Value operator()(const double v) { return v; }
Value operator()(const uint64_t& v) { return static_cast<double>(v); }
Value operator()(const int64_t& v) { return static_cast<double>(v); }
Value operator()(const std::string& s) noexcept { return s; }
Value operator()(const bool b) noexcept { return b; }
Value operator()(const NullValue) noexcept { return Null; }
Value operator()(const double v) noexcept { return v; }
Value operator()(const uint64_t& v) noexcept { return static_cast<double>(v); }
Value operator()(const int64_t& v) noexcept { return static_cast<double>(v); }
};
Value ValueConverter<mbgl::Value>::toExpressionValue(const mbgl::Value& value) {

View File

@@ -16,13 +16,13 @@
namespace mbgl {
namespace {
Point<int64_t> latLonToTileCoodinates(const Point<double>& point, const mbgl::CanonicalTileID& canonical) {
Point<int64_t> latLonToTileCoodinates(const Point<double>& point, const mbgl::CanonicalTileID& canonical) noexcept {
const double size = util::EXTENT * std::pow(2, canonical.z);
auto x = (point.x + util::LONGITUDE_MAX) * size / util::DEGREES_MAX;
auto y = (util::LONGITUDE_MAX -
util::rad2deg(std::log(std::tan(point.y * M_PI / util::DEGREES_MAX + M_PI / 4.0)))) *
size / util::DEGREES_MAX;
const auto x = (point.x + util::LONGITUDE_MAX) * size / util::DEGREES_MAX;
const auto y = (util::LONGITUDE_MAX -
util::rad2deg(std::log(std::tan(point.y * M_PI / util::DEGREES_MAX + M_PI / 4.0)))) *
size / util::DEGREES_MAX;
Point<int64_t> p;
p.x = (util::clamp<int64_t>(
@@ -72,7 +72,7 @@ MultiPolygon<int64_t> getTilePolygons(const Feature::geometry_type& polygonGeoSe
[](const auto&) { return MultiPolygon<int64_t>(); });
}
void updatePoint(Point<int64_t>& p, WithinBBox& bbox, const WithinBBox& polyBBox, const int64_t worldSize) {
void updatePoint(Point<int64_t>& p, WithinBBox& bbox, const WithinBBox& polyBBox, const int64_t worldSize) noexcept {
if (p.x < polyBBox[0] || p.x > polyBBox[2]) {
const auto getShift = [](Point<int64_t>& point, const int64_t polygonSide, const int64_t size) -> int64_t {
if (point.x - polygonSide > size / 2) {
@@ -325,9 +325,9 @@ mbgl::Value Within::serialize() const {
return std::vector<mbgl::Value>{{getOperator(), serialized}};
}
bool Within::operator==(const Expression& e) const {
bool Within::operator==(const Expression& e) const noexcept {
if (e.getKind() == Kind::Within) {
auto rhs = static_cast<const Within*>(&e);
const auto* rhs = static_cast<const Within*>(&e);
return geoJSONSource == rhs->geoJSONSource && geometries == rhs->geometries;
}
return false;
@@ -337,10 +337,6 @@ std::vector<std::optional<Value>> Within::possibleOutputs() const {
return {{true}, {false}};
}
std::string Within::getOperator() const {
return "within";
}
} // namespace expression
} // namespace style
} // namespace mbgl

View File

@@ -27,7 +27,7 @@ unsigned long BackgroundLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const BackgroundLayer::Impl& BackgroundLayerProperties::layerImpl() const {
const BackgroundLayer::Impl& BackgroundLayerProperties::layerImpl() const noexcept {
return static_cast<const BackgroundLayer::Impl&>(*baseImpl);
}

View File

@@ -47,7 +47,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const BackgroundLayer::Impl& layerImpl() const;
const BackgroundLayer::Impl& layerImpl() const noexcept;
// Data members.
CrossfadeParameters crossfade;
BackgroundPaintProperties::PossiblyEvaluated evaluated;

View File

@@ -25,7 +25,7 @@ unsigned long CircleLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const CircleLayer::Impl& CircleLayerProperties::layerImpl() const {
const CircleLayer::Impl& CircleLayerProperties::layerImpl() const noexcept {
return static_cast<const CircleLayer::Impl&>(*baseImpl);
}

View File

@@ -95,7 +95,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const CircleLayer::Impl& layerImpl() const;
const CircleLayer::Impl& layerImpl() const noexcept;
// Data members.
CirclePaintProperties::PossiblyEvaluated evaluated;
};

View File

@@ -27,7 +27,7 @@ unsigned long FillExtrusionLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const FillExtrusionLayer::Impl& FillExtrusionLayerProperties::layerImpl() const {
const FillExtrusionLayer::Impl& FillExtrusionLayerProperties::layerImpl() const noexcept {
return static_cast<const FillExtrusionLayer::Impl&>(*baseImpl);
}

View File

@@ -72,7 +72,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const FillExtrusionLayer::Impl& layerImpl() const;
const FillExtrusionLayer::Impl& layerImpl() const noexcept;
// Data members.
CrossfadeParameters crossfade;
FillExtrusionPaintProperties::PossiblyEvaluated evaluated;

View File

@@ -27,7 +27,7 @@ unsigned long FillLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const FillLayer::Impl& FillLayerProperties::layerImpl() const {
const FillLayer::Impl& FillLayerProperties::layerImpl() const noexcept {
return static_cast<const FillLayer::Impl&>(*baseImpl);
}

View File

@@ -76,7 +76,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const FillLayer::Impl& layerImpl() const;
const FillLayer::Impl& layerImpl() const noexcept;
// Data members.
CrossfadeParameters crossfade;
FillPaintProperties::PossiblyEvaluated evaluated;

View File

@@ -25,7 +25,7 @@ unsigned long HeatmapLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const HeatmapLayer::Impl& HeatmapLayerProperties::layerImpl() const {
const HeatmapLayer::Impl& HeatmapLayerProperties::layerImpl() const noexcept {
return static_cast<const HeatmapLayer::Impl&>(*baseImpl);
}

View File

@@ -55,7 +55,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const HeatmapLayer::Impl& layerImpl() const;
const HeatmapLayer::Impl& layerImpl() const noexcept;
// Data members.
HeatmapPaintProperties::PossiblyEvaluated evaluated;
};

View File

@@ -25,7 +25,7 @@ unsigned long HillshadeLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const HillshadeLayer::Impl& HillshadeLayerProperties::layerImpl() const {
const HillshadeLayer::Impl& HillshadeLayerProperties::layerImpl() const noexcept {
return static_cast<const HillshadeLayer::Impl&>(*baseImpl);
}

View File

@@ -61,7 +61,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const HillshadeLayer::Impl& layerImpl() const;
const HillshadeLayer::Impl& layerImpl() const noexcept;
// Data members.
HillshadePaintProperties::PossiblyEvaluated evaluated;
};

View File

@@ -36,7 +36,7 @@ unsigned long <%- camelize(type) %>LayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const <%- camelize(type) %>Layer::Impl& <%- camelize(type) %>LayerProperties::layerImpl() const {
const <%- camelize(type) %>Layer::Impl& <%- camelize(type) %>LayerProperties::layerImpl() const noexcept {
return static_cast<const <%- camelize(type) %>Layer::Impl&>(*baseImpl);
}

View File

@@ -78,7 +78,7 @@ public:
expression::Dependency getDependencies() const noexcept override;
const <%- camelize(type) %>Layer::Impl& layerImpl() const;
const <%- camelize(type) %>Layer::Impl& layerImpl() const noexcept;
// Data members.
<% if (type === 'background' || type === 'fill' || type === 'line' || type === 'fill-extrusion') { -%>
CrossfadeParameters crossfade;

View File

@@ -27,7 +27,7 @@ unsigned long LineLayerProperties::constantsMask() const {
return evaluated.constantsMask();
}
const LineLayer::Impl& LineLayerProperties::layerImpl() const {
const LineLayer::Impl& LineLayerProperties::layerImpl() const noexcept {
return static_cast<const LineLayer::Impl&>(*baseImpl);
}

Some files were not shown because too many files have changed in this diff Show More