reorganization into smaller test units
This commit is contained in:
		
							parent
							
								
									2d3374c8b2
								
							
						
					
					
						commit
						38f562af2a
					
				
					 9 changed files with 2026 additions and 1918 deletions
				
			
		| 
						 | 
					@ -25,7 +25,7 @@ matrix:
 | 
				
			||||||
        - touch src/json.hpp
 | 
					        - touch src/json.hpp
 | 
				
			||||||
        - make json_unit CXXFLAGS="-fprofile-arcs -ftest-coverage -std=c++11 -lstdc++" CXX=$COMPILER
 | 
					        - make json_unit CXXFLAGS="-fprofile-arcs -ftest-coverage -std=c++11 -lstdc++" CXX=$COMPILER
 | 
				
			||||||
        - test/json_unit "*"
 | 
					        - test/json_unit "*"
 | 
				
			||||||
        - coveralls --exclude test/src/catch.hpp --exclude test/src/unit*.cpp --include src/json.hpp --gcov-options '\-lp' --gcov 'gcov-4.9'
 | 
					        - coveralls --exclude test/src/catch.hpp --exclude test/src/unit-algorithms.cpp --exclude test/src/unit-allocator.cpp --exclude test/src/unit-capacity.cpp --exclude test/src/unit-class_const_iterator.cpp --exclude test/src/unit-class_iterator.cpp --exclude test/src/unit-class_lexer.cpp --exclude test/src/unit-class_parser.cpp --exclude test/src/unit-comparison.cpp --exclude test/src/unit-concepts.cpp --exclude test/src/unit-constructor1.cpp --exclude test/src/unit-constructor2.cpp --exclude test/src/unit-convenience.cpp --exclude test/src/unit-conversions.cpp --exclude test/src/unit-deserialization.cpp --exclude test/src/unit-element_access1.cpp --exclude test/src/unit-element_access2.cpp --exclude test/src/unit-inspection.cpp --exclude test/src/unit-iterator_wrapper.cpp --exclude test/src/unit-iterators1.cpp --exclude test/src/unit-iterators2.cpp --exclude test/src/unit-json_patch.cpp --exclude test/src/unit-json_pointer.cpp --exclude test/src/unit-modifiers.cpp --exclude test/src/unit-pointer_access.cpp --exclude test/src/unit-readme.cpp --exclude test/src/unit-reference_access.cpp --exclude test/src/unit-regression.cpp --exclude test/src/unit-serialization.cpp --exclude test/src/unit-testsuites.cpp --exclude test/src/unit-unicode.cpp --include src/json.hpp --gcov-options '\-lp' --gcov 'gcov-4.9'
 | 
				
			||||||
      env: COMPILER=g++-4.9
 | 
					      env: COMPILER=g++-4.9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - os: linux
 | 
					    - os: linux
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,14 +12,17 @@ add_executable(${JSON_UNITTEST_TARGET_NAME}
 | 
				
			||||||
    "src/unit-class_parser.cpp"
 | 
					    "src/unit-class_parser.cpp"
 | 
				
			||||||
    "src/unit-comparison.cpp"
 | 
					    "src/unit-comparison.cpp"
 | 
				
			||||||
    "src/unit-concepts.cpp"
 | 
					    "src/unit-concepts.cpp"
 | 
				
			||||||
    "src/unit-constructor.cpp"
 | 
					    "src/unit-constructor1.cpp"
 | 
				
			||||||
 | 
					    "src/unit-constructor2.cpp"
 | 
				
			||||||
    "src/unit-convenience.cpp"
 | 
					    "src/unit-convenience.cpp"
 | 
				
			||||||
    "src/unit-conversions.cpp"
 | 
					    "src/unit-conversions.cpp"
 | 
				
			||||||
    "src/unit-deserialization.cpp"
 | 
					    "src/unit-deserialization.cpp"
 | 
				
			||||||
    "src/unit-element_access.cpp"
 | 
					    "src/unit-element_access1.cpp"
 | 
				
			||||||
 | 
					    "src/unit-element_access2.cpp"
 | 
				
			||||||
    "src/unit-inspection.cpp"
 | 
					    "src/unit-inspection.cpp"
 | 
				
			||||||
    "src/unit-iterator_wrapper.cpp"
 | 
					    "src/unit-iterator_wrapper.cpp"
 | 
				
			||||||
    "src/unit-iterators.cpp"
 | 
					    "src/unit-iterators1.cpp"
 | 
				
			||||||
 | 
					    "src/unit-iterators2.cpp"
 | 
				
			||||||
    "src/unit-json_patch.cpp"
 | 
					    "src/unit-json_patch.cpp"
 | 
				
			||||||
    "src/unit-json_pointer.cpp"
 | 
					    "src/unit-json_pointer.cpp"
 | 
				
			||||||
    "src/unit-modifiers.cpp"
 | 
					    "src/unit-modifiers.cpp"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,14 +16,17 @@ SOURCES = src/unit.cpp \
 | 
				
			||||||
          src/unit-class_parser.cpp \
 | 
					          src/unit-class_parser.cpp \
 | 
				
			||||||
          src/unit-comparison.cpp \
 | 
					          src/unit-comparison.cpp \
 | 
				
			||||||
          src/unit-concepts.cpp \
 | 
					          src/unit-concepts.cpp \
 | 
				
			||||||
          src/unit-constructor.cpp \
 | 
					          src/unit-constructor1.cpp \
 | 
				
			||||||
 | 
					          src/unit-constructor2.cpp \
 | 
				
			||||||
          src/unit-convenience.cpp \
 | 
					          src/unit-convenience.cpp \
 | 
				
			||||||
          src/unit-conversions.cpp \
 | 
					          src/unit-conversions.cpp \
 | 
				
			||||||
          src/unit-deserialization.cpp \
 | 
					          src/unit-deserialization.cpp \
 | 
				
			||||||
          src/unit-element_access.cpp \
 | 
					          src/unit-element_access1.cpp \
 | 
				
			||||||
 | 
					          src/unit-element_access2.cpp \
 | 
				
			||||||
          src/unit-inspection.cpp \
 | 
					          src/unit-inspection.cpp \
 | 
				
			||||||
          src/unit-iterator_wrapper.cpp \
 | 
					          src/unit-iterator_wrapper.cpp \
 | 
				
			||||||
          src/unit-iterators.cpp \
 | 
					          src/unit-iterators1.cpp \
 | 
				
			||||||
 | 
					          src/unit-iterators2.cpp \
 | 
				
			||||||
          src/unit-json_patch.cpp \
 | 
					          src/unit-json_patch.cpp \
 | 
				
			||||||
          src/unit-json_pointer.cpp \
 | 
					          src/unit-json_pointer.cpp \
 | 
				
			||||||
          src/unit-modifiers.cpp \
 | 
					          src/unit-modifiers.cpp \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1309,162 +1309,3 @@ TEST_CASE("constructors")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST_CASE("other constructors and destructor")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    SECTION("copy constructor")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SECTION("object")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j {{"foo", 1}, {"bar", false}};
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("array")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j {"foo", 1, 42.23, false};
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("null")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(nullptr);
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("boolean")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(true);
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("string")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j("Hello world");
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (integer)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42);
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42u);
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (floating-point)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42.23);
 | 
					 | 
				
			||||||
            json k(j);
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("move constructor")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
 | 
					 | 
				
			||||||
        CHECK(j.type() == json::value_t::object);
 | 
					 | 
				
			||||||
        json k(std::move(j));
 | 
					 | 
				
			||||||
        CHECK(k.type() == json::value_t::object);
 | 
					 | 
				
			||||||
        CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("copy assignment")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SECTION("object")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j {{"foo", 1}, {"bar", false}};
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("array")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j {"foo", 1, 42.23, false};
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("null")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(nullptr);
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("boolean")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(true);
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("string")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j("Hello world");
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (integer)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42);
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42u);
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("number (floating-point)")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            json j(42.23);
 | 
					 | 
				
			||||||
            json k;
 | 
					 | 
				
			||||||
            k = j;
 | 
					 | 
				
			||||||
            CHECK(j == k);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("destructor")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SECTION("object")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto j = new json {{"foo", 1}, {"bar", false}};
 | 
					 | 
				
			||||||
            delete j;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("array")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto j = new json {"foo", 1, 1u, false, 23.42};
 | 
					 | 
				
			||||||
            delete j;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("string")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto j = new json("Hello world");
 | 
					 | 
				
			||||||
            delete j;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										191
									
								
								test/src/unit-constructor2.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								test/src/unit-constructor2.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,191 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    __ _____ _____ _____
 | 
				
			||||||
 | 
					 __|  |   __|     |   | |  JSON for Modern C++ (test suite)
 | 
				
			||||||
 | 
					|  |  |__   |  |  | | | |  version 2.0.2
 | 
				
			||||||
 | 
					|_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the MIT License <http://opensource.org/licenses/MIT>.
 | 
				
			||||||
 | 
					Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby  granted, free of charge, to any  person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated  documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software  without restriction, including without  limitation the rights
 | 
				
			||||||
 | 
					to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
 | 
				
			||||||
 | 
					copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
 | 
				
			||||||
 | 
					AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "catch.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "json.hpp"
 | 
				
			||||||
 | 
					using nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("other constructors and destructor")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SECTION("copy constructor")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SECTION("object")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j {{"foo", 1}, {"bar", false}};
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("array")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j {"foo", 1, 42.23, false};
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("null")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(nullptr);
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("boolean")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(true);
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("string")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j("Hello world");
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (integer)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42);
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42u);
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (floating-point)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42.23);
 | 
				
			||||||
 | 
					            json k(j);
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("move constructor")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
 | 
				
			||||||
 | 
					        CHECK(j.type() == json::value_t::object);
 | 
				
			||||||
 | 
					        json k(std::move(j));
 | 
				
			||||||
 | 
					        CHECK(k.type() == json::value_t::object);
 | 
				
			||||||
 | 
					        CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("copy assignment")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SECTION("object")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j {{"foo", 1}, {"bar", false}};
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("array")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j {"foo", 1, 42.23, false};
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("null")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(nullptr);
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("boolean")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(true);
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("string")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j("Hello world");
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (integer)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42);
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42u);
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("number (floating-point)")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            json j(42.23);
 | 
				
			||||||
 | 
					            json k;
 | 
				
			||||||
 | 
					            k = j;
 | 
				
			||||||
 | 
					            CHECK(j == k);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("destructor")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SECTION("object")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto j = new json {{"foo", 1}, {"bar", false}};
 | 
				
			||||||
 | 
					            delete j;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("array")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto j = new json {"foo", 1, 1u, false, 23.42};
 | 
				
			||||||
 | 
					            delete j;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("string")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto j = new json("Hello world");
 | 
				
			||||||
 | 
					            delete j;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										947
									
								
								test/src/unit-element_access1.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										947
									
								
								test/src/unit-element_access1.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,947 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    __ _____ _____ _____
 | 
				
			||||||
 | 
					 __|  |   __|     |   | |  JSON for Modern C++ (test suite)
 | 
				
			||||||
 | 
					|  |  |__   |  |  | | | |  version 2.0.2
 | 
				
			||||||
 | 
					|_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the MIT License <http://opensource.org/licenses/MIT>.
 | 
				
			||||||
 | 
					Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby  granted, free of charge, to any  person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated  documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software  without restriction, including without  limitation the rights
 | 
				
			||||||
 | 
					to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
 | 
				
			||||||
 | 
					copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
 | 
				
			||||||
 | 
					AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "catch.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "json.hpp"
 | 
				
			||||||
 | 
					using nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("element access 1")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SECTION("array")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					        const json j_const = j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("access specified element with bounds checking")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("access within bounds")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CHECK(j.at(0) == json(1));
 | 
				
			||||||
 | 
					                CHECK(j.at(1) == json(1u));
 | 
				
			||||||
 | 
					                CHECK(j.at(2) == json(true));
 | 
				
			||||||
 | 
					                CHECK(j.at(3) == json(nullptr));
 | 
				
			||||||
 | 
					                CHECK(j.at(4) == json("string"));
 | 
				
			||||||
 | 
					                CHECK(j.at(5) == json(42.23));
 | 
				
			||||||
 | 
					                CHECK(j.at(6) == json(json::object()));
 | 
				
			||||||
 | 
					                CHECK(j.at(7) == json({1, 2, 3}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CHECK(j_const.at(0) == json(1));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(1) == json(1u));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(2) == json(true));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(3) == json(nullptr));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(4) == json("string"));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(5) == json(42.23));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(6) == json(json::object()));
 | 
				
			||||||
 | 
					                CHECK(j_const.at(7) == json({1, 2, 3}));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("access outside bounds")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CHECK_THROWS_AS(j.at(8), std::out_of_range);
 | 
				
			||||||
 | 
					                CHECK_THROWS_AS(j_const.at(8), std::out_of_range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CHECK_THROWS_WITH(j.at(8), "array index 8 is out of range");
 | 
				
			||||||
 | 
					                CHECK_THROWS_WITH(j_const.at(8), "array index 8 is out of range");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("access on non-array type")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SECTION("null")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::null);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with null");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("boolean")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::boolean);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with boolean");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with boolean");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("string")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::string);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with string");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with string");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("object")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::object);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with object");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with object");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (integer)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_integer);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_unsigned);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (floating-point)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_float);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("front and back")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            CHECK(j.front() == json(1));
 | 
				
			||||||
 | 
					            CHECK(j_const.front() == json(1));
 | 
				
			||||||
 | 
					            CHECK(j.back() == json({1, 2, 3}));
 | 
				
			||||||
 | 
					            CHECK(j_const.back() == json({1, 2, 3}));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("access specified element")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("access within bounds")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CHECK(j[0] == json(1));
 | 
				
			||||||
 | 
					                CHECK(j[1] == json(1u));
 | 
				
			||||||
 | 
					                CHECK(j[2] == json(true));
 | 
				
			||||||
 | 
					                CHECK(j[3] == json(nullptr));
 | 
				
			||||||
 | 
					                CHECK(j[4] == json("string"));
 | 
				
			||||||
 | 
					                CHECK(j[5] == json(42.23));
 | 
				
			||||||
 | 
					                CHECK(j[6] == json(json::object()));
 | 
				
			||||||
 | 
					                CHECK(j[7] == json({1, 2, 3}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CHECK(j_const[0] == json(1));
 | 
				
			||||||
 | 
					                CHECK(j_const[1] == json(1u));
 | 
				
			||||||
 | 
					                CHECK(j_const[2] == json(true));
 | 
				
			||||||
 | 
					                CHECK(j_const[3] == json(nullptr));
 | 
				
			||||||
 | 
					                CHECK(j_const[4] == json("string"));
 | 
				
			||||||
 | 
					                CHECK(j_const[5] == json(42.23));
 | 
				
			||||||
 | 
					                CHECK(j_const[6] == json(json::object()));
 | 
				
			||||||
 | 
					                CHECK(j_const[7] == json({1, 2, 3}));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("access on non-array type")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SECTION("null")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    SECTION("standard tests")
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json j_nonarray(json::value_t::null);
 | 
				
			||||||
 | 
					                        const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                        CHECK_NOTHROW(j_nonarray[0]);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with null");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    SECTION("implicit transformation to properly filled array")
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json j_nonarray;
 | 
				
			||||||
 | 
					                        j_nonarray[3] = 42;
 | 
				
			||||||
 | 
					                        CHECK(j_nonarray == json({nullptr, nullptr, nullptr, 42}));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("boolean")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::boolean);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with boolean");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with boolean");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("string")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::string);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with string");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with string");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("object")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::object);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with object");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with object");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (integer)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_integer);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_unsigned);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (floating-point)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonarray(json::value_t::number_float);
 | 
				
			||||||
 | 
					                    const json j_nonarray_const(j_nonarray);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("remove specified element")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("remove element by index")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(0);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(1);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(2);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(3);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, true, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(4);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(5);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, true, nullptr, "string", json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(6);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, {1, 2, 3}}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    jarray.erase(7);
 | 
				
			||||||
 | 
					                    CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object()}));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(jarray.erase(8), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(jarray.erase(8), "array index 8 is out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("remove element by iterator")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SECTION("erase(begin())")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::iterator it2 = jarray.erase(jarray.begin());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(1u));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::const_iterator it2 = jarray.erase(jarray.cbegin());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(1u));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("erase(begin(), end())")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json::array());
 | 
				
			||||||
 | 
					                        CHECK(it2 == jarray.end());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json::array());
 | 
				
			||||||
 | 
					                        CHECK(it2 == jarray.cend());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("erase(begin(), begin())")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(1));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(1));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("erase at offset")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::iterator it = jarray.begin() + 4;
 | 
				
			||||||
 | 
					                        json::iterator it2 = jarray.erase(it);
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(42.23));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::const_iterator it = jarray.cbegin() + 4;
 | 
				
			||||||
 | 
					                        json::const_iterator it2 = jarray.erase(it);
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json(42.23));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("erase subrange")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::iterator it2 = jarray.erase(jarray.begin() + 3, jarray.begin() + 6);
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json::object());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json::const_iterator it2 = jarray.erase(jarray.cbegin() + 3, jarray.cbegin() + 6);
 | 
				
			||||||
 | 
					                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
 | 
				
			||||||
 | 
					                        CHECK(*it2 == json::object());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("different arrays")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json jarray2 = {"foo", "bar"};
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.begin()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin()), "iterator does not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
				
			||||||
 | 
					                        json jarray2 = {"foo", "bar"};
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error);
 | 
				
			||||||
 | 
					                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()), "iterator does not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),
 | 
				
			||||||
 | 
					                                          "iterators do not fit current value");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("remove element by index in non-array type")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                SECTION("null")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("boolean")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::boolean);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with boolean");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("string")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::string);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with string");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("object")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::object);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with object");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (integer)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::number_integer);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::number_unsigned);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                SECTION("number (floating-point)")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j_nonobject(json::value_t::number_float);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("other values")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SECTION("front and back")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.front(), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.back(), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.front(), "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.back(), "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j{};
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.front(), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.back(), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.front(), "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.back(), "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("string")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "foo";
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j = "bar";
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (boolean)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = false;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j = true;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (integer)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j = 17;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (floating point)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    const json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK(j.front() == j);
 | 
				
			||||||
 | 
					                    CHECK(j.back() == j);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("erase with one valid iterator")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("string")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "foo";
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "bar";
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (boolean)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = false;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = true;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (integer)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (floating point)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("erase with one invalid iterator")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("string")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "foo";
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "bar";
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (boolean)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = false;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = true;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (integer)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (floating point)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("erase with two valid iterators")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.end()), "cannot use erase() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()), "cannot use erase() with null");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("string")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "foo";
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin(), j.end());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "bar";
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (boolean)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = false;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin(), j.end());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = true;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (integer)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin(), j.end());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin(), j.end());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (floating point)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    json::iterator it = j.erase(j.begin(), j.end());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
				
			||||||
 | 
					                    CHECK(j.type() == json::value_t::null);
 | 
				
			||||||
 | 
					                    CHECK(it == j.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("erase with two invalid iterators")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("string")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "foo";
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = "bar";
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (boolean)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = false;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = true;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (integer)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (unsigned)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 17u;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("number (floating point)")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    json j = 23.42;
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -31,466 +31,8 @@ SOFTWARE.
 | 
				
			||||||
#include "json.hpp"
 | 
					#include "json.hpp"
 | 
				
			||||||
using nlohmann::json;
 | 
					using nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_CASE("element access")
 | 
					TEST_CASE("element access 2")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SECTION("array")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
        const json j_const = j;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("access specified element with bounds checking")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("access within bounds")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                CHECK(j.at(0) == json(1));
 | 
					 | 
				
			||||||
                CHECK(j.at(1) == json(1u));
 | 
					 | 
				
			||||||
                CHECK(j.at(2) == json(true));
 | 
					 | 
				
			||||||
                CHECK(j.at(3) == json(nullptr));
 | 
					 | 
				
			||||||
                CHECK(j.at(4) == json("string"));
 | 
					 | 
				
			||||||
                CHECK(j.at(5) == json(42.23));
 | 
					 | 
				
			||||||
                CHECK(j.at(6) == json(json::object()));
 | 
					 | 
				
			||||||
                CHECK(j.at(7) == json({1, 2, 3}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                CHECK(j_const.at(0) == json(1));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(1) == json(1u));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(2) == json(true));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(3) == json(nullptr));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(4) == json("string"));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(5) == json(42.23));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(6) == json(json::object()));
 | 
					 | 
				
			||||||
                CHECK(j_const.at(7) == json({1, 2, 3}));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("access outside bounds")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                CHECK_THROWS_AS(j.at(8), std::out_of_range);
 | 
					 | 
				
			||||||
                CHECK_THROWS_AS(j_const.at(8), std::out_of_range);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                CHECK_THROWS_WITH(j.at(8), "array index 8 is out of range");
 | 
					 | 
				
			||||||
                CHECK_THROWS_WITH(j_const.at(8), "array index 8 is out of range");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("access on non-array type")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                SECTION("null")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::null);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with null");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("boolean")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::boolean);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with boolean");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with boolean");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("string")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::string);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with string");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with string");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("object")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::object);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with object");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with object");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (integer)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_integer);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_unsigned);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (floating-point)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_float);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const.at(0), "cannot use at() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("front and back")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            CHECK(j.front() == json(1));
 | 
					 | 
				
			||||||
            CHECK(j_const.front() == json(1));
 | 
					 | 
				
			||||||
            CHECK(j.back() == json({1, 2, 3}));
 | 
					 | 
				
			||||||
            CHECK(j_const.back() == json({1, 2, 3}));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("access specified element")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("access within bounds")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                CHECK(j[0] == json(1));
 | 
					 | 
				
			||||||
                CHECK(j[1] == json(1u));
 | 
					 | 
				
			||||||
                CHECK(j[2] == json(true));
 | 
					 | 
				
			||||||
                CHECK(j[3] == json(nullptr));
 | 
					 | 
				
			||||||
                CHECK(j[4] == json("string"));
 | 
					 | 
				
			||||||
                CHECK(j[5] == json(42.23));
 | 
					 | 
				
			||||||
                CHECK(j[6] == json(json::object()));
 | 
					 | 
				
			||||||
                CHECK(j[7] == json({1, 2, 3}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                CHECK(j_const[0] == json(1));
 | 
					 | 
				
			||||||
                CHECK(j_const[1] == json(1u));
 | 
					 | 
				
			||||||
                CHECK(j_const[2] == json(true));
 | 
					 | 
				
			||||||
                CHECK(j_const[3] == json(nullptr));
 | 
					 | 
				
			||||||
                CHECK(j_const[4] == json("string"));
 | 
					 | 
				
			||||||
                CHECK(j_const[5] == json(42.23));
 | 
					 | 
				
			||||||
                CHECK(j_const[6] == json(json::object()));
 | 
					 | 
				
			||||||
                CHECK(j_const[7] == json({1, 2, 3}));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("access on non-array type")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                SECTION("null")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    SECTION("standard tests")
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json j_nonarray(json::value_t::null);
 | 
					 | 
				
			||||||
                        const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                        CHECK_NOTHROW(j_nonarray[0]);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with null");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    SECTION("implicit transformation to properly filled array")
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json j_nonarray;
 | 
					 | 
				
			||||||
                        j_nonarray[3] = 42;
 | 
					 | 
				
			||||||
                        CHECK(j_nonarray == json({nullptr, nullptr, nullptr, 42}));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("boolean")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::boolean);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with boolean");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with boolean");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("string")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::string);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with string");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with string");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("object")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::object);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with object");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with object");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (integer)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_integer);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_unsigned);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (floating-point)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonarray(json::value_t::number_float);
 | 
					 | 
				
			||||||
                    const json j_nonarray_const(j_nonarray);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("remove specified element")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("remove element by index")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(0);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(1);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(2);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(3);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, true, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(4);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(5);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, true, nullptr, "string", json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(6);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, {1, 2, 3}}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    jarray.erase(7);
 | 
					 | 
				
			||||||
                    CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object()}));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(jarray.erase(8), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(jarray.erase(8), "array index 8 is out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("remove element by iterator")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                SECTION("erase(begin())")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::iterator it2 = jarray.erase(jarray.begin());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(1u));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::const_iterator it2 = jarray.erase(jarray.cbegin());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(1u));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("erase(begin(), end())")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.end());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json::array());
 | 
					 | 
				
			||||||
                        CHECK(it2 == jarray.end());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cend());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json::array());
 | 
					 | 
				
			||||||
                        CHECK(it2 == jarray.cend());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("erase(begin(), begin())")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::iterator it2 = jarray.erase(jarray.begin(), jarray.begin());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(1));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::const_iterator it2 = jarray.erase(jarray.cbegin(), jarray.cbegin());
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(1));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("erase at offset")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::iterator it = jarray.begin() + 4;
 | 
					 | 
				
			||||||
                        json::iterator it2 = jarray.erase(it);
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(42.23));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::const_iterator it = jarray.cbegin() + 4;
 | 
					 | 
				
			||||||
                        json::const_iterator it2 = jarray.erase(it);
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json(42.23));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("erase subrange")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::iterator it2 = jarray.erase(jarray.begin() + 3, jarray.begin() + 6);
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json::object());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json::const_iterator it2 = jarray.erase(jarray.cbegin() + 3, jarray.cbegin() + 6);
 | 
					 | 
				
			||||||
                        CHECK(jarray == json({1, 1u, true, json::object(), {1, 2, 3}}));
 | 
					 | 
				
			||||||
                        CHECK(*it2 == json::object());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("different arrays")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json jarray2 = {"foo", "bar"};
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.begin()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin()), "iterator does not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray.begin(), jarray2.end()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        json jarray = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
 | 
					 | 
				
			||||||
                        json jarray2 = {"foo", "bar"};
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error);
 | 
					 | 
				
			||||||
                        CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin()), "iterator does not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray.cbegin(), jarray2.cend()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),
 | 
					 | 
				
			||||||
                                          "iterators do not fit current value");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("remove element by index in non-array type")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                SECTION("null")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("boolean")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::boolean);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with boolean");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("string")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::string);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with string");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("object")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::object);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with object");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (integer)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::number_integer);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::number_unsigned);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                SECTION("number (floating-point)")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j_nonobject(json::value_t::number_float);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("object")
 | 
					    SECTION("object")
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
 | 
					        json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
 | 
				
			||||||
| 
						 | 
					@ -1414,458 +956,4 @@ TEST_CASE("element access")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("other values")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SECTION("front and back")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.front(), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.back(), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.front(), "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.back(), "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j{};
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.front(), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.back(), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.front(), "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.back(), "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("string")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "foo";
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j = "bar";
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (boolean)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = false;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j = true;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (integer)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j = 17;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (floating point)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    const json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK(j.front() == j);
 | 
					 | 
				
			||||||
                    CHECK(j.back() == j);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("erase with one valid iterator")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("string")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "foo";
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "bar";
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (boolean)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = false;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = true;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (integer)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (floating point)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("erase with one invalid iterator")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("string")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "foo";
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "bar";
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (boolean)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = false;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = true;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (integer)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (floating point)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("erase with two valid iterators")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.end()), "cannot use erase() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()), "cannot use erase() with null");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("string")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "foo";
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin(), j.end());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "bar";
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (boolean)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = false;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin(), j.end());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = true;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (integer)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin(), j.end());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin(), j.end());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (floating point)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    json::iterator it = j.erase(j.begin(), j.end());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    json::const_iterator it = j.erase(j.cbegin(), j.cend());
 | 
					 | 
				
			||||||
                    CHECK(j.type() == json::value_t::null);
 | 
					 | 
				
			||||||
                    CHECK(it == j.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("erase with two invalid iterators")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("string")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "foo";
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = "bar";
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (boolean)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = false;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = true;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (integer)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (unsigned)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 17u;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("number (floating point)")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.end(), j.end()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.begin(), j.begin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    json j = 23.42;
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cend(), j.cend()), "iterators out of range");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cbegin()), "iterators out of range");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ SOFTWARE.
 | 
				
			||||||
#include "json.hpp"
 | 
					#include "json.hpp"
 | 
				
			||||||
using nlohmann::json;
 | 
					using nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_CASE("iterators")
 | 
					TEST_CASE("iterators 1")
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SECTION("basic behavior")
 | 
					    SECTION("basic behavior")
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -1511,842 +1511,4 @@ TEST_CASE("iterators")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("iterator comparisons")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (json& j : j_values)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto it1 = j.begin();
 | 
					 | 
				
			||||||
            auto it2 = j.begin();
 | 
					 | 
				
			||||||
            auto it3 = j.begin();
 | 
					 | 
				
			||||||
            ++it2;
 | 
					 | 
				
			||||||
            ++it3;
 | 
					 | 
				
			||||||
            ++it3;
 | 
					 | 
				
			||||||
            auto it1_c = j.cbegin();
 | 
					 | 
				
			||||||
            auto it2_c = j.cbegin();
 | 
					 | 
				
			||||||
            auto it3_c = j.cbegin();
 | 
					 | 
				
			||||||
            ++it2_c;
 | 
					 | 
				
			||||||
            ++it3_c;
 | 
					 | 
				
			||||||
            ++it3_c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                CHECK(it1 == it1);
 | 
					 | 
				
			||||||
                CHECK(not (it1 == it2));
 | 
					 | 
				
			||||||
                CHECK(not (it1 == it3));
 | 
					 | 
				
			||||||
                CHECK(not (it2 == it3));
 | 
					 | 
				
			||||||
                CHECK(it1_c == it1_c);
 | 
					 | 
				
			||||||
                CHECK(not (it1_c == it2_c));
 | 
					 | 
				
			||||||
                CHECK(not (it1_c == it3_c));
 | 
					 | 
				
			||||||
                CHECK(not (it2_c == it3_c));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: not equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // check definition
 | 
					 | 
				
			||||||
                CHECK( (it1 != it1) == not(it1 == it1) );
 | 
					 | 
				
			||||||
                CHECK( (it1 != it2) == not(it1 == it2) );
 | 
					 | 
				
			||||||
                CHECK( (it1 != it3) == not(it1 == it3) );
 | 
					 | 
				
			||||||
                CHECK( (it2 != it3) == not(it2 == it3) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
 | 
					 | 
				
			||||||
                CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: smaller
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 < it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK(not (it1 < it1));
 | 
					 | 
				
			||||||
                    CHECK(it1 < it2);
 | 
					 | 
				
			||||||
                    CHECK(it1 < it3);
 | 
					 | 
				
			||||||
                    CHECK(it2 < it3);
 | 
					 | 
				
			||||||
                    CHECK(not (it1_c < it1_c));
 | 
					 | 
				
			||||||
                    CHECK(it1_c < it2_c);
 | 
					 | 
				
			||||||
                    CHECK(it1_c < it3_c);
 | 
					 | 
				
			||||||
                    CHECK(it2_c < it3_c);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: less than or equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 <= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it1) == not(it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it2) == not(it2 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it3) == not(it3 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 <= it3) == not(it3 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: greater than
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 > it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it1) == (it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it2) == (it2 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it3) == (it3 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 > it3) == (it3 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: greater than or equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 >= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it1) == not(it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it2) == not(it1 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it3) == not(it1 < it3) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 >= it3) == not(it2 < it3) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // check exceptions if different objects are compared
 | 
					 | 
				
			||||||
        for (auto j : j_values)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            for (auto k : j_values)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j != k)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.begin() == k.begin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.begin() < k.begin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("iterator arithmetic")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
 | 
					 | 
				
			||||||
        json j_array = {1, 2, 3, 4, 5, 6};
 | 
					 | 
				
			||||||
        json j_null = nullptr;
 | 
					 | 
				
			||||||
        json j_value = 42;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("addition and subtraction")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("object")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("array")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.begin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_array.begin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_array.begin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_array.begin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(*it == json(4));
 | 
					 | 
				
			||||||
                    it -= 2;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(2));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.cbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_array.cbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_array.cbegin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_array.cbegin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(*it == json(4));
 | 
					 | 
				
			||||||
                    it -= 2;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(2));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.begin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_null.begin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_null.begin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_null.begin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_null.end());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(it == j_null.end());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.cbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_null.cbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_null.cbegin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_null.cbegin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_null.cend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(it == j_null.cend());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("value")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.begin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_value.begin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_value.begin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_value.begin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_value.end());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(42));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.cbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_value.cbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_value.cbegin());
 | 
					 | 
				
			||||||
                    CHECK((it - j_value.cbegin()) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_value.cend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(42));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("subscript operator")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("object")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("array")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.begin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(1));
 | 
					 | 
				
			||||||
                    CHECK(it[1] == json(2));
 | 
					 | 
				
			||||||
                    CHECK(it[2] == json(3));
 | 
					 | 
				
			||||||
                    CHECK(it[3] == json(4));
 | 
					 | 
				
			||||||
                    CHECK(it[4] == json(5));
 | 
					 | 
				
			||||||
                    CHECK(it[5] == json(6));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.cbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(1));
 | 
					 | 
				
			||||||
                    CHECK(it[1] == json(2));
 | 
					 | 
				
			||||||
                    CHECK(it[2] == json(3));
 | 
					 | 
				
			||||||
                    CHECK(it[3] == json(4));
 | 
					 | 
				
			||||||
                    CHECK(it[4] == json(5));
 | 
					 | 
				
			||||||
                    CHECK(it[5] == json(6));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.begin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.cbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("value")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.begin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(42));
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.cbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(42));
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("reverse iterator comparisons")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (json& j : j_values)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto it1 = j.rbegin();
 | 
					 | 
				
			||||||
            auto it2 = j.rbegin();
 | 
					 | 
				
			||||||
            auto it3 = j.rbegin();
 | 
					 | 
				
			||||||
            ++it2;
 | 
					 | 
				
			||||||
            ++it3;
 | 
					 | 
				
			||||||
            ++it3;
 | 
					 | 
				
			||||||
            auto it1_c = j.crbegin();
 | 
					 | 
				
			||||||
            auto it2_c = j.crbegin();
 | 
					 | 
				
			||||||
            auto it3_c = j.crbegin();
 | 
					 | 
				
			||||||
            ++it2_c;
 | 
					 | 
				
			||||||
            ++it3_c;
 | 
					 | 
				
			||||||
            ++it3_c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                CHECK(it1 == it1);
 | 
					 | 
				
			||||||
                CHECK(not (it1 == it2));
 | 
					 | 
				
			||||||
                CHECK(not (it1 == it3));
 | 
					 | 
				
			||||||
                CHECK(not (it2 == it3));
 | 
					 | 
				
			||||||
                CHECK(it1_c == it1_c);
 | 
					 | 
				
			||||||
                CHECK(not (it1_c == it2_c));
 | 
					 | 
				
			||||||
                CHECK(not (it1_c == it3_c));
 | 
					 | 
				
			||||||
                CHECK(not (it2_c == it3_c));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: not equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // check definition
 | 
					 | 
				
			||||||
                CHECK( (it1 != it1) == not(it1 == it1) );
 | 
					 | 
				
			||||||
                CHECK( (it1 != it2) == not(it1 == it2) );
 | 
					 | 
				
			||||||
                CHECK( (it1 != it3) == not(it1 == it3) );
 | 
					 | 
				
			||||||
                CHECK( (it2 != it3) == not(it2 == it3) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
 | 
					 | 
				
			||||||
                CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
 | 
					 | 
				
			||||||
                CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: smaller
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 < it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 < it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK(not (it1 < it1));
 | 
					 | 
				
			||||||
                    CHECK(it1 < it2);
 | 
					 | 
				
			||||||
                    CHECK(it1 < it3);
 | 
					 | 
				
			||||||
                    CHECK(it2 < it3);
 | 
					 | 
				
			||||||
                    CHECK(not (it1_c < it1_c));
 | 
					 | 
				
			||||||
                    CHECK(it1_c < it2_c);
 | 
					 | 
				
			||||||
                    CHECK(it1_c < it3_c);
 | 
					 | 
				
			||||||
                    CHECK(it2_c < it3_c);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: less than or equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 <= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 <= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it1) == not(it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it2) == not(it2 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 <= it3) == not(it3 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 <= it3) == not(it3 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: greater than
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 > it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 > it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it1) == (it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it2) == (it2 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 > it3) == (it3 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 > it3) == (it3 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // comparison: greater than or equal
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j.type() == json::value_t::object)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it2, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2 >= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1 >= it3, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // check definition
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it1) == not(it1 < it1) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it2) == not(it1 < it2) );
 | 
					 | 
				
			||||||
                    CHECK( (it1 >= it3) == not(it1 < it3) );
 | 
					 | 
				
			||||||
                    CHECK( (it2 >= it3) == not(it2 < it3) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
 | 
					 | 
				
			||||||
                    CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // check exceptions if different objects are compared
 | 
					 | 
				
			||||||
        for (auto j : j_values)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            for (auto k : j_values)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (j != k)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.rbegin() == k.rbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.crbegin() == k.crbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.rbegin() < k.rbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(j.crbegin() < k.crbegin(), std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "cannot compare iterators of different containers");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SECTION("reverse iterator arithmetic")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
 | 
					 | 
				
			||||||
        json j_array = {1, 2, 3, 4, 5, 6};
 | 
					 | 
				
			||||||
        json j_null = nullptr;
 | 
					 | 
				
			||||||
        json j_value = 42;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("addition and subtraction")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("object")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("array")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.rbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_array.rbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_array.rbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_array.rbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(*it == json(3));
 | 
					 | 
				
			||||||
                    it -= 2;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(5));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.crbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_array.crbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_array.crbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_array.crbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(*it == json(3));
 | 
					 | 
				
			||||||
                    it -= 2;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(5));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.rbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_null.rbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_null.rbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_null.rbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_null.rend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(it == j_null.rend());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.crbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_null.crbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_null.crbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_null.crbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_null.crend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(it == j_null.crend());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("value")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.rbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_value.rbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_value.rbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_value.rbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_value.rend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(42));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.crbegin();
 | 
					 | 
				
			||||||
                    it += 3;
 | 
					 | 
				
			||||||
                    CHECK((j_value.crbegin() + 3) == it);
 | 
					 | 
				
			||||||
                    CHECK((it - 3) == j_value.crbegin());
 | 
					 | 
				
			||||||
                    CHECK((j_value.crbegin() - it) == 3);
 | 
					 | 
				
			||||||
                    CHECK(it != j_value.crend());
 | 
					 | 
				
			||||||
                    it -= 3;
 | 
					 | 
				
			||||||
                    CHECK(*it == json(42));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SECTION("subscript operator")
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SECTION("object")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_object.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("array")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.rbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(6));
 | 
					 | 
				
			||||||
                    CHECK(it[1] == json(5));
 | 
					 | 
				
			||||||
                    CHECK(it[2] == json(4));
 | 
					 | 
				
			||||||
                    CHECK(it[3] == json(3));
 | 
					 | 
				
			||||||
                    CHECK(it[4] == json(2));
 | 
					 | 
				
			||||||
                    CHECK(it[5] == json(1));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_array.crbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(6));
 | 
					 | 
				
			||||||
                    CHECK(it[1] == json(5));
 | 
					 | 
				
			||||||
                    CHECK(it[2] == json(4));
 | 
					 | 
				
			||||||
                    CHECK(it[3] == json(3));
 | 
					 | 
				
			||||||
                    CHECK(it[4] == json(2));
 | 
					 | 
				
			||||||
                    CHECK(it[5] == json(1));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("null")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.rbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_null.crbegin();
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SECTION("value")
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.rbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(42));
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    auto it = j_value.crbegin();
 | 
					 | 
				
			||||||
                    CHECK(it[0] == json(42));
 | 
					 | 
				
			||||||
                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
					 | 
				
			||||||
                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										873
									
								
								test/src/unit-iterators2.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										873
									
								
								test/src/unit-iterators2.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,873 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    __ _____ _____ _____
 | 
				
			||||||
 | 
					 __|  |   __|     |   | |  JSON for Modern C++ (test suite)
 | 
				
			||||||
 | 
					|  |  |__   |  |  | | | |  version 2.0.2
 | 
				
			||||||
 | 
					|_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the MIT License <http://opensource.org/licenses/MIT>.
 | 
				
			||||||
 | 
					Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby  granted, free of charge, to any  person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated  documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software  without restriction, including without  limitation the rights
 | 
				
			||||||
 | 
					to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
 | 
				
			||||||
 | 
					copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
 | 
				
			||||||
 | 
					AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "catch.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "json.hpp"
 | 
				
			||||||
 | 
					using nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_CASE("iterators 2")
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SECTION("iterator comparisons")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (json& j : j_values)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto it1 = j.begin();
 | 
				
			||||||
 | 
					            auto it2 = j.begin();
 | 
				
			||||||
 | 
					            auto it3 = j.begin();
 | 
				
			||||||
 | 
					            ++it2;
 | 
				
			||||||
 | 
					            ++it3;
 | 
				
			||||||
 | 
					            ++it3;
 | 
				
			||||||
 | 
					            auto it1_c = j.cbegin();
 | 
				
			||||||
 | 
					            auto it2_c = j.cbegin();
 | 
				
			||||||
 | 
					            auto it3_c = j.cbegin();
 | 
				
			||||||
 | 
					            ++it2_c;
 | 
				
			||||||
 | 
					            ++it3_c;
 | 
				
			||||||
 | 
					            ++it3_c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CHECK(it1 == it1);
 | 
				
			||||||
 | 
					                CHECK(not (it1 == it2));
 | 
				
			||||||
 | 
					                CHECK(not (it1 == it3));
 | 
				
			||||||
 | 
					                CHECK(not (it2 == it3));
 | 
				
			||||||
 | 
					                CHECK(it1_c == it1_c);
 | 
				
			||||||
 | 
					                CHECK(not (it1_c == it2_c));
 | 
				
			||||||
 | 
					                CHECK(not (it1_c == it3_c));
 | 
				
			||||||
 | 
					                CHECK(not (it2_c == it3_c));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: not equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // check definition
 | 
				
			||||||
 | 
					                CHECK( (it1 != it1) == not(it1 == it1) );
 | 
				
			||||||
 | 
					                CHECK( (it1 != it2) == not(it1 == it2) );
 | 
				
			||||||
 | 
					                CHECK( (it1 != it3) == not(it1 == it3) );
 | 
				
			||||||
 | 
					                CHECK( (it2 != it3) == not(it2 == it3) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
 | 
				
			||||||
 | 
					                CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: smaller
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 < it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK(not (it1 < it1));
 | 
				
			||||||
 | 
					                    CHECK(it1 < it2);
 | 
				
			||||||
 | 
					                    CHECK(it1 < it3);
 | 
				
			||||||
 | 
					                    CHECK(it2 < it3);
 | 
				
			||||||
 | 
					                    CHECK(not (it1_c < it1_c));
 | 
				
			||||||
 | 
					                    CHECK(it1_c < it2_c);
 | 
				
			||||||
 | 
					                    CHECK(it1_c < it3_c);
 | 
				
			||||||
 | 
					                    CHECK(it2_c < it3_c);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: less than or equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 <= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it1) == not(it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it2) == not(it2 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it3) == not(it3 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 <= it3) == not(it3 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: greater than
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 > it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it1) == (it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it2) == (it2 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it3) == (it3 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 > it3) == (it3 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: greater than or equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 >= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it1) == not(it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it2) == not(it1 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it3) == not(it1 < it3) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 >= it3) == not(it2 < it3) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check exceptions if different objects are compared
 | 
				
			||||||
 | 
					        for (auto j : j_values)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            for (auto k : j_values)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j != k)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.begin() == k.begin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.begin() < k.begin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("iterator arithmetic")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
 | 
				
			||||||
 | 
					        json j_array = {1, 2, 3, 4, 5, 6};
 | 
				
			||||||
 | 
					        json j_null = nullptr;
 | 
				
			||||||
 | 
					        json j_value = 42;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("addition and subtraction")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("object")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("array")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.begin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_array.begin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_array.begin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_array.begin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(*it == json(4));
 | 
				
			||||||
 | 
					                    it -= 2;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(2));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.cbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_array.cbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_array.cbegin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_array.cbegin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(*it == json(4));
 | 
				
			||||||
 | 
					                    it -= 2;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(2));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.begin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_null.begin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_null.begin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_null.begin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_null.end());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(it == j_null.end());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.cbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_null.cbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_null.cbegin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_null.cbegin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_null.cend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(it == j_null.cend());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("value")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.begin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_value.begin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_value.begin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_value.begin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_value.end());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(42));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.cbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_value.cbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_value.cbegin());
 | 
				
			||||||
 | 
					                    CHECK((it - j_value.cbegin()) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_value.cend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(42));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("subscript operator")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("object")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("array")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.begin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(1));
 | 
				
			||||||
 | 
					                    CHECK(it[1] == json(2));
 | 
				
			||||||
 | 
					                    CHECK(it[2] == json(3));
 | 
				
			||||||
 | 
					                    CHECK(it[3] == json(4));
 | 
				
			||||||
 | 
					                    CHECK(it[4] == json(5));
 | 
				
			||||||
 | 
					                    CHECK(it[5] == json(6));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.cbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(1));
 | 
				
			||||||
 | 
					                    CHECK(it[1] == json(2));
 | 
				
			||||||
 | 
					                    CHECK(it[2] == json(3));
 | 
				
			||||||
 | 
					                    CHECK(it[3] == json(4));
 | 
				
			||||||
 | 
					                    CHECK(it[4] == json(5));
 | 
				
			||||||
 | 
					                    CHECK(it[5] == json(6));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.begin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.cbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("value")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.begin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(42));
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.cbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(42));
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("reverse iterator comparisons")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (json& j : j_values)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto it1 = j.rbegin();
 | 
				
			||||||
 | 
					            auto it2 = j.rbegin();
 | 
				
			||||||
 | 
					            auto it3 = j.rbegin();
 | 
				
			||||||
 | 
					            ++it2;
 | 
				
			||||||
 | 
					            ++it3;
 | 
				
			||||||
 | 
					            ++it3;
 | 
				
			||||||
 | 
					            auto it1_c = j.crbegin();
 | 
				
			||||||
 | 
					            auto it2_c = j.crbegin();
 | 
				
			||||||
 | 
					            auto it3_c = j.crbegin();
 | 
				
			||||||
 | 
					            ++it2_c;
 | 
				
			||||||
 | 
					            ++it3_c;
 | 
				
			||||||
 | 
					            ++it3_c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CHECK(it1 == it1);
 | 
				
			||||||
 | 
					                CHECK(not (it1 == it2));
 | 
				
			||||||
 | 
					                CHECK(not (it1 == it3));
 | 
				
			||||||
 | 
					                CHECK(not (it2 == it3));
 | 
				
			||||||
 | 
					                CHECK(it1_c == it1_c);
 | 
				
			||||||
 | 
					                CHECK(not (it1_c == it2_c));
 | 
				
			||||||
 | 
					                CHECK(not (it1_c == it3_c));
 | 
				
			||||||
 | 
					                CHECK(not (it2_c == it3_c));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: not equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // check definition
 | 
				
			||||||
 | 
					                CHECK( (it1 != it1) == not(it1 == it1) );
 | 
				
			||||||
 | 
					                CHECK( (it1 != it2) == not(it1 == it2) );
 | 
				
			||||||
 | 
					                CHECK( (it1 != it3) == not(it1 == it3) );
 | 
				
			||||||
 | 
					                CHECK( (it2 != it3) == not(it2 == it3) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it1_c) == not(it1_c == it1_c) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it2_c) == not(it1_c == it2_c) );
 | 
				
			||||||
 | 
					                CHECK( (it1_c != it3_c) == not(it1_c == it3_c) );
 | 
				
			||||||
 | 
					                CHECK( (it2_c != it3_c) == not(it2_c == it3_c) );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: smaller
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 < it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 < it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 < it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 < it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c < it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c < it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK(not (it1 < it1));
 | 
				
			||||||
 | 
					                    CHECK(it1 < it2);
 | 
				
			||||||
 | 
					                    CHECK(it1 < it3);
 | 
				
			||||||
 | 
					                    CHECK(it2 < it3);
 | 
				
			||||||
 | 
					                    CHECK(not (it1_c < it1_c));
 | 
				
			||||||
 | 
					                    CHECK(it1_c < it2_c);
 | 
				
			||||||
 | 
					                    CHECK(it1_c < it3_c);
 | 
				
			||||||
 | 
					                    CHECK(it2_c < it3_c);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: less than or equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 <= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 <= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 <= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 <= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c <= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c <= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it1) == not(it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it2) == not(it2 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 <= it3) == not(it3 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 <= it3) == not(it3 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it1_c) == not(it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it2_c) == not(it2_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c <= it3_c) == not(it3_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c <= it3_c) == not(it3_c < it2_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: greater than
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 > it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 > it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 > it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 > it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c > it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c > it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it1) == (it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it2) == (it2 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 > it3) == (it3 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 > it3) == (it3 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it1_c) == (it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it2_c) == (it2_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c > it3_c) == (it3_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c > it3_c) == (it3_c < it2_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // comparison: greater than or equal
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j.type() == json::value_t::object)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it2, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2 >= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1 >= it3, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it1_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it1, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it2, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2 >= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1 >= it3, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it1_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it2_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it2_c >= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it1_c >= it3_c, "cannot compare order of object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check definition
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it1) == not(it1 < it1) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it2) == not(it1 < it2) );
 | 
				
			||||||
 | 
					                    CHECK( (it1 >= it3) == not(it1 < it3) );
 | 
				
			||||||
 | 
					                    CHECK( (it2 >= it3) == not(it2 < it3) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it1_c) == not(it1_c < it1_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it2_c) == not(it1_c < it2_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it1_c >= it3_c) == not(it1_c < it3_c) );
 | 
				
			||||||
 | 
					                    CHECK( (it2_c >= it3_c) == not(it2_c < it3_c) );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check exceptions if different objects are compared
 | 
				
			||||||
 | 
					        for (auto j : j_values)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            for (auto k : j_values)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (j != k)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.rbegin() == k.rbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.crbegin() == k.crbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.rbegin() < k.rbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(j.crbegin() < k.crbegin(), std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "cannot compare iterators of different containers");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SECTION("reverse iterator arithmetic")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
 | 
				
			||||||
 | 
					        json j_array = {1, 2, 3, 4, 5, 6};
 | 
				
			||||||
 | 
					        json j_null = nullptr;
 | 
				
			||||||
 | 
					        json j_value = 42;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("addition and subtraction")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("object")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it += 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it += 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it + 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it + 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it -= 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it -= 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - 1, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - 1, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it - it, std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("array")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.rbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_array.rbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_array.rbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_array.rbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(*it == json(3));
 | 
				
			||||||
 | 
					                    it -= 2;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(5));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.crbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_array.crbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_array.crbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_array.crbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(*it == json(3));
 | 
				
			||||||
 | 
					                    it -= 2;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(5));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.rbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_null.rbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_null.rbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_null.rbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_null.rend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(it == j_null.rend());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.crbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_null.crbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_null.crbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_null.crbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_null.crend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(it == j_null.crend());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("value")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.rbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_value.rbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_value.rbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_value.rbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_value.rend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(42));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.crbegin();
 | 
				
			||||||
 | 
					                    it += 3;
 | 
				
			||||||
 | 
					                    CHECK((j_value.crbegin() + 3) == it);
 | 
				
			||||||
 | 
					                    CHECK((it - 3) == j_value.crbegin());
 | 
				
			||||||
 | 
					                    CHECK((j_value.crbegin() - it) == 3);
 | 
				
			||||||
 | 
					                    CHECK(it != j_value.crend());
 | 
				
			||||||
 | 
					                    it -= 3;
 | 
				
			||||||
 | 
					                    CHECK(*it == json(42));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SECTION("subscript operator")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SECTION("object")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_object.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::domain_error);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("array")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.rbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(6));
 | 
				
			||||||
 | 
					                    CHECK(it[1] == json(5));
 | 
				
			||||||
 | 
					                    CHECK(it[2] == json(4));
 | 
				
			||||||
 | 
					                    CHECK(it[3] == json(3));
 | 
				
			||||||
 | 
					                    CHECK(it[4] == json(2));
 | 
				
			||||||
 | 
					                    CHECK(it[5] == json(1));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_array.crbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(6));
 | 
				
			||||||
 | 
					                    CHECK(it[1] == json(5));
 | 
				
			||||||
 | 
					                    CHECK(it[2] == json(4));
 | 
				
			||||||
 | 
					                    CHECK(it[3] == json(3));
 | 
				
			||||||
 | 
					                    CHECK(it[4] == json(2));
 | 
				
			||||||
 | 
					                    CHECK(it[5] == json(1));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("null")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.rbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_null.crbegin();
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[0], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[0], "cannot get value");
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SECTION("value")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.rbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(42));
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto it = j_value.crbegin();
 | 
				
			||||||
 | 
					                    CHECK(it[0] == json(42));
 | 
				
			||||||
 | 
					                    CHECK_THROWS_AS(it[1], std::out_of_range);
 | 
				
			||||||
 | 
					                    CHECK_THROWS_WITH(it[1], "cannot get value");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue