diff options
-rw-r--r-- | cmake/mason-dependencies.cmake | 2 | ||||
-rw-r--r-- | include/mbgl/style/expression/expression.hpp | 446 | ||||
-rw-r--r-- | include/mbgl/util/chrono.hpp | 7 | ||||
-rw-r--r-- | include/mbgl/util/enum.hpp | 37 |
4 files changed, 255 insertions, 237 deletions
diff --git a/cmake/mason-dependencies.cmake b/cmake/mason-dependencies.cmake index 826dcf2e45..deb5bcd8b7 100644 --- a/cmake/mason-dependencies.cmake +++ b/cmake/mason-dependencies.cmake @@ -4,7 +4,7 @@ mason_use(geometry VERSION 0.9.3 HEADER_ONLY) mason_use(variant VERSION 1.1.4 HEADER_ONLY) mason_use(unique_resource VERSION cba309e HEADER_ONLY) mason_use(rapidjson VERSION 1.1.0 HEADER_ONLY) -mason_use(boost VERSION 1.65.1 HEADER_ONLY) +mason_use(boost VERSION 1.67.0 HEADER_ONLY) mason_use(geojsonvt VERSION 6.6.0 HEADER_ONLY) mason_use(supercluster VERSION 0.2.2 HEADER_ONLY) mason_use(kdbush VERSION 0.1.1-1 HEADER_ONLY) diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp index bfd1e08ee7..e817a642a4 100644 --- a/include/mbgl/style/expression/expression.hpp +++ b/include/mbgl/style/expression/expression.hpp @@ -1,215 +1,231 @@ -#pragma once - -#include <mbgl/util/optional.hpp> -#include <mbgl/util/variant.hpp> -#include <mbgl/util/color.hpp> -#include <mbgl/style/expression/type.hpp> -#include <mbgl/style/expression/value.hpp> -#include <mbgl/style/expression/parsing_context.hpp> - -#include <array> -#include <vector> -#include <memory> - -namespace mbgl { - -class GeometryTileFeature; - -namespace style { -namespace expression { - -class EvaluationError { -public: - std::string message; -}; - -class EvaluationContext { -public: - EvaluationContext(float zoom_) : zoom(zoom_), feature(nullptr) {} - EvaluationContext(GeometryTileFeature const * feature_) : zoom(optional<float>()), feature(feature_) {} - EvaluationContext(float zoom_, GeometryTileFeature const * feature_) : - zoom(zoom_), feature(feature_) - {} - EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> colorRampParameter_) : - zoom(std::move(zoom_)), feature(feature_), colorRampParameter(std::move(colorRampParameter_)) - {} - - optional<float> zoom; - GeometryTileFeature const * feature; - optional<double> colorRampParameter; -}; - -template <typename T> -class Result : private variant<EvaluationError, T> { -public: - using variant<EvaluationError, T>::variant; - using Value = T; - - Result() = default; - - explicit operator bool () const { - 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 { - assert(this->template is<T>()); - return std::addressof(this->template get<T>()); - } - - T* operator->() { - assert(this->template is<T>()); - return std::addressof(this->template get<T>()); - } - - T& operator*() { - assert(this->template is<T>()); - return this->template get<T>(); - } - - const T& operator*() const { - assert(this->template is<T>()); - return this->template get<T>(); - } - - const EvaluationError& error() const { - assert(this->template is<EvaluationError>()); - return this->template get<EvaluationError>(); - } -}; - -class EvaluationResult : public Result<Value> { -public: - using Result::Result; // NOLINT - - EvaluationResult() = default; - - EvaluationResult(const std::array<double, 4>& arr) : - Result(toExpressionValue(arr)) - {} - - // used only for the special (private) "error" expression - EvaluationResult(const type::ErrorType&) { - assert(false); - } -}; - -/* - Expression is an abstract class that serves as an interface and base class - for particular expression implementations. - - CompoundExpression implements the majority of expressions in the spec by - inferring the argument and output from a simple function (const T0& arg0, - const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are member types of - mbgl::style::expression::Value. - - The other Expression subclasses (Let, Curve, Match, etc.) exist in order to - implement expressions that need specialized parsing, type checking, or - evaluation logic that can't be handled by CompoundExpression's inference - mechanism. - - Each Expression subclass also provides a static - ParseResult ExpressionClass::parse(const V&, ParsingContext), - which handles parsing a style-spec JSON representation of the expression. -*/ - -enum class Kind : int32_t { - Coalesce, - CompoundExpression, - Literal, - ArrayAssertion, - At, - Interpolate, - Assertion, - Length, - Step, - Let, - Var, - CollatorExpression, - Coercion, - Match, - Error, - Case, - Any, - All, - Comparison, -}; - -class Expression { -public: - Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {} - virtual ~Expression() = default; - - 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; }; - type::Type getType() const { return type; }; - - EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const; - - /** - * Statically analyze the expression, attempting to enumerate possible outputs. Returns - * an array of values plus the sentinel null optional value, used to indicate that the - * complete set of outputs is statically undecidable. - */ - virtual std::vector<optional<Value>> possibleOutputs() const = 0; - - virtual mbgl::Value serialize() const { - std::vector<mbgl::Value> serialized; - serialized.emplace_back(getOperator()); - eachChild([&](const Expression &child) { - serialized.emplace_back(child.serialize()); - }); - return serialized; - }; - - virtual std::string getOperator() const = 0; - -protected: - template <typename T> - static bool childrenEqual(const T& lhs, const T& rhs) { - 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; - } - return true; - } - - static bool childEqual(const std::unique_ptr<Expression>& lhs, const std::unique_ptr<Expression>& rhs) { - return *lhs == *rhs; - } - - template <typename T> - static bool childEqual(const std::pair<T, std::unique_ptr<Expression>>& lhs, - const std::pair<T, std::unique_ptr<Expression>>& rhs) { - return lhs.first == rhs.first && *(lhs.second) == *(rhs.second); - } - - template <typename T> - static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs, - const std::pair<T, std::shared_ptr<Expression>>& rhs) { - 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) { - return *(lhs.first) == *(rhs.first) && *(lhs.second) == *(rhs.second); - } - -private: - Kind kind; - type::Type type; -}; - -} // namespace expression -} // namespace style -} // namespace mbgl +#pragma once
+
+#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/expression/type.hpp>
+#include <mbgl/style/expression/value.hpp>
+#include <mbgl/util/color.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/variant.hpp>
+
+#include <array>
+#include <memory>
+#include <vector>
+
+namespace mbgl {
+
+class GeometryTileFeature;
+
+namespace style {
+namespace expression {
+
+class EvaluationError {
+public:
+ std::string message;
+};
+
+class EvaluationContext {
+public:
+ EvaluationContext(float zoom_) : zoom(zoom_), feature(nullptr) {
+ }
+ EvaluationContext(GeometryTileFeature const* feature_)
+ : zoom(optional<float>()), feature(feature_) {
+ }
+ EvaluationContext(float zoom_, GeometryTileFeature const* feature_)
+ : zoom(zoom_), feature(feature_) {
+ }
+ EvaluationContext(optional<float> zoom_,
+ GeometryTileFeature const* feature_,
+ optional<double> colorRampParameter_)
+ : zoom(std::move(zoom_)),
+ feature(feature_),
+ colorRampParameter(std::move(colorRampParameter_)) {
+ }
+
+ optional<float> zoom;
+ GeometryTileFeature const* feature;
+ optional<double> colorRampParameter;
+};
+
+template <typename T>
+class Result : private variant<EvaluationError, T> {
+public:
+ // using variant<EvaluationError, T>::variant;
+ template <class... Args>
+ Result(Args&&... args) : variant<EvaluationError, T>(std::forward<Args>(args)...) {
+ }
+ using Value = T;
+
+ Result() = default;
+
+ explicit operator bool() const {
+ 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 {
+ assert(this->template is<T>());
+ return std::addressof(this->template get<T>());
+ }
+
+ T* operator->() {
+ assert(this->template is<T>());
+ return std::addressof(this->template get<T>());
+ }
+
+ T& operator*() {
+ assert(this->template is<T>());
+ return this->template get<T>();
+ }
+
+ const T& operator*() const {
+ assert(this->template is<T>());
+ return this->template get<T>();
+ }
+
+ const EvaluationError& error() const {
+ assert(this->template is<EvaluationError>());
+ return this->template get<EvaluationError>();
+ }
+};
+
+class EvaluationResult : public Result<Value> {
+public:
+ using Result::Result; // NOLINT
+
+ EvaluationResult() = default;
+
+ EvaluationResult(const std::array<double, 4>& arr) : Result(toExpressionValue(arr)) {
+ }
+
+ // used only for the special (private) "error" expression
+ EvaluationResult(const type::ErrorType&) {
+ assert(false);
+ }
+};
+
+/*
+ Expression is an abstract class that serves as an interface and base class
+ for particular expression implementations.
+
+ CompoundExpression implements the majority of expressions in the spec by
+ inferring the argument and output from a simple function (const T0& arg0,
+ const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are member types of
+ mbgl::style::expression::Value.
+
+ The other Expression subclasses (Let, Curve, Match, etc.) exist in order to
+ implement expressions that need specialized parsing, type checking, or
+ evaluation logic that can't be handled by CompoundExpression's inference
+ mechanism.
+
+ Each Expression subclass also provides a static
+ ParseResult ExpressionClass::parse(const V&, ParsingContext),
+ which handles parsing a style-spec JSON representation of the expression.
+*/
+
+enum class Kind : int32_t {
+ Coalesce,
+ CompoundExpression,
+ Literal,
+ ArrayAssertion,
+ At,
+ Interpolate,
+ Assertion,
+ Length,
+ Step,
+ Let,
+ Var,
+ CollatorExpression,
+ Coercion,
+ Match,
+ Error,
+ Case,
+ Any,
+ All,
+ Comparison,
+};
+
+class Expression {
+public:
+ Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {
+ }
+ virtual ~Expression() = default;
+
+ 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;
+ };
+ type::Type getType() const {
+ return type;
+ };
+
+ EvaluationResult evaluate(optional<float> zoom,
+ const Feature& feature,
+ optional<double> colorRampParameter) const;
+
+ /**
+ * Statically analyze the expression, attempting to enumerate possible outputs. Returns
+ * an array of values plus the sentinel null optional value, used to indicate that the
+ * complete set of outputs is statically undecidable.
+ */
+ virtual std::vector<optional<Value>> possibleOutputs() const = 0;
+
+ virtual mbgl::Value serialize() const {
+ std::vector<mbgl::Value> serialized;
+ serialized.emplace_back(getOperator());
+ eachChild([&](const Expression& child) { serialized.emplace_back(child.serialize()); });
+ return serialized;
+ };
+
+ virtual std::string getOperator() const = 0;
+
+protected:
+ template <typename T>
+ static bool childrenEqual(const T& lhs, const T& rhs) {
+ 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;
+ }
+ return true;
+ }
+
+ static bool childEqual(const std::unique_ptr<Expression>& lhs,
+ const std::unique_ptr<Expression>& rhs) {
+ return *lhs == *rhs;
+ }
+
+ template <typename T>
+ static bool childEqual(const std::pair<T, std::unique_ptr<Expression>>& lhs,
+ const std::pair<T, std::unique_ptr<Expression>>& rhs) {
+ return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
+ }
+
+ template <typename T>
+ static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs,
+ const std::pair<T, std::shared_ptr<Expression>>& rhs) {
+ 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) {
+ return *(lhs.first) == *(rhs.first) && *(lhs.second) == *(rhs.second);
+ }
+
+private:
+ Kind kind;
+ type::Type type;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/util/chrono.hpp b/include/mbgl/util/chrono.hpp index 723cd131e3..7384f5437d 100644 --- a/include/mbgl/util/chrono.hpp +++ b/include/mbgl/util/chrono.hpp @@ -11,7 +11,7 @@ using Seconds = std::chrono::seconds; using Milliseconds = std::chrono::milliseconds; using TimePoint = Clock::time_point; -using Duration = Clock::duration; +using Duration = Clock::duration; // Used to measure second-precision times, such as times gathered from HTTP responses. using Timestamp = std::chrono::time_point<std::chrono::system_clock, Seconds>; @@ -28,18 +28,19 @@ std::string rfc1123(Timestamp); // YYYY-mm-dd HH:MM:SS e.g. "2015-11-26 16:11:23" std::string iso8601(Timestamp); -Timestamp parseTimestamp(const char *); +Timestamp parseTimestamp(const char*); Timestamp parseTimestamp(const int32_t timestamp); // C++17 polyfill +/* template <class Rep, class Period, class = std::enable_if_t< std::chrono::duration<Rep, Period>::min() < std::chrono::duration<Rep, Period>::zero()>> constexpr std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d) { return d >= d.zero() ? d : -d; } - +*/ } // namespace util } // namespace mbgl diff --git a/include/mbgl/util/enum.hpp b/include/mbgl/util/enum.hpp index 608befd3c4..5d67e394ba 100644 --- a/include/mbgl/util/enum.hpp +++ b/include/mbgl/util/enum.hpp @@ -12,26 +12,27 @@ template <typename T> class Enum { public: using Type = T; - static const char * toString(T); + static const char* toString(T); static optional<T> toEnum(const std::string&); }; -#define MBGL_DEFINE_ENUM(T, values...) \ - \ -static const constexpr std::pair<const T, const char *> T##_names[] = values; \ - \ -template <> \ -const char * Enum<T>::toString(T t) { \ - auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \ - [&] (const auto& v) { return t == v.first; }); \ - assert(it != std::end(T##_names)); return it->second; \ -} \ - \ -template <> \ -optional<T> Enum<T>::toEnum(const std::string& s) { \ - auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \ - [&] (const auto& v) { return s == v.second; }); \ - return it == std::end(T##_names) ? optional<T>() : it->first; \ -} +#define MBGL_DEFINE_ENUM(T, ...) \ + \ + static const constexpr std::pair<const T, const char*> T##_names[] = values; \ + \ + template <> \ + const char* Enum<T>::toString(T t) { \ + auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \ + [&](const auto& v) { return t == v.first; }); \ + assert(it != std::end(T##_names)); \ + return it->second; \ + } \ + \ + template <> \ + optional<T> Enum<T>::toEnum(const std::string& s) { \ + auto it = std::find_if(std::begin(T##_names), std::end(T##_names), \ + [&](const auto& v) { return s == v.second; }); \ + return it == std::end(T##_names) ? optional<T>() : it->first; \ + } } // namespace mbgl |