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