diff options
author | constantined <nobody@constantined.com> | 2013-07-23 04:48:14 +0300 |
---|---|---|
committer | constantined <nobody@constantined.com> | 2013-07-23 04:48:14 +0300 |
commit | 2227389fa8fa1b9ff19234838fc7b641e935125b (patch) | |
tree | 8c8459f756467a2310ea0f386c22c059d3831b75 /src/json/json_spirit_value.h | |
parent | c83d4d2170bf00863bd5c21c6eaea91b00390e72 (diff) |
JSON Spirit updated to v4.06
Diffstat (limited to 'src/json/json_spirit_value.h')
-rw-r--r-- | src/json/json_spirit_value.h | 203 |
1 files changed, 137 insertions, 66 deletions
diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h index 7e83a2a7e3..a5020405d4 100644 --- a/src/json/json_spirit_value.h +++ b/src/json/json_spirit_value.h @@ -1,10 +1,10 @@ #ifndef JSON_SPIRIT_VALUE #define JSON_SPIRIT_VALUE -// Copyright John W. Wilkinson 2007 - 2009. +// Copyright John W. Wilkinson 2007 - 2013 // Distributed under the MIT License, see accompanying file LICENSE.txt -// json spirit version 4.03 +// json spirit version 4.06 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once @@ -21,11 +21,20 @@ #include <boost/shared_ptr.hpp> #include <boost/variant.hpp> +// comment out the value types you don't need to reduce build times and intermediate file sizes +#define JSON_SPIRIT_VALUE_ENABLED +#define JSON_SPIRIT_WVALUE_ENABLED +#define JSON_SPIRIT_MVALUE_ENABLED +#define JSON_SPIRIT_WMVALUE_ENABLED + namespace json_spirit { enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; - static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; + static std::string value_type_to_string( Value_type vtype ); + + struct Null{}; + 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 @@ -49,6 +58,12 @@ namespace json_spirit Value_impl( boost::uint64_t value ); Value_impl( double value ); + template< class Iter > + Value_impl( Iter first, Iter last ); // constructor from containers, e.g. std::vector or std::list + + template< BOOST_VARIANT_ENUM_PARAMS( typename T ) > + Value_impl( const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& variant ); // constructor for compatible variant types + Value_impl( const Value_impl& other ); bool operator==( const Value_impl& lhs ) const; @@ -81,13 +96,32 @@ namespace json_spirit 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; + typedef boost::variant< boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + String_type, bool, boost::int64_t, double, Null, boost::uint64_t > Variant; - Value_type type_; Variant v_; - bool is_uint64_; + + class Variant_converter_visitor : public boost::static_visitor< Variant > + { + public: + + template< typename T, typename A, template< typename, typename > class Cont > + Variant operator()( const Cont< T, A >& cont ) const + { + return Array( cont.begin(), cont.end() ); + } + + Variant operator()( int i ) const + { + return static_cast< boost::int64_t >( i ); + } + + template<class T> + Variant operator()( const T& t ) const + { + return t; + } + }; }; // vector objects @@ -98,6 +132,10 @@ namespace json_spirit typedef typename Config::String_type String_type; typedef typename Config::Value_type Value_type; + Pair_impl() + { + } + Pair_impl( const String_type& name, const Value_type& value ); bool operator==( const Pair_impl& lhs ) const; @@ -106,6 +144,7 @@ namespace json_spirit Value_type value_; }; +#if defined( JSON_SPIRIT_VALUE_ENABLED ) || defined( JSON_SPIRIT_WVALUE_ENABLED ) template< class String > struct Config_vector { @@ -122,30 +161,32 @@ namespace json_spirit return obj.back().value_; } - static String_type get_name( const Pair_type& pair ) + static const String_type& get_name( const Pair_type& pair ) { return pair.name_; } - static Value_type get_value( const Pair_type& pair ) + static const Value_type& get_value( const Pair_type& pair ) { return pair.value_; } }; +#endif // typedefs for ASCII +#ifdef JSON_SPIRIT_VALUE_ENABLED 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; +#endif // typedefs for Unicode -#ifndef BOOST_NO_STD_WSTRING - +#if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) typedef Config_vector< std::wstring > wConfig; typedef wConfig::Value_type wValue; @@ -156,6 +197,7 @@ namespace json_spirit // map objects +#if defined( JSON_SPIRIT_MVALUE_ENABLED ) || defined( JSON_SPIRIT_WMVALUE_ENABLED ) template< class String > struct Config_map { @@ -163,135 +205,134 @@ namespace json_spirit 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; + typedef std::pair< const String_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 ) + static const String_type& get_name( const Pair_type& pair ) { return pair.first; } - static Value_type get_value( const Pair_type& pair ) + static const Value_type& get_value( const Pair_type& pair ) { return pair.second; } }; +#endif // typedefs for ASCII +#ifdef JSON_SPIRIT_MVALUE_ENABLED typedef Config_map< std::string > mConfig; typedef mConfig::Value_type mValue; typedef mConfig::Object_type mObject; typedef mConfig::Array_type mArray; +#endif // typedefs for Unicode -#ifndef BOOST_NO_STD_WSTRING - +#if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( 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 + inline bool operator==( const Null&, const Null& ) + { + return true; + } + 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 ) + : v_( Null() ) { } template< class Config > Value_impl< Config >::Value_impl( const Const_str_ptr value ) - : type_( str_type ) - , v_( String_type( value ) ) - , is_uint64_( false ) + : v_( String_type( value ) ) { } template< class Config > Value_impl< Config >::Value_impl( const String_type& value ) - : type_( str_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Object& value ) - : type_( obj_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Array& value ) - : type_( array_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( bool value ) - : type_( bool_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( int value ) - : type_( int_type ) - , v_( static_cast< boost::int64_t >( value ) ) - , is_uint64_( false ) + : v_( static_cast< boost::int64_t >( value ) ) { } template< class Config > Value_impl< Config >::Value_impl( boost::int64_t value ) - : type_( int_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } 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 ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( double value ) - : type_( real_type ) - , v_( value ) - , is_uint64_( false ) + : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) - : type_( other.type() ) - , v_( other.v_ ) - , is_uint64_( other.is_uint64_ ) + : v_( other.v_ ) + { + } + + template< class Config > + template< class Iter > + Value_impl< Config >::Value_impl( Iter first, Iter last ) + : v_( Array( first, last ) ) + { + } + + template< class Config > + template< BOOST_VARIANT_ENUM_PARAMS( typename T ) > + Value_impl< Config >::Value_impl( const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& variant ) + : v_( boost::apply_visitor( Variant_converter_visitor(), variant) ) { } @@ -300,9 +341,7 @@ namespace json_spirit { Value_impl tmp( lhs ); - std::swap( type_, tmp.type_ ); std::swap( v_, tmp.v_ ); - std::swap( is_uint64_, tmp.is_uint64_ ); return *this; } @@ -320,13 +359,18 @@ namespace json_spirit template< class Config > Value_type Value_impl< Config >::type() const { - return type_; + if( is_uint64() ) + { + return int_type; + } + + return static_cast< Value_type >( v_.which() ); } template< class Config > bool Value_impl< Config >::is_uint64() const { - return is_uint64_; + return v_.which() == null_type + 1; } template< class Config > @@ -342,8 +386,7 @@ namespace json_spirit { std::ostringstream os; - ///// Bitcoin: Tell the types by name instead of by number - os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; + os << "get_value< " << value_type_to_string( vtype ) << " > called on " << value_type_to_string( type() ) << " Value"; throw std::runtime_error( os.str() ); } @@ -352,7 +395,7 @@ namespace json_spirit template< class Config > const typename Config::String_type& Value_impl< Config >::get_str() const { - check_type( str_type ); + check_type( str_type ); return *boost::get< String_type >( &v_ ); } @@ -368,7 +411,7 @@ namespace json_spirit template< class Config > const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const { - check_type( array_type ); + check_type( array_type ); return *boost::get< Array >( &v_ ); } @@ -376,7 +419,7 @@ namespace json_spirit template< class Config > bool Value_impl< Config >::get_bool() const { - check_type( bool_type ); + check_type( bool_type ); return boost::get< bool >( v_ ); } @@ -384,7 +427,7 @@ namespace json_spirit template< class Config > int Value_impl< Config >::get_int() const { - check_type( int_type ); + check_type( int_type ); return static_cast< int >( get_int64() ); } @@ -392,7 +435,12 @@ namespace json_spirit template< class Config > boost::int64_t Value_impl< Config >::get_int64() const { - check_type( int_type ); + check_type( int_type ); + + if( is_uint64() ) + { + return static_cast< boost::int64_t >( get_uint64() ); + } return boost::get< boost::int64_t >( v_ ); } @@ -400,9 +448,14 @@ namespace json_spirit template< class Config > boost::uint64_t Value_impl< Config >::get_uint64() const { - check_type( int_type ); + check_type( int_type ); - return static_cast< boost::uint64_t >( get_int64() ); + if( !is_uint64() ) + { + return static_cast< boost::uint64_t >( get_int64() ); + } + + return boost::get< boost::uint64_t >( v_ ); } template< class Config > @@ -414,7 +467,7 @@ namespace json_spirit : static_cast< double >( get_int64() ); } - check_type( real_type ); + check_type( real_type ); return boost::get< double >( v_ ); } @@ -422,7 +475,7 @@ namespace json_spirit template< class Config > typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() { - check_type( obj_type ); + check_type( obj_type ); return *boost::get< Object >( &v_ ); } @@ -430,7 +483,7 @@ namespace json_spirit template< class Config > typename Value_impl< Config >::Array& Value_impl< Config >::get_array() { - check_type( array_type ); + check_type( array_type ); return *boost::get< Array >( &v_ ); } @@ -529,6 +582,24 @@ namespace json_spirit { return internal_::get_value( *this, internal_::Type_to_type< T >() ); } + + static std::string value_type_to_string( const Value_type vtype ) + { + switch( vtype ) + { + case obj_type: return "Object"; + case array_type: return "Array"; + case str_type: return "string"; + case bool_type: return "boolean"; + case int_type: return "integer"; + case real_type: return "real"; + case null_type: return "null"; + } + + assert( false ); + + return "unknown type"; + } } #endif |