Bytemaster's Boost Libraries
|
00001 #ifndef _BOOST_RPC_JSON_VALUE_HPP_ 00002 #define _BOOST_RPC_JSON_VALUE_HPP_ 00003 #include <boost/variant/recursive_variant.hpp> 00004 #include <boost/lexical_cast.hpp> 00005 #include <boost/variant.hpp> 00006 #include <stdexcept> 00007 #include <vector> 00008 #include <map> 00009 #include <stdint.h> 00010 00011 namespace boost { namespace rpc { namespace json { 00012 struct null_t{ 00013 null_t(){} 00014 friend std::ostream& operator<<( std::ostream& os, const null_t& ){ return os; } 00015 }; 00016 class object; 00017 class array; 00018 00019 typedef boost::variant< null_t, double, bool, std::string, 00020 boost::recursive_wrapper<object>, 00021 boost::recursive_wrapper<array> > value_variant; 00022 00023 struct value { 00024 template<typename T> 00025 value( const T& v = null_t() ) :val(v){} 00026 value( uint64_t v ):val( double(v) ){} 00027 value( int64_t v ):val( double(v) ){} 00028 value( char v ):val( double(v) ){} 00029 value( uint8_t v ):val( double(v) ){} 00030 value( int16_t v ):val( double(v) ){} 00031 value( uint16_t v ):val( double(v) ){} 00032 value():val(null_t()){} 00033 00034 template<typename T> 00035 operator const T&()const; 00036 template<typename T> 00037 operator T&(); 00038 00039 operator int()const { return boost::get<double>(val); } 00040 operator int64_t()const { return boost::get<double>(val); } 00041 operator uint64_t()const { return boost::get<double>(val); } 00042 operator uint32_t()const { return boost::get<double>(val); } 00043 operator uint16_t()const { return boost::get<double>(val); } 00044 operator uint8_t()const { return boost::get<double>(val); } 00045 operator int16_t()const { return boost::get<double>(val); } 00046 operator int8_t()const { return boost::get<double>(val); } 00047 operator double()const { return boost::get<double>(val); } 00048 operator float()const { return boost::get<float>(val); } 00049 operator bool()const { return boost::get<bool>(val); } 00050 operator std::string()const { std::stringstream ss; ss << val; return ss.str(); } 00051 00052 inline value& operator = ( uint64_t v ) { val = (double)v; } 00053 inline value& operator = ( int64_t v ) { val = (double)v; } 00054 inline value& operator = ( uint32_t v ) { val = (double)v; } 00055 inline value& operator = ( int32_t v ) { val = (double)v; } 00056 inline value& operator = ( uint16_t v ) { val = (double)v; } 00057 inline value& operator = ( int16_t v ) { val = (double)v; } 00058 inline value& operator = ( uint8_t v ) { val = (double)v; } 00059 inline value& operator = ( int8_t v ) { val = (double)v; } 00060 00061 template<typename T> 00062 inline value& operator = ( const T& v ) { 00063 val = v; 00064 return *this; 00065 } 00066 00067 // treat it like an array or object 00068 value& operator[]( const std::string& index ); 00069 const value& operator[]( const std::string& )const; 00070 value& operator[]( uint32_t index ); 00071 const value& operator[]( uint32_t index )const; 00072 00073 size_t size(); 00074 void resize( uint32_t size ); 00075 void clear(); 00076 00077 value_variant val; 00078 }; 00079 00080 template<typename T> 00081 value& operator << ( value& val, const T& v ) { 00082 return val; 00083 } 00084 00085 void read( const std::string& j, value& v ); 00086 void write( const value& v, std::string& j ); 00087 std::ostream& write(std::ostream& os, const boost::rpc::json::value& v ); 00088 00089 namespace detail { 00090 struct key_val { 00091 key_val( const std::string& k = "" ):key(k){} 00092 std::string key; 00093 value val; 00094 }; 00095 } 00096 00097 class object { 00098 public: 00099 value& operator[]( const std::string& index ); 00100 const value& operator[]( const std::string& index )const; 00101 friend std::ostream& operator<<( std::ostream& os, const object& ){ return os; } 00102 inline void clear() { keys.clear(); } 00103 inline void reserve( size_t s ) { keys.reserve(s); } 00104 00105 std::vector< detail::key_val > keys; 00106 }; 00107 00108 class array { 00109 public: 00110 typedef std::vector<value>::const_iterator const_iterator; 00111 00112 inline void clear() { vals.clear(); } 00113 inline size_t size()const { return vals.size(); } 00114 inline value& operator[]( uint32_t idx ) { return vals[idx]; } 00115 inline const value& operator[]( uint32_t idx )const { return vals[idx]; } 00116 inline value& back() { return vals.back(); } 00117 inline const value& back()const { return vals.back(); } 00118 inline const_iterator begin()const { return vals.begin(); } 00119 inline void push_back( const value& v ) { vals.push_back(v); } 00120 inline void resize( size_t s ) { vals.resize(s); } 00121 inline void reserve( size_t s ) { vals.reserve(s); } 00122 00123 friend std::ostream& operator<<( std::ostream& os, const array& ){ return os; } 00124 std::vector< value > vals; 00125 }; 00126 00127 00128 00129 namespace detail { 00130 template<typename Result> 00131 struct cast_visitor : public boost::static_visitor<Result> { 00132 template<typename InType> 00133 Result operator()( const InType& d )const { 00134 return boost::lexical_cast<Result>(d); 00135 } 00136 }; 00137 00138 template<typename T> 00139 struct index_visitor : public boost::static_visitor<T> { 00140 index_visitor( int index = 0 ):m_index(index){} 00141 T operator()( const boost::variant<int,std::string,double,null_t>& )const { 00142 BOOST_THROW_EXCEPTION( std::out_of_range( "not an object or array" ) ); 00143 typename boost::remove_reference<T>::type* val; 00144 return *val; 00145 } 00146 T operator()( const json::array& d )const { 00147 return d[m_index]; 00148 } 00149 T operator()( const json::object& d )const { 00150 return d[boost::lexical_cast<std::string>(m_index)]; 00151 } 00152 T operator()( json::array& d )const { 00153 return d[m_index]; 00154 } 00155 T operator()( json::object& d )const { 00156 return d[boost::lexical_cast<std::string>(m_index)]; 00157 } 00158 int m_index; 00159 }; 00160 template<typename T> 00161 struct key_visitor : public boost::static_visitor<T> { 00162 key_visitor( const std::string& key = 0 ):m_key(key){} 00163 00164 T operator()( const boost::variant<int,std::string,double,null_t>& )const { 00165 BOOST_THROW_EXCEPTION( std::out_of_range( "not an object or array" ) ); 00166 typename boost::remove_reference<T>::type* val; 00167 return *val; 00168 } 00169 T operator()( const json::array& d )const { 00170 return d[boost::lexical_cast<int>(m_key)]; 00171 } 00172 T operator()( const json::object& d )const { 00173 return d[m_key]; 00174 } 00175 T operator()( json::array& d )const { 00176 return d[boost::lexical_cast<int>(m_key)]; 00177 } 00178 T operator()( json::object& d )const { 00179 return d[m_key]; 00180 } 00181 std::string m_key; 00182 }; 00183 }; 00184 00185 template<typename T> 00186 value::operator const T&()const { 00187 return boost::get<T>(val);//boost::apply_visitor( detail::cast_visitor<T>(), val); 00188 } 00189 template<typename T> 00190 value::operator T&() { 00191 return boost::get<T>(val);//boost::apply_visitor( detail::cast_visitor<T>(), val); 00192 } 00193 00194 }}} 00195 00196 00197 #endif