1 #ifndef JSON_SPIRIT_VALUE
2 #define JSON_SPIRIT_VALUE
4 // Copyright John W. Wilkinson 2007 - 2009.
5 // Distributed under the MIT License, see accompanying file LICENSE.txt
7 // json spirit version 4.03
9 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
19 #include <boost/config.hpp>
20 #include <boost/cstdint.hpp>
21 #include <boost/shared_ptr.hpp>
22 #include <boost/variant.hpp>
26 enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
27 static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
29 template< class Config > // Config determines whether the value uses std::string or std::wstring and
30 // whether JSON Objects are represented as vectors or maps
35 typedef Config Config_type;
36 typedef typename Config::String_type String_type;
37 typedef typename Config::Object_type Object;
38 typedef typename Config::Array_type Array;
39 typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
41 Value_impl(); // creates null value
42 Value_impl( Const_str_ptr value );
43 Value_impl( const String_type& value );
44 Value_impl( const Object& value );
45 Value_impl( const Array& value );
46 Value_impl( bool value );
47 Value_impl( int value );
48 Value_impl( boost::int64_t value );
49 Value_impl( boost::uint64_t value );
50 Value_impl( double value );
52 Value_impl( const Value_impl& other );
54 bool operator==( const Value_impl& lhs ) const;
56 Value_impl& operator=( const Value_impl& lhs );
58 Value_type type() const;
60 bool is_uint64() const;
63 const String_type& get_str() const;
64 const Object& get_obj() const;
65 const Array& get_array() const;
66 bool get_bool() const;
68 boost::int64_t get_int64() const;
69 boost::uint64_t get_uint64() const;
70 double get_real() const;
75 template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
76 // or double d = value.get_value< double >();
78 static const Value_impl null;
82 void check_type( const Value_type vtype ) const;
84 typedef boost::variant< String_type,
85 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
86 bool, boost::int64_t, double > Variant;
95 template< class Config >
98 typedef typename Config::String_type String_type;
99 typedef typename Config::Value_type Value_type;
101 Pair_impl( const String_type& name, const Value_type& value );
103 bool operator==( const Pair_impl& lhs ) const;
109 template< class String >
112 typedef String String_type;
113 typedef Value_impl< Config_vector > Value_type;
114 typedef Pair_impl < Config_vector > Pair_type;
115 typedef std::vector< Value_type > Array_type;
116 typedef std::vector< Pair_type > Object_type;
118 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
120 obj.push_back( Pair_type( name , value ) );
122 return obj.back().value_;
125 static String_type get_name( const Pair_type& pair )
130 static Value_type get_value( const Pair_type& pair )
136 // typedefs for ASCII
138 typedef Config_vector< std::string > Config;
140 typedef Config::Value_type Value;
141 typedef Config::Pair_type Pair;
142 typedef Config::Object_type Object;
143 typedef Config::Array_type Array;
145 // typedefs for Unicode
147 #ifndef BOOST_NO_STD_WSTRING
149 typedef Config_vector< std::wstring > wConfig;
151 typedef wConfig::Value_type wValue;
152 typedef wConfig::Pair_type wPair;
153 typedef wConfig::Object_type wObject;
154 typedef wConfig::Array_type wArray;
159 template< class String >
162 typedef String String_type;
163 typedef Value_impl< Config_map > Value_type;
164 typedef std::vector< Value_type > Array_type;
165 typedef std::map< String_type, Value_type > Object_type;
166 typedef typename Object_type::value_type Pair_type;
168 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
170 return obj[ name ] = value;
173 static String_type get_name( const Pair_type& pair )
178 static Value_type get_value( const Pair_type& pair )
184 // typedefs for ASCII
186 typedef Config_map< std::string > mConfig;
188 typedef mConfig::Value_type mValue;
189 typedef mConfig::Object_type mObject;
190 typedef mConfig::Array_type mArray;
192 // typedefs for Unicode
194 #ifndef BOOST_NO_STD_WSTRING
196 typedef Config_map< std::wstring > wmConfig;
198 typedef wmConfig::Value_type wmValue;
199 typedef wmConfig::Object_type wmObject;
200 typedef wmConfig::Array_type wmArray;
204 ///////////////////////////////////////////////////////////////////////////////////////////////
208 template< class Config >
209 const Value_impl< Config > Value_impl< Config >::null;
211 template< class Config >
212 Value_impl< Config >::Value_impl()
214 , is_uint64_( false )
218 template< class Config >
219 Value_impl< Config >::Value_impl( const Const_str_ptr value )
221 , v_( String_type( value ) )
222 , is_uint64_( false )
226 template< class Config >
227 Value_impl< Config >::Value_impl( const String_type& value )
230 , is_uint64_( false )
234 template< class Config >
235 Value_impl< Config >::Value_impl( const Object& value )
238 , is_uint64_( false )
242 template< class Config >
243 Value_impl< Config >::Value_impl( const Array& value )
244 : type_( array_type )
246 , is_uint64_( false )
250 template< class Config >
251 Value_impl< Config >::Value_impl( bool value )
254 , is_uint64_( false )
258 template< class Config >
259 Value_impl< Config >::Value_impl( int value )
261 , v_( static_cast< boost::int64_t >( value ) )
262 , is_uint64_( false )
266 template< class Config >
267 Value_impl< Config >::Value_impl( boost::int64_t value )
270 , is_uint64_( false )
274 template< class Config >
275 Value_impl< Config >::Value_impl( boost::uint64_t value )
277 , v_( static_cast< boost::int64_t >( value ) )
282 template< class Config >
283 Value_impl< Config >::Value_impl( double value )
286 , is_uint64_( false )
290 template< class Config >
291 Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
292 : type_( other.type() )
294 , is_uint64_( other.is_uint64_ )
298 template< class Config >
299 Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
301 Value_impl tmp( lhs );
303 std::swap( type_, tmp.type_ );
304 std::swap( v_, tmp.v_ );
305 std::swap( is_uint64_, tmp.is_uint64_ );
310 template< class Config >
311 bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
313 if( this == &lhs ) return true;
315 if( type() != lhs.type() ) return false;
320 template< class Config >
321 Value_type Value_impl< Config >::type() const
326 template< class Config >
327 bool Value_impl< Config >::is_uint64() const
332 template< class Config >
333 bool Value_impl< Config >::is_null() const
335 return type() == null_type;
338 template< class Config >
339 void Value_impl< Config >::check_type( const Value_type vtype ) const
341 if( type() != vtype )
343 std::ostringstream os;
345 ///// Bitcoin: Tell the types by name instead of by number
346 os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
348 throw std::runtime_error( os.str() );
352 template< class Config >
353 const typename Config::String_type& Value_impl< Config >::get_str() const
355 check_type( str_type );
357 return *boost::get< String_type >( &v_ );
360 template< class Config >
361 const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
363 check_type( obj_type );
365 return *boost::get< Object >( &v_ );
368 template< class Config >
369 const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
371 check_type( array_type );
373 return *boost::get< Array >( &v_ );
376 template< class Config >
377 bool Value_impl< Config >::get_bool() const
379 check_type( bool_type );
381 return boost::get< bool >( v_ );
384 template< class Config >
385 int Value_impl< Config >::get_int() const
387 check_type( int_type );
389 return static_cast< int >( get_int64() );
392 template< class Config >
393 boost::int64_t Value_impl< Config >::get_int64() const
395 check_type( int_type );
397 return boost::get< boost::int64_t >( v_ );
400 template< class Config >
401 boost::uint64_t Value_impl< Config >::get_uint64() const
403 check_type( int_type );
405 return static_cast< boost::uint64_t >( get_int64() );
408 template< class Config >
409 double Value_impl< Config >::get_real() const
411 if( type() == int_type )
413 return is_uint64() ? static_cast< double >( get_uint64() )
414 : static_cast< double >( get_int64() );
417 check_type( real_type );
419 return boost::get< double >( v_ );
422 template< class Config >
423 typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
425 check_type( obj_type );
427 return *boost::get< Object >( &v_ );
430 template< class Config >
431 typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
433 check_type( array_type );
435 return *boost::get< Array >( &v_ );
438 template< class Config >
439 Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
445 template< class Config >
446 bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
448 if( this == &lhs ) return true;
450 return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
453 // converts a C string, ie. 8 bit char array, to a string object
455 template < class String_type >
456 String_type to_str( const char* c_str )
460 for( const char* p = c_str; *p != 0; ++p )
472 template< typename T >
477 template< class Value >
478 int get_value( const Value& value, Type_to_type< int > )
480 return value.get_int();
483 template< class Value >
484 boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
486 return value.get_int64();
489 template< class Value >
490 boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
492 return value.get_uint64();
495 template< class Value >
496 double get_value( const Value& value, Type_to_type< double > )
498 return value.get_real();
501 template< class Value >
502 typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
504 return value.get_str();
507 template< class Value >
508 typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
510 return value.get_array();
513 template< class Value >
514 typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
516 return value.get_obj();
519 template< class Value >
520 bool get_value( const Value& value, Type_to_type< bool > )
522 return value.get_bool();
526 template< class Config >
527 template< typename T >
528 T Value_impl< Config >::get_value() const
530 return internal_::get_value( *this, internal_::Type_to_type< T >() );