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