Bytemaster's Boost Libraries
/Users/dlarimer/dev/libs/rpc/include/boost/rpc/json/value.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Defines