#pragma once #include #include #include #include #include #include #include #include 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 std::enable_if::value && !std::is_pointer::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 std::enable_if::value, js::Value>::type to_json(T const & x); // boost::fusion magics template struct write_itr{ typedef typename boost::mpl::next::type next_t; typedef boost::fusion::extension::struct_member_name name_t; static inline void exec(js::Object & obj, const T& x){ obj[name_t::call()] = to_json(boost::fusion::at(x)); write_itr::exec(obj, x); } }; template struct write_itr::type>{ static inline void exec(js::Object & obj, const T& x) {} }; // Compound types (need recursion) template typename std::enable_if::value, js::Value>::type to_json(T const & x){ js::Object obj; write_itr>::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 std::enable_if::value, T>::type from_json(js::Value const & x){ return x.getInt64(); } template typename std::enable_if::value, T>::type from_json(js::Value const & x){ return x.getReal(); } template typename std::enable_if::value, T>::type from_json(js::Value const & x){ return x.getString(); } // Compound types (need recursion) template typename std::enable_if::value && !std::is_same::value, T>::type from_json(js::Value const & x); // boost::fusion magics template struct read_itr{ typedef typename boost::fusion::result_of::value_at::type current_t; typedef typename boost::mpl::next::type next_t; typedef boost::fusion::extension::struct_member_name name_t; static inline void exec(js::Object const & obj, T& x){ try{ boost::fusion::at(x) = from_json(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::exec(obj, x); } }; template struct read_itr::type>{ static inline void exec(js::Object const & obj, T& x) {} }; // Compound types (need recursion) template typename std::enable_if::value && !std::is_same::value, T>::type from_json(js::Value const & x){ T ret; read_itr>::exec(x.getObject(), ret); return ret; }