You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.4 KiB
123 lines
3.4 KiB
#pragma once
|
|
|
|
#include <utility>
|
|
#include <type_traits>
|
|
#include <stdexcept>
|
|
|
|
#include <boost/fusion/include/define_struct.hpp>
|
|
#include <boost/fusion/include/for_each.hpp>
|
|
#include <boost/fusion/include/at.hpp>
|
|
|
|
#include <json_spirit/json_spirit.h>
|
|
|
|
namespace js = json_spirit;
|
|
|
|
inline js::Value parse_json(std::string const & in){
|
|
js::Value value;
|
|
js::read(in, value);
|
|
return value;
|
|
}
|
|
|
|
inline std::string write_json(js::Value const & v){
|
|
return js::write(v);
|
|
}
|
|
|
|
/*
|
|
*** WRITING ***
|
|
Note: Does not yet support arrays, only basic types, std::strings and user defined types (with boost::fusion adaption)
|
|
*/
|
|
|
|
// Basic types
|
|
template <typename T>
|
|
typename std::enable_if<!std::is_class<T>::value && !std::is_pointer<T>::value, js::Value>::type to_json(T const & x){
|
|
return x;
|
|
}
|
|
|
|
inline js::Value to_json(std::string const & x){
|
|
return x;
|
|
}
|
|
|
|
// Compound types (need recursion)
|
|
template <typename T>
|
|
typename std::enable_if<std::is_class<T>::value, js::Value>::type to_json(T const & x);
|
|
|
|
// boost::fusion magics
|
|
template<typename T, typename N>
|
|
struct write_itr{
|
|
typedef typename boost::mpl::next<N>::type next_t;
|
|
typedef boost::fusion::extension::struct_member_name<T, N::value> name_t;
|
|
|
|
static inline void exec(js::Object & obj, const T& x){
|
|
obj[name_t::call()] = to_json(boost::fusion::at<N>(x));
|
|
write_itr<T, next_t>::exec(obj, x);
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct write_itr<T, typename boost::fusion::result_of::size<T>::type>{
|
|
static inline void exec(js::Object & obj, const T& x) {}
|
|
};
|
|
|
|
// Compound types (need recursion)
|
|
template <typename T>
|
|
typename std::enable_if<std::is_class<T>::value, js::Value>::type to_json(T const & x){
|
|
js::Object obj;
|
|
write_itr<T, boost::mpl::int_<0>>::exec(obj, x);
|
|
return obj;
|
|
}
|
|
|
|
|
|
/*
|
|
*** READING ***
|
|
Note: Does not yet support arrays, only basic types, std::strings and user defined types (with boost::fusion adaption)
|
|
*/
|
|
|
|
// Basic types
|
|
template <typename T>
|
|
typename std::enable_if<std::is_integral<T>::value, T>::type from_json(js::Value const & x){
|
|
return x.getInt64();
|
|
}
|
|
|
|
template <typename T>
|
|
typename std::enable_if<std::is_floating_point<T>::value, T>::type from_json(js::Value const & x){
|
|
return x.getReal();
|
|
}
|
|
|
|
template <typename T>
|
|
typename std::enable_if<std::is_same<T, std::string>::value, T>::type from_json(js::Value const & x){
|
|
return x.getString();
|
|
}
|
|
|
|
// Compound types (need recursion)
|
|
template <typename T>
|
|
typename std::enable_if<std::is_class<T>::value && !std::is_same<T, std::string>::value, T>::type from_json(js::Value const & x);
|
|
|
|
// boost::fusion magics
|
|
template<typename T, typename N>
|
|
struct read_itr{
|
|
typedef typename boost::fusion::result_of::value_at<T, N>::type current_t;
|
|
typedef typename boost::mpl::next<N>::type next_t;
|
|
typedef boost::fusion::extension::struct_member_name<T, N::value> name_t;
|
|
|
|
static inline void exec(js::Object const & obj, T& x){
|
|
try{
|
|
boost::fusion::at<N>(x) = from_json<current_t>(obj.at(name_t::call()));
|
|
} catch(std::out_of_range& e) {
|
|
throw std::out_of_range(e.what() + std::string(": ") + name_t::call());
|
|
}
|
|
read_itr<T, next_t>::exec(obj, x);
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct read_itr<T, typename boost::fusion::result_of::size<T>::type>{
|
|
static inline void exec(js::Object const & obj, T& x) {}
|
|
};
|
|
|
|
// Compound types (need recursion)
|
|
template <typename T>
|
|
typename std::enable_if<std::is_class<T>::value && !std::is_same<T, std::string>::value, T>::type from_json(js::Value const & x){
|
|
T ret;
|
|
read_itr<T, boost::mpl::int_<0>>::exec(x.getObject(), ret);
|
|
return ret;
|
|
}
|
|
|