1 #ifndef JSON_SPIRIT_VALUE
2 #define JSON_SPIRIT_VALUE
4 // Copyright John W. Wilkinson 2007 - 2011
5 // Distributed under the MIT License, see accompanying file LICENSE.txt
7 // json spirit version 4.05
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>
24 // comment out the value types you don't need to reduce build times and intermediate file sizes
25 #define JSON_SPIRIT_VALUE_ENABLED
26 //#define JSON_SPIRIT_WVALUE_ENABLED
27 #define JSON_SPIRIT_MVALUE_ENABLED
28 //#define JSON_SPIRIT_WMVALUE_ENABLED
32 enum Value_type
{ obj_type
, array_type
, str_type
, bool_type
, int_type
, real_type
, null_type
};
36 template< class Config
> // Config determines whether the value uses std::string or std::wstring and
37 // whether JSON Objects are represented as vectors or maps
42 typedef Config Config_type
;
43 typedef typename
Config::String_type String_type
;
44 typedef typename
Config::Object_type Object
;
45 typedef typename
Config::Array_type Array
;
46 typedef typename
String_type::const_pointer Const_str_ptr
; // eg const char*
48 Value_impl(); // creates null value
49 Value_impl( Const_str_ptr value
);
50 Value_impl( const String_type
& value
);
51 Value_impl( const Object
& value
);
52 Value_impl( const Array
& value
);
53 Value_impl( bool value
);
54 Value_impl( int value
);
55 Value_impl( boost::int64_t value
);
56 Value_impl( boost::uint64_t value
);
57 Value_impl( double value
);
59 template< class Iter
>
60 Value_impl( Iter first
, Iter last
); // constructor from containers, e.g. std::vector or std::list
62 template< BOOST_VARIANT_ENUM_PARAMS( typename T
) >
63 Value_impl( const boost::variant
< BOOST_VARIANT_ENUM_PARAMS(T
) >& variant
); // constructor for compatible variant types
65 Value_impl( const Value_impl
& other
);
67 bool operator==( const Value_impl
& lhs
) const;
69 Value_impl
& operator=( const Value_impl
& lhs
);
71 Value_type
type() const;
73 bool is_uint64() const;
76 const String_type
& get_str() const;
77 const Object
& get_obj() const;
78 const Array
& get_array() const;
79 bool get_bool() const;
81 boost::int64_t get_int64() const;
82 boost::uint64_t get_uint64() const;
83 double get_real() const;
88 template< typename T
> T
get_value() const; // example usage: int i = value.get_value< int >();
89 // or double d = value.get_value< double >();
91 static const Value_impl null
;
95 void check_type( const Value_type vtype
) const;
97 typedef boost::variant
< boost::recursive_wrapper
< Object
>, boost::recursive_wrapper
< Array
>,
98 String_type
, bool, boost::int64_t, double, Null
, boost::uint64_t > Variant
;
102 class Variant_converter_visitor
: public boost::static_visitor
< Variant
>
106 template< typename T
, typename A
, template< typename
, typename
> class Cont
>
107 Variant
operator()( const Cont
< T
, A
>& cont
) const
109 return Array( cont
.begin(), cont
.end() );
112 Variant
operator()( int i
) const
114 return static_cast< boost::int64_t >( i
);
118 Variant
operator()( const T
& t
) const
127 template< class Config
>
130 typedef typename
Config::String_type String_type
;
131 typedef typename
Config::Value_type Value_type
;
137 Pair_impl( const String_type
& name
, const Value_type
& value
);
139 bool operator==( const Pair_impl
& lhs
) const;
145 #if defined( JSON_SPIRIT_VALUE_ENABLED ) || defined( JSON_SPIRIT_WVALUE_ENABLED )
146 template< class String
>
149 typedef String String_type
;
150 typedef Value_impl
< Config_vector
> Value_type
;
151 typedef Pair_impl
< Config_vector
> Pair_type
;
152 typedef std::vector
< Value_type
> Array_type
;
153 typedef std::vector
< Pair_type
> Object_type
;
155 static Value_type
& add( Object_type
& obj
, const String_type
& name
, const Value_type
& value
)
157 obj
.push_back( Pair_type( name
, value
) );
159 return obj
.back().value_
;
162 static String_type
get_name( const Pair_type
& pair
)
167 static Value_type
get_value( const Pair_type
& pair
)
174 // typedefs for ASCII
176 #ifdef JSON_SPIRIT_VALUE_ENABLED
177 typedef Config_vector
< std::string
> Config
;
179 typedef Config::Value_type Value
;
180 typedef Config::Pair_type Pair
;
181 typedef Config::Object_type Object
;
182 typedef Config::Array_type Array
;
185 // typedefs for Unicode
187 #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING )
188 typedef Config_vector
< std::wstring
> wConfig
;
190 typedef wConfig::Value_type wValue
;
191 typedef wConfig::Pair_type wPair
;
192 typedef wConfig::Object_type wObject
;
193 typedef wConfig::Array_type wArray
;
198 #if defined( JSON_SPIRIT_MVALUE_ENABLED ) || defined( JSON_SPIRIT_WMVALUE_ENABLED )
199 template< class String
>
202 typedef String String_type
;
203 typedef Value_impl
< Config_map
> Value_type
;
204 typedef std::vector
< Value_type
> Array_type
;
205 typedef std::map
< String_type
, Value_type
> Object_type
;
206 typedef std::pair
< String_type
, Value_type
> Pair_type
;
208 static Value_type
& add( Object_type
& obj
, const String_type
& name
, const Value_type
& value
)
210 return obj
[ name
] = value
;
213 static String_type
get_name( const Pair_type
& pair
)
218 static Value_type
get_value( const Pair_type
& pair
)
225 // typedefs for ASCII
227 #ifdef JSON_SPIRIT_MVALUE_ENABLED
228 typedef Config_map
< std::string
> mConfig
;
230 typedef mConfig::Value_type mValue
;
231 typedef mConfig::Object_type mObject
;
232 typedef mConfig::Array_type mArray
;
235 // typedefs for Unicode
237 #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING )
238 typedef Config_map
< std::wstring
> wmConfig
;
240 typedef wmConfig::Value_type wmValue
;
241 typedef wmConfig::Object_type wmObject
;
242 typedef wmConfig::Array_type wmArray
;
245 ///////////////////////////////////////////////////////////////////////////////////////////////
249 inline bool operator==( const Null
&, const Null
& )
254 template< class Config
>
255 const Value_impl
< Config
> Value_impl
< Config
>::null
;
257 template< class Config
>
258 Value_impl
< Config
>::Value_impl()
263 template< class Config
>
264 Value_impl
< Config
>::Value_impl( const Const_str_ptr value
)
265 : v_( String_type( value
) )
269 template< class Config
>
270 Value_impl
< Config
>::Value_impl( const String_type
& value
)
275 template< class Config
>
276 Value_impl
< Config
>::Value_impl( const Object
& value
)
281 template< class Config
>
282 Value_impl
< Config
>::Value_impl( const Array
& value
)
287 template< class Config
>
288 Value_impl
< Config
>::Value_impl( bool value
)
293 template< class Config
>
294 Value_impl
< Config
>::Value_impl( int value
)
295 : v_( static_cast< boost::int64_t >( value
) )
299 template< class Config
>
300 Value_impl
< Config
>::Value_impl( boost::int64_t value
)
305 template< class Config
>
306 Value_impl
< Config
>::Value_impl( boost::uint64_t value
)
311 template< class Config
>
312 Value_impl
< Config
>::Value_impl( double value
)
317 template< class Config
>
318 Value_impl
< Config
>::Value_impl( const Value_impl
< Config
>& other
)
323 template< class Config
>
324 template< class Iter
>
325 Value_impl
< Config
>::Value_impl( Iter first
, Iter last
)
326 : v_( Array( first
, last
) )
330 template< class Config
>
331 template< BOOST_VARIANT_ENUM_PARAMS( typename T
) >
332 Value_impl
< Config
>::Value_impl( const boost::variant
< BOOST_VARIANT_ENUM_PARAMS(T
) >& variant
)
333 : v_( boost::apply_visitor( Variant_converter_visitor(), variant
) )
337 template< class Config
>
338 Value_impl
< Config
>& Value_impl
< Config
>::operator=( const Value_impl
& lhs
)
340 Value_impl
tmp( lhs
);
342 std::swap( v_
, tmp
.v_
);
347 template< class Config
>
348 bool Value_impl
< Config
>::operator==( const Value_impl
& lhs
) const
350 if( this == &lhs
) return true;
352 if( type() != lhs
.type() ) return false;
357 template< class Config
>
358 Value_type Value_impl
< Config
>::type() const
365 return static_cast< Value_type
>( v_
.which() );
368 template< class Config
>
369 bool Value_impl
< Config
>::is_uint64() const
371 return v_
.which() == null_type
+ 1;
374 template< class Config
>
375 bool Value_impl
< Config
>::is_null() const
377 return type() == null_type
;
380 template< class Config
>
381 void Value_impl
< Config
>::check_type( const Value_type vtype
) const
383 if( type() != vtype
)
385 std::ostringstream os
;
387 os
<< "value type is " << type() << " not " << vtype
;
389 throw std::runtime_error( os
.str() );
393 template< class Config
>
394 const typename
Config::String_type
& Value_impl
< Config
>::get_str() const
396 check_type( str_type
);
398 return *boost::get
< String_type
>( &v_
);
401 template< class Config
>
402 const typename Value_impl
< Config
>::Object
& Value_impl
< Config
>::get_obj() const
404 check_type( obj_type
);
406 return *boost::get
< Object
>( &v_
);
409 template< class Config
>
410 const typename Value_impl
< Config
>::Array
& Value_impl
< Config
>::get_array() const
412 check_type( array_type
);
414 return *boost::get
< Array
>( &v_
);
417 template< class Config
>
418 bool Value_impl
< Config
>::get_bool() const
420 check_type( bool_type
);
422 return boost::get
< bool >( v_
);
425 template< class Config
>
426 int Value_impl
< Config
>::get_int() const
428 check_type( int_type
);
430 return static_cast< int >( get_int64() );
433 template< class Config
>
434 boost::int64_t Value_impl
< Config
>::get_int64() const
436 check_type( int_type
);
440 return static_cast< boost::int64_t >( get_uint64() );
443 return boost::get
< boost::int64_t >( v_
);
446 template< class Config
>
447 boost::uint64_t Value_impl
< Config
>::get_uint64() const
449 check_type( int_type
);
453 return static_cast< boost::uint64_t >( get_int64() );
456 return boost::get
< boost::uint64_t >( v_
);
459 template< class Config
>
460 double Value_impl
< Config
>::get_real() const
462 if( type() == int_type
)
464 return is_uint64() ? static_cast< double >( get_uint64() )
465 : static_cast< double >( get_int64() );
468 check_type( real_type
);
470 return boost::get
< double >( v_
);
473 template< class Config
>
474 typename Value_impl
< Config
>::Object
& Value_impl
< Config
>::get_obj()
476 check_type( obj_type
);
478 return *boost::get
< Object
>( &v_
);
481 template< class Config
>
482 typename Value_impl
< Config
>::Array
& Value_impl
< Config
>::get_array()
484 check_type( array_type
);
486 return *boost::get
< Array
>( &v_
);
489 template< class Config
>
490 Pair_impl
< Config
>::Pair_impl( const String_type
& name
, const Value_type
& value
)
496 template< class Config
>
497 bool Pair_impl
< Config
>::operator==( const Pair_impl
< Config
>& lhs
) const
499 if( this == &lhs
) return true;
501 return ( name_
== lhs
.name_
) && ( value_
== lhs
.value_
);
504 // converts a C string, ie. 8 bit char array, to a string object
506 template < class String_type
>
507 String_type
to_str( const char* c_str
)
511 for( const char* p
= c_str
; *p
!= 0; ++p
)
523 template< typename T
>
528 template< class Value
>
529 int get_value( const Value
& value
, Type_to_type
< int > )
531 return value
.get_int();
534 template< class Value
>
535 boost::int64_t get_value( const Value
& value
, Type_to_type
< boost::int64_t > )
537 return value
.get_int64();
540 template< class Value
>
541 boost::uint64_t get_value( const Value
& value
, Type_to_type
< boost::uint64_t > )
543 return value
.get_uint64();
546 template< class Value
>
547 double get_value( const Value
& value
, Type_to_type
< double > )
549 return value
.get_real();
552 template< class Value
>
553 typename
Value::String_type
get_value( const Value
& value
, Type_to_type
< typename
Value::String_type
> )
555 return value
.get_str();
558 template< class Value
>
559 typename
Value::Array
get_value( const Value
& value
, Type_to_type
< typename
Value::Array
> )
561 return value
.get_array();
564 template< class Value
>
565 typename
Value::Object
get_value( const Value
& value
, Type_to_type
< typename
Value::Object
> )
567 return value
.get_obj();
570 template< class Value
>
571 bool get_value( const Value
& value
, Type_to_type
< bool > )
573 return value
.get_bool();
577 template< class Config
>
578 template< typename T
>
579 T Value_impl
< Config
>::get_value() const
581 return internal_::get_value( *this, internal_::Type_to_type
< T
>() );