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:
@ -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;
|
||||||
|
|
||||||
|
@ -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>>
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void convert(std::string & value, const JsonNode & node)
|
||||||
|
{
|
||||||
|
value = node.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
void convert(std::set<Type> & value, const JsonNode & node)
|
||||||
|
{
|
||||||
|
value.clear();
|
||||||
|
for(const JsonVector::value_type & entry : node.Vector())
|
||||||
{
|
{
|
||||||
static T convertImpl(const JsonNode & node)
|
value.insert(entry.convertTo<Type>());
|
||||||
{
|
}
|
||||||
return T((int)node.Float());
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename Type>
|
||||||
struct JsonConvImpl<T, 0>
|
void convert(std::vector<Type> & value, const JsonNode & node)
|
||||||
|
{
|
||||||
|
value.clear();
|
||||||
|
for(const JsonVector::value_type & entry : node.Vector())
|
||||||
{
|
{
|
||||||
static T convertImpl(const JsonNode & node)
|
value.push_back(entry.convertTo<Type>());
|
||||||
{
|
}
|
||||||
return T(node.Float());
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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>
|
|
||||||
struct JsonConverter<std::vector<Type> >
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
||||||
|
Reference in New Issue
Block a user