1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-05 00:49:09 +02:00

Simplified template magic in JsonNode

This commit is contained in:
Ivan Savenko
2024-02-13 13:51:24 +02:00
parent 08a27663f9
commit e73516b7d1
2 changed files with 48 additions and 91 deletions

View File

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

View File

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