summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-12-03 16:31:09 +0200
committerKonstantin Käfer <mail@kkaefer.com>2018-12-03 16:35:42 +0200
commit4ee32910ffb806b92faab877b3eccc0593b03ae3 (patch)
tree627a1a109bb93d05a10edb0c27797fa7df0c4534
parentaefcb1176a819c63d515cbf520ac4739cb05fcf7 (diff)
downloadqtlocation-mapboxgl-4ee32910ffb806b92faab877b3eccc0593b03ae3.tar.gz
[core] use constexpr map using eternal for expression lookups
-rw-r--r--.gitmodules3
-rw-r--r--cmake/core.cmake1
-rw-r--r--cmake/vendor.cmake1
-rw-r--r--include/mbgl/style/expression/parsing_context.hpp3
-rw-r--r--src/mbgl/style/expression/is_expression.cpp4
-rw-r--r--src/mbgl/style/expression/parsing_context.cpp79
m---------vendor/eternal0
-rw-r--r--vendor/eternal.cmake5
8 files changed, 55 insertions, 41 deletions
diff --git a/.gitmodules b/.gitmodules
index b7cb5780c8..7962589160 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -76,3 +76,6 @@
[submodule "vendor/glfw"]
path = vendor/glfw
url = https://github.com/glfw/glfw.git
+[submodule "vendor/eternal"]
+ path = vendor/eternal
+ url = https://github.com/mapbox/eternal.git
diff --git a/cmake/core.cmake b/cmake/core.cmake
index c5961cd904..6773af87fc 100644
--- a/cmake/core.cmake
+++ b/cmake/core.cmake
@@ -9,6 +9,7 @@ target_include_directories(mbgl-core
target_link_libraries(mbgl-core PRIVATE
earcut.hpp
+ eternal
expected
geojson-vt-cpp
kdbush.hpp
diff --git a/cmake/vendor.cmake b/cmake/vendor.cmake
index 557b0062d9..ddeefad76d 100644
--- a/cmake/vendor.cmake
+++ b/cmake/vendor.cmake
@@ -7,6 +7,7 @@ include(${CMAKE_SOURCE_DIR}/vendor/benchmark.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/boost.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/cheap-ruler-cpp.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/earcut.hpp.cmake)
+include(${CMAKE_SOURCE_DIR}/vendor/eternal.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/expected.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/geojson-vt-cpp.cmake)
include(${CMAKE_SOURCE_DIR}/vendor/geojson.hpp.cmake)
diff --git a/include/mbgl/style/expression/parsing_context.hpp b/include/mbgl/style/expression/parsing_context.hpp
index dde907ec2c..08151a2b7d 100644
--- a/include/mbgl/style/expression/parsing_context.hpp
+++ b/include/mbgl/style/expression/parsing_context.hpp
@@ -178,8 +178,7 @@ private:
};
using ParseFunction = ParseResult (*)(const conversion::Convertible&, ParsingContext&);
-using ExpressionRegistry = std::unordered_map<std::string, ParseFunction>;
-const ExpressionRegistry& getExpressionRegistry();
+ParseFunction getExpression(const std::string&);
} // namespace expression
} // namespace style
diff --git a/src/mbgl/style/expression/is_expression.cpp b/src/mbgl/style/expression/is_expression.cpp
index acf074c25b..34f0fec7a3 100644
--- a/src/mbgl/style/expression/is_expression.cpp
+++ b/src/mbgl/style/expression/is_expression.cpp
@@ -12,13 +12,11 @@ namespace expression {
using namespace mbgl::style::conversion;
bool isExpression(const Convertible& value) {
- const ExpressionRegistry& registry = getExpressionRegistry();
-
if (!isArray(value) || arrayLength(value) == 0) return false;
optional<std::string> name = toString(arrayMember(value, 0));
if (!name) return false;
- return (registry.find(*name) != registry.end()) ||
+ return getExpression(*name) ||
(CompoundExpressionRegistry::definitions.find(*name) != CompoundExpressionRegistry::definitions.end());
}
diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp
index 34fbc5c380..79a2f251e2 100644
--- a/src/mbgl/style/expression/parsing_context.cpp
+++ b/src/mbgl/style/expression/parsing_context.cpp
@@ -29,6 +29,8 @@
#include <mbgl/util/string.hpp>
+#include <mapbox/eternal.hpp>
+
namespace mbgl {
namespace style {
namespace expression {
@@ -95,39 +97,45 @@ ParseResult ParsingContext::parse(const Convertible& value, std::size_t index_,
return child.parse(value);
}
-const ExpressionRegistry& getExpressionRegistry() {
- static ExpressionRegistry registry {{
- {"==", parseComparison},
- {"!=", parseComparison},
- {">", parseComparison},
- {"<", parseComparison},
- {">=", parseComparison},
- {"<=", parseComparison},
- {"all", All::parse},
- {"any", Any::parse},
- {"array", Assertion::parse},
- {"at", At::parse},
- {"boolean", Assertion::parse},
- {"case", Case::parse},
- {"coalesce", Coalesce::parse},
- {"collator", CollatorExpression::parse},
- {"format", FormatExpression::parse},
- {"interpolate", parseInterpolate},
- {"length", Length::parse},
- {"let", Let::parse},
- {"literal", Literal::parse},
- {"match", parseMatch},
- {"number", Assertion::parse},
- {"object", Assertion::parse},
- {"step", Step::parse},
- {"string", Assertion::parse},
- {"to-boolean", Coercion::parse},
- {"to-color", Coercion::parse},
- {"to-number", Coercion::parse},
- {"to-string", Coercion::parse},
- {"var", Var::parse}
- }};
- return registry;
+MAPBOX_ETERNAL_CONSTEXPR const auto expressionRegistry = mapbox::eternal::hash_map<mapbox::eternal::string, ParseFunction>({
+ {"==", parseComparison},
+ {"!=", parseComparison},
+ {">", parseComparison},
+ {"<", parseComparison},
+ {">=", parseComparison},
+ {"<=", parseComparison},
+ {"all", All::parse},
+ {"any", Any::parse},
+ {"array", Assertion::parse},
+ {"at", At::parse},
+ {"boolean", Assertion::parse},
+ {"case", Case::parse},
+ {"coalesce", Coalesce::parse},
+ {"collator", CollatorExpression::parse},
+ {"format", FormatExpression::parse},
+ {"interpolate", parseInterpolate},
+ {"length", Length::parse},
+ {"let", Let::parse},
+ {"literal", Literal::parse},
+ {"match", parseMatch},
+ {"number", Assertion::parse},
+ {"object", Assertion::parse},
+ {"step", Step::parse},
+ {"string", Assertion::parse},
+ {"to-boolean", Coercion::parse},
+ {"to-color", Coercion::parse},
+ {"to-number", Coercion::parse},
+ {"to-string", Coercion::parse},
+ {"var", Var::parse}
+});
+
+ParseFunction getExpression(const std::string& name) {
+ auto parseFunction = expressionRegistry.find(name.c_str());
+ if (parseFunction != expressionRegistry.end()) {
+ return parseFunction->second;
+ } else {
+ return nullptr;
+ }
}
ParseResult ParsingContext::parse(const Convertible& value, optional<TypeAnnotationOption> typeAnnotationOption) {
@@ -150,9 +158,8 @@ ParseResult ParsingContext::parse(const Convertible& value, optional<TypeAnnotat
return ParseResult();
}
- const ExpressionRegistry& registry = getExpressionRegistry();
- auto parseFunction = registry.find(*op);
- if (parseFunction != registry.end()) {
+ auto parseFunction = expressionRegistry.find(op->c_str());
+ if (parseFunction != expressionRegistry.end()) {
parsed = parseFunction->second(value, *this);
} else {
parsed = parseCompoundExpression(*op, value, *this);
diff --git a/vendor/eternal b/vendor/eternal
new file mode 160000
+Subproject 960f4c85262add96a79aa2fef5d3363cc2ae234
diff --git a/vendor/eternal.cmake b/vendor/eternal.cmake
new file mode 100644
index 0000000000..1239a8a43d
--- /dev/null
+++ b/vendor/eternal.cmake
@@ -0,0 +1,5 @@
+add_library(eternal INTERFACE)
+
+target_include_directories(eternal SYSTEM INTERFACE
+ ${CMAKE_SOURCE_DIR}/vendor/eternal/include
+)