123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- #ifndef JSON_SPIRIT_VALUE
- #define JSON_SPIRIT_VALUE
- // Copyright John W. Wilkinson 2007 - 2009.
- // Distributed under the MIT License, see accompanying file LICENSE.txt
- // json spirit version 4.03
- #if defined(_MSC_VER) && (_MSC_VER >= 1020)
- # pragma once
- #endif
- #include <vector>
- #include <map>
- #include <string>
- #include <cassert>
- #include <sstream>
- #include <stdexcept>
- #include <boost/config.hpp>
- #include <boost/cstdint.hpp>
- #include <boost/shared_ptr.hpp>
- #include <boost/variant.hpp>
- namespace json_spirit
- {
- enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
- template< class Config > // Config determines whether the value uses std::string or std::wstring and
- // whether JSON Objects are represented as vectors or maps
- class Value_impl
- {
- public:
- typedef Config Config_type;
- typedef typename Config::String_type String_type;
- typedef typename Config::Object_type Object;
- typedef typename Config::Array_type Array;
- typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
- Value_impl(); // creates null value
- Value_impl( Const_str_ptr value );
- Value_impl( const String_type& value );
- Value_impl( const Object& value );
- Value_impl( const Array& value );
- Value_impl( bool value );
- Value_impl( int value );
- Value_impl( boost::int64_t value );
- Value_impl( boost::uint64_t value );
- Value_impl( double value );
- Value_impl( const Value_impl& other );
- bool operator==( const Value_impl& lhs ) const;
- Value_impl& operator=( const Value_impl& lhs );
- Value_type type() const;
- bool is_uint64() const;
- bool is_null() const;
- const String_type& get_str() const;
- const Object& get_obj() const;
- const Array& get_array() const;
- bool get_bool() const;
- int get_int() const;
- boost::int64_t get_int64() const;
- boost::uint64_t get_uint64() const;
- double get_real() const;
- Object& get_obj();
- Array& get_array();
- template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
- // or double d = value.get_value< double >();
- static const Value_impl null;
- private:
- void check_type( const Value_type vtype ) const;
- typedef boost::variant< String_type,
- boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
- bool, boost::int64_t, double > Variant;
- Value_type type_;
- Variant v_;
- bool is_uint64_;
- };
- // vector objects
- template< class Config >
- struct Pair_impl
- {
- typedef typename Config::String_type String_type;
- typedef typename Config::Value_type Value_type;
- Pair_impl( const String_type& name, const Value_type& value );
- bool operator==( const Pair_impl& lhs ) const;
- String_type name_;
- Value_type value_;
- };
- template< class String >
- struct Config_vector
- {
- typedef String String_type;
- typedef Value_impl< Config_vector > Value_type;
- typedef Pair_impl < Config_vector > Pair_type;
- typedef std::vector< Value_type > Array_type;
- typedef std::vector< Pair_type > Object_type;
- static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
- {
- obj.push_back( Pair_type( name , value ) );
- return obj.back().value_;
- }
-
- static String_type get_name( const Pair_type& pair )
- {
- return pair.name_;
- }
-
- static Value_type get_value( const Pair_type& pair )
- {
- return pair.value_;
- }
- };
- // typedefs for ASCII
- typedef Config_vector< std::string > Config;
- typedef Config::Value_type Value;
- typedef Config::Pair_type Pair;
- typedef Config::Object_type Object;
- typedef Config::Array_type Array;
- // typedefs for Unicode
- #ifndef BOOST_NO_STD_WSTRING
- typedef Config_vector< std::wstring > wConfig;
- typedef wConfig::Value_type wValue;
- typedef wConfig::Pair_type wPair;
- typedef wConfig::Object_type wObject;
- typedef wConfig::Array_type wArray;
- #endif
- // map objects
- template< class String >
- struct Config_map
- {
- typedef String String_type;
- typedef Value_impl< Config_map > Value_type;
- typedef std::vector< Value_type > Array_type;
- typedef std::map< String_type, Value_type > Object_type;
- typedef typename Object_type::value_type Pair_type;
- static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
- {
- return obj[ name ] = value;
- }
-
- static String_type get_name( const Pair_type& pair )
- {
- return pair.first;
- }
-
- static Value_type get_value( const Pair_type& pair )
- {
- return pair.second;
- }
- };
- // typedefs for ASCII
- typedef Config_map< std::string > mConfig;
- typedef mConfig::Value_type mValue;
- typedef mConfig::Object_type mObject;
- typedef mConfig::Array_type mArray;
- // typedefs for Unicode
- #ifndef BOOST_NO_STD_WSTRING
- typedef Config_map< std::wstring > wmConfig;
- typedef wmConfig::Value_type wmValue;
- typedef wmConfig::Object_type wmObject;
- typedef wmConfig::Array_type wmArray;
- #endif
- ///////////////////////////////////////////////////////////////////////////////////////////////
- //
- // implementation
- template< class Config >
- const Value_impl< Config > Value_impl< Config >::null;
- template< class Config >
- Value_impl< Config >::Value_impl()
- : type_( null_type )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( const Const_str_ptr value )
- : type_( str_type )
- , v_( String_type( value ) )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( const String_type& value )
- : type_( str_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( const Object& value )
- : type_( obj_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( const Array& value )
- : type_( array_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( bool value )
- : type_( bool_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( int value )
- : type_( int_type )
- , v_( static_cast< boost::int64_t >( value ) )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( boost::int64_t value )
- : type_( int_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( boost::uint64_t value )
- : type_( int_type )
- , v_( static_cast< boost::int64_t >( value ) )
- , is_uint64_( true )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( double value )
- : type_( real_type )
- , v_( value )
- , is_uint64_( false )
- {
- }
- template< class Config >
- Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
- : type_( other.type() )
- , v_( other.v_ )
- , is_uint64_( other.is_uint64_ )
- {
- }
- template< class Config >
- Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
- {
- Value_impl tmp( lhs );
- std::swap( type_, tmp.type_ );
- std::swap( v_, tmp.v_ );
- std::swap( is_uint64_, tmp.is_uint64_ );
- return *this;
- }
- template< class Config >
- bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
- {
- if( this == &lhs ) return true;
- if( type() != lhs.type() ) return false;
- return v_ == lhs.v_;
- }
- template< class Config >
- Value_type Value_impl< Config >::type() const
- {
- return type_;
- }
- template< class Config >
- bool Value_impl< Config >::is_uint64() const
- {
- return is_uint64_;
- }
- template< class Config >
- bool Value_impl< Config >::is_null() const
- {
- return type() == null_type;
- }
- template< class Config >
- void Value_impl< Config >::check_type( const Value_type vtype ) const
- {
- if( type() != vtype )
- {
- std::ostringstream os;
- os << "value type is " << type() << " not " << vtype;
- throw std::runtime_error( os.str() );
- }
- }
- template< class Config >
- const typename Config::String_type& Value_impl< Config >::get_str() const
- {
- check_type( str_type );
- return *boost::get< String_type >( &v_ );
- }
- template< class Config >
- const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
- {
- check_type( obj_type );
- return *boost::get< Object >( &v_ );
- }
-
- template< class Config >
- const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
- {
- check_type( array_type );
- return *boost::get< Array >( &v_ );
- }
-
- template< class Config >
- bool Value_impl< Config >::get_bool() const
- {
- check_type( bool_type );
- return boost::get< bool >( v_ );
- }
-
- template< class Config >
- int Value_impl< Config >::get_int() const
- {
- check_type( int_type );
- return static_cast< int >( get_int64() );
- }
-
- template< class Config >
- boost::int64_t Value_impl< Config >::get_int64() const
- {
- check_type( int_type );
- return boost::get< boost::int64_t >( v_ );
- }
-
- template< class Config >
- boost::uint64_t Value_impl< Config >::get_uint64() const
- {
- check_type( int_type );
- return static_cast< boost::uint64_t >( get_int64() );
- }
- template< class Config >
- double Value_impl< Config >::get_real() const
- {
- if( type() == int_type )
- {
- return is_uint64() ? static_cast< double >( get_uint64() )
- : static_cast< double >( get_int64() );
- }
- check_type( real_type );
- return boost::get< double >( v_ );
- }
- template< class Config >
- typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
- {
- check_type( obj_type );
- return *boost::get< Object >( &v_ );
- }
- template< class Config >
- typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
- {
- check_type( array_type );
- return *boost::get< Array >( &v_ );
- }
- template< class Config >
- Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
- : name_( name )
- , value_( value )
- {
- }
- template< class Config >
- bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
- {
- if( this == &lhs ) return true;
- return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
- }
- // converts a C string, ie. 8 bit char array, to a string object
- //
- template < class String_type >
- String_type to_str( const char* c_str )
- {
- String_type result;
- for( const char* p = c_str; *p != 0; ++p )
- {
- result += *p;
- }
- return result;
- }
- //
- namespace internal_
- {
- template< typename T >
- struct Type_to_type
- {
- };
- template< class Value >
- int get_value( const Value& value, Type_to_type< int > )
- {
- return value.get_int();
- }
-
- template< class Value >
- boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
- {
- return value.get_int64();
- }
-
- template< class Value >
- boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
- {
- return value.get_uint64();
- }
-
- template< class Value >
- double get_value( const Value& value, Type_to_type< double > )
- {
- return value.get_real();
- }
-
- template< class Value >
- typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
- {
- return value.get_str();
- }
-
- template< class Value >
- typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
- {
- return value.get_array();
- }
-
- template< class Value >
- typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
- {
- return value.get_obj();
- }
-
- template< class Value >
- bool get_value( const Value& value, Type_to_type< bool > )
- {
- return value.get_bool();
- }
- }
- template< class Config >
- template< typename T >
- T Value_impl< Config >::get_value() const
- {
- return internal_::get_value( *this, internal_::Type_to_type< T >() );
- }
- }
- #endif
|