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/shared_ptr.hpp>
21 #include <boost/variant.hpp>
25 enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
26 static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
28 template< class Config > // Config determines whether the value uses std::string or std::wstring and
29 // whether JSON Objects are represented as vectors or maps
34 typedef Config Config_type;
35 typedef typename Config::String_type String_type;
36 typedef typename Config::Object_type Object;
37 typedef typename Config::Array_type Array;
38 typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
40 Value_impl(); // creates null value
41 Value_impl( Const_str_ptr value );
42 Value_impl( const String_type& value );
43 Value_impl( const Object& value );
44 Value_impl( const Array& value );
45 Value_impl( bool value );
46 Value_impl( int value );
47 Value_impl( int64_t value );
48 Value_impl( uint64_t value );
49 Value_impl( double value );
51 Value_impl( const Value_impl& other );
53 bool operator==( const Value_impl& lhs ) const;
55 Value_impl& operator=( const Value_impl& lhs );
57 Value_type type() const;
59 bool is_uint64() const;
62 const String_type& get_str() const;
63 const Object& get_obj() const;
64 const Array& get_array() const;
65 bool get_bool() const;
67 int64_t get_int64() const;
68 uint64_t get_uint64() const;
69 double get_real() const;
74 template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
75 // or double d = value.get_value< double >();
77 static const Value_impl null;
81 void check_type( const Value_type vtype ) const;
83 typedef boost::variant< String_type,
84 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
85 bool, int64_t, double > Variant;
94 template< class Config >
97 typedef typename Config::String_type String_type;
98 typedef typename Config::Value_type Value_type;
100 Pair_impl( const String_type& name, const Value_type& value );
102 bool operator==( const Pair_impl& lhs ) const;
108 template< class String >
111 typedef String String_type;
112 typedef Value_impl< Config_vector > Value_type;
113 typedef Pair_impl < Config_vector > Pair_type;
114 typedef std::vector< Value_type > Array_type;
115 typedef std::vector< Pair_type > Object_type;
117 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
119 obj.push_back( Pair_type( name , value ) );
121 return obj.back().value_;
124 static String_type get_name( const Pair_type& pair )
129 static Value_type get_value( const Pair_type& pair )
135 // typedefs for ASCII
137 typedef Config_vector< std::string > Config;
139 typedef Config::Value_type Value;
140 typedef Config::Pair_type Pair;
141 typedef Config::Object_type Object;
142 typedef Config::Array_type Array;
144 // typedefs for Unicode
146 #ifndef BOOST_NO_STD_WSTRING
148 typedef Config_vector< std::wstring > wConfig;
150 typedef wConfig::Value_type wValue;
151 typedef wConfig::Pair_type wPair;
152 typedef wConfig::Object_type wObject;
153 typedef wConfig::Array_type wArray;
158 template< class String >
161 typedef String String_type;
162 typedef Value_impl< Config_map > Value_type;
163 typedef std::vector< Value_type > Array_type;
164 typedef std::map< String_type, Value_type > Object_type;
165 typedef typename Object_type::value_type Pair_type;
167 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
169 return obj[ name ] = value;
172 static String_type get_name( const Pair_type& pair )
177 static Value_type get_value( const Pair_type& pair )
183 // typedefs for ASCII
185 typedef Config_map< std::string > mConfig;
187 typedef mConfig::Value_type mValue;
188 typedef mConfig::Object_type mObject;
189 typedef mConfig::Array_type mArray;
191 // typedefs for Unicode
193 #ifndef BOOST_NO_STD_WSTRING
195 typedef Config_map< std::wstring > wmConfig;
197 typedef wmConfig::Value_type wmValue;
198 typedef wmConfig::Object_type wmObject;
199 typedef wmConfig::Array_type wmArray;
203 ///////////////////////////////////////////////////////////////////////////////////////////////
207 template< class Config >
208 const Value_impl< Config > Value_impl< Config >::null;
210 template< class Config >
211 Value_impl< Config >::Value_impl()
213 , is_uint64_( false )
217 template< class Config >
218 Value_impl< Config >::Value_impl( const Const_str_ptr value )
220 , v_( String_type( value ) )
221 , is_uint64_( false )
225 template< class Config >
226 Value_impl< Config >::Value_impl( const String_type& value )
229 , is_uint64_( false )
233 template< class Config >
234 Value_impl< Config >::Value_impl( const Object& value )
237 , is_uint64_( false )
241 template< class Config >
242 Value_impl< Config >::Value_impl( const Array& value )
243 : type_( array_type )
245 , is_uint64_( false )
249 template< class Config >
250 Value_impl< Config >::Value_impl( bool value )
253 , is_uint64_( false )
257 template< class Config >
258 Value_impl< Config >::Value_impl( int value )
260 , v_( static_cast< int64_t >( value ) )
261 , is_uint64_( false )
265 template< class Config >
266 Value_impl< Config >::Value_impl( int64_t value )
269 , is_uint64_( false )
273 template< class Config >
274 Value_impl< Config >::Value_impl( uint64_t value )
276 , v_( static_cast< int64_t >( value ) )
281 template< class Config >
282 Value_impl< Config >::Value_impl( double value )
285 , is_uint64_( false )
289 template< class Config >
290 Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
291 : type_( other.type() )
293 , is_uint64_( other.is_uint64_ )
297 template< class Config >
298 Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
300 Value_impl tmp( lhs );
302 std::swap( type_, tmp.type_ );
303 std::swap( v_, tmp.v_ );
304 std::swap( is_uint64_, tmp.is_uint64_ );
309 template< class Config >
310 bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
312 if( this == &lhs ) return true;
314 if( type() != lhs.type() ) return false;
319 template< class Config >
320 Value_type Value_impl< Config >::type() const
325 template< class Config >
326 bool Value_impl< Config >::is_uint64() const
331 template< class Config >
332 bool Value_impl< Config >::is_null() const
334 return type() == null_type;
337 template< class Config >
338 void Value_impl< Config >::check_type( const Value_type vtype ) const
340 if( type() != vtype )
342 std::ostringstream os;
344 ///// Bitcoin: Tell the types by name instead of by number
345 os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
347 throw std::runtime_error( os.str() );
351 template< class Config >
352 const typename Config::String_type& Value_impl< Config >::get_str() const
354 check_type( str_type );
356 return *boost::get< String_type >( &v_ );
359 template< class Config >
360 const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
362 check_type( obj_type );
364 return *boost::get< Object >( &v_ );
367 template< class Config >
368 const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
370 check_type( array_type );
372 return *boost::get< Array >( &v_ );
375 template< class Config >
376 bool Value_impl< Config >::get_bool() const
378 check_type( bool_type );
380 return boost::get< bool >( v_ );
383 template< class Config >
384 int Value_impl< Config >::get_int() const
386 check_type( int_type );
388 return static_cast< int >( get_int64() );
391 template< class Config >
392 int64_t Value_impl< Config >::get_int64() const
394 check_type( int_type );
396 return boost::get< int64_t >( v_ );
399 template< class Config >
400 uint64_t Value_impl< Config >::get_uint64() const
402 check_type( int_type );
404 return static_cast< uint64_t >( get_int64() );
407 template< class Config >
408 double Value_impl< Config >::get_real() const
410 if( type() == int_type )
412 return is_uint64() ? static_cast< double >( get_uint64() )
413 : static_cast< double >( get_int64() );
416 check_type( real_type );
418 return boost::get< double >( v_ );
421 template< class Config >
422 typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
424 check_type( obj_type );
426 return *boost::get< Object >( &v_ );
429 template< class Config >
430 typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
432 check_type( array_type );
434 return *boost::get< Array >( &v_ );
437 template< class Config >
438 Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
444 template< class Config >
445 bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
447 if( this == &lhs ) return true;
449 return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
452 // converts a C string, ie. 8 bit char array, to a string object
454 template < class String_type >
455 String_type to_str( const char* c_str )
459 for( const char* p = c_str; *p != 0; ++p )
471 template< typename T >
476 template< class Value >
477 int get_value( const Value& value, Type_to_type< int > )
479 return value.get_int();
482 template< class Value >
483 int64_t get_value( const Value& value, Type_to_type< int64_t > )
485 return value.get_int64();
488 template< class Value >
489 uint64_t get_value( const Value& value, Type_to_type< uint64_t > )
491 return value.get_uint64();
494 template< class Value >
495 double get_value( const Value& value, Type_to_type< double > )
497 return value.get_real();
500 template< class Value >
501 typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
503 return value.get_str();
506 template< class Value >
507 typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
509 return value.get_array();
512 template< class Value >
513 typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
515 return value.get_obj();
518 template< class Value >
519 bool get_value( const Value& value, Type_to_type< bool > )
521 return value.get_bool();
525 template< class Config >
526 template< typename T >
527 T Value_impl< Config >::get_value() const
529 return internal_::get_value( *this, internal_::Type_to_type< T >() );