Reputation: 93264
I'm creating a library that wraps JsonCpp allowing the user to write template specializations to define conversions from Json::Value
to T
and from T
to Json::Value
. It works, but the specialization syntax is very inelegant and I would like to improve it by avoiding repetitions.
Here's how you can currently define a conversion:
namespace ssvuj // my library's namespace
{
namespace Internal
{
template<> struct FromJson<sf::Color>
{
inline static sf::Color conv(const Obj& mObj)
{
return sf::Color(as<float>(mObj, 0), as<float>(mObj, 1), as<float>(mObj, 2), as<float>(mObj, 3));
}
};
template<> struct ToJson<sf::Color>
{
inline static Obj conv(const sf::Color& mValue)
{
Obj result;
set(result, 0, mValue.r);
set(result, 1, mValue.g);
set(result, 2, mValue.b);
set(result, 3, mValue.a);
return result;
}
};
}
}
// example usage
ssvuj::Obj objColor; // this Json object contains sf::Color data
ssvuj::Obj objEmpty; // this Json object is empty
sf::Color colorFromObj{ssvuj::as<sf::Color>(objColor)}; // color is initialized by "deserializing" the Json object
ssvuj::set(objEmpty, colorFromObj); // the color is "serialized" into the empty Json object
Problems I notice:
sf::Color
in this casestatic void
(I tried specializing functions, but it doesn't work for partial specializations such as T = std::vector<T>
)The only way I can think of making this less verbose and more elegant is a macro, but there probably is something I can do without using the preprocessor. Ideas?
Upvotes: 1
Views: 245
Reputation: 93264
My solution was implementing template<typename T> class Converter;
, that the user can specialize.
Example:
template<> struct Converter<sf::Color>
{
using T = sf::Color;
inline static void fromObj(T& mValue, const Obj& mObj)
{
mValue.r = as<float>(mObj, 0);
mValue.g = as<float>(mObj, 1);
mValue.b = as<float>(mObj, 2);
mValue.a = as<float>(mObj, 3);
}
inline static void toObj(Obj& mObj, const T& mValue)
{
set(mObj, 0, mValue.r);
set(mObj, 1, mValue.g);
set(mObj, 2, mValue.b);
set(mObj, 3, mValue.a);
}
};
Upvotes: 0
Reputation: 67723
For the ToJson
direction, you don't need a template at all - it's sufficient to overload a free function on the input type:
inline static Obj conv(const sf::Color& mValue)
{
Obj result;
set(result, 0, mValue.r);
set(result, 1, mValue.g);
set(result, 2, mValue.b);
set(result, 3, mValue.a);
return result;
}
Upvotes: 3