Flow123d  master-f44eb46
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 - 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 {
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
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 
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 
134  {
135  }
136 
137  Pair_impl( const String_type& name, const Value_type& value );
138 
139  bool operator==( const Pair_impl& lhs ) const;
140 
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;
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;
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
229 
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 >
259  : v_( Null() )
260  {
261  }
262 
263  template< class Config >
265  : v_( String_type( value ) )
266  {
267  }
268 
269  template< class Config >
271  : v_( value )
272  {
273  }
274 
275  template< class Config >
277  : v_( value )
278  {
279  }
280 
281  template< class Config >
283  : v_( value )
284  {
285  }
286 
287  template< class Config >
289  : v_( value )
290  {
291  }
292 
293  template< class Config >
295  : v_( static_cast< boost::int64_t >( value ) )
296  {
297  }
298 
299  template< class Config >
301  : v_( value )
302  {
303  }
304 
305  template< class Config >
307  : v_( value )
308  {
309  }
310 
311  template< class Config >
313  : v_( value )
314  {
315  }
316 
317  template< class Config >
319  : v_( other.v_ )
320  {
321  }
322 
323  template< class Config >
324  template< class Iter >
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 >
339  {
340  Value_impl tmp( lhs );
341 
342  std::swap( v_, tmp.v_ );
343 
344  return *this;
345  }
346 
347  template< class Config >
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 >
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 >
370  {
371  return v_.which() == null_type + 1;
372  }
373 
374  template< class Config >
376  {
377  return type() == null_type;
378  }
379 
380  template< class Config >
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 >
403  {
404  check_type( obj_type );
405 
406  return *boost::get< Object >( &v_ );
407  }
408 
409  template< class Config >
411  {
412  check_type( array_type );
413 
414  return *boost::get< Array >( &v_ );
415  }
416 
417  template< class Config >
419  {
420  check_type( bool_type );
421 
422  return boost::get< bool >( v_ );
423  }
424 
425  template< class Config >
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 >
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 >
475  {
476  check_type( obj_type );
477 
478  return *boost::get< Object >( &v_ );
479  }
480 
481  template< class Config >
483  {
484  check_type( array_type );
485 
486  return *boost::get< Array >( &v_ );
487  }
488 
489  template< class Config >
491  : name_( name )
492  , value_( value )
493  {
494  }
495 
496  template< class Config >
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 >
525  {
526  };
527 
528  template< class Value >
530  {
531  return value.get_int();
532  }
533 
534  template< class Value >
536  {
537  return value.get_int64();
538  }
539 
540  template< class Value >
542  {
543  return value.get_uint64();
544  }
545 
546  template< class Value >
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 >
560  {
561  return value.get_array();
562  }
563 
564  template< class Value >
566  {
567  return value.get_obj();
568  }
569 
570  template< class Value >
572  {
573  return value.get_bool();
574  }
575  }
576 
577  template< class Config >
578  template< typename T >
580  {
582  }
583 }
584 
585 #endif
General iterator template. Provides iterator over objects of type Object in some container.
Variant operator()(const Cont< T, A > &cont) const
boost::uint64_t get_uint64() const
Value_impl & operator=(const Value_impl &lhs)
Config::String_type String_type
boost::variant< boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, String_type, bool, boost::int64_t, double, Null, boost::uint64_t > Variant
Config::Array_type Array
const Object & get_obj() const
static const Value_impl null
Config::Object_type Object
const Array & get_array() const
const String_type & get_str() const
String_type::const_pointer Const_str_ptr
void check_type(const Value_type vtype) const
bool operator==(const Value_impl &lhs) const
Value_type type() const
boost::int64_t get_int64() const
@ Value
static constexpr bool value
Definition: json.hpp:87
int get_value(const Value &value, Type_to_type< int >)
bool get_value(const Value &value, Type_to_type< bool >)
mConfig::Object_type mObject
Config_map< std::string > mConfig
mConfig::Value_type mValue
String_type to_str(const char *c_str)
mConfig::Array_type mArray
bool operator==(const Null &, const Null &)
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:8688
Value_impl< Config_map > Value_type
std::vector< Value_type > Array_type
std::map< String_type, Value_type > Object_type
static String_type get_name(const Pair_type &pair)
std::pair< String_type, Value_type > Pair_type
static Value_type get_value(const Pair_type &pair)
static Value_type & add(Object_type &obj, const String_type &name, const Value_type &value)
bool operator==(const Pair_impl &lhs) const
Config::String_type String_type
Config::Value_type Value_type