A toolkit for working with phylogenetic data.
v0.18.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
json/document.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_FORMATS_JSON_DOCUMENT_H_
2 #define GENESIS_UTILS_FORMATS_JSON_DOCUMENT_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2017 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
27 /*
28  The code in this and the following source files is a heavily altered adaption of the excellent
29  "JSON for Modern C++" library by Niels Lohmann, see https://github.com/nlohmann/json
30 
31  * lib/utils/formats/json/document.hpp
32  * lib/utils/formats/json/document.cpp
33  * lib/utils/formats/json/iterator.hpp
34 
35  We adapted the original code by splitting it into different classes, using our naming convention
36  and name spaces, removed not needed functionality and wrote our own reading/parsing routines.
37 
38  For the files listed above, we need to include the following original license:
39 
40  MIT License
41 
42  Copyright (c) 2013-2017 Niels Lohmann
43 
44  Permission is hereby granted, free of charge, to any person obtaining a copy
45  of this software and associated documentation files (the "Software"), to deal
46  in the Software without restriction, including without limitation the rights
47  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48  copies of the Software, and to permit persons to whom the Software is
49  furnished to do so, subject to the following conditions:
50 
51  The above copyright notice and this permission notice shall be included in all
52  copies or substantial portions of the Software.
53 
54  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
60  SOFTWARE.
61  */
62 
70 #include <cassert>
71 #include <cmath>
72 #include <cstdint>
73 #include <limits>
74 #include <stdexcept>
75 #include <string>
76 #include <map>
77 #include <memory>
78 #include <vector>
79 
80 namespace genesis {
81 namespace utils {
82 
83 // =================================================================================================
84 // Forward Declarations
85 // =================================================================================================
86 
87 template<typename U>
89 
90 class JsonDocument;
91 
92 bool operator==(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
93 bool operator==(JsonDocument const& v, std::nullptr_t) noexcept;
94 bool operator==(std::nullptr_t, JsonDocument const& v) noexcept;
95 bool operator!=(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
96 bool operator!=(JsonDocument const& v, std::nullptr_t) noexcept;
97 bool operator!=(std::nullptr_t, JsonDocument const& v) noexcept;
98 bool operator<(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
99 bool operator<=(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
100 bool operator>(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
101 bool operator>=(JsonDocument const& lhs, JsonDocument const& rhs) noexcept;
102 
103 // =================================================================================================
104 // JsonValue
105 // =================================================================================================
106 
115 {
116  // ---------------------------------------------------------------------------------------------
117  // Friends and Asserts
118  // ---------------------------------------------------------------------------------------------
119 
120  friend class JsonIterator<JsonDocument>;
121  friend class JsonIterator<JsonDocument const>;
122 
123 public:
124 
125  // ---------------------------------------------------------------------------------------------
126  // Tyepdefs and Enums
127  // ---------------------------------------------------------------------------------------------
128 
129  using value_type = JsonDocument;
130  using reference = JsonDocument&;
131  using const_reference = JsonDocument const&;
132 
133  using pointer = JsonDocument*;
134  using const_pointer = JsonDocument const*;
135 
138 
139  using difference_type = std::ptrdiff_t;
140  using size_type = std::size_t;
141 
142  using ArrayType = std::vector< JsonDocument >;
143  using ObjectType = std::map< std::string, JsonDocument >;
144  using StringType = std::string;
145 
146  using BooleanType = bool;
147  using NumberFloatType = double;
148  using NumberSignedType = std::int64_t;
149  using NumberUnsignedType = std::uint64_t;
150 
151  enum class ValueType : uint8_t
152  {
153  kNull,
154 
155  kArray,
156  kObject,
157  kString,
158 
159  kBoolean,
160  kNumberFloat,
161  kNumberSigned,
162  kNumberUnsigned
163  };
164 
165  // ---------------------------------------------------------------------------------------------
166  // Value Union
167  // ---------------------------------------------------------------------------------------------
168 
169 private:
170 
171  union ValueUnion
172  {
173  ArrayType* array;
174  ObjectType* object;
175  StringType* string;
176 
177  BooleanType boolean;
178  NumberFloatType number_float;
179  NumberSignedType number_signed;
180  NumberUnsignedType number_unsigned;
181 
182  ValueUnion() = default;
183 
184  ValueUnion( ValueType t )
185  {
186  switch( t ) {
187  case ValueType::kNull: {
188  break;
189  }
190  case ValueType::kArray: {
191  array = create<ArrayType>();
192  break;
193  }
194  case ValueType::kObject: {
195  object = create<ObjectType>();
196  break;
197  }
198  case ValueType::kString: {
199  string = create<StringType>("");
200  break;
201  }
202  case ValueType::kBoolean: {
203  boolean = false;
204  break;
205  }
206  case ValueType::kNumberFloat: {
207  number_float = 0.0;
208  break;
209  }
210  case ValueType::kNumberSigned: {
211  number_signed = 0;
212  break;
213  }
214  case ValueType::kNumberUnsigned: {
215  number_unsigned = 0;
216  break;
217  }
218  default: {
219  throw std::runtime_error( "Invalid Json Value Type." );
220  }
221  }
222  }
223 
224  ValueUnion( ArrayType const&v )
225  : array( create<ArrayType>(v) )
226  {}
227 
228  ValueUnion( ObjectType const& v )
229  : object( create<ObjectType>(v) )
230  {}
231 
232  ValueUnion( StringType const& v )
233  : string( create<StringType>(v) )
234  {}
235 
236  ValueUnion( BooleanType v )
237  : boolean(v)
238  {}
239 
240  ValueUnion( NumberFloatType v )
241  : number_float(v)
242  {}
243 
244  ValueUnion( NumberSignedType v )
245  : number_signed(v)
246  {}
247 
248  ValueUnion( NumberUnsignedType v )
249  : number_unsigned(v)
250  {}
251  };
252 
253  // ---------------------------------------------------------------------------------------------
254  // Constructors and and Rule of Five
255  // ---------------------------------------------------------------------------------------------
256 
257 public:
258 
259  // -------------------------------------------------------------------------
260  // Basic Constructors
261  // -------------------------------------------------------------------------
262 
269  JsonDocument( std::nullptr_t = nullptr )
270  : JsonDocument( ValueType::kNull )
271  {
272  assert_invariant();
273  }
274 
279  // We use the ValueUnion( ValueType t ) constructor to init the value according to type.
280  : type_( type )
281  , value_( type )
282  {
283  assert_invariant();
284  }
285 
290  : type_( ValueType::kArray )
291  , value_( v )
292  {
293  assert_invariant();
294  }
295 
300  : type_( ValueType::kObject )
301  , value_( v )
302  {
303  assert_invariant();
304  }
305 
310  : type_( ValueType::kString )
311  , value_( v )
312  {
313  assert_invariant();
314  }
315 
319  JsonDocument( typename StringType::value_type const* v )
320  : type_( ValueType::kString )
321  , value_( StringType(v) )
322  {
323  assert_invariant();
324  }
325 
330  : type_( ValueType::kBoolean )
331  , value_( v )
332  {
333  assert_invariant();
334  }
335 
339  template<typename T, typename std::enable_if<
340  not (std::is_same<T, int>::value) and
341  std::is_same<T, NumberSignedType>::value,
342  int>::type = 0>
343  JsonDocument(const NumberSignedType val)
344  : type_(ValueType::kNumberSigned)
345  , value_(val)
346  {
347  assert_invariant();
348  }
349 
353  JsonDocument( int const val )
354  : type_(ValueType::kNumberSigned)
355  , value_( static_cast<NumberSignedType>(val) )
356  {
357  assert_invariant();
358  }
359 
363  template<typename T, typename std::enable_if<
364  not (std::is_same<T, int>::value) and
365  std::is_same<T, NumberUnsignedType>::value,
366  int>::type = 0>
367  JsonDocument(const NumberUnsignedType val) noexcept
368  : type_(ValueType::kNumberUnsigned), value_(val)
369  {
370  assert_invariant();
371  }
372 
382  : type_( ValueType::kNumberFloat )
383  , value_( val )
384  {
385  // replace infinity and NAN by null
386  if( not std::isfinite(val) ) {
387  type_ = ValueType::kNull;
388  value_ = ValueUnion();
389  }
390 
391  assert_invariant();
392  }
393 
394  // -------------------------------------------------------------------------
395  // Advanced Constructors
396  // -------------------------------------------------------------------------
397 
401  JsonDocument(
402  std::initializer_list<JsonDocument> init,
403  bool type_deduction = true,
404  ValueType manual_type = ValueType::kArray
405  );
406 
410  JsonDocument( size_t n, JsonDocument const& val )
411  : type_( ValueType::kArray )
412  {
413  value_.array = create<ArrayType>( n, val );
414  assert_invariant();
415  }
416 
417  template<
418  class CompatibleArrayTypeT, typename std::enable_if<
419  not std::is_same<CompatibleArrayTypeT, typename JsonDocument::iterator>::value and
420  not std::is_same<CompatibleArrayTypeT, typename JsonDocument::const_iterator>::value and
421  // not std::is_same<CompatibleArrayTypeT, typename JsonDocument_t::reverse_iterator>::value and
422  // not std::is_same<CompatibleArrayTypeT, typename JsonDocument_t::const_reverse_iterator>::value and
423  not std::is_same<CompatibleArrayTypeT, typename ArrayType::iterator>::value and
424  not std::is_same<CompatibleArrayTypeT, typename ArrayType::const_iterator>::value and
425  std::is_constructible<JsonDocument, typename CompatibleArrayTypeT::value_type>::value, int>::type = 0
426  >
427  JsonDocument(const CompatibleArrayTypeT& val)
428  : type_(ValueType::kArray)
429  {
430  using std::begin;
431  using std::end;
432  value_.array = create<ArrayType>(begin(val), end(val));
433  assert_invariant();
434  }
435 
442  template<class CompatibleObjectType,
443  typename std::enable_if<
444  std::is_constructible<
445  typename ObjectType::key_type, typename CompatibleObjectType::key_type
446  >::value and
447  std::is_constructible<
448  JsonDocument, typename CompatibleObjectType::mapped_type
449  >::value,
450  int
451  >::type = 0
452  >
453  JsonDocument( CompatibleObjectType const& val )
454  : type_( ValueType::kObject )
455  {
456  using std::begin;
457  using std::end;
458  value_.object = create<ObjectType>( begin(val), end(val) );
459  assert_invariant();
460  }
461 
468  template<class CompatibleStringType, typename std::enable_if<
469  std::is_constructible<StringType, CompatibleStringType>::value, int>::type = 0
470  >
471  JsonDocument(const CompatibleStringType& val)
472  : JsonDocument( StringType(val) )
473  {
474  assert_invariant();
475  }
476 
477  // -------------------------------------------------------------------------
478  // Rule of Five
479  // -------------------------------------------------------------------------
480 
484  JsonDocument( JsonDocument const& other );
485 
489  JsonDocument( JsonDocument&& other );
490 
494  JsonDocument& operator = ( JsonDocument other );
495 
499  ~JsonDocument();
500 
501  // -------------------------------------------------------------------------
502  // Factory Method Construction
503  // -------------------------------------------------------------------------
504 
508  static JsonDocument array(
509  std::initializer_list<JsonDocument> init = std::initializer_list<JsonDocument>()
510  ) {
511  return JsonDocument( init, false, ValueType::kArray );
512  }
513 
517  static JsonDocument object(
518  std::initializer_list<JsonDocument> init = std::initializer_list<JsonDocument>()
519  ) {
520  return JsonDocument( init, false, ValueType::kObject );
521  }
522 
526  static JsonDocument string(
527  std::string const& init
528  ) {
529  return JsonDocument( init );
530  }
531 
535  static JsonDocument boolean(
536  BooleanType value
537  ) {
538  auto result = JsonDocument( ValueType::kBoolean );
539  result.value_ = value;
540  return result;
541  }
542 
546  static JsonDocument number_float(
547  NumberFloatType value
548  ) {
549  auto result = JsonDocument( ValueType::kNumberFloat );
550  result.value_ = value;
551  return result;
552  }
553 
557  static JsonDocument number_signed(
558  NumberSignedType value
559  ) {
560  auto result = JsonDocument( ValueType::kNumberSigned );
561  result.value_ = value;
562  return result;
563  }
564 
568  static JsonDocument number_unsigned(
569  NumberUnsignedType value
570  ) {
571  auto result = JsonDocument( ValueType::kNumberUnsigned );
572  result.value_ = value;
573  return result;
574  }
575 
576  // ---------------------------------------------------------------------------------------------
577  // Type Inspection
578  // ---------------------------------------------------------------------------------------------
579 
580 public:
581 
585  ValueType type() const
586  {
587  return type_;
588  }
589 
593  bool is_primitive() const
594  {
595  return is_null() or is_string() or is_boolean() or is_number();
596  }
597 
601  bool is_structured() const
602  {
603  return is_array() or is_object();
604  }
605 
609  bool is_null() const
610  {
611  return type_ == ValueType::kNull;
612  }
613 
617  bool is_array() const
618  {
619  return type_ == ValueType::kArray;
620  }
621 
625  bool is_object() const
626  {
627  return type_ == ValueType::kObject;
628  }
629 
633  bool is_string() const
634  {
635  return type_ == ValueType::kString;
636  }
637 
641  bool is_boolean() const
642  {
643  return type_ == ValueType::kBoolean;
644  }
645 
650  bool is_number() const
651  {
652  return is_number_float() or is_number_integer();
653  }
654 
658  bool is_number_float() const
659  {
660  return type_ == ValueType::kNumberFloat;
661  }
662 
666  bool is_number_integer() const
667  {
668  return is_number_signed() or is_number_unsigned();
669  }
670 
674  bool is_number_signed() const
675  {
676  return type_ == ValueType::kNumberSigned;
677  }
678 
682  bool is_number_unsigned() const
683  {
684  return type_ == ValueType::kNumberUnsigned;
685  }
686 
687  // ---------------------------------------------------------------------------------------------
688  // Capacity
689  // ---------------------------------------------------------------------------------------------
690 
691 public:
692 
693  bool empty() const;
694  size_t size() const;
695  size_t max_size() const;
696 
697  // ---------------------------------------------------------------------------------------------
698  // Value Access
699  // ---------------------------------------------------------------------------------------------
700 
701 public:
702 
703  ArrayType& get_array();
704  ArrayType const& get_array() const;
705 
706  ObjectType& get_object();
707  ObjectType const& get_object() const;
708 
709  StringType& get_string();
710  StringType const& get_string() const;
711 
712  BooleanType& get_boolean();
713  BooleanType get_boolean() const;
714 
715  NumberFloatType& get_number_float();
716  NumberFloatType get_number_float() const;
717 
718  NumberSignedType& get_number_signed();
719  NumberSignedType get_number_signed() const;
720 
721  NumberUnsignedType& get_number_unsigned();
722  NumberUnsignedType get_number_unsigned() const;
723 
724  template<typename T>
725  T get_number() const
726  {
727  if( is_number_float() ) {
728  return value_.number_float;
729  } else if( is_number_signed() ) {
730  return value_.number_signed;
731  } else if( is_number_unsigned() ) {
732  return value_.number_unsigned;
733  } else {
734  throw std::domain_error( "Cannot use get_number<T>() with " + type_name() + "." );
735  }
736  }
737 
738  // ---------------------------------------------------------------------------------------------
739  // Element Access
740  // ---------------------------------------------------------------------------------------------
741 
742 public:
743 
744  JsonDocument& at( size_t index );
745  JsonDocument const& at( size_t index ) const;
746 
747  JsonDocument& at( typename ObjectType::key_type const& key );
748  JsonDocument const& at( typename ObjectType::key_type const& key ) const;
749 
750  JsonDocument& operator [] ( size_t index );
751  JsonDocument const& operator [] ( size_t index ) const;
752 
753  JsonDocument& operator [] ( typename ObjectType::key_type const& key );
754  JsonDocument const& operator [] ( typename ObjectType::key_type const& key ) const;
755 
756  // ---------------------------------------------------------------------------------------------
757  // Lookup
758  // ---------------------------------------------------------------------------------------------
759 
766  iterator find( typename JsonDocument::ObjectType::key_type key );
767 
771  const_iterator find(typename JsonDocument::ObjectType::key_type key) const;
772 
779  size_type count(typename ObjectType::key_type key) const;
780 
781  // ---------------------------------------------------------------------------------------------
782  // Iterators
783  // ---------------------------------------------------------------------------------------------
784 
785 public:
786 
790  iterator begin() noexcept;
791 
795  const_iterator begin() const noexcept;
796 
800  const_iterator cbegin() const noexcept;
801 
805  iterator end() noexcept;
806 
810  const_iterator end() const noexcept;
811 
815  const_iterator cend() const noexcept;
816 
817  // ---------------------------------------------------------------------------------------------
818  // Modifiers
819  // ---------------------------------------------------------------------------------------------
820 
821 public:
822 
840  void clear();
841 
849  void push_back( JsonDocument&& val );
850 
854  void push_back( JsonDocument const& val );
855 
862  void push_back( typename ObjectType::value_type const& val );
863 
864  template<class... Args>
865  void emplace_back( Args&& ... args )
866  {
867  // emplace_back only works for null objects or arrays
868  if( not(is_null() or is_array()) ) {
869  throw std::domain_error("Cannot use emplace_back() with " + type_name());
870  }
871 
872  // transform null object into an array
873  if( is_null() ) {
874  type_ = ValueType::kArray;
875  value_ = ValueType::kArray;
876  assert_invariant();
877  }
878 
879  // add element to array (perfect forwarding)
880  value_.array->emplace_back( std::forward<Args>(args)... );
881  }
882 
883  // ---------------------------------------------------------------------------------------------
884  // Lexicographical Comparison Operators
885  // ---------------------------------------------------------------------------------------------
886 
887 public:
888 
902  friend bool operator==(const_reference lhs, const_reference rhs) noexcept;
903 
911  friend bool operator==(const_reference v, std::nullptr_t) noexcept
912  {
913  return v.is_null();
914  }
915 
919  friend bool operator==(std::nullptr_t, const_reference v) noexcept
920  {
921  return v.is_null();
922  }
923 
929  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
930  {
931  return not (lhs == rhs);
932  }
933 
939  friend bool operator!=(const_reference v, std::nullptr_t) noexcept
940  {
941  return not v.is_null();
942  }
943 
949  friend bool operator!=(std::nullptr_t, const_reference v) noexcept
950  {
951  return not v.is_null();
952  }
953 
967  friend bool operator<(const_reference lhs, const_reference rhs) noexcept;
968 
975  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
976  {
977  return not (rhs < lhs);
978  }
979 
986  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
987  {
988  return not (lhs <= rhs);
989  }
990 
997  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
998  {
999  return not (lhs < rhs);
1000  }
1001 
1002 private:
1003 
1012  friend bool operator<(const ValueType lhs, const ValueType rhs) noexcept;
1013 
1014  // ---------------------------------------------------------------------------------------------
1015  // Convenience Functions
1016  // ---------------------------------------------------------------------------------------------
1017 
1018 public:
1019 
1020  std::string type_name() const;
1021 
1022  // ---------------------------------------------------------------------------------------------
1023  // Helper Functions
1024  // ---------------------------------------------------------------------------------------------
1025 
1026 private:
1027 
1031  template<typename T, typename... Args>
1032  static T* create( Args&& ... args )
1033  {
1034  // Avoid memory leaks.
1035  std::allocator<T> alloc;
1036  auto deleter = [&](T * object)
1037  {
1038  alloc.deallocate(object, 1);
1039  };
1040  std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1041  alloc.construct(object.get(), std::forward<Args>(args)...);
1042  assert(object != nullptr);
1043  return object.release();
1044 
1045  // auto object = new T(std::forward<Args>(args)...);
1046  // assert( object != nullptr );
1047  // return object;
1048  }
1049 
1050  template<typename T>
1051  static void destroy( T* ptr )
1052  {
1053  std::allocator<T> alloc;
1054  alloc.destroy(ptr);
1055  alloc.deallocate(ptr, 1);
1056 
1057  // delete ptr;
1058  }
1059 
1060  void assert_invariant() const
1061  {
1062  assert( type_ != ValueType::kArray or value_.array != nullptr );
1063  assert( type_ != ValueType::kObject or value_.object != nullptr );
1064  assert( type_ != ValueType::kString or value_.string != nullptr );
1065  }
1066 
1067  // ---------------------------------------------------------------------------------------------
1068  // Data Members
1069  // ---------------------------------------------------------------------------------------------
1070 
1071 private:
1072 
1073  ValueType type_ = ValueType::kNull;
1074  ValueUnion value_ = {};
1075 
1076 };
1077 
1078 } // namespace utils
1079 } // namespace genesis
1080 
1081 #endif // include guard
JsonDocument(StringType const &v)
Create a string, explicitly.
bool is_number_float() const
Return true iff the JSON value is a float number.
JsonDocument(const NumberFloatType val)
Create a floating-point number (explicit).
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
Compare less than or equal.
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
Compare not equal.
static JsonDocument number_signed(NumberSignedType value)
Explicitly create a signed number.
bool is_array() const
Return true iff the JSON value is an array.
static JsonDocument array(std::initializer_list< JsonDocument > init=std::initializer_list< JsonDocument >())
Explicitly create an array from an initializer list.
friend bool operator==(const_reference v, std::nullptr_t) noexcept
Compare equal.
bool is_boolean() const
Return true iff the JSON value is a boolean.
bool operator<(JsonDocument::const_reference lhs, JsonDocument::const_reference rhs) noexcept
JsonDocument(ArrayType const &v)
Create an array, explicitly.
JsonDocument const * const_pointer
bool is_number() const
Return true iff the JSON value is a number, i.e., a float or signed or unsigned integer.
JsonDocument(const CompatibleStringType &val)
Create a string (implicit).
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
Compare greater than or equal.
JsonDocument(const CompatibleArrayTypeT &val)
bool is_null() const
Return true iff the JSON value is null.
bool is_structured() const
Return true iff the JSON type is structured (array or object).
std::map< std::string, JsonDocument > ObjectType
JsonDocument(BooleanType v)
Create a boolean, explicitly.
static JsonDocument object(std::initializer_list< JsonDocument > init=std::initializer_list< JsonDocument >())
Explicitly create an object from an initializer list.
JsonDocument(CompatibleObjectType const &val)
Create an object (implicit).
JsonDocument(int const val)
Create a signed integer number from an enum type (explicit).
JsonDocument(ObjectType const &v)
Create an object, explicitly.
bool is_number_unsigned() const
Return true iff the JSON value is an unsigned integer number.
friend bool operator==(std::nullptr_t, const_reference v) noexcept
Compare equal.
bool is_string() const
Return true iff the JSON value is a string.
static JsonDocument boolean(BooleanType value)
Explicitly create a boolean.
JsonDocument(size_t n, JsonDocument const &val)
Construct an array with n many copies of val.
JsonDocument(typename StringType::value_type const *v)
Create a string, explicitly, using a char pointer.
static JsonDocument string(std::string const &init)
Explicitly create a string.
ValueType type() const
Return the type of the JSON value.
bool is_number_integer() const
Return true iff the JSON value is a signed or unsigned integer number.
JsonDocument(std::nullptr_t=nullptr)
Create a null object.
bool is_number_signed() const
Return true iff the JSON value is a signed integer number.
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
Compare greater than.
Store a Json value of any kind.
std::vector< JsonDocument > ArrayType
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
Compare not equal.
bool operator==(SortedVector< T > const &lhs, SortedVector< T > const &rhs)
bool is_primitive() const
Return true iff the JSON type is primitive (string, number, boolean, or null).
Template for a random access iterator for the JsonDocument class.
static JsonDocument number_unsigned(NumberUnsignedType value)
Explicitly create an unsigned number.
JsonDocument(ValueType type)
Create an empty value of the given type.
bool is_object() const
Return true iff the JSON value is an object.
JsonDocument const & const_reference
static JsonDocument number_float(NumberFloatType value)
Explicitly create a float number.
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
Compare not equal.