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 >() );