87 std::initializer_list<JsonDocument> init,
93 bool is_an_object = std::all_of(
97 return element.is_array() and element.size() == 2 and element[0].is_string();
102 if( not type_deduction ) {
105 is_an_object =
false;
110 throw std::domain_error(
"Invalid initializer list for creating Json object ." );
123 value_.object->emplace( *(element[0].value_.string), element[1] );
130 value_.array = create<ArrayType>( init );
141 : type_( other.type_ )
144 other.assert_invariant();
148 value_ = *other.value_.object;
152 value_ = *other.value_.array;
156 value_ = *other.value_.string;
160 value_ = other.value_.boolean;
164 value_ = other.value_.number_float;
168 value_ = other.value_.number_signed;
172 value_ = other.value_.number_unsigned;
188 : type_(
std::move( other.type_ ))
189 , value_(
std::move( other.value_ ))
192 other.assert_invariant();
208 other.assert_invariant();
212 swap( type_, other.type_ );
213 swap( value_, other.value_ );
229 destroy<ArrayType>( value_.array );
233 destroy<ObjectType>( value_.object );
237 destroy<StringType>( value_.string );
260 return value_.array->empty();
264 return value_.object->empty();
282 return value_.array->size();
286 return value_.object->size();
300 return value_.array->max_size();
304 return value_.object->max_size();
320 throw std::domain_error(
"Cannot use get_array() with " +
type_name() +
"." );
322 return *value_.array;
328 throw std::domain_error(
"Cannot use get_array() with " +
type_name() +
"." );
330 return *value_.array;
336 throw std::domain_error(
"Cannot use get_object() with " +
type_name() +
"." );
338 return *value_.object;
344 throw std::domain_error(
"Cannot use get_object() with " +
type_name() +
"." );
346 return *value_.object;
352 throw std::domain_error(
"Cannot use get_string() with " +
type_name() +
"." );
354 return *value_.string;
360 throw std::domain_error(
"Cannot use get_string() with " +
type_name() +
"." );
362 return *value_.string;
368 throw std::domain_error(
"Cannot use get_boolean() with " +
type_name() +
"." );
370 return value_.boolean;
376 throw std::domain_error(
"Cannot use get_boolean() with " +
type_name() +
"." );
378 return value_.boolean;
384 throw std::domain_error(
"Cannot use get_number_float() with " +
type_name() +
"." );
386 return value_.number_float;
392 throw std::domain_error(
"Cannot use get_number_float() with " +
type_name() +
"." );
394 return value_.number_float;
400 throw std::domain_error(
"Cannot use get_number_signed() with " +
type_name() +
"." );
402 return value_.number_signed;
408 throw std::domain_error(
"Cannot use get_number_signed() with " +
type_name() +
"." );
410 return value_.number_signed;
416 throw std::domain_error(
"Cannot use get_number_unsigned() with " +
type_name() +
"." );
418 return value_.number_unsigned;
424 throw std::domain_error(
"Cannot use get_number_unsigned() with " +
type_name() +
"." );
426 return value_.number_unsigned;
438 return value_.array->at( index );
440 throw std::out_of_range(
445 throw std::domain_error(
"Cannot use at() with " +
type_name() );
454 return value_.array->at( index );
456 throw std::out_of_range(
461 throw std::domain_error(
"Cannot use at() with " +
type_name() );
470 return value_.object->at( key );
472 throw std::out_of_range(
473 "Invalid key '" + key +
"' for object access." 477 throw std::domain_error(
"Cannot use at() with " +
type_name() );
486 return value_.object->at( key );
488 throw std::out_of_range(
489 "Invalid key '" + key +
"' for object access." 493 throw std::domain_error(
"Cannot use at() with " +
type_name() );
502 value_.array = create<ArrayType>();
508 if( index >= value_.array->size() ) {
509 value_.array->insert(
511 index - value_.array->size() + 1,
516 return value_.array->operator[]( index );
518 throw std::domain_error(
"Cannot use operator[] with " +
type_name() );
525 return value_.array->operator[]( index );
527 throw std::domain_error(
"Cannot use operator[] with " +
type_name() );
536 value_.object = create<ObjectType>();
542 return value_.object->operator[]( key );
544 throw std::domain_error(
"Cannot use operator[] with " +
type_name() );
552 assert(value_.object->find(key) != value_.object->end());
553 return value_.object->find(key)->second;
555 throw std::domain_error(
"Cannot use operator[] with " +
type_name() );
567 result.iterator_.object_iterator = value_.object->find(key);
574 auto result =
cend();
576 result.iterator_.object_iterator = value_.object->find(key);
584 return is_object() ? value_.object->count(key) : 0;
637 value_.number_signed = 0;
641 value_.number_unsigned = 0;
645 value_.number_float = 0.0;
649 value_.boolean =
false;
653 value_.string->clear();
657 value_.array->clear();
661 value_.object->clear();
674 throw std::domain_error(
"Cannot use push_back() with " +
type_name());
685 value_.array->push_back(std::move(val));
694 throw std::domain_error(
"cannot use push_back() with " +
type_name());
705 value_.array->push_back(val);
712 throw std::domain_error(
"Cannot use push_back() with " +
type_name());
723 value_.object->insert(val);
732 const auto lhs_type = lhs.type();
733 const auto rhs_type = rhs.type();
740 if( lhs_type == rhs_type ) {
743 return *lhs.value_.array == *rhs.value_.array;
746 return *lhs.value_.object == *rhs.value_.object;
752 return *lhs.value_.string == *rhs.value_.string;
755 return lhs.value_.boolean == rhs.value_.boolean;
758 return lhs.value_.number_signed == rhs.value_.number_signed;
761 return lhs.value_.number_unsigned == rhs.value_.number_unsigned;
764 return lhs.value_.number_float == rhs.value_.number_float;
772 return static_cast<NumberFloatType>(lhs.value_.number_signed) == rhs.value_.number_float;
775 return lhs.value_.number_float ==
static_cast<NumberFloatType>(rhs.value_.number_signed);
778 return static_cast<NumberFloatType>(lhs.value_.number_unsigned) == rhs.value_.number_float;
781 return lhs.value_.number_float ==
static_cast<NumberFloatType>(rhs.value_.number_unsigned);
784 return static_cast<NumberSignedType>(lhs.value_.number_unsigned) == rhs.value_.number_signed;
787 return lhs.value_.number_signed ==
static_cast<NumberSignedType>(rhs.value_.number_unsigned);
795 const auto lhs_type = lhs.type();
796 const auto rhs_type = rhs.type();
803 if( lhs_type == rhs_type ) {
806 return *lhs.value_.array < *rhs.value_.array;
809 return *lhs.value_.object < *rhs.value_.object;
815 return *lhs.value_.string < *rhs.value_.string;
818 return lhs.value_.boolean < rhs.value_.boolean;
821 return lhs.value_.number_signed < rhs.value_.number_signed;
824 return lhs.value_.number_unsigned < rhs.value_.number_unsigned;
827 return lhs.value_.number_float < rhs.value_.number_float;
835 return static_cast<NumberFloatType>(lhs.value_.number_signed) < rhs.value_.number_float;
838 return lhs.value_.number_float <
static_cast<NumberFloatType>(rhs.value_.number_signed);
841 return static_cast<NumberFloatType>(lhs.value_.number_unsigned) < rhs.value_.number_float;
844 return lhs.value_.number_float <
static_cast<NumberFloatType>(rhs.value_.number_unsigned);
847 return lhs.value_.number_signed <
static_cast<NumberSignedType>(rhs.value_.number_unsigned);
850 return static_cast<NumberSignedType>(lhs.value_.number_unsigned) < rhs.value_.number_signed;
862 static std::array<uint8_t, 8> order = {{
873 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
902 return "signed integer";
905 return "unsigned integer";
911 return "invalid type";
bool is_boolean() const
Return true iff the JSON value is a boolean.
void push_back(JsonDocument &&val)
Add a Json value to an array.
void clear()
Clears the content of a JSON value and resets it to the default value as if JsonDocument(ValueType) w...
JsonDocument & at(size_t index)
bool is_number_signed() const
Return true iff the JSON value is a signed integer number.
JsonDocument & operator[](size_t index)
std::uint64_t NumberUnsignedType
void swap(SequenceSet &lhs, SequenceSet &rhs)
bool is_string() const
Return true iff the JSON value is a string.
const_iterator cend() const
Return a const iterator to one past the last element.
ObjectType & get_object()
JsonDocument & operator=(JsonDocument other)
Copy assignment.
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
std::map< std::string, JsonDocument > ObjectType
bool is_object() const
Return true iff the JSON value is an object.
std::int64_t NumberSignedType
friend bool operator<(const_reference lhs, const_reference rhs)
Compare less than.
void swap(NexusTaxa &lhs, NexusTaxa &rhs)
NumberFloatType & get_number_float()
iterator begin()
Return an iterator to the first element.
const_iterator cbegin() const
Return a const iterator to the first element.
NumberUnsignedType & get_number_unsigned()
size_type count(typename ObjectType::key_type key) const
Return the number of occurrences of a key in a JSON object.
friend bool operator==(const_reference lhs, const_reference rhs)
Compare equal.
JsonDocument(std::nullptr_t=nullptr)
Create a null object.
StringType & get_string()
BooleanType & get_boolean()
iterator find(typename JsonDocument::ObjectType::key_type key)
Find an element in a JSON object.
Provides easy and fast logging functionality.
iterator end()
Return an iterator to one past the last element.
Store a Json value of any kind.
std::vector< JsonDocument > ArrayType
Template for a random access iterator for the JsonDocument class.
NumberSignedType & get_number_signed()
std::shared_ptr< BaseOutputTarget > to_string(std::string &target_string)
Obtain an output target for writing to a string.
bool is_number_unsigned() const
Return true iff the JSON value is an unsigned integer number.
bool is_null() const
Return true iff the JSON value is null.
std::string type_name() const
bool is_number_float() const
Return true iff the JSON value is a float number.
JsonDocument const & const_reference
~JsonDocument()
Destructor.
bool is_array() const
Return true iff the JSON value is an array.