]> git.proxmox.com Git - ceph.git/blob - ceph/src/json_spirit/json_spirit_value.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / json_spirit / json_spirit_value.h
1 #ifndef JSON_SPIRIT_VALUE
2 #define JSON_SPIRIT_VALUE
3
4 // Copyright John W. Wilkinson 2007 - 2011
5 // Distributed under the MIT License, see accompanying file LICENSE.txt
6
7 // json spirit version 4.05
8
9 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
10 # pragma once
11 #endif
12
13 #include <vector>
14 #include <map>
15 #include <string>
16 #include <cassert>
17 #include <sstream>
18 #include <stdexcept>
19 #include <boost/config.hpp>
20 #include <boost/cstdint.hpp>
21 #include <boost/shared_ptr.hpp>
22 #include <boost/variant.hpp>
23
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
29
30 namespace json_spirit
31 {
32 enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
33
34 struct Null{};
35
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
38 class Value_impl
39 {
40 public:
41
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*
47
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 );
58
59 template< class Iter >
60 Value_impl( Iter first, Iter last ); // constructor from containers, e.g. std::vector or std::list
61
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
64
65 Value_impl( const Value_impl& other );
66
67 bool operator==( const Value_impl& lhs ) const;
68
69 Value_impl& operator=( const Value_impl& lhs );
70
71 Value_type type() const;
72
73 bool is_uint64() const;
74 bool is_null() const;
75
76 const String_type& get_str() const;
77 const Object& get_obj() const;
78 const Array& get_array() const;
79 bool get_bool() const;
80 int get_int() const;
81 boost::int64_t get_int64() const;
82 boost::uint64_t get_uint64() const;
83 double get_real() const;
84
85 Object& get_obj();
86 Array& get_array();
87
88 template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
89 // or double d = value.get_value< double >();
90
91 static const Value_impl null;
92
93 private:
94
95 void check_type( const Value_type vtype ) const;
96
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;
99
100 Variant v_;
101
102 class Variant_converter_visitor : public boost::static_visitor< Variant >
103 {
104 public:
105
106 template< typename T, typename A, template< typename, typename > class Cont >
107 Variant operator()( const Cont< T, A >& cont ) const
108 {
109 return Array( cont.begin(), cont.end() );
110 }
111
112 Variant operator()( int i ) const
113 {
114 return static_cast< boost::int64_t >( i );
115 }
116
117 template<class T>
118 Variant operator()( const T& t ) const
119 {
120 return t;
121 }
122 };
123 };
124
125 // vector objects
126
127 template< class Config >
128 struct Pair_impl
129 {
130 typedef typename Config::String_type String_type;
131 typedef typename Config::Value_type Value_type;
132
133 Pair_impl()
134 {
135 }
136
137 Pair_impl( const String_type& name, const Value_type& value );
138
139 bool operator==( const Pair_impl& lhs ) const;
140
141 String_type name_;
142 Value_type value_;
143 };
144
145 #if defined( JSON_SPIRIT_VALUE_ENABLED ) || defined( JSON_SPIRIT_WVALUE_ENABLED )
146 template< class String >
147 struct Config_vector
148 {
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;
154
155 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
156 {
157 obj.push_back( Pair_type( name , value ) );
158
159 return obj.back().value_;
160 }
161
162 static String_type get_name( const Pair_type& pair )
163 {
164 return pair.name_;
165 }
166
167 static Value_type get_value( const Pair_type& pair )
168 {
169 return pair.value_;
170 }
171 };
172 #endif
173
174 // typedefs for ASCII
175
176 #ifdef JSON_SPIRIT_VALUE_ENABLED
177 typedef Config_vector< std::string > Config;
178
179 typedef Config::Value_type Value;
180 typedef Config::Pair_type Pair;
181 typedef Config::Object_type Object;
182 typedef Config::Array_type Array;
183 #endif
184
185 // typedefs for Unicode
186
187 #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING )
188 typedef Config_vector< std::wstring > wConfig;
189
190 typedef wConfig::Value_type wValue;
191 typedef wConfig::Pair_type wPair;
192 typedef wConfig::Object_type wObject;
193 typedef wConfig::Array_type wArray;
194 #endif
195
196 // map objects
197
198 #if defined( JSON_SPIRIT_MVALUE_ENABLED ) || defined( JSON_SPIRIT_WMVALUE_ENABLED )
199 template< class String >
200 struct Config_map
201 {
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;
207
208 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
209 {
210 return obj[ name ] = value;
211 }
212
213 static String_type get_name( const Pair_type& pair )
214 {
215 return pair.first;
216 }
217
218 static Value_type get_value( const Pair_type& pair )
219 {
220 return pair.second;
221 }
222 };
223 #endif
224
225 // typedefs for ASCII
226
227 #ifdef JSON_SPIRIT_MVALUE_ENABLED
228 typedef Config_map< std::string > mConfig;
229
230 typedef mConfig::Value_type mValue;
231 typedef mConfig::Object_type mObject;
232 typedef mConfig::Array_type mArray;
233 #endif
234
235 // typedefs for Unicode
236
237 #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING )
238 typedef Config_map< std::wstring > wmConfig;
239
240 typedef wmConfig::Value_type wmValue;
241 typedef wmConfig::Object_type wmObject;
242 typedef wmConfig::Array_type wmArray;
243 #endif
244
245 ///////////////////////////////////////////////////////////////////////////////////////////////
246 //
247 // implementation
248
249 inline bool operator==( const Null&, const Null& )
250 {
251 return true;
252 }
253
254 template< class Config >
255 const Value_impl< Config > Value_impl< Config >::null;
256
257 template< class Config >
258 Value_impl< Config >::Value_impl()
259 : v_( Null() )
260 {
261 }
262
263 template< class Config >
264 Value_impl< Config >::Value_impl( const Const_str_ptr value )
265 : v_( String_type( value ) )
266 {
267 }
268
269 template< class Config >
270 Value_impl< Config >::Value_impl( const String_type& value )
271 : v_( value )
272 {
273 }
274
275 template< class Config >
276 Value_impl< Config >::Value_impl( const Object& value )
277 : v_( value )
278 {
279 }
280
281 template< class Config >
282 Value_impl< Config >::Value_impl( const Array& value )
283 : v_( value )
284 {
285 }
286
287 template< class Config >
288 Value_impl< Config >::Value_impl( bool value )
289 : v_( value )
290 {
291 }
292
293 template< class Config >
294 Value_impl< Config >::Value_impl( int value )
295 : v_( static_cast< boost::int64_t >( value ) )
296 {
297 }
298
299 template< class Config >
300 Value_impl< Config >::Value_impl( boost::int64_t value )
301 : v_( value )
302 {
303 }
304
305 template< class Config >
306 Value_impl< Config >::Value_impl( boost::uint64_t value )
307 : v_( value )
308 {
309 }
310
311 template< class Config >
312 Value_impl< Config >::Value_impl( double value )
313 : v_( value )
314 {
315 }
316
317 template< class Config >
318 Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
319 : v_( other.v_ )
320 {
321 }
322
323 template< class Config >
324 template< class Iter >
325 Value_impl< Config >::Value_impl( Iter first, Iter last )
326 : v_( Array( first, last ) )
327 {
328 }
329
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) )
334 {
335 }
336
337 template< class Config >
338 Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
339 {
340 Value_impl tmp( lhs );
341
342 std::swap( v_, tmp.v_ );
343
344 return *this;
345 }
346
347 template< class Config >
348 bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
349 {
350 if( this == &lhs ) return true;
351
352 if( type() != lhs.type() ) return false;
353
354 return v_ == lhs.v_;
355 }
356
357 template< class Config >
358 Value_type Value_impl< Config >::type() const
359 {
360 if( is_uint64() )
361 {
362 return int_type;
363 }
364
365 return static_cast< Value_type >( v_.which() );
366 }
367
368 template< class Config >
369 bool Value_impl< Config >::is_uint64() const
370 {
371 return v_.which() == null_type + 1;
372 }
373
374 template< class Config >
375 bool Value_impl< Config >::is_null() const
376 {
377 return type() == null_type;
378 }
379
380 template< class Config >
381 void Value_impl< Config >::check_type( const Value_type vtype ) const
382 {
383 if( type() != vtype )
384 {
385 std::ostringstream os;
386
387 os << "value type is " << type() << " not " << vtype;
388
389 throw std::runtime_error( os.str() );
390 }
391 }
392
393 template< class Config >
394 const typename Config::String_type& Value_impl< Config >::get_str() const
395 {
396 check_type( str_type );
397
398 return *boost::get< String_type >( &v_ );
399 }
400
401 template< class Config >
402 const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
403 {
404 check_type( obj_type );
405
406 return *boost::get< Object >( &v_ );
407 }
408
409 template< class Config >
410 const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
411 {
412 check_type( array_type );
413
414 return *boost::get< Array >( &v_ );
415 }
416
417 template< class Config >
418 bool Value_impl< Config >::get_bool() const
419 {
420 check_type( bool_type );
421
422 return boost::get< bool >( v_ );
423 }
424
425 template< class Config >
426 int Value_impl< Config >::get_int() const
427 {
428 check_type( int_type );
429
430 return static_cast< int >( get_int64() );
431 }
432
433 template< class Config >
434 boost::int64_t Value_impl< Config >::get_int64() const
435 {
436 check_type( int_type );
437
438 if( is_uint64() )
439 {
440 return static_cast< boost::int64_t >( get_uint64() );
441 }
442
443 return boost::get< boost::int64_t >( v_ );
444 }
445
446 template< class Config >
447 boost::uint64_t Value_impl< Config >::get_uint64() const
448 {
449 check_type( int_type );
450
451 if( !is_uint64() )
452 {
453 return static_cast< boost::uint64_t >( get_int64() );
454 }
455
456 return boost::get< boost::uint64_t >( v_ );
457 }
458
459 template< class Config >
460 double Value_impl< Config >::get_real() const
461 {
462 if( type() == int_type )
463 {
464 return is_uint64() ? static_cast< double >( get_uint64() )
465 : static_cast< double >( get_int64() );
466 }
467
468 check_type( real_type );
469
470 return boost::get< double >( v_ );
471 }
472
473 template< class Config >
474 typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
475 {
476 check_type( obj_type );
477
478 return *boost::get< Object >( &v_ );
479 }
480
481 template< class Config >
482 typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
483 {
484 check_type( array_type );
485
486 return *boost::get< Array >( &v_ );
487 }
488
489 template< class Config >
490 Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
491 : name_( name )
492 , value_( value )
493 {
494 }
495
496 template< class Config >
497 bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
498 {
499 if( this == &lhs ) return true;
500
501 return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
502 }
503
504 // converts a C string, ie. 8 bit char array, to a string object
505 //
506 template < class String_type >
507 String_type to_str( const char* c_str )
508 {
509 String_type result;
510
511 for( const char* p = c_str; *p != 0; ++p )
512 {
513 result += *p;
514 }
515
516 return result;
517 }
518
519 //
520
521 namespace internal_
522 {
523 template< typename T >
524 struct Type_to_type
525 {
526 };
527
528 template< class Value >
529 int get_value( const Value& value, Type_to_type< int > )
530 {
531 return value.get_int();
532 }
533
534 template< class Value >
535 boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
536 {
537 return value.get_int64();
538 }
539
540 template< class Value >
541 boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
542 {
543 return value.get_uint64();
544 }
545
546 template< class Value >
547 double get_value( const Value& value, Type_to_type< double > )
548 {
549 return value.get_real();
550 }
551
552 template< class Value >
553 typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
554 {
555 return value.get_str();
556 }
557
558 template< class Value >
559 typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
560 {
561 return value.get_array();
562 }
563
564 template< class Value >
565 typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
566 {
567 return value.get_obj();
568 }
569
570 template< class Value >
571 bool get_value( const Value& value, Type_to_type< bool > )
572 {
573 return value.get_bool();
574 }
575 }
576
577 template< class Config >
578 template< typename T >
579 T Value_impl< Config >::get_value() const
580 {
581 return internal_::get_value( *this, internal_::Type_to_type< T >() );
582 }
583 }
584
585 #endif