summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-02-05 15:56:46 -0800
committerAnsis Brammanis <brammanis@gmail.com>2015-02-05 16:46:13 -0800
commit3a8aaad6a799fd4ab1feb47a47a7ffa0d05c1cc0 (patch)
treefdf3f3c402a870e3e0485b25f0c0bd423487b2fb /src
parent6e95c3b2e189e91a6244eef58ad1057258b2724b (diff)
downloadqtlocation-mapboxgl-3a8aaad6a799fd4ab1feb47a47a7ffa0d05c1cc0.tar.gz
make everything a function
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/style/function_properties.cpp20
-rw-r--r--src/mbgl/style/property_value.hpp21
-rw-r--r--src/mbgl/style/style_parser.cpp162
-rw-r--r--src/mbgl/style/style_parser.hpp4
-rw-r--r--src/mbgl/util/interpolate.hpp20
5 files changed, 133 insertions, 94 deletions
diff --git a/src/mbgl/style/function_properties.cpp b/src/mbgl/style/function_properties.cpp
index 81b1c85c72..2ea3682b8f 100644
--- a/src/mbgl/style/function_properties.cpp
+++ b/src/mbgl/style/function_properties.cpp
@@ -14,6 +14,16 @@ template <> inline float defaultStopsValue() { return 1.0f; }
template <> inline Color defaultStopsValue() { return {{ 0, 0, 0, 1 }}; }
template <> inline std::vector<float> defaultStopsValue() { return {{ 1, 0 }}; }
+template <> inline std:: string defaultStopsValue() { return {}; }
+template <> inline TranslateAnchorType defaultStopsValue() { return {}; };
+template <> inline RotateAnchorType defaultStopsValue() { return {}; };
+template <> inline CapType defaultStopsValue() { return {}; };
+template <> inline JoinType defaultStopsValue() { return {}; };
+template <> inline PlacementType defaultStopsValue() { return {}; };
+template <> inline TextAnchorType defaultStopsValue() { return {}; };
+template <> inline TextJustifyType defaultStopsValue() { return {}; };
+template <> inline TextTransformType defaultStopsValue() { return {}; };
+template <> inline RotationAlignmentType defaultStopsValue() { return {}; };
template <typename T>
T StopsFunction<T>::evaluate(float z) const {
@@ -67,4 +77,14 @@ template float StopsFunction<float>::evaluate(float z) const;
template Color StopsFunction<Color>::evaluate(float z) const;
template std::vector<float> StopsFunction<std::vector<float>>::evaluate(float z) const;
+template std::string StopsFunction<std::string>::evaluate(float z) const;
+template TranslateAnchorType StopsFunction<TranslateAnchorType>::evaluate(float z) const;
+template RotateAnchorType StopsFunction<RotateAnchorType>::evaluate(float z) const;
+template CapType StopsFunction<CapType>::evaluate(float z) const;
+template JoinType StopsFunction<JoinType>::evaluate(float z) const;
+template PlacementType StopsFunction<PlacementType>::evaluate(float z) const;
+template TextAnchorType StopsFunction<TextAnchorType>::evaluate(float z) const;
+template TextJustifyType StopsFunction<TextJustifyType>::evaluate(float z) const;
+template TextTransformType StopsFunction<TextTransformType>::evaluate(float z) const;
+template RotationAlignmentType StopsFunction<RotationAlignmentType>::evaluate(float z) const;
}
diff --git a/src/mbgl/style/property_value.hpp b/src/mbgl/style/property_value.hpp
index c7fe823025..00f72ea643 100644
--- a/src/mbgl/style/property_value.hpp
+++ b/src/mbgl/style/property_value.hpp
@@ -11,18 +11,17 @@
namespace mbgl {
typedef mapbox::util::variant<
- std::string,
- TranslateAnchorType,
- RotateAnchorType,
- bool,
- CapType,
- JoinType,
+ Function<std::string>,
+ Function<TranslateAnchorType>,
+ Function<RotateAnchorType>,
+ Function<CapType>,
+ Function<JoinType>,
VisibilityType,
- PlacementType,
- RotationAlignmentType,
- TextTransformType,
- TextJustifyType,
- TextAnchorType,
+ Function<PlacementType>,
+ Function<RotationAlignmentType>,
+ Function<TextTransformType>,
+ Function<TextJustifyType>,
+ Function<TextAnchorType>,
Function<bool>,
Function<float>,
Function<Color>,
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 4120ef470b..15a9f64aad 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -228,53 +228,40 @@ std::tuple<bool,std::vector<float>> parseFloatArray(JSVal value) {
}
template <>
-bool StyleParser::parseFunctionArgument(JSVal value) {
- JSVal rvalue = replaceConstant(value);
- if (rvalue.IsBool()) {
- return rvalue.GetBool();
- } else if (rvalue.IsNumber()) {
- return rvalue.GetDouble();
- } else {
- Log::Warning(Event::ParseStyle, "function argument must be a boolean or numeric value");
- return false;
- }
-}
-
-template <>
-float StyleParser::parseFunctionArgument(JSVal value) {
+std::tuple<bool, float> StyleParser::parseProperty(JSVal value, const char*) {
JSVal rvalue = replaceConstant(value);
if (rvalue.IsNumber()) {
- return rvalue.GetDouble();
+ return { true, rvalue.GetDouble() };
} else {
Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
- return 0.0f;
+ return { false, 0.0f };
}
}
template <>
-Color StyleParser::parseFunctionArgument(JSVal value) {
+std::tuple<bool, Color> StyleParser::parseProperty(JSVal value, const char*) {
JSVal rvalue = replaceConstant(value);
- return parseColor(rvalue);
+ return { true, parseColor(rvalue) };
}
template <>
-Faded<std::vector<float>> StyleParser::parseFunctionArgument(JSVal value) {
+std::tuple<bool, Faded<std::vector<float>>> StyleParser::parseProperty(JSVal value, const char*) {
Faded<std::vector<float>> parsed;
JSVal rvalue = replaceConstant(value);
parsed.to = std::get<1>(parseFloatArray(rvalue));
- return parsed;
+ return { true, parsed };
}
template <>
-Faded<std::string> StyleParser::parseFunctionArgument(JSVal value) {
+std::tuple<bool, Faded<std::string>> StyleParser::parseProperty(JSVal value, const char*) {
JSVal rvalue = replaceConstant(value);
Faded<std::string> parsed;
if (rvalue.IsString()) {
parsed.to = { value.GetString(), value.GetStringLength() };
- return parsed;
+ return { true, parsed };
} else {
Log::Warning(Event::ParseStyle, "function argument must be a string");
- return parsed;
+ return { false, parsed };
}
}
@@ -302,7 +289,7 @@ std::tuple<bool, std::vector<std::pair<float, T>>> StyleParser::parseStops(JSVal
return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
}
- stops.emplace_back(z.GetDouble(), parseFunctionArgument<T>(stop[rapidjson::SizeType(1)]));
+ stops.emplace_back(z.GetDouble(), std::get<1>(parseProperty<T>(replaceConstant(stop[rapidjson::SizeType(1)]), "")));
} else {
Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
@@ -315,7 +302,12 @@ template <typename T> inline float defaultBaseValue() { return 1.75; }
template <> inline float defaultBaseValue<Color>() { return 1.0; }
template <typename T>
-std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
+std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value, const char *) {
+
+ if (!value.IsObject()) {
+ return std::tuple<bool, Function<T>> { true, ConstantFunction<T>(std::get<1>(parseProperty<T>(value, ""))) };
+ }
+
if (!value.HasMember("stops")) {
Log::Warning(Event::ParseStyle, "function must specify a function type");
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
@@ -528,41 +520,57 @@ template<> std::tuple<bool, PropertyTransition> StyleParser::parseProperty(JSVal
return std::tuple<bool, PropertyTransition> { true, std::move(transition) };
}
+template<> std::tuple<bool, Function<std::string>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<std::string>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<TranslateAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<TranslateAnchorType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<RotateAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<RotateAnchorType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<CapType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<CapType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<JoinType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<JoinType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<PlacementType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<PlacementType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<TextAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<TextAnchorType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<TextJustifyType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<TextJustifyType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<TextTransformType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<TextTransformType>(value, property_name);
+}
+
+template<> std::tuple<bool, Function<RotationAlignmentType>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ return parseFunction<RotationAlignmentType>(value, property_name);
+}
+
+
template<> std::tuple<bool, Function<bool>> StyleParser::parseProperty(JSVal value, const char *property_name) {
- if (value.IsObject()) {
- return parseFunction<bool>(value);
- } else if (value.IsNumber()) {
- return std::tuple<bool, Function<bool>> { true, ConstantFunction<bool>(value.GetDouble()) };
- } else if (value.IsBool()) {
- return std::tuple<bool, Function<bool>> { true, ConstantFunction<bool>(value.GetBool()) };
- } else {
- Log::Warning(Event::ParseStyle, "value of '%s' must be convertible to boolean, or a boolean function", property_name);
- return std::tuple<bool, Function<bool>> { false, ConstantFunction<bool>(false) };
- }
+ return parseFunction<bool>(value, property_name);
}
template<> std::tuple<bool, Function<float>> StyleParser::parseProperty(JSVal value, const char *property_name) {
- if (value.IsObject()) {
- return parseFunction<float>(value);
- } else if (value.IsNumber()) {
- return std::tuple<bool, Function<float>> { true, ConstantFunction<float>(value.GetDouble()) };
- } else if (value.IsBool()) {
- return std::tuple<bool, Function<float>> { true, ConstantFunction<float>(value.GetBool()) };
- } else {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", property_name);
- return std::tuple<bool, Function<float>> { false, ConstantFunction<float>(0) };
- }
+ return parseFunction<float>(value, property_name);
}
template<> std::tuple<bool, Function<Color>> StyleParser::parseProperty(JSVal value, const char *property_name) {
- if (value.IsObject()) {
- return parseFunction<Color>(value);
- } else if (value.IsString()) {
- return std::tuple<bool, Function<Color>> { true, ConstantFunction<Color>(parseColor(value)) };
- } else {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a color, or a color function", property_name);
- return std::tuple<bool, Function<Color>> { false, ConstantFunction<Color>(Color {{ 0, 0, 0, 0 }}) };
- }
+ return parseFunction<Color>(value, property_name);
}
template<> std::tuple<bool, PiecewiseConstantFunction<Faded<std::vector<float>>>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) {
@@ -745,7 +753,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("fill-outline-color-transition", Key::FillOutlineColor, klass, value);
parseOptionalProperty<Function<float>>("fill-translate", { Key::FillTranslateX, Key::FillTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("fill-translate-transition", Key::FillTranslate, klass, value);
- parseOptionalProperty<TranslateAnchorType>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value);
+ parseOptionalProperty<Function<TranslateAnchorType>>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value);
parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("fill-image", Key::FillImage, klass, value, "fill-image-transition");
parseOptionalProperty<Function<float>>("line-opacity", Key::LineOpacity, klass, value);
@@ -754,7 +762,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("line-color-transition", Key::LineColor, klass, value);
parseOptionalProperty<Function<float>>("line-translate", { Key::LineTranslateX, Key::LineTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("line-translate-transition", Key::LineTranslate, klass, value);
- parseOptionalProperty<TranslateAnchorType>("line-translate-anchor", Key::LineTranslateAnchor, klass, value);
+ parseOptionalProperty<Function<TranslateAnchorType>>("line-translate-anchor", Key::LineTranslateAnchor, klass, value);
parseOptionalProperty<Function<float>>("line-width", Key::LineWidth, klass, value);
parseOptionalProperty<PropertyTransition>("line-width-transition", Key::LineWidth, klass, value);
parseOptionalProperty<Function<float>>("line-gap-width", Key::LineGapWidth, klass, value);
@@ -779,7 +787,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("icon-halo-blur-transition", Key::IconHaloBlur, klass, value);
parseOptionalProperty<Function<float>>("icon-translate", { Key::IconTranslateX, Key::IconTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("icon-translate-transition", Key::IconTranslate, klass, value);
- parseOptionalProperty<TranslateAnchorType>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value);
+ parseOptionalProperty<Function<TranslateAnchorType>>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value);
parseOptionalProperty<Function<float>>("text-opacity", Key::TextOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("text-opacity-transition", Key::TextOpacity, klass, value);
@@ -795,7 +803,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("text-halo-blur-transition", Key::TextHaloBlur, klass, value);
parseOptionalProperty<Function<float>>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("text-translate-transition", Key::TextTranslate, klass, value);
- parseOptionalProperty<TranslateAnchorType>("text-translate-anchor", Key::TextTranslateAnchor, klass, value);
+ parseOptionalProperty<Function<TranslateAnchorType>>("text-translate-anchor", Key::TextTranslateAnchor, klass, value);
parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("raster-opacity-transition", Key::RasterOpacity, klass, value);
@@ -820,42 +828,42 @@ void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) {
parseVisibility<VisibilityType>(*bucket, value);
- parseOptionalProperty<CapType>("line-cap", Key::LineCap, bucket->layout, value);
- parseOptionalProperty<JoinType>("line-join", Key::LineJoin, bucket->layout, value);
+ parseOptionalProperty<Function<CapType>>("line-cap", Key::LineCap, bucket->layout, value);
+ parseOptionalProperty<Function<JoinType>>("line-join", Key::LineJoin, bucket->layout, value);
parseOptionalProperty<Function<float>>("line-miter-limit", Key::LineMiterLimit, bucket->layout, value);
parseOptionalProperty<Function<float>>("line-round-limit", Key::LineRoundLimit, bucket->layout, value);
- parseOptionalProperty<PlacementType>("symbol-placement", Key::SymbolPlacement, bucket->layout, value);
+ parseOptionalProperty<Function<PlacementType>>("symbol-placement", Key::SymbolPlacement, bucket->layout, value);
parseOptionalProperty<Function<float>>("symbol-min-distance", Key::SymbolMinDistance, bucket->layout, value);
- parseOptionalProperty<bool>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value);
- parseOptionalProperty<bool>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value);
- parseOptionalProperty<bool>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value);
- parseOptionalProperty<bool>("icon-optional", Key::IconOptional, bucket->layout, value);
- parseOptionalProperty<RotationAlignmentType>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("icon-optional", Key::IconOptional, bucket->layout, value);
+ parseOptionalProperty<Function<RotationAlignmentType>>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value);
parseOptionalProperty<Function<float>>("icon-max-size", Key::IconMaxSize, bucket->layout, value);
- parseOptionalProperty<std::string>("icon-image", Key::IconImage, bucket->layout, value);
+ parseOptionalProperty<Function<std::string>>("icon-image", Key::IconImage, bucket->layout, value);
parseOptionalProperty<Function<float>>("icon-rotate", Key::IconRotate, bucket->layout, value);
parseOptionalProperty<Function<float>>("icon-padding", Key::IconPadding, bucket->layout, value);
- parseOptionalProperty<bool>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value);
parseOptionalProperty<Function<float>>("icon-offset", { Key::IconOffsetX, Key::IconOffsetY }, bucket->layout, value);
- parseOptionalProperty<RotationAlignmentType>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value);
- parseOptionalProperty<std::string>("text-field", Key::TextField, bucket->layout, value);
- parseOptionalProperty<std::string>("text-font", Key::TextFont, bucket->layout, value);
+ parseOptionalProperty<Function<RotationAlignmentType>>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value);
+ parseOptionalProperty<Function<std::string>>("text-field", Key::TextField, bucket->layout, value);
+ parseOptionalProperty<Function<std::string>>("text-font", Key::TextFont, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-max-size", Key::TextMaxSize, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-max-width", Key::TextMaxWidth, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-line-height", Key::TextLineHeight, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-letter-spacing", Key::TextLetterSpacing, bucket->layout, value);
- parseOptionalProperty<TextJustifyType>("text-justify", Key::TextJustify, bucket->layout, value);
- parseOptionalProperty<TextAnchorType>("text-anchor", Key::TextAnchor, bucket->layout, value);
+ parseOptionalProperty<Function<TextJustifyType>>("text-justify", Key::TextJustify, bucket->layout, value);
+ parseOptionalProperty<Function<TextAnchorType>>("text-anchor", Key::TextAnchor, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-max-angle", Key::TextMaxAngle, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-rotate", Key::TextRotate, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-padding", Key::TextPadding, bucket->layout, value);
- parseOptionalProperty<bool>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value);
- parseOptionalProperty<TextTransformType>("text-transform", Key::TextTransform, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value);
+ parseOptionalProperty<Function<TextTransformType>>("text-transform", Key::TextTransform, bucket->layout, value);
parseOptionalProperty<Function<float>>("text-offset", { Key::TextOffsetX, Key::TextOffsetY }, bucket->layout, value);
- parseOptionalProperty<bool>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value);
- parseOptionalProperty<bool>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value);
- parseOptionalProperty<bool>("text-optional", Key::TextOptional, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value);
+ parseOptionalProperty<Function<bool>>("text-optional", Key::TextOptional, bucket->layout, value);
}
diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp
index d25c705792..a32e6dd1d3 100644
--- a/src/mbgl/style/style_parser.hpp
+++ b/src/mbgl/style/style_parser.hpp
@@ -83,12 +83,10 @@ private:
std::tuple<bool, T> parseProperty(JSVal value, const char *property_name, JSVal transition);
template <typename T>
- std::tuple<bool, Function<T>> parseFunction(JSVal value);
+ std::tuple<bool, Function<T>> parseFunction(JSVal value, const char *);
template <typename T>
std::tuple<bool, PiecewiseConstantFunction<T>> parsePiecewiseConstantFunction(JSVal value, std::chrono::steady_clock::duration duration);
template <typename T>
- T parseFunctionArgument(JSVal value);
- template <typename T>
std::tuple<bool, std::vector<std::pair<float, T>>> parseStops(JSVal value);
FilterExpression parseFilter(JSVal);
diff --git a/src/mbgl/util/interpolate.hpp b/src/mbgl/util/interpolate.hpp
index 952d7b9c10..a2998233b5 100644
--- a/src/mbgl/util/interpolate.hpp
+++ b/src/mbgl/util/interpolate.hpp
@@ -4,6 +4,8 @@
#include <array>
#include <vector>
+#include <mbgl/style/types.hpp>
+
namespace mbgl {
namespace util {
@@ -22,9 +24,21 @@ inline std::array<T, 4> interpolate(const std::array<T, 4>& a, const std::array<
}};
}
-inline std::vector<float> interpolate(const std::vector<float> &a, const std::vector<float>, const double) {
- return a;
-}
+// fake interpolations that just return the first value
+template<> inline bool interpolate(const bool a, const bool, const double) { return a; }
+template<> inline std::vector<float> interpolate(const std::vector<float> a, const std::vector<float>, const double) { return a; }
+template<> inline std::string interpolate(const std::string a, const std::string, const double) { return a; }
+template<> inline TranslateAnchorType interpolate(const TranslateAnchorType a, const TranslateAnchorType, const double) { return a; }
+template<> inline RotateAnchorType interpolate(const RotateAnchorType a, const RotateAnchorType, const double) { return a; }
+template<> inline CapType interpolate(const CapType a, const CapType, const double) { return a; }
+template<> inline JoinType interpolate(const JoinType a, const JoinType, const double) { return a; }
+template<> inline PlacementType interpolate(const PlacementType a, const PlacementType, const double) { return a; }
+template<> inline TextAnchorType interpolate(const TextAnchorType a, const TextAnchorType, const double) { return a; }
+template<> inline TextJustifyType interpolate(const TextJustifyType a, const TextJustifyType, const double) { return a; }
+template<> inline TextTransformType interpolate(const TextTransformType a, const TextTransformType, const double) { return a; }
+template<> inline RotationAlignmentType interpolate(const RotationAlignmentType a, const RotationAlignmentType, const double) { return a; }
+
+
}
}