added assertions (#168)
This commit is contained in:
		
							parent
							
								
									d27c8a8ea8
								
							
						
					
					
						commit
						4a452f11f9
					
				
					 2 changed files with 318 additions and 4 deletions
				
			
		
							
								
								
									
										161
									
								
								src/json.hpp
									
										
									
									
									
								
							
							
						
						
									
										161
									
								
								src/json.hpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -40,6 +40,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation.
 | 
			
		|||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <ciso646>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
| 
						 | 
				
			
			@ -1417,6 +1418,8 @@ class basic_json
 | 
			
		|||
            m_type = value_t::object;
 | 
			
		||||
            m_value = value_t::object;
 | 
			
		||||
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
 | 
			
		||||
            for (auto& element : init)
 | 
			
		||||
            {
 | 
			
		||||
                m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
 | 
			
		||||
| 
						 | 
				
			
			@ -1607,24 +1610,28 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::number_integer:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.number_integer = first.m_object->m_value.number_integer;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::number_float:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.number_float = first.m_object->m_value.number_float;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::boolean:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.boolean = first.m_object->m_value.boolean;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value = *first.m_object->m_value.string;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1643,6 +1650,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            default:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1679,18 +1687,21 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.object != nullptr);
 | 
			
		||||
                m_value = *other.m_value.object;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.array != nullptr);
 | 
			
		||||
                m_value = *other.m_value.array;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.string != nullptr);
 | 
			
		||||
                m_value = *other.m_value.string;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2166,6 +2177,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return T(m_value.object->begin(), m_value.object->end());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2179,6 +2191,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return *(m_value.object);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2201,6 +2214,7 @@ class basic_json
 | 
			
		|||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            T to_vector;
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            std::transform(m_value.array->begin(), m_value.array->end(),
 | 
			
		||||
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -2225,6 +2239,7 @@ class basic_json
 | 
			
		|||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<T> to_vector;
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            to_vector.reserve(m_value.array->size());
 | 
			
		||||
            std::transform(m_value.array->begin(), m_value.array->end(),
 | 
			
		||||
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 | 
			
		||||
| 
						 | 
				
			
			@ -2249,6 +2264,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return T(m_value.array->begin(), m_value.array->end());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2262,6 +2278,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return *(m_value.array);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2279,6 +2296,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_string())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.string != nullptr);
 | 
			
		||||
            return *m_value.string;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2624,6 +2642,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->at(idx);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2667,6 +2686,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->at(idx);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2714,6 +2734,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->at(key);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2761,6 +2782,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->at(key);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2812,6 +2834,7 @@ class basic_json
 | 
			
		|||
        // [] only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            for (size_t i = m_value.array->size(); i <= idx; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                m_value.array->push_back(basic_json());
 | 
			
		||||
| 
						 | 
				
			
			@ -2849,6 +2872,7 @@ class basic_json
 | 
			
		|||
        // at only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return m_value.array->operator[](idx);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2896,6 +2920,7 @@ class basic_json
 | 
			
		|||
        // [] only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->operator[](key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2936,6 +2961,8 @@ class basic_json
 | 
			
		|||
        // [] only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            assert(m_value.object->find(key) != m_value.object->end());
 | 
			
		||||
            return m_value.object->find(key)->second;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2986,6 +3013,7 @@ class basic_json
 | 
			
		|||
        // at only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->operator[](key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3029,6 +3057,8 @@ class basic_json
 | 
			
		|||
        // at only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            assert(m_value.object->find(key) != m_value.object->end());
 | 
			
		||||
            return m_value.object->find(key)->second;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3275,12 +3305,14 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3378,6 +3410,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
 | 
			
		||||
                                              last.m_it.object_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3385,6 +3418,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
 | 
			
		||||
                                             last.m_it.array_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3430,6 +3464,7 @@ class basic_json
 | 
			
		|||
        // this erase only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->erase(key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3472,6 +3507,7 @@ class basic_json
 | 
			
		|||
                throw std::out_of_range("index out of range");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3503,6 +3539,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            result.m_it.object_iterator = m_value.object->find(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3519,6 +3556,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            result.m_it.object_iterator = m_value.object->find(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3546,6 +3584,7 @@ class basic_json
 | 
			
		|||
    size_type count(typename object_t::key_type key) const
 | 
			
		||||
    {
 | 
			
		||||
        // return 0 for all nonobject types
 | 
			
		||||
        assert(not is_object() or m_value.object != nullptr);
 | 
			
		||||
        return is_object() ? m_value.object->count(key) : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3864,11 +3903,13 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->empty();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->empty();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3920,11 +3961,13 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3974,11 +4017,13 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->max_size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->max_size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4049,18 +4094,21 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.string != nullptr);
 | 
			
		||||
                m_value.string->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                m_value.array->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                m_value.object->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -4108,6 +4156,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array (move semantics)
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        m_value.array->push_back(std::move(val));
 | 
			
		||||
        // invalidate object
 | 
			
		||||
        val.m_type = value_t::null;
 | 
			
		||||
| 
						 | 
				
			
			@ -4143,6 +4192,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        m_value.array->push_back(val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4192,6 +4242,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array
 | 
			
		||||
        assert(m_value.object != nullptr);
 | 
			
		||||
        m_value.object->insert(val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4240,6 +4291,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // insert to array and return iterator
 | 
			
		||||
            iterator result(this);
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -4295,6 +4347,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // insert to array and return iterator
 | 
			
		||||
            iterator result(this);
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -4360,6 +4413,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        // insert to array and return iterator
 | 
			
		||||
        iterator result(this);
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        result.m_it.array_iterator = m_value.array->insert(
 | 
			
		||||
                                         pos.m_it.array_iterator,
 | 
			
		||||
                                         first.m_it.array_iterator,
 | 
			
		||||
| 
						 | 
				
			
			@ -4407,6 +4461,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        // insert to array and return iterator
 | 
			
		||||
        iterator result(this);
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -4464,6 +4519,7 @@ class basic_json
 | 
			
		|||
        // swap only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            std::swap(*(m_value.array), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4497,6 +4553,7 @@ class basic_json
 | 
			
		|||
        // swap only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            std::swap(*(m_value.object), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4530,6 +4587,7 @@ class basic_json
 | 
			
		|||
        // swap only works for strings
 | 
			
		||||
        if (is_string())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.string != nullptr);
 | 
			
		||||
            std::swap(*(m_value.string), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4614,21 +4672,43 @@ class basic_json
 | 
			
		|||
            switch (lhs_type)
 | 
			
		||||
            {
 | 
			
		||||
                case value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.array != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.array != nullptr);
 | 
			
		||||
                    return *lhs.m_value.array == *rhs.m_value.array;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.object != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.object != nullptr);
 | 
			
		||||
                    return *lhs.m_value.object == *rhs.m_value.object;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::null:
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::string:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.string != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.string != nullptr);
 | 
			
		||||
                    return *lhs.m_value.string == *rhs.m_value.string;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::boolean:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.boolean == rhs.m_value.boolean;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_integer:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_float:
 | 
			
		||||
                {
 | 
			
		||||
                    return approx(lhs.m_value.number_float, rhs.m_value.number_float);
 | 
			
		||||
                }
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 | 
			
		||||
| 
						 | 
				
			
			@ -4763,21 +4843,43 @@ class basic_json
 | 
			
		|||
            switch (lhs_type)
 | 
			
		||||
            {
 | 
			
		||||
                case value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.array != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.array != nullptr);
 | 
			
		||||
                    return *lhs.m_value.array < *rhs.m_value.array;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.object != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.object != nullptr);
 | 
			
		||||
                    return *lhs.m_value.object < *rhs.m_value.object;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::null:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::string:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.string != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.string != nullptr);
 | 
			
		||||
                    return *lhs.m_value.string < *rhs.m_value.string;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::boolean:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.boolean < rhs.m_value.boolean;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_integer:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_integer < rhs.m_value.number_integer;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_float:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_float < rhs.m_value.number_float;
 | 
			
		||||
                }
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 | 
			
		||||
| 
						 | 
				
			
			@ -5254,6 +5356,8 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
 | 
			
		||||
                if (m_value.object->empty())
 | 
			
		||||
                {
 | 
			
		||||
                    o << "{}";
 | 
			
		||||
| 
						 | 
				
			
			@ -5294,6 +5398,8 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
 | 
			
		||||
                if (m_value.array->empty())
 | 
			
		||||
                {
 | 
			
		||||
                    o << "[]";
 | 
			
		||||
| 
						 | 
				
			
			@ -5332,6 +5438,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.string != nullptr);
 | 
			
		||||
                o << string_t("\"") << escape_string(*m_value.string) << "\"";
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -5509,6 +5616,8 @@ class basic_json
 | 
			
		|||
            /// return key of the iterator
 | 
			
		||||
            typename basic_json::string_t key() const
 | 
			
		||||
            {
 | 
			
		||||
                assert(anchor.m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
                switch (anchor.m_object->type())
 | 
			
		||||
                {
 | 
			
		||||
                    // use integer array index as key
 | 
			
		||||
| 
						 | 
				
			
			@ -5597,6 +5706,8 @@ class basic_json
 | 
			
		|||
        /// constructor for a given JSON instance
 | 
			
		||||
        const_iterator(pointer object) : m_object(object)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5622,6 +5733,8 @@ class basic_json
 | 
			
		|||
        /// copy constructor given a nonconst iterator
 | 
			
		||||
        const_iterator(const iterator& other) : m_object(other.m_object)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5666,16 +5779,20 @@ class basic_json
 | 
			
		|||
        /// set the iterator to the first value
 | 
			
		||||
        void set_begin()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object != nullptr);
 | 
			
		||||
                    m_it.object_iterator = m_object->m_value.object->begin();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array != nullptr);
 | 
			
		||||
                    m_it.array_iterator = m_object->m_value.array->begin();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -5698,16 +5815,20 @@ class basic_json
 | 
			
		|||
        /// set the iterator past the last value
 | 
			
		||||
        void set_end()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object != nullptr);
 | 
			
		||||
                    m_it.object_iterator = m_object->m_value.object->end();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array != nullptr);
 | 
			
		||||
                    m_it.array_iterator = m_object->m_value.array->end();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -5724,15 +5845,21 @@ class basic_json
 | 
			
		|||
        /// return a reference to the value pointed to by the iterator
 | 
			
		||||
        reference operator*() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object);
 | 
			
		||||
                    assert(m_it.object_iterator != m_object->m_value.object->end());
 | 
			
		||||
                    return m_it.object_iterator->second;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array);
 | 
			
		||||
                    assert(m_it.array_iterator != m_object->m_value.array->end());
 | 
			
		||||
                    return *m_it.array_iterator;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5758,15 +5885,21 @@ class basic_json
 | 
			
		|||
        /// dereference the iterator
 | 
			
		||||
        pointer operator->() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object);
 | 
			
		||||
                    assert(m_it.object_iterator != m_object->m_value.object->end());
 | 
			
		||||
                    return &(m_it.object_iterator->second);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array);
 | 
			
		||||
                    assert(m_it.array_iterator != m_object->m_value.array->end());
 | 
			
		||||
                    return &*m_it.array_iterator;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5795,6 +5928,8 @@ class basic_json
 | 
			
		|||
        /// pre-increment (++it)
 | 
			
		||||
        const_iterator& operator++()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5830,6 +5965,8 @@ class basic_json
 | 
			
		|||
        /// pre-decrement (--it)
 | 
			
		||||
        const_iterator& operator--()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5863,6 +6000,8 @@ class basic_json
 | 
			
		|||
                throw std::domain_error("cannot compare iterators of different containers");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5897,6 +6036,8 @@ class basic_json
 | 
			
		|||
                throw std::domain_error("cannot compare iterators of different containers");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5937,6 +6078,8 @@ class basic_json
 | 
			
		|||
        /// add to iterator
 | 
			
		||||
        const_iterator& operator+=(difference_type i)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5985,6 +6128,8 @@ class basic_json
 | 
			
		|||
        /// return difference
 | 
			
		||||
        difference_type operator-(const const_iterator& other) const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -6007,6 +6152,8 @@ class basic_json
 | 
			
		|||
        /// access to successor
 | 
			
		||||
        reference operator[](difference_type n) const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -6041,6 +6188,8 @@ class basic_json
 | 
			
		|||
        /// return the key of an object iterator
 | 
			
		||||
        typename object_t::key_type key() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            if (m_object->is_object())
 | 
			
		||||
            {
 | 
			
		||||
                return m_it.object_iterator->first;
 | 
			
		||||
| 
						 | 
				
			
			@ -6353,6 +6502,7 @@ class basic_json
 | 
			
		|||
            : m_stream(nullptr), m_buffer(s)
 | 
			
		||||
        {
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start = m_cursor = m_content;
 | 
			
		||||
            m_limit = m_content + s.size();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -6361,8 +6511,10 @@ class basic_json
 | 
			
		|||
        explicit lexer(std::istream* s) noexcept
 | 
			
		||||
            : m_stream(s), m_buffer()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_stream != nullptr);
 | 
			
		||||
            getline(*m_stream, m_buffer);
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start = m_cursor = m_content;
 | 
			
		||||
            m_limit = m_content + m_buffer.size();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -6511,6 +6663,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // remember the begin of the token
 | 
			
		||||
            m_start = m_cursor;
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -7302,7 +7455,7 @@ basic_json_parser_64:
 | 
			
		|||
        /// append data from the stream to the internal buffer
 | 
			
		||||
        void yyfill() noexcept
 | 
			
		||||
        {
 | 
			
		||||
            if (not m_stream or not * m_stream)
 | 
			
		||||
            if (m_stream == nullptr or not * m_stream)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -7313,10 +7466,12 @@ basic_json_parser_64:
 | 
			
		|||
 | 
			
		||||
            m_buffer.erase(0, static_cast<size_t>(offset_start));
 | 
			
		||||
            std::string line;
 | 
			
		||||
            assert(m_stream != nullptr);
 | 
			
		||||
            std::getline(*m_stream, line);
 | 
			
		||||
            m_buffer += "\n" + line; // add line with newline symbol
 | 
			
		||||
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start  = m_content;
 | 
			
		||||
            m_marker = m_start + offset_marker;
 | 
			
		||||
            m_cursor = m_start + offset_cursor;
 | 
			
		||||
| 
						 | 
				
			
			@ -7326,6 +7481,7 @@ basic_json_parser_64:
 | 
			
		|||
        /// return string representation of last read token
 | 
			
		||||
        string_t get_token() const noexcept
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
 | 
			
		||||
                            static_cast<size_t>(m_cursor - m_start));
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -7475,6 +7631,7 @@ basic_json_parser_64:
 | 
			
		|||
        {
 | 
			
		||||
            // conversion
 | 
			
		||||
            typename string_t::value_type* endptr;
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
            const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
 | 
			
		||||
                                                &endptr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -7485,7 +7642,7 @@ basic_json_parser_64:
 | 
			
		|||
 | 
			
		||||
      private:
 | 
			
		||||
        /// optional input stream
 | 
			
		||||
        std::istream* m_stream;
 | 
			
		||||
        std::istream* m_stream = nullptr;
 | 
			
		||||
        /// the buffer
 | 
			
		||||
        string_t m_buffer;
 | 
			
		||||
        /// the buffer pointer
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation.
 | 
			
		|||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <ciso646>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
| 
						 | 
				
			
			@ -1417,6 +1418,8 @@ class basic_json
 | 
			
		|||
            m_type = value_t::object;
 | 
			
		||||
            m_value = value_t::object;
 | 
			
		||||
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
 | 
			
		||||
            for (auto& element : init)
 | 
			
		||||
            {
 | 
			
		||||
                m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
 | 
			
		||||
| 
						 | 
				
			
			@ -1607,24 +1610,28 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::number_integer:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.number_integer = first.m_object->m_value.number_integer;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::number_float:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.number_float = first.m_object->m_value.number_float;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::boolean:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value.boolean = first.m_object->m_value.boolean;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                m_value = *first.m_object->m_value.string;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1643,6 +1650,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            default:
 | 
			
		||||
            {
 | 
			
		||||
                assert(first.m_object != nullptr);
 | 
			
		||||
                throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1679,18 +1687,21 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.object != nullptr);
 | 
			
		||||
                m_value = *other.m_value.object;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.array != nullptr);
 | 
			
		||||
                m_value = *other.m_value.array;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(other.m_value.string != nullptr);
 | 
			
		||||
                m_value = *other.m_value.string;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2166,6 +2177,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return T(m_value.object->begin(), m_value.object->end());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2179,6 +2191,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return *(m_value.object);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2201,6 +2214,7 @@ class basic_json
 | 
			
		|||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            T to_vector;
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            std::transform(m_value.array->begin(), m_value.array->end(),
 | 
			
		||||
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -2225,6 +2239,7 @@ class basic_json
 | 
			
		|||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<T> to_vector;
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            to_vector.reserve(m_value.array->size());
 | 
			
		||||
            std::transform(m_value.array->begin(), m_value.array->end(),
 | 
			
		||||
                           std::inserter(to_vector, to_vector.end()), [](basic_json i)
 | 
			
		||||
| 
						 | 
				
			
			@ -2249,6 +2264,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return T(m_value.array->begin(), m_value.array->end());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2262,6 +2278,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return *(m_value.array);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2279,6 +2296,7 @@ class basic_json
 | 
			
		|||
    {
 | 
			
		||||
        if (is_string())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.string != nullptr);
 | 
			
		||||
            return *m_value.string;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2624,6 +2642,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->at(idx);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2667,6 +2686,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->at(idx);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2714,6 +2734,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->at(key);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2761,6 +2782,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->at(key);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::out_of_range& e)
 | 
			
		||||
| 
						 | 
				
			
			@ -2812,6 +2834,7 @@ class basic_json
 | 
			
		|||
        // [] only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            for (size_t i = m_value.array->size(); i <= idx; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                m_value.array->push_back(basic_json());
 | 
			
		||||
| 
						 | 
				
			
			@ -2849,6 +2872,7 @@ class basic_json
 | 
			
		|||
        // at only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            return m_value.array->operator[](idx);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2896,6 +2920,7 @@ class basic_json
 | 
			
		|||
        // [] only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->operator[](key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2936,6 +2961,8 @@ class basic_json
 | 
			
		|||
        // [] only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            assert(m_value.object->find(key) != m_value.object->end());
 | 
			
		||||
            return m_value.object->find(key)->second;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2986,6 +3013,7 @@ class basic_json
 | 
			
		|||
        // at only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->operator[](key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3029,6 +3057,8 @@ class basic_json
 | 
			
		|||
        // at only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            assert(m_value.object->find(key) != m_value.object->end());
 | 
			
		||||
            return m_value.object->find(key)->second;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3275,12 +3305,14 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3378,6 +3410,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
 | 
			
		||||
                                              last.m_it.object_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3385,6 +3418,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
 | 
			
		||||
                                             last.m_it.array_iterator);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3430,6 +3464,7 @@ class basic_json
 | 
			
		|||
        // this erase only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            return m_value.object->erase(key);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3472,6 +3507,7 @@ class basic_json
 | 
			
		|||
                throw std::out_of_range("index out of range");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -3503,6 +3539,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            result.m_it.object_iterator = m_value.object->find(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3519,6 +3556,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            result.m_it.object_iterator = m_value.object->find(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3546,6 +3584,7 @@ class basic_json
 | 
			
		|||
    size_type count(typename object_t::key_type key) const
 | 
			
		||||
    {
 | 
			
		||||
        // return 0 for all nonobject types
 | 
			
		||||
        assert(not is_object() or m_value.object != nullptr);
 | 
			
		||||
        return is_object() ? m_value.object->count(key) : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3864,11 +3903,13 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->empty();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->empty();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3920,11 +3961,13 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3974,11 +4017,13 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                return m_value.array->max_size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                return m_value.object->max_size();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4049,18 +4094,21 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.string != nullptr);
 | 
			
		||||
                m_value.string->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
                m_value.array->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
                m_value.object->clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -4108,6 +4156,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array (move semantics)
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        m_value.array->push_back(std::move(val));
 | 
			
		||||
        // invalidate object
 | 
			
		||||
        val.m_type = value_t::null;
 | 
			
		||||
| 
						 | 
				
			
			@ -4143,6 +4192,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        m_value.array->push_back(val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4192,6 +4242,7 @@ class basic_json
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // add element to array
 | 
			
		||||
        assert(m_value.object != nullptr);
 | 
			
		||||
        m_value.object->insert(val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4240,6 +4291,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // insert to array and return iterator
 | 
			
		||||
            iterator result(this);
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -4295,6 +4347,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // insert to array and return iterator
 | 
			
		||||
            iterator result(this);
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -4360,6 +4413,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        // insert to array and return iterator
 | 
			
		||||
        iterator result(this);
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        result.m_it.array_iterator = m_value.array->insert(
 | 
			
		||||
                                         pos.m_it.array_iterator,
 | 
			
		||||
                                         first.m_it.array_iterator,
 | 
			
		||||
| 
						 | 
				
			
			@ -4407,6 +4461,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
        // insert to array and return iterator
 | 
			
		||||
        iterator result(this);
 | 
			
		||||
        assert(m_value.array != nullptr);
 | 
			
		||||
        result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -4464,6 +4519,7 @@ class basic_json
 | 
			
		|||
        // swap only works for arrays
 | 
			
		||||
        if (is_array())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.array != nullptr);
 | 
			
		||||
            std::swap(*(m_value.array), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4497,6 +4553,7 @@ class basic_json
 | 
			
		|||
        // swap only works for objects
 | 
			
		||||
        if (is_object())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.object != nullptr);
 | 
			
		||||
            std::swap(*(m_value.object), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4530,6 +4587,7 @@ class basic_json
 | 
			
		|||
        // swap only works for strings
 | 
			
		||||
        if (is_string())
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_value.string != nullptr);
 | 
			
		||||
            std::swap(*(m_value.string), other);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -4614,21 +4672,43 @@ class basic_json
 | 
			
		|||
            switch (lhs_type)
 | 
			
		||||
            {
 | 
			
		||||
                case value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.array != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.array != nullptr);
 | 
			
		||||
                    return *lhs.m_value.array == *rhs.m_value.array;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.object != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.object != nullptr);
 | 
			
		||||
                    return *lhs.m_value.object == *rhs.m_value.object;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::null:
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::string:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.string != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.string != nullptr);
 | 
			
		||||
                    return *lhs.m_value.string == *rhs.m_value.string;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::boolean:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.boolean == rhs.m_value.boolean;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_integer:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_float:
 | 
			
		||||
                {
 | 
			
		||||
                    return approx(lhs.m_value.number_float, rhs.m_value.number_float);
 | 
			
		||||
                }
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 | 
			
		||||
| 
						 | 
				
			
			@ -4763,21 +4843,43 @@ class basic_json
 | 
			
		|||
            switch (lhs_type)
 | 
			
		||||
            {
 | 
			
		||||
                case value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.array != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.array != nullptr);
 | 
			
		||||
                    return *lhs.m_value.array < *rhs.m_value.array;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.object != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.object != nullptr);
 | 
			
		||||
                    return *lhs.m_value.object < *rhs.m_value.object;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::null:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::string:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(lhs.m_value.string != nullptr);
 | 
			
		||||
                    assert(rhs.m_value.string != nullptr);
 | 
			
		||||
                    return *lhs.m_value.string < *rhs.m_value.string;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::boolean:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.boolean < rhs.m_value.boolean;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_integer:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_integer < rhs.m_value.number_integer;
 | 
			
		||||
                }
 | 
			
		||||
                case value_t::number_float:
 | 
			
		||||
                {
 | 
			
		||||
                    return lhs.m_value.number_float < rhs.m_value.number_float;
 | 
			
		||||
                }
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
 | 
			
		||||
| 
						 | 
				
			
			@ -5254,6 +5356,8 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            case value_t::object:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.object != nullptr);
 | 
			
		||||
 | 
			
		||||
                if (m_value.object->empty())
 | 
			
		||||
                {
 | 
			
		||||
                    o << "{}";
 | 
			
		||||
| 
						 | 
				
			
			@ -5294,6 +5398,8 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::array:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.array != nullptr);
 | 
			
		||||
 | 
			
		||||
                if (m_value.array->empty())
 | 
			
		||||
                {
 | 
			
		||||
                    o << "[]";
 | 
			
		||||
| 
						 | 
				
			
			@ -5332,6 +5438,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            case value_t::string:
 | 
			
		||||
            {
 | 
			
		||||
                assert(m_value.string != nullptr);
 | 
			
		||||
                o << string_t("\"") << escape_string(*m_value.string) << "\"";
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -5509,6 +5616,8 @@ class basic_json
 | 
			
		|||
            /// return key of the iterator
 | 
			
		||||
            typename basic_json::string_t key() const
 | 
			
		||||
            {
 | 
			
		||||
                assert(anchor.m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
                switch (anchor.m_object->type())
 | 
			
		||||
                {
 | 
			
		||||
                    // use integer array index as key
 | 
			
		||||
| 
						 | 
				
			
			@ -5597,6 +5706,8 @@ class basic_json
 | 
			
		|||
        /// constructor for a given JSON instance
 | 
			
		||||
        const_iterator(pointer object) : m_object(object)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5622,6 +5733,8 @@ class basic_json
 | 
			
		|||
        /// copy constructor given a nonconst iterator
 | 
			
		||||
        const_iterator(const iterator& other) : m_object(other.m_object)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5666,16 +5779,20 @@ class basic_json
 | 
			
		|||
        /// set the iterator to the first value
 | 
			
		||||
        void set_begin()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object != nullptr);
 | 
			
		||||
                    m_it.object_iterator = m_object->m_value.object->begin();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array != nullptr);
 | 
			
		||||
                    m_it.array_iterator = m_object->m_value.array->begin();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -5698,16 +5815,20 @@ class basic_json
 | 
			
		|||
        /// set the iterator past the last value
 | 
			
		||||
        void set_end()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object != nullptr);
 | 
			
		||||
                    m_it.object_iterator = m_object->m_value.object->end();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array != nullptr);
 | 
			
		||||
                    m_it.array_iterator = m_object->m_value.array->end();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -5724,15 +5845,21 @@ class basic_json
 | 
			
		|||
        /// return a reference to the value pointed to by the iterator
 | 
			
		||||
        reference operator*() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object);
 | 
			
		||||
                    assert(m_it.object_iterator != m_object->m_value.object->end());
 | 
			
		||||
                    return m_it.object_iterator->second;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array);
 | 
			
		||||
                    assert(m_it.array_iterator != m_object->m_value.array->end());
 | 
			
		||||
                    return *m_it.array_iterator;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5758,15 +5885,21 @@ class basic_json
 | 
			
		|||
        /// dereference the iterator
 | 
			
		||||
        pointer operator->() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.object);
 | 
			
		||||
                    assert(m_it.object_iterator != m_object->m_value.object->end());
 | 
			
		||||
                    return &(m_it.object_iterator->second);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case basic_json::value_t::array:
 | 
			
		||||
                {
 | 
			
		||||
                    assert(m_object->m_value.array);
 | 
			
		||||
                    assert(m_it.array_iterator != m_object->m_value.array->end());
 | 
			
		||||
                    return &*m_it.array_iterator;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5795,6 +5928,8 @@ class basic_json
 | 
			
		|||
        /// pre-increment (++it)
 | 
			
		||||
        const_iterator& operator++()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5830,6 +5965,8 @@ class basic_json
 | 
			
		|||
        /// pre-decrement (--it)
 | 
			
		||||
        const_iterator& operator--()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5863,6 +6000,8 @@ class basic_json
 | 
			
		|||
                throw std::domain_error("cannot compare iterators of different containers");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5897,6 +6036,8 @@ class basic_json
 | 
			
		|||
                throw std::domain_error("cannot compare iterators of different containers");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5937,6 +6078,8 @@ class basic_json
 | 
			
		|||
        /// add to iterator
 | 
			
		||||
        const_iterator& operator+=(difference_type i)
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -5985,6 +6128,8 @@ class basic_json
 | 
			
		|||
        /// return difference
 | 
			
		||||
        difference_type operator-(const const_iterator& other) const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -6007,6 +6152,8 @@ class basic_json
 | 
			
		|||
        /// access to successor
 | 
			
		||||
        reference operator[](difference_type n) const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            switch (m_object->m_type)
 | 
			
		||||
            {
 | 
			
		||||
                case basic_json::value_t::object:
 | 
			
		||||
| 
						 | 
				
			
			@ -6041,6 +6188,8 @@ class basic_json
 | 
			
		|||
        /// return the key of an object iterator
 | 
			
		||||
        typename object_t::key_type key() const
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_object != nullptr);
 | 
			
		||||
 | 
			
		||||
            if (m_object->is_object())
 | 
			
		||||
            {
 | 
			
		||||
                return m_it.object_iterator->first;
 | 
			
		||||
| 
						 | 
				
			
			@ -6353,6 +6502,7 @@ class basic_json
 | 
			
		|||
            : m_stream(nullptr), m_buffer(s)
 | 
			
		||||
        {
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start = m_cursor = m_content;
 | 
			
		||||
            m_limit = m_content + s.size();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -6361,8 +6511,10 @@ class basic_json
 | 
			
		|||
        explicit lexer(std::istream* s) noexcept
 | 
			
		||||
            : m_stream(s), m_buffer()
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_stream != nullptr);
 | 
			
		||||
            getline(*m_stream, m_buffer);
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start = m_cursor = m_content;
 | 
			
		||||
            m_limit = m_content + m_buffer.size();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -6511,6 +6663,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            // remember the begin of the token
 | 
			
		||||
            m_start = m_cursor;
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
 | 
			
		||||
            /*!re2c
 | 
			
		||||
                re2c:define:YYCTYPE   = lexer_char_t;
 | 
			
		||||
| 
						 | 
				
			
			@ -6581,7 +6734,7 @@ class basic_json
 | 
			
		|||
        /// append data from the stream to the internal buffer
 | 
			
		||||
        void yyfill() noexcept
 | 
			
		||||
        {
 | 
			
		||||
            if (not m_stream or not * m_stream)
 | 
			
		||||
            if (m_stream == nullptr or not * m_stream)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -6592,10 +6745,12 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
            m_buffer.erase(0, static_cast<size_t>(offset_start));
 | 
			
		||||
            std::string line;
 | 
			
		||||
            assert(m_stream != nullptr);
 | 
			
		||||
            std::getline(*m_stream, line);
 | 
			
		||||
            m_buffer += "\n" + line; // add line with newline symbol
 | 
			
		||||
 | 
			
		||||
            m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
 | 
			
		||||
            assert(m_content != nullptr);
 | 
			
		||||
            m_start  = m_content;
 | 
			
		||||
            m_marker = m_start + offset_marker;
 | 
			
		||||
            m_cursor = m_start + offset_cursor;
 | 
			
		||||
| 
						 | 
				
			
			@ -6605,6 +6760,7 @@ class basic_json
 | 
			
		|||
        /// return string representation of last read token
 | 
			
		||||
        string_t get_token() const noexcept
 | 
			
		||||
        {
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
            return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
 | 
			
		||||
                            static_cast<size_t>(m_cursor - m_start));
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -6754,6 +6910,7 @@ class basic_json
 | 
			
		|||
        {
 | 
			
		||||
            // conversion
 | 
			
		||||
            typename string_t::value_type* endptr;
 | 
			
		||||
            assert(m_start != nullptr);
 | 
			
		||||
            const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
 | 
			
		||||
                                                &endptr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6764,7 +6921,7 @@ class basic_json
 | 
			
		|||
 | 
			
		||||
      private:
 | 
			
		||||
        /// optional input stream
 | 
			
		||||
        std::istream* m_stream;
 | 
			
		||||
        std::istream* m_stream = nullptr;
 | 
			
		||||
        /// the buffer
 | 
			
		||||
        string_t m_buffer;
 | 
			
		||||
        /// the buffer pointer
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue