#ifndef JSON_SERIALIZER_HPP #define JSON_SERIALIZER_HPP #include <boost/type_traits.hpp> // is_array, is_class, remove_bounds #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/next_prior.hpp> #include <boost/fusion/mpl.hpp> #include <boost/fusion/adapted.hpp> // BOOST_FUSION_ADAPT_STRUCT // boost::fusion::result_of::value_at #include <boost/fusion/sequence/intrinsic/value_at.hpp> #include <boost/fusion/include/value_at.hpp> // boost::fusion::result_of::size #include <boost/fusion/sequence/intrinsic/size.hpp> #include <boost/fusion/include/size.hpp> // boost::fusion::at #include <boost/fusion/sequence/intrinsic/at.hpp> #include <boost/fusion/include/at.hpp> namespace json { // Forward template < typename T > struct serializer; namespace detail { namespace iterator { template < typename S, typename N > struct Comma { template < typename Ostream > static inline void comma(Ostream& os) { os << ", "; } }; template < typename S > struct Comma< S, typename boost::mpl::prior< typename boost::fusion::result_of::size< S >::type >::type > { template < typename Ostream > static inline void comma(Ostream& os) { } }; // Iteracion sobre una estructura template < typename S, typename N > struct StructImpl { // Tipo del campo actual typedef typename boost::fusion::result_of::value_at< S, N >::type current_t; typedef typename boost::mpl::next< N >::type next_t; typedef boost::fusion::extension::struct_member_name< S, N::value > name_t; template < typename Ostream > static inline void serialize(Ostream& os, const S& s) { os << "\"" << name_t::call() << "\": "; ::json::serializer< current_t >::serialize(os, boost::fusion::at< N >(s)); // Insert comma or not Comma< S, N >::comma(os); StructImpl< S, next_t >::serialize(os, s); } }; // Fin de la iteracion sobre estructuras. template < typename S > struct StructImpl< S, typename boost::fusion::result_of::size< S >::type > { template < typename Ostream > static inline void serialize(Ostream& os, const S& s) { // Nada que hacer } }; // Iterador sobre una estructura. Template fachada. template < typename S > struct Struct : StructImpl< S, boost::mpl::int_< 0 > > {}; } // iterator template < typename T > struct array_serializer { typedef array_serializer< T > type; typedef typename boost::remove_bounds< T >::type slice_t; static const size_t size = sizeof(T) / sizeof(slice_t); template < typename Ostream > static inline void serialize(Ostream& os, const T& t) { os << "["; for(size_t idx=0; idx<size; idx++) { ::json::serializer< slice_t >::serialize(os, t[idx]); if (idx != size-1) os << ", "; } os << "]"; } }; template < typename T > struct struct_serializer { typedef struct_serializer< T > type; template < typename Ostream > static inline void serialize(Ostream& os, const T& t) { os << "{"; iterator::Struct< T >::serialize(os, t); os << "}"; } }; template < typename T > struct arithmetic_serializer { typedef arithmetic_serializer< T > type; template < typename Ostream > static inline void serialize(Ostream& os, const T& t) { os << t; } }; template < typename T > struct calculate_serializer { typedef typename boost::mpl::eval_if< boost::is_array< T >, boost::mpl::identity< array_serializer < T > >, //else typename boost::mpl::eval_if< boost::is_class< T >, boost::mpl::identity< struct_serializer < T > >, //else boost::mpl::identity< arithmetic_serializer < T > > > >::type type; }; } // detail template < typename T > struct serializer : public detail::calculate_serializer < T >::type { }; } // json #endif // JSON_SERIALIZER_HPP
Sample usage:
#include "json.hpp" #include <iostream> struct my_other_struct { int my_other_integer; }; struct my_struct { int my_integer; typedef int my_array_t[2]; my_array_t my_array; typedef my_other_struct my_other_structs_t[3]; my_other_structs_t my_other_structs; }; BOOST_FUSION_ADAPT_STRUCT(my_struct, (int, my_integer) (my_struct::my_array_t, my_array) (my_struct::my_other_structs_t, my_other_structs)) BOOST_FUSION_ADAPT_STRUCT(my_other_struct, (int, my_other_integer)) int main(int argc, char *argv[]) { my_struct s1 = my_struct(); json::serializer< my_struct >::serialize(std::cout, s1); std::cout << std::endl; }
Result:
{"my_integer": 0, "my_array": [0, 0], "my_other_structs": [{"my_other_integer": 0}, {"my_other_integer": 0}, {"my_other_integer": 0}]}
Boost C++ Libraries 1.45.0 or greater required!
He visitado varios sitios web sin embargo la calidad de audio para canciones de audio existentes en este sitio web es realmente muy buen. Traductores Jurados Sevilla
ReplyDelete