Преглед изворни кода

Simplified template magic in JsonNode

Ivan Savenko пре 1 година
родитељ
комит
e73516b7d1
2 измењених фајлова са 44 додато и 87 уклоњено
  1. 0 2
      lib/json/JsonNode.cpp
  2. 44 85
      lib/json/JsonNode.h

+ 0 - 2
lib/json/JsonNode.cpp

@@ -49,8 +49,6 @@ Node & resolvePointer(Node & in, const std::string & pointer)
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-using namespace JsonDetail;
-
 class LibClasses;
 class CModHandler;
 

+ 44 - 85
lib/json/JsonNode.h

@@ -138,106 +138,65 @@ public:
 
 namespace JsonDetail
 {
-	// conversion helpers for JsonNode::convertTo (partial template function instantiation is illegal in c++)
 
-	template <typename T, int arithm>
-	struct JsonConvImpl;
-
-	template <typename T>
-	struct JsonConvImpl<T, 1>
-	{
-		static T convertImpl(const JsonNode & node)
-		{
-			return T((int)node.Float());
-		}
-	};
-
-	template <typename T>
-	struct JsonConvImpl<T, 0>
-	{
-		static T convertImpl(const JsonNode & node)
-		{
-			return T(node.Float());
-		}
-	};
+inline void convert(bool & value, const JsonNode & node)
+{
+	value = node.Bool();
+}
 
-	template<typename Type>
-	struct JsonConverter
-	{
-		static Type convert(const JsonNode & node)
-		{
-			///this should be triggered only for numeric types and enums
-			static_assert(std::is_arithmetic_v<Type> || std::is_enum_v<Type> || std::is_class_v<Type>, "Unsupported type for JsonNode::convertTo()!");
-			return JsonConvImpl<Type, std::is_enum_v<Type> || std::is_class_v<Type> >::convertImpl(node);
+template<typename T>
+auto convert(T & value, const JsonNode & node) -> std::enable_if_t<std::is_integral_v<T>>
+{
+	value = node.Integer();
+}
 
-		}
-	};
+template<typename T>
+auto convert(T & value, const JsonNode & node) -> std::enable_if_t<std::is_floating_point_v<T>>
+{
+	value = node.Float();
+}
 
-	template<typename Type>
-	struct JsonConverter<std::map<std::string, Type> >
-	{
-		static std::map<std::string, Type> convert(const JsonNode & node)
-		{
-			std::map<std::string, Type> ret;
-			for (const JsonMap::value_type & entry : node.Struct())
-			{
-				ret.insert(entry.first, entry.second.convertTo<Type>());
-			}
-			return ret;
-		}
-	};
+inline void convert(std::string & value, const JsonNode & node)
+{
+	value = node.String();
+}
 
-	template<typename Type>
-	struct JsonConverter<std::set<Type> >
-	{
-		static std::set<Type> convert(const JsonNode & node)
-		{
-			std::set<Type> ret;
-			for(const JsonVector::value_type & entry : node.Vector())
-			{
-				ret.insert(entry.convertTo<Type>());
-			}
-			return ret;
-		}
-	};
+template <typename Type>
+void convert(std::map<std::string,Type> & value, const JsonNode & node)
+{
+	value.clear();
+	for (const JsonMap::value_type & entry : node.Struct())
+		value.insert(entry.first, entry.second.convertTo<Type>());
+}
 
-	template<typename Type>
-	struct JsonConverter<std::vector<Type> >
+template <typename Type>
+void convert(std::set<Type> & value, const JsonNode & node)
+{
+	value.clear();
+	for(const JsonVector::value_type & entry : node.Vector())
 	{
-		static std::vector<Type> convert(const JsonNode & node)
-		{
-			std::vector<Type> ret;
-			for (const JsonVector::value_type & entry: node.Vector())
-			{
-				ret.push_back(entry.convertTo<Type>());
-			}
-			return ret;
-		}
-	};
+		value.insert(entry.convertTo<Type>());
+	}
+}
 
-	template<>
-	struct JsonConverter<std::string>
+template <typename Type>
+void convert(std::vector<Type> & value, const JsonNode & node)
+{
+	value.clear();
+	for(const JsonVector::value_type & entry : node.Vector())
 	{
-		static std::string convert(const JsonNode & node)
-		{
-			return node.String();
-		}
-	};
+		value.push_back(entry.convertTo<Type>());
+	}
+}
 
-	template<>
-	struct JsonConverter<bool>
-	{
-		static bool convert(const JsonNode & node)
-		{
-			return node.Bool();
-		}
-	};
 }
 
 template<typename Type>
 Type JsonNode::convertTo() const
 {
-	return JsonDetail::JsonConverter<Type>::convert(*this);
+	Type result;
+	JsonDetail::convert(result, *this);
+	return result;
 }
 
 VCMI_LIB_NAMESPACE_END