diff --git a/src/json.hpp b/src/json.hpp
index dbb18576..7c8be3d4 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -6441,7 +6441,7 @@ class basic_json
             return result;
         }
 
-        /// return name of values of type token_type
+        /// return name of values of type token_type (only used for errors)
         static std::string token_type_name(token_type t)
         {
             switch (t)
diff --git a/test/unit.cpp b/test/unit.cpp
index 6386fd69..ebf3fb2a 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -10,9 +10,6 @@
 #define CATCH_CONFIG_MAIN
 #include "catch.hpp"
 
-// macro to check exception names (see https://github.com/philsquared/Catch/issues/563)
-#define CHECK_THROWS_NAME(block, exception, name) { try { block; } catch ( exception &e ) { CHECK(e.what() == std::string(name)); } }
-
 #include <array>
 #include <deque>
 #include <forward_list>
@@ -898,8 +895,8 @@ TEST_CASE("constructors")
             SECTION("object with error")
             {
                 CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }), std::logic_error);
-                CHECK_THROWS_NAME(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }),
-                std::logic_error, "cannot create object from initializer list");
+                CHECK_THROWS_WITH(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }),
+                "cannot create object from initializer list");
             }
 
             SECTION("empty array")
@@ -973,20 +970,16 @@ TEST_CASE("constructors")
                     json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
                     CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), std::domain_error);
                     CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), std::domain_error);
-                    CHECK_THROWS_NAME(json(jobject.begin(), jobject2.end()), std::domain_error,
-                                      "iterators are not compatible");
-                    CHECK_THROWS_NAME(json(jobject2.begin(), jobject.end()), std::domain_error,
-                                      "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jobject.begin(), jobject2.end()), "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jobject2.begin(), jobject.end()), "iterators are not compatible");
                 }
                 {
                     json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
                     json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
                     CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), std::domain_error);
                     CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), std::domain_error);
-                    CHECK_THROWS_NAME(json(jobject.cbegin(), jobject2.cend()), std::domain_error,
-                                      "iterators are not compatible");
-                    CHECK_THROWS_NAME(json(jobject2.cbegin(), jobject.cend()), std::domain_error,
-                                      "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jobject.cbegin(), jobject2.cend()), "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jobject2.cbegin(), jobject.cend()), "iterators are not compatible");
                 }
             }
         }
@@ -1042,20 +1035,16 @@ TEST_CASE("constructors")
                     json jarray2 = {2, 3, 4, 5};
                     CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), std::domain_error);
                     CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), std::domain_error);
-                    CHECK_THROWS_NAME(json(jarray.begin(), jarray2.end()), std::domain_error,
-                                      "iterators are not compatible");
-                    CHECK_THROWS_NAME(json(jarray2.begin(), jarray.end()), std::domain_error,
-                                      "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jarray.begin(), jarray2.end()), "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jarray2.begin(), jarray.end()), "iterators are not compatible");
                 }
                 {
                     json jarray = {1, 2, 3, 4};
                     json jarray2 = {2, 3, 4, 5};
                     CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), std::domain_error);
                     CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), std::domain_error);
-                    CHECK_THROWS_NAME(json(jarray.cbegin(), jarray2.cend()), std::domain_error,
-                                      "iterators are not compatible");
-                    CHECK_THROWS_NAME(json(jarray2.cbegin(), jarray.cend()), std::domain_error,
-                                      "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jarray.cbegin(), jarray2.cend()), "iterators are not compatible");
+                    CHECK_THROWS_WITH(json(jarray2.cbegin(), jarray.cend()), "iterators are not compatible");
                 }
             }
         }
@@ -1069,14 +1058,12 @@ TEST_CASE("constructors")
                     {
                         json j;
                         CHECK_THROWS_AS(json(j.begin(), j.end()), std::domain_error);
-                        CHECK_THROWS_NAME(json(j.begin(), j.end()), std::domain_error,
-                                          "cannot use construct with iterators from null");
+                        CHECK_THROWS_WITH(json(j.begin(), j.end()), "cannot use construct with iterators from null");
                     }
                     {
                         json j;
                         CHECK_THROWS_AS(json(j.cbegin(), j.cend()), std::domain_error);
-                        CHECK_THROWS_NAME(json(j.cbegin(), j.cend()), std::domain_error,
-                                          "cannot use construct with iterators from null");
+                        CHECK_THROWS_WITH(json(j.cbegin(), j.cend()), "cannot use construct with iterators from null");
                     }
                 }
 
@@ -1145,15 +1132,15 @@ TEST_CASE("constructors")
                         json j = "foo";
                         CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
                     }
                     {
                         json j = "bar";
                         CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
                     }
                 }
 
@@ -1163,15 +1150,15 @@ TEST_CASE("constructors")
                         json j = false;
                         CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
                     }
                     {
                         json j = true;
                         CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
                     }
                 }
 
@@ -1181,15 +1168,15 @@ TEST_CASE("constructors")
                         json j = 17;
                         CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
                     }
                     {
                         json j = 17;
                         CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
                     }
                 }
 
@@ -1199,15 +1186,15 @@ TEST_CASE("constructors")
                         json j = 23.42;
                         CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.end(), j.end()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.begin(), j.begin()), "iterators out of range");
                     }
                     {
                         json j = 23.42;
                         CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
                         CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
-                        CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                        CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cend(), j.cend()), "iterators out of range");
+                        CHECK_THROWS_WITH(json(j.cbegin(), j.cbegin()), "iterators out of range");
                     }
                 }
             }
@@ -1687,17 +1674,17 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::object_t>(),
                               "type must be object, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::array).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::array).get<json::object_t>(),
                               "type must be object, but is array");
-            CHECK_THROWS_NAME(json(json::value_t::string).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::string).get<json::object_t>(),
                               "type must be object, but is string");
-            CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),
                               "type must be object, but is boolean");
-            CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::object_t>(),
                               "type must be object, but is number");
-            CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::object_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::object_t>(),
                               "type must be object, but is number");
         }
     }
@@ -1782,17 +1769,17 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::array_t>(),
                               "type must be array, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::object).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::object).get<json::array_t>(),
                               "type must be array, but is object");
-            CHECK_THROWS_NAME(json(json::value_t::string).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::string).get<json::array_t>(),
                               "type must be array, but is string");
-            CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::array_t>(),
                               "type must be array, but is boolean");
-            CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::array_t>(),
                               "type must be array, but is number");
-            CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::array_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::array_t>(),
                               "type must be array, but is number");
         }
     }
@@ -1859,17 +1846,17 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::string_t>(),
                               "type must be string, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::object).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::object).get<json::string_t>(),
                               "type must be string, but is object");
-            CHECK_THROWS_NAME(json(json::value_t::array).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::array).get<json::string_t>(),
                               "type must be string, but is array");
-            CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
                               "type must be string, but is boolean");
-            CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::string_t>(),
                               "type must be string, but is number");
-            CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::string_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::string_t>(),
                               "type must be string, but is number");
         }
     }
@@ -1918,17 +1905,17 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::boolean_t>(),
                               "type must be boolean, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::object).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
                               "type must be boolean, but is object");
-            CHECK_THROWS_NAME(json(json::value_t::array).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::array).get<json::boolean_t>(),
                               "type must be boolean, but is array");
-            CHECK_THROWS_NAME(json(json::value_t::string).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
                               "type must be boolean, but is string");
-            CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::boolean_t>(),
                               "type must be boolean, but is number");
-            CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::boolean_t>(),
                               "type must be boolean, but is number");
         }
     }
@@ -2162,15 +2149,15 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::number_integer_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_integer_t>(),
                               "type must be number, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::object).get<json::number_integer_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_integer_t>(),
                               "type must be number, but is object");
-            CHECK_THROWS_NAME(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_integer_t>(),
                               "type must be number, but is array");
-            CHECK_THROWS_NAME(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_integer_t>(),
                               "type must be number, but is string");
-            CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_integer_t>(),
                               "type must be number, but is boolean");
 
             CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
@@ -2412,15 +2399,15 @@ TEST_CASE("value conversion")
             CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), std::logic_error);
             CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error);
 
-            CHECK_THROWS_NAME(json(json::value_t::null).get<json::number_float_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_float_t>(),
                               "type must be number, but is null");
-            CHECK_THROWS_NAME(json(json::value_t::object).get<json::number_float_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_float_t>(),
                               "type must be number, but is object");
-            CHECK_THROWS_NAME(json(json::value_t::array).get<json::number_float_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_float_t>(),
                               "type must be number, but is array");
-            CHECK_THROWS_NAME(json(json::value_t::string).get<json::number_float_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_float_t>(),
                               "type must be number, but is string");
-            CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error,
+            CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_float_t>(),
                               "type must be number, but is boolean");
 
             CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
@@ -2498,8 +2485,7 @@ TEST_CASE("value conversion")
             SECTION("exception in case of a non-object type")
             {
                 CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), std::logic_error);
-                CHECK_THROWS_NAME((json().get<std::map<std::string, int>>()), std::logic_error,
-                                  "type must be object, but is null");
+                CHECK_THROWS_WITH((json().get<std::map<std::string, int>>()), "type must be object, but is null");
             }
         }
 
@@ -2565,14 +2551,10 @@ TEST_CASE("value conversion")
                 CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error);
                 CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error);
 
-                CHECK_THROWS_NAME((json().get<std::list<int>>()), std::logic_error,
-                                  "type must be array, but is null");
-                CHECK_THROWS_NAME((json().get<std::vector<int>>()), std::logic_error,
-                                  "type must be array, but is null");
-                CHECK_THROWS_NAME((json().get<std::vector<json>>()), std::logic_error,
-                                  "type must be array, but is null");
-                CHECK_THROWS_NAME((json().get<std::list<json>>()), std::logic_error,
-                                  "type must be array, but is null");
+                CHECK_THROWS_WITH((json().get<std::list<int>>()), "type must be array, but is null");
+                CHECK_THROWS_WITH((json().get<std::vector<int>>()), "type must be array, but is null");
+                CHECK_THROWS_WITH((json().get<std::vector<json>>()), "type must be array, but is null");
+                CHECK_THROWS_WITH((json().get<std::list<json>>()), "type must be array, but is null");
             }
         }
     }
@@ -2791,8 +2773,8 @@ TEST_CASE("element access")
                 CHECK_THROWS_AS(j.at(7), std::out_of_range);
                 CHECK_THROWS_AS(j_const.at(7), std::out_of_range);
 
-                CHECK_THROWS_NAME(j.at(7), std::out_of_range, "array index 7 is out of range");
-                CHECK_THROWS_NAME(j_const.at(7), std::out_of_range, "array index 7 is out of range");
+                CHECK_THROWS_WITH(j.at(7), "array index 7 is out of range");
+                CHECK_THROWS_WITH(j_const.at(7), "array index 7 is out of range");
             }
 
             SECTION("access on non-array type")
@@ -2804,8 +2786,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with null");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with null");
+                    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")
@@ -2815,8 +2797,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with boolean");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with boolean");
+                    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")
@@ -2826,8 +2808,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with string");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with string");
+                    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")
@@ -2837,8 +2819,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with object");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with object");
+                    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)")
@@ -2848,8 +2830,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with number");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with number");
+                    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)")
@@ -2859,8 +2841,8 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
                     CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
 
-                    CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with number");
-                    CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with number");
+                    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");
                 }
             }
         }
@@ -2904,7 +2886,7 @@ TEST_CASE("element access")
                         const json j_nonarray_const(j_nonarray);
                         CHECK_NOTHROW(j_nonarray[0]);
                         CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
-                        CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with null");
+                        CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with null");
                     }
 
                     SECTION("implicit transformation to properly filled array")
@@ -2921,8 +2903,8 @@ TEST_CASE("element access")
                     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_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with boolean");
-                    CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with boolean");
+                    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")
@@ -2931,8 +2913,8 @@ TEST_CASE("element access")
                     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_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with string");
-                    CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with string");
+                    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")
@@ -2941,8 +2923,8 @@ TEST_CASE("element access")
                     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_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with object");
-                    CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with object");
+                    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)")
@@ -2951,8 +2933,8 @@ TEST_CASE("element access")
                     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_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with number");
+                    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)")
@@ -2961,8 +2943,8 @@ TEST_CASE("element access")
                     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_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_nonarray[0], "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_nonarray_const[0], "cannot use operator[] with number");
                 }
             }
         }
@@ -3009,7 +2991,7 @@ TEST_CASE("element access")
                 {
                     json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
                     CHECK_THROWS_AS(jarray.erase(7), std::out_of_range);
-                    CHECK_THROWS_NAME(jarray.erase(7), std::out_of_range, "index out of range");
+                    CHECK_THROWS_WITH(jarray.erase(7), "index out of range");
                 }
             }
 
@@ -3107,13 +3089,12 @@ TEST_CASE("element access")
                         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_NAME(jarray.erase(jarray2.begin()), std::domain_error,
-                                          "iterator does not fit current value");
-                        CHECK_THROWS_NAME(jarray.erase(jarray.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_NAME(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error,
+                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray.end()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error,
+                        CHECK_THROWS_WITH(jarray.erase(jarray2.begin(), jarray2.end()),
                                           "iterators do not fit current value");
                     }
                     {
@@ -3124,13 +3105,12 @@ TEST_CASE("element access")
                         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_NAME(jarray.erase(jarray2.cbegin()), std::domain_error,
-                                          "iterator does not fit current value");
-                        CHECK_THROWS_NAME(jarray.erase(jarray.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_NAME(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error,
+                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray.cend()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error,
+                        CHECK_THROWS_WITH(jarray.erase(jarray2.cbegin(), jarray2.cend()),
                                           "iterators do not fit current value");
                     }
                 }
@@ -3142,42 +3122,42 @@ TEST_CASE("element access")
                 {
                     json j_nonobject(json::value_t::null);
                     CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with null");
+                    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_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with boolean");
+                    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_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with string");
+                    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_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with object");
+                    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_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with number");
+                    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_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with number");
+                    CHECK_THROWS_WITH(j_nonobject.erase(0), "cannot use erase() with number");
                 }
             }
         }
@@ -3213,8 +3193,8 @@ TEST_CASE("element access")
             {
                 CHECK_THROWS_AS(j.at("foo"), std::out_of_range);
                 CHECK_THROWS_AS(j_const.at("foo"), std::out_of_range);
-                CHECK_THROWS_NAME(j.at("foo"), std::out_of_range, "key 'foo' not found");
-                CHECK_THROWS_NAME(j_const.at("foo"), std::out_of_range, "key 'foo' not found");
+                CHECK_THROWS_WITH(j.at("foo"), "key 'foo' not found");
+                CHECK_THROWS_WITH(j_const.at("foo"), "key 'foo' not found");
             }
 
             SECTION("access on non-object type")
@@ -3225,8 +3205,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with null");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with null");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with null");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with null");
                 }
 
                 SECTION("boolean")
@@ -3235,8 +3215,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with boolean");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with boolean");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with boolean");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with boolean");
                 }
 
                 SECTION("string")
@@ -3245,8 +3225,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with string");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with string");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with string");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with string");
                 }
 
                 SECTION("array")
@@ -3255,8 +3235,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with array");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with array");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with array");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with array");
                 }
 
                 SECTION("number (integer)")
@@ -3265,8 +3245,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with number");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with number");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number");
                 }
 
                 SECTION("number (floating-point)")
@@ -3275,8 +3255,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with number");
-                    CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with number");
+                    CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number");
+                    CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number");
                 }
             }
         }
@@ -3332,9 +3312,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with null");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with null");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with null");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with null");
                 }
 
                 SECTION("boolean")
@@ -3343,10 +3322,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error,
-                                      "cannot use value() with boolean");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with boolean");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with boolean");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with boolean");
                 }
 
                 SECTION("string")
@@ -3355,9 +3332,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with string");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with string");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with string");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with string");
                 }
 
                 SECTION("array")
@@ -3366,9 +3342,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with array");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with array");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with array");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with array");
                 }
 
                 SECTION("number (integer)")
@@ -3377,9 +3352,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with number");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with number");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number");
                 }
 
                 SECTION("number (floating-point)")
@@ -3388,9 +3362,8 @@ TEST_CASE("element access")
                     const json j_nonobject_const(j_nonobject);
                     CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
                     CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with number");
-                    CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
-                                      "cannot use value() with number");
+                    CHECK_THROWS_WITH(j_nonobject.value("foo", 1), "cannot use value() with number");
+                    CHECK_THROWS_WITH(j_nonobject_const.value("foo", 1), "cannot use value() with number");
                 }
             }
         }
@@ -3463,8 +3436,8 @@ TEST_CASE("element access")
                     CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with null");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with null");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with null");
                 }
 
@@ -3476,12 +3449,11 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with boolean");
-                    CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with boolean");
+                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with boolean");
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error,
-                                      "cannot use operator[] with boolean");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with boolean");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with boolean");
                 }
 
@@ -3493,11 +3465,11 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with string");
-                    CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with string");
+                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with string");
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with string");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with string");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with string");
                 }
 
@@ -3509,11 +3481,10 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with array");
-                    CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
-                                      "cannot use operator[] with array");
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with array");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with array");
+                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")], "cannot use operator[] with array");
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with array");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with array");
                 }
 
@@ -3525,11 +3496,11 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with number");
                 }
 
@@ -3541,11 +3512,11 @@ TEST_CASE("element access")
                     CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
                     CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_nonobject["foo"], "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
-                    CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
+                    CHECK_THROWS_WITH(j_const_nonobject["foo"], "cannot use operator[] with number");
+                    CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
                                       "cannot use operator[] with number");
                 }
             }
@@ -3684,13 +3655,12 @@ TEST_CASE("element access")
                         CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error);
                         CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error);
                         CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error);
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.begin()), std::domain_error,
-                                          "iterator does not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin()), "iterator does not fit current value");
+                        CHECK_THROWS_WITH(jobject.erase(jobject.begin(), jobject2.end()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject.end()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.begin(), jobject2.end()),
                                           "iterators do not fit current value");
                     }
                     {
@@ -3700,13 +3670,12 @@ TEST_CASE("element access")
                         CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error);
                         CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error);
                         CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error);
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin()), std::domain_error,
-                                          "iterator does not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin()), "iterator does not fit current value");
+                        CHECK_THROWS_WITH(jobject.erase(jobject.cbegin(), jobject2.cend()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject.cend()),
                                           "iterators do not fit current value");
-                        CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error,
+                        CHECK_THROWS_WITH(jobject.erase(jobject2.cbegin(), jobject2.cend()),
                                           "iterators do not fit current value");
                     }
                 }
@@ -3718,42 +3687,42 @@ TEST_CASE("element access")
                 {
                     json j_nonobject(json::value_t::null);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with null");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with null");
                 }
 
                 SECTION("boolean")
                 {
                     json j_nonobject(json::value_t::boolean);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with boolean");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with boolean");
                 }
 
                 SECTION("string")
                 {
                     json j_nonobject(json::value_t::string);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with string");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with string");
                 }
 
                 SECTION("array")
                 {
                     json j_nonobject(json::value_t::array);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with array");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with array");
                 }
 
                 SECTION("number (integer)")
                 {
                     json j_nonobject(json::value_t::number_integer);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with number");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number");
                 }
 
                 SECTION("number (floating-point)")
                 {
                     json j_nonobject(json::value_t::number_float);
                     CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
-                    CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with number");
+                    CHECK_THROWS_WITH(j_nonobject.erase("foo"), "cannot use erase() with number");
                 }
             }
         }
@@ -3929,15 +3898,15 @@ TEST_CASE("element access")
                     json j;
                     CHECK_THROWS_AS(j.front(), std::out_of_range);
                     CHECK_THROWS_AS(j.back(), std::out_of_range);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
+                    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_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
+                    CHECK_THROWS_WITH(j.front(), "cannot get value");
+                    CHECK_THROWS_WITH(j.back(), "cannot get value");
                 }
             }
 
@@ -3947,15 +3916,11 @@ TEST_CASE("element access")
                     json j = "foo";
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
                 {
                     const json j = "bar";
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
             }
 
@@ -3965,15 +3930,11 @@ TEST_CASE("element access")
                     json j = false;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
                 {
                     const json j = true;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
             }
 
@@ -3983,15 +3944,11 @@ TEST_CASE("element access")
                     json j = 17;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
                 {
                     const json j = 17;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
             }
 
@@ -4001,15 +3958,11 @@ TEST_CASE("element access")
                     json j = 23.42;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
                 {
                     const json j = 23.42;
                     CHECK(j.front() == j);
                     CHECK(j.back() == j);
-                    CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
                 }
             }
         }
@@ -4021,12 +3974,12 @@ TEST_CASE("element access")
                 {
                     json j;
                     CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error);
-                    CHECK_THROWS_NAME(j.erase(j.begin()), std::domain_error, "cannot use erase() with null");
+                    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_NAME(j.erase(j.begin()), std::domain_error, "cannot use erase() with null");
+                    CHECK_THROWS_WITH(j.erase(j.begin()), "cannot use erase() with null");
                 }
             }
 
@@ -4102,12 +4055,12 @@ TEST_CASE("element access")
                 {
                     json j = "foo";
                     CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
-                    CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator 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_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
+                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
                 }
             }
 
@@ -4116,12 +4069,12 @@ TEST_CASE("element access")
                 {
                     json j = false;
                     CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
-                    CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator 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_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
+                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
                 }
             }
 
@@ -4130,12 +4083,12 @@ TEST_CASE("element access")
                 {
                     json j = 17;
                     CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
-                    CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator 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_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
+                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
                 }
             }
 
@@ -4144,12 +4097,12 @@ TEST_CASE("element access")
                 {
                     json j = 23.42;
                     CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
-                    CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator 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_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
+                    CHECK_THROWS_WITH(j.erase(j.cend()), "iterator out of range");
                 }
             }
         }
@@ -4161,12 +4114,12 @@ TEST_CASE("element access")
                 {
                     json j;
                     CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error);
-                    CHECK_THROWS_NAME(j.erase(j.begin(), j.end()), std::domain_error, "cannot use erase() with null");
+                    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_NAME(j.erase(j.cbegin(), j.cend()), std::domain_error, "cannot use erase() with null");
+                    CHECK_THROWS_WITH(j.erase(j.cbegin(), j.cend()), "cannot use erase() with null");
                 }
             }
 
@@ -4243,15 +4196,15 @@ TEST_CASE("element access")
                     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_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators 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_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators 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");
                 }
             }
 
@@ -4261,15 +4214,15 @@ TEST_CASE("element access")
                     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_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators 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_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators 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");
                 }
             }
 
@@ -4279,15 +4232,15 @@ TEST_CASE("element access")
                     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_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators 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_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators 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");
                 }
             }
 
@@ -4297,15 +4250,15 @@ TEST_CASE("element access")
                     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_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators 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_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
-                    CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators 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");
                 }
             }
         }
@@ -4510,10 +4463,10 @@ TEST_CASE("iterators")
                 auto it = j.begin();
                 auto cit = j_const.cbegin();
                 CHECK_THROWS_AS(it.key(), std::domain_error);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
                 CHECK(it.value() == json(true));
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
                 CHECK(cit.value() == json(true));
 
                 auto rit = j.rend();
@@ -4522,10 +4475,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(rit.value(), std::out_of_range);
                 CHECK_THROWS_AS(crit.key(), std::domain_error);
                 CHECK_THROWS_AS(crit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(rit.value(), "cannot get value");
+                CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(crit.value(), "cannot get value");
             }
         }
 
@@ -4714,10 +4667,10 @@ TEST_CASE("iterators")
                 auto it = j.begin();
                 auto cit = j_const.cbegin();
                 CHECK_THROWS_AS(it.key(), std::domain_error);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
                 CHECK(it.value() == json("hello world"));
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
                 CHECK(cit.value() == json("hello world"));
 
                 auto rit = j.rend();
@@ -4726,10 +4679,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(rit.value(), std::out_of_range);
                 CHECK_THROWS_AS(crit.key(), std::domain_error);
                 CHECK_THROWS_AS(crit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(rit.value(), "cannot get value");
+                CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(crit.value(), "cannot get value");
             }
         }
 
@@ -4911,10 +4864,10 @@ TEST_CASE("iterators")
                 auto it = j.begin();
                 auto cit = j_const.cbegin();
                 CHECK_THROWS_AS(it.key(), std::domain_error);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
                 CHECK(it.value() == json(1));
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
                 CHECK(cit.value() == json(1));
             }
         }
@@ -5288,10 +5241,10 @@ TEST_CASE("iterators")
                 auto it = j.begin();
                 auto cit = j_const.cbegin();
                 CHECK_THROWS_AS(it.key(), std::domain_error);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
                 CHECK(it.value() == json(23));
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
                 CHECK(cit.value() == json(23));
 
                 auto rit = j.rend();
@@ -5300,10 +5253,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(rit.value(), std::out_of_range);
                 CHECK_THROWS_AS(crit.key(), std::domain_error);
                 CHECK_THROWS_AS(crit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(rit.value(), "cannot get value");
+                CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(crit.value(), "cannot get value");
             }
         }
 
@@ -5492,10 +5445,10 @@ TEST_CASE("iterators")
                 auto it = j.begin();
                 auto cit = j_const.cbegin();
                 CHECK_THROWS_AS(it.key(), std::domain_error);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
                 CHECK(it.value() == json(23.42));
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
                 CHECK(cit.value() == json(23.42));
 
                 auto rit = j.rend();
@@ -5504,10 +5457,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(rit.value(), std::out_of_range);
                 CHECK_THROWS_AS(crit.key(), std::domain_error);
                 CHECK_THROWS_AS(crit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(rit.value(), "cannot get value");
+                CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(crit.value(), "cannot get value");
             }
         }
 
@@ -5569,10 +5522,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(it.value(), std::out_of_range);
                 CHECK_THROWS_AS(cit.key(), std::domain_error);
                 CHECK_THROWS_AS(cit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(it.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(cit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(it.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(it.value(), "cannot get value");
+                CHECK_THROWS_WITH(cit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(cit.value(), "cannot get value");
 
                 auto rit = j.rend();
                 auto crit = j.crend();
@@ -5580,10 +5533,10 @@ TEST_CASE("iterators")
                 CHECK_THROWS_AS(rit.value(), std::out_of_range);
                 CHECK_THROWS_AS(crit.key(), std::domain_error);
                 CHECK_THROWS_AS(crit.value(), std::out_of_range);
-                CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
-                CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
-                CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(rit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(rit.value(), "cannot get value");
+                CHECK_THROWS_WITH(crit.key(), "cannot use key() for non-object iterators");
+                CHECK_THROWS_WITH(crit.value(), "cannot get value");
             }
         }
     }
@@ -5644,14 +5597,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 < it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 < it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 < it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 < it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c < it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -5678,14 +5631,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 <= it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 <= it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 <= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 <= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -5713,14 +5666,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 > it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 > it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 > it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 > it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c > it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -5748,14 +5701,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 >= it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 >= it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 >= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 >= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -5781,17 +5734,13 @@ TEST_CASE("iterators")
                 {
                     CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error);
                     CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error);
-                    CHECK_THROWS_NAME(j.begin() == k.begin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
-                    CHECK_THROWS_NAME(j.cbegin() == k.cbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
+                    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_NAME(j.begin() < k.begin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
-                    CHECK_THROWS_NAME(j.cbegin() < k.cbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
+                    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");
                 }
             }
         }
@@ -5811,52 +5760,52 @@ TEST_CASE("iterators")
                 {
                     auto it = j_object.begin();
                     CHECK_THROWS_AS(it += 1, std::domain_error);
-                    CHECK_THROWS_NAME(it += 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it += 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it + 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it + 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it -= 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it -= 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
                 }
             }
 
@@ -5941,15 +5890,15 @@ TEST_CASE("iterators")
                     auto it = j_object.begin();
                     CHECK_THROWS_AS(it[0], std::domain_error);
                     CHECK_THROWS_AS(it[1], std::domain_error);
-                    CHECK_THROWS_NAME(it[0], std::domain_error, "cannot use operator[] for object iterators");
-                    CHECK_THROWS_NAME(it[1], std::domain_error, "cannot use operator[] for object iterators");
+                    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_NAME(it[0], std::domain_error, "cannot use operator[] for object iterators");
-                    CHECK_THROWS_NAME(it[1], std::domain_error, "cannot use operator[] for object iterators");
+                    CHECK_THROWS_WITH(it[0], "cannot use operator[] for object iterators");
+                    CHECK_THROWS_WITH(it[1], "cannot use operator[] for object iterators");
                 }
             }
 
@@ -5981,15 +5930,15 @@ TEST_CASE("iterators")
                     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_NAME(it[0], std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    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_NAME(it[0], std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    CHECK_THROWS_WITH(it[0], "cannot get value");
+                    CHECK_THROWS_WITH(it[1], "cannot get value");
                 }
             }
 
@@ -5999,13 +5948,13 @@ TEST_CASE("iterators")
                     auto it = j_value.begin();
                     CHECK(it[0] == json(42));
                     CHECK_THROWS_AS(it[1], std::out_of_range);
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    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_NAME(it[1], std::out_of_range, "cannot get value");
+                    CHECK_THROWS_WITH(it[1], "cannot get value");
                 }
             }
         }
@@ -6067,14 +6016,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 < it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 < it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 < it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 < it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c < it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c < it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -6101,14 +6050,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 <= it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 <= it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 <= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 <= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -6136,14 +6085,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 > it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 > it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 > it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 > it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c > it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c > it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -6171,14 +6120,14 @@ TEST_CASE("iterators")
                     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_NAME(it1 >= it1, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 >= it2, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2 >= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1 >= it3, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it1_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it2_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it2_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
-                    CHECK_THROWS_NAME(it1_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
+                    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
                 {
@@ -6204,17 +6153,13 @@ TEST_CASE("iterators")
                 {
                     CHECK_THROWS_AS(j.rbegin() == k.rbegin(), std::domain_error);
                     CHECK_THROWS_AS(j.crbegin() == k.crbegin(), std::domain_error);
-                    CHECK_THROWS_NAME(j.rbegin() == k.rbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
-                    CHECK_THROWS_NAME(j.crbegin() == k.crbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
+                    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_NAME(j.rbegin() < k.rbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
-                    CHECK_THROWS_NAME(j.crbegin() < k.crbegin(), std::domain_error,
-                                      "cannot compare iterators of different containers");
+                    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");
                 }
             }
         }
@@ -6234,52 +6179,52 @@ TEST_CASE("iterators")
                 {
                     auto it = j_object.rbegin();
                     CHECK_THROWS_AS(it += 1, std::domain_error);
-                    CHECK_THROWS_NAME(it += 1, std::domain_error, "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 += 1, std::domain_error);
-                    CHECK_THROWS_NAME(it += 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it + 1, std::domain_error, "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 + 1, std::domain_error);
-                    CHECK_THROWS_NAME(it + 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it -= 1, std::domain_error, "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 -= 1, std::domain_error);
-                    CHECK_THROWS_NAME(it -= 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - 1, std::domain_error, "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 - 1, std::domain_error);
-                    CHECK_THROWS_NAME(it - 1, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it - it, "cannot use offsets with object iterators");
                 }
             }
 
@@ -6364,15 +6309,15 @@ TEST_CASE("iterators")
                     auto it = j_object.rbegin();
                     CHECK_THROWS_AS(it[0], std::domain_error);
                     CHECK_THROWS_AS(it[1], std::domain_error);
-                    CHECK_THROWS_NAME(it[0], std::domain_error, "cannot use offsets with object iterators");
-                    CHECK_THROWS_NAME(it[1], std::domain_error, "cannot use offsets with object iterators");
+                    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_NAME(it[0], std::domain_error, "cannot use offsets with object iterators");
-                    CHECK_THROWS_NAME(it[1], std::domain_error, "cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[0], "cannot use offsets with object iterators");
+                    CHECK_THROWS_WITH(it[1], "cannot use offsets with object iterators");
                 }
             }
 
@@ -6404,15 +6349,15 @@ TEST_CASE("iterators")
                     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_NAME(it[0], std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    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_NAME(it[0], std::out_of_range, "cannot get value");
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    CHECK_THROWS_WITH(it[0], "cannot get value");
+                    CHECK_THROWS_WITH(it[1], "cannot get value");
                 }
             }
 
@@ -6422,13 +6367,13 @@ TEST_CASE("iterators")
                     auto it = j_value.rbegin();
                     CHECK(it[0] == json(42));
                     CHECK_THROWS_AS(it[1], std::out_of_range);
-                    CHECK_THROWS_NAME(it[1], std::out_of_range, "cannot get value");
+                    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_NAME(it[1], std::out_of_range, "cannot get value");
+                    CHECK_THROWS_WITH(it[1], "cannot get value");
                 }
             }
         }
@@ -7029,7 +6974,7 @@ TEST_CASE("modifiers")
                 {
                     json j = 1;
                     CHECK_THROWS_AS(j.push_back("Hello"), std::domain_error);
-                    CHECK_THROWS_NAME(j.push_back("Hello"), std::domain_error, "cannot use push_back() with number");
+                    CHECK_THROWS_WITH(j.push_back("Hello"), "cannot use push_back() with number");
                 }
             }
 
@@ -7059,7 +7004,7 @@ TEST_CASE("modifiers")
                     json j = 1;
                     json k("Hello");
                     CHECK_THROWS_AS(j.push_back(k), std::domain_error);
-                    CHECK_THROWS_NAME(j.push_back(k), std::domain_error, "cannot use push_back() with number");
+                    CHECK_THROWS_WITH(j.push_back(k), "cannot use push_back() with number");
                 }
             }
         }
@@ -7092,7 +7037,7 @@ TEST_CASE("modifiers")
                 json j = 1;
                 json k("Hello");
                 CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error);
-                CHECK_THROWS_NAME(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error,
+                CHECK_THROWS_WITH(j.push_back(json::object_t::value_type({"one", 1})),
                                   "cannot use push_back() with number");
             }
         }
@@ -7125,7 +7070,7 @@ TEST_CASE("modifiers")
                 {
                     json j = 1;
                     CHECK_THROWS_AS(j += "Hello", std::domain_error);
-                    CHECK_THROWS_NAME(j += "Hello", std::domain_error, "cannot use push_back() with number");
+                    CHECK_THROWS_WITH(j += "Hello", "cannot use push_back() with number");
                 }
             }
 
@@ -7155,7 +7100,7 @@ TEST_CASE("modifiers")
                     json j = 1;
                     json k("Hello");
                     CHECK_THROWS_AS(j += k, std::domain_error);
-                    CHECK_THROWS_NAME(j += k, std::domain_error, "cannot use push_back() with number");
+                    CHECK_THROWS_WITH(j += k, "cannot use push_back() with number");
                 }
             }
         }
@@ -7188,7 +7133,7 @@ TEST_CASE("modifiers")
                 json j = 1;
                 json k("Hello");
                 CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), std::domain_error);
-                CHECK_THROWS_NAME(j += json::object_t::value_type({"one", 1}), std::domain_error,
+                CHECK_THROWS_WITH(j += json::object_t::value_type({"one", 1}),
                                   "cannot use push_back() with number");
             }
         }
@@ -7327,10 +7272,10 @@ TEST_CASE("modifiers")
                 CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
                                 std::domain_error);
 
-                CHECK_THROWS_NAME(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error,
+                CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
                                   "passed iterators may not belong to container");
-                CHECK_THROWS_NAME(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
-                                  std::domain_error, "iterators do not fit");
+                CHECK_THROWS_WITH(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
+                                  "iterators do not fit");
             }
         }
 
@@ -7376,15 +7321,14 @@ TEST_CASE("modifiers")
                                            j_yet_another_array.end()), std::domain_error);
             CHECK_THROWS_AS(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), std::domain_error);
 
-            CHECK_THROWS_NAME(j_array.insert(j_another_array.end(), 10), std::domain_error,
+            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10), "iterator does not fit current value");
+            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_value),
                               "iterator does not fit current value");
-            CHECK_THROWS_NAME(j_array.insert(j_another_array.end(), j_value), std::domain_error,
+            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), 10, 11),
                               "iterator does not fit current value");
-            CHECK_THROWS_NAME(j_array.insert(j_another_array.end(), 10, 11), std::domain_error,
-                              "iterator does not fit current value");
-            CHECK_THROWS_NAME(j_array.insert(j_another_array.end(), j_yet_another_array.begin(),
-                                             j_yet_another_array.end()), std::domain_error, "iterator does not fit current value");
-            CHECK_THROWS_NAME(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), std::domain_error,
+            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), j_yet_another_array.begin(),
+                                             j_yet_another_array.end()), "iterator does not fit current value");
+            CHECK_THROWS_WITH(j_array.insert(j_another_array.end(), {1, 2, 3, 4}),
                               "iterator does not fit current value");
         }
 
@@ -7400,15 +7344,12 @@ TEST_CASE("modifiers")
                                               j_yet_another_array.end()), std::domain_error);
             CHECK_THROWS_AS(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), std::domain_error);
 
-            CHECK_THROWS_NAME(j_nonarray.insert(j_nonarray.end(), 10), std::domain_error,
-                              "cannot use insert() with number");
-            CHECK_THROWS_NAME(j_nonarray.insert(j_nonarray.end(), j_value), std::domain_error,
-                              "cannot use insert() with number");
-            CHECK_THROWS_NAME(j_nonarray.insert(j_nonarray.end(), 10, 11), std::domain_error,
-                              "cannot use insert() with number");
-            CHECK_THROWS_NAME(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
-                                                j_yet_another_array.end()), std::domain_error, "cannot use insert() with number");
-            CHECK_THROWS_NAME(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), std::domain_error,
+            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10), "cannot use insert() with number");
+            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_value), "cannot use insert() with number");
+            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), 10, 11), "cannot use insert() with number");
+            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
+                                                j_yet_another_array.end()), "cannot use insert() with number");
+            CHECK_THROWS_WITH(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}),
                               "cannot use insert() with number");
         }
     }
@@ -7462,7 +7403,7 @@ TEST_CASE("modifiers")
                 json::array_t a = {"foo", "bar", "baz"};
 
                 CHECK_THROWS_AS(j.swap(a), std::domain_error);
-                CHECK_THROWS_NAME(j.swap(a), std::domain_error, "cannot use swap() with number");
+                CHECK_THROWS_WITH(j.swap(a), "cannot use swap() with number");
             }
         }
 
@@ -7488,7 +7429,7 @@ TEST_CASE("modifiers")
                 json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
 
                 CHECK_THROWS_AS(j.swap(o), std::domain_error);
-                CHECK_THROWS_NAME(j.swap(o), std::domain_error, "cannot use swap() with number");
+                CHECK_THROWS_WITH(j.swap(o), "cannot use swap() with number");
             }
         }
 
@@ -7514,7 +7455,7 @@ TEST_CASE("modifiers")
                 json::string_t s = "Hallo Welt";
 
                 CHECK_THROWS_AS(j.swap(s), std::domain_error);
-                CHECK_THROWS_NAME(j.swap(s), std::domain_error, "cannot use swap() with number");
+                CHECK_THROWS_WITH(j.swap(s), "cannot use swap() with number");
             }
         }
     }
@@ -7899,7 +7840,7 @@ TEST_CASE("iterator class")
                 json j(json::value_t::null);
                 json::iterator it = j.begin();
                 CHECK_THROWS_AS(*it, std::out_of_range);
-                CHECK_THROWS_NAME(*it, std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(*it, "cannot get value");
             }
 
             SECTION("number")
@@ -7909,7 +7850,7 @@ TEST_CASE("iterator class")
                 CHECK(*it == json(17));
                 it = j.end();
                 CHECK_THROWS_AS(*it, std::out_of_range);
-                CHECK_THROWS_NAME(*it, std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(*it, "cannot get value");
             }
 
             SECTION("object")
@@ -7934,7 +7875,7 @@ TEST_CASE("iterator class")
                 json j(json::value_t::null);
                 json::iterator it = j.begin();
                 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
-                CHECK_THROWS_NAME(it->type_name(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(it->type_name(), "cannot get value");
             }
 
             SECTION("number")
@@ -7944,7 +7885,7 @@ TEST_CASE("iterator class")
                 CHECK(it->type_name() == "number");
                 it = j.end();
                 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
-                CHECK_THROWS_NAME(it->type_name(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(it->type_name(), "cannot get value");
             }
 
             SECTION("object")
@@ -8267,7 +8208,7 @@ TEST_CASE("const_iterator class")
                 json j(json::value_t::null);
                 json::const_iterator it = j.cbegin();
                 CHECK_THROWS_AS(*it, std::out_of_range);
-                CHECK_THROWS_NAME(*it, std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(*it, "cannot get value");
             }
 
             SECTION("number")
@@ -8277,7 +8218,7 @@ TEST_CASE("const_iterator class")
                 CHECK(*it == json(17));
                 it = j.cend();
                 CHECK_THROWS_AS(*it, std::out_of_range);
-                CHECK_THROWS_NAME(*it, std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(*it, "cannot get value");
             }
 
             SECTION("object")
@@ -8302,7 +8243,7 @@ TEST_CASE("const_iterator class")
                 json j(json::value_t::null);
                 json::const_iterator it = j.cbegin();
                 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
-                CHECK_THROWS_NAME(it->type_name(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(it->type_name(), "cannot get value");
             }
 
             SECTION("number")
@@ -8312,7 +8253,7 @@ TEST_CASE("const_iterator class")
                 CHECK(it->type_name() == "number");
                 it = j.cend();
                 CHECK_THROWS_AS(it->type_name(), std::out_of_range);
-                CHECK_THROWS_NAME(it->type_name(), std::out_of_range, "cannot get value");
+                CHECK_THROWS_WITH(it->type_name(), "cannot get value");
             }
 
             SECTION("object")
@@ -8711,8 +8652,7 @@ TEST_CASE("lexer class")
     {
         CHECK(json::lexer::to_unicode(0x1F4A9) == "💩");
         CHECK_THROWS_AS(json::lexer::to_unicode(0x200000), std::out_of_range);
-        CHECK_THROWS_NAME(json::lexer::to_unicode(0x200000), std::out_of_range,
-                          "code points above 0x10FFFF are invalid");
+        CHECK_THROWS_WITH(json::lexer::to_unicode(0x200000), "code points above 0x10FFFF are invalid");
     }
 }
 
@@ -8772,19 +8712,15 @@ TEST_CASE("parser class")
             {
                 // error: tab in string
                 CHECK_THROWS_AS(json::parser("\"\t\"").parse(), std::invalid_argument);
-                CHECK_THROWS_NAME(json::parser("\"\t\"").parse(), std::invalid_argument,
-                                  "parse error - unexpected '\"'");
+                CHECK_THROWS_WITH(json::parser("\"\t\"").parse(), "parse error - unexpected '\"'");
                 // error: newline in string
                 CHECK_THROWS_AS(json::parser("\"\n\"").parse(), std::invalid_argument);
                 CHECK_THROWS_AS(json::parser("\"\r\"").parse(), std::invalid_argument);
-                CHECK_THROWS_NAME(json::parser("\"\n\"").parse(), std::invalid_argument,
-                                  "parse error - unexpected '\"'");
-                CHECK_THROWS_NAME(json::parser("\"\r\"").parse(), std::invalid_argument,
-                                  "parse error - unexpected '\"'");
+                CHECK_THROWS_WITH(json::parser("\"\n\"").parse(), "parse error - unexpected '\"'");
+                CHECK_THROWS_WITH(json::parser("\"\r\"").parse(), "parse error - unexpected '\"'");
                 // error: backspace in string
                 CHECK_THROWS_AS(json::parser("\"\b\"").parse(), std::invalid_argument);
-                CHECK_THROWS_NAME(json::parser("\"\b\"").parse(), std::invalid_argument,
-                                  "parse error - unexpected '\"'");
+                CHECK_THROWS_WITH(json::parser("\"\b\"").parse(), "parse error - unexpected '\"'");
             }
 
             SECTION("escaped")
@@ -8922,37 +8858,33 @@ TEST_CASE("parser class")
                 CHECK_THROWS_AS(json::parser("-0e-:").parse(), std::invalid_argument);
                 CHECK_THROWS_AS(json::parser("-0f").parse(), std::invalid_argument);
 
-                CHECK_THROWS_NAME(json::parser("01").parse(), std::invalid_argument,
-                                  "parse error - 0 is not a number");
-                CHECK_THROWS_NAME(json::parser("--1").parse(), std::invalid_argument,
-                                  "parse error - unexpected '-'");
-                CHECK_THROWS_NAME(json::parser("1.").parse(), std::invalid_argument,
-                                  "parse error - 1 is not a number");
-                CHECK_THROWS_NAME(json::parser("1E").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("01").parse(), "parse error - 0 is not a number");
+                CHECK_THROWS_WITH(json::parser("--1").parse(), "parse error - unexpected '-'");
+                CHECK_THROWS_WITH(json::parser("1.").parse(), "parse error - 1 is not a number");
+                CHECK_THROWS_WITH(json::parser("1E").parse(),
                                   "parse error - unexpected 'E'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("1E-").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("1E-").parse(),
                                   "parse error - unexpected 'E'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("1.E1").parse(), std::invalid_argument,
-                                  "parse error - 1 is not a number");
-                CHECK_THROWS_NAME(json::parser("-1E").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("1.E1").parse(), "parse error - 1 is not a number");
+                CHECK_THROWS_WITH(json::parser("-1E").parse(),
                                   "parse error - unexpected 'E'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0E#").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0E#").parse(),
                                   "parse error - unexpected 'E'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0E-#").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0E-#").parse(),
                                   "parse error - unexpected 'E'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0#").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0#").parse(),
                                   "parse error - unexpected '#'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0.0:").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0.0:").parse(),
                                   "parse error - unexpected ':'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0.0Z").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0.0Z").parse(),
                                   "parse error - unexpected 'Z'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0E123:").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0E123:").parse(),
                                   "parse error - unexpected ':'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0e0-:").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0e0-:").parse(),
                                   "parse error - unexpected '-'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0e-:").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0e-:").parse(),
                                   "parse error - unexpected 'e'; expected end of input");
-                CHECK_THROWS_NAME(json::parser("-0f").parse(), std::invalid_argument,
+                CHECK_THROWS_WITH(json::parser("-0f").parse(),
                                   "parse error - unexpected 'f'; expected end of input");
             }
         }
@@ -8975,52 +8907,51 @@ TEST_CASE("parser class")
         CHECK_THROWS_AS(json::parser("1E.").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("1E/").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("1E:").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("0.").parse(), std::invalid_argument,
-                          "parse error - 0 is not a number");
-        CHECK_THROWS_NAME(json::parser("-").parse(), std::invalid_argument, "parse error - unexpected '-'");
-        CHECK_THROWS_NAME(json::parser("--").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("0.").parse(), "parse error - 0 is not a number");
+        CHECK_THROWS_WITH(json::parser("-").parse(), "parse error - unexpected '-'");
+        CHECK_THROWS_WITH(json::parser("--").parse(),
                           "parse error - unexpected '-'");
-        CHECK_THROWS_NAME(json::parser("-0.").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("-0.").parse(),
                           "parse error - -0 is not a number");
-        CHECK_THROWS_NAME(json::parser("-.").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("-.").parse(),
                           "parse error - unexpected '-'");
-        CHECK_THROWS_NAME(json::parser("-:").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("-:").parse(),
                           "parse error - unexpected '-'");
-        CHECK_THROWS_NAME(json::parser("0.:").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("0.:").parse(),
                           "parse error - 0 is not a number");
-        CHECK_THROWS_NAME(json::parser("e.").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("e.").parse(),
                           "parse error - unexpected 'e'");
-        CHECK_THROWS_NAME(json::parser("1e.").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1e.").parse(),
                           "parse error - unexpected 'e'; expected end of input");
-        CHECK_THROWS_NAME(json::parser("1e/").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1e/").parse(),
                           "parse error - unexpected 'e'; expected end of input");
-        CHECK_THROWS_NAME(json::parser("1e:").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1e:").parse(),
                           "parse error - unexpected 'e'; expected end of input");
-        CHECK_THROWS_NAME(json::parser("1E.").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1E.").parse(),
                           "parse error - unexpected 'E'; expected end of input");
-        CHECK_THROWS_NAME(json::parser("1E/").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1E/").parse(),
                           "parse error - unexpected 'E'; expected end of input");
-        CHECK_THROWS_NAME(json::parser("1E:").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("1E:").parse(),
                           "parse error - unexpected 'E'; expected end of input");
 
         // unexpected end of null
         CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("nu").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("nul").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("n").parse(), std::invalid_argument, "parse error - unexpected 'n'");
-        CHECK_THROWS_NAME(json::parser("nu").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("n").parse(), "parse error - unexpected 'n'");
+        CHECK_THROWS_WITH(json::parser("nu").parse(),
                           "parse error - unexpected 'n'");
-        CHECK_THROWS_NAME(json::parser("nul").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("nul").parse(),
                           "parse error - unexpected 'n'");
 
         // unexpected end of true
         CHECK_THROWS_AS(json::parser("t").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("tr").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("tru").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("t").parse(), std::invalid_argument, "parse error - unexpected 't'");
-        CHECK_THROWS_NAME(json::parser("tr").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("t").parse(), "parse error - unexpected 't'");
+        CHECK_THROWS_WITH(json::parser("tr").parse(),
                           "parse error - unexpected 't'");
-        CHECK_THROWS_NAME(json::parser("tru").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("tru").parse(),
                           "parse error - unexpected 't'");
 
         // unexpected end of false
@@ -9028,12 +8959,12 @@ TEST_CASE("parser class")
         CHECK_THROWS_AS(json::parser("fa").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("fal").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("fals").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("f").parse(), std::invalid_argument, "parse error - unexpected 'f'");
-        CHECK_THROWS_NAME(json::parser("fa").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("f").parse(), "parse error - unexpected 'f'");
+        CHECK_THROWS_WITH(json::parser("fa").parse(),
                           "parse error - unexpected 'f'");
-        CHECK_THROWS_NAME(json::parser("fal").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("fal").parse(),
                           "parse error - unexpected 'f'");
-        CHECK_THROWS_NAME(json::parser("fals").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("fals").parse(),
                           "parse error - unexpected 'f'");
 
         // missing/unexpected end of array
@@ -9042,15 +8973,15 @@ TEST_CASE("parser class")
         CHECK_THROWS_AS(json::parser("[1,").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("[1,]").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("]").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("[").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("[").parse(),
                           "parse error - unexpected end of input");
-        CHECK_THROWS_NAME(json::parser("[1").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("[1").parse(),
                           "parse error - unexpected end of input; expected ']'");
-        CHECK_THROWS_NAME(json::parser("[1,").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("[1,").parse(),
                           "parse error - unexpected end of input");
-        CHECK_THROWS_NAME(json::parser("[1,]").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("[1,]").parse(),
                           "parse error - unexpected ']'");
-        CHECK_THROWS_NAME(json::parser("]").parse(), std::invalid_argument, "parse error - unexpected ']'");
+        CHECK_THROWS_WITH(json::parser("]").parse(), "parse error - unexpected ']'");
 
         // missing/unexpected end of object
         CHECK_THROWS_AS(json::parser("{").parse(), std::invalid_argument);
@@ -9059,17 +8990,17 @@ TEST_CASE("parser class")
         CHECK_THROWS_AS(json::parser("{\"foo\":}").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("{\"foo\":1,}").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("}").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("{").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("{").parse(),
                           "parse error - unexpected end of input; expected string literal");
-        CHECK_THROWS_NAME(json::parser("{\"foo\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("{\"foo\"").parse(),
                           "parse error - unexpected end of input; expected ':'");
-        CHECK_THROWS_NAME(json::parser("{\"foo\":").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("{\"foo\":").parse(),
                           "parse error - unexpected end of input");
-        CHECK_THROWS_NAME(json::parser("{\"foo\":}").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("{\"foo\":}").parse(),
                           "parse error - unexpected '}'");
-        CHECK_THROWS_NAME(json::parser("{\"foo\":1,}").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("{\"foo\":1,}").parse(),
                           "parse error - unexpected '}'; expected string literal");
-        CHECK_THROWS_NAME(json::parser("}").parse(), std::invalid_argument, "parse error - unexpected '}'");
+        CHECK_THROWS_WITH(json::parser("}").parse(), "parse error - unexpected '}'");
 
         // missing/unexpected end of string
         CHECK_THROWS_AS(json::parser("\"").parse(), std::invalid_argument);
@@ -9078,17 +9009,17 @@ TEST_CASE("parser class")
         CHECK_THROWS_AS(json::parser("\"\\u0\"").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("\"\\u01\"").parse(), std::invalid_argument);
         CHECK_THROWS_AS(json::parser("\"\\u012\"").parse(), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parser("\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"").parse(),
                           "parse error - unexpected '\"'");
-        CHECK_THROWS_NAME(json::parser("\"\\\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"\\\"").parse(),
                           "parse error - unexpected '\"'");
-        CHECK_THROWS_NAME(json::parser("\"\\u\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"\\u\"").parse(),
                           "parse error - unexpected '\"'");
-        CHECK_THROWS_NAME(json::parser("\"\\u0\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"\\u0\"").parse(),
                           "parse error - unexpected '\"'");
-        CHECK_THROWS_NAME(json::parser("\"\\u01\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"\\u01\"").parse(),
                           "parse error - unexpected '\"'");
-        CHECK_THROWS_NAME(json::parser("\"\\u012\"").parse(), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parser("\"\\u012\"").parse(),
                           "parse error - unexpected '\"'");
 
         // invalid escapes
@@ -9122,7 +9053,7 @@ TEST_CASE("parser class")
                 default:
                 {
                     CHECK_THROWS_AS(json::parser(s).parse(), std::invalid_argument);
-                    CHECK_THROWS_NAME(json::parser(s).parse(), std::invalid_argument, "parse error - unexpected '\"'");
+                    CHECK_THROWS_WITH(json::parser(s).parse(), "parse error - unexpected '\"'");
                     break;
                 }
             }
@@ -9192,26 +9123,26 @@ TEST_CASE("parser class")
                     CHECK_THROWS_AS(json::parser(s3).parse(), std::invalid_argument);
                     CHECK_THROWS_AS(json::parser(s4).parse(), std::invalid_argument);
 
-                    CHECK_THROWS_NAME(json::parser(s1).parse(), std::invalid_argument, "parse error - unexpected '\"'");
-                    CHECK_THROWS_NAME(json::parser(s2).parse(), std::invalid_argument, "parse error - unexpected '\"'");
-                    CHECK_THROWS_NAME(json::parser(s3).parse(), std::invalid_argument, "parse error - unexpected '\"'");
-                    CHECK_THROWS_NAME(json::parser(s4).parse(), std::invalid_argument, "parse error - unexpected '\"'");
+                    CHECK_THROWS_WITH(json::parser(s1).parse(), "parse error - unexpected '\"'");
+                    CHECK_THROWS_WITH(json::parser(s2).parse(), "parse error - unexpected '\"'");
+                    CHECK_THROWS_WITH(json::parser(s3).parse(), "parse error - unexpected '\"'");
+                    CHECK_THROWS_WITH(json::parser(s4).parse(), "parse error - unexpected '\"'");
                 }
             }
         }
 
         // missing part of a surrogate pair
         CHECK_THROWS_AS(json::parse("\"\\uD80C\""), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parse("\"\\uD80C\""), std::invalid_argument, "missing low surrogate");
+        CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), "missing low surrogate");
         // invalid surrogate pair
         CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), std::invalid_argument);
         CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), std::invalid_argument);
         CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), std::invalid_argument);
-        CHECK_THROWS_NAME(json::parse("\"\\uD80C\\uD80C\""), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""),
                           "missing or wrong low surrogate");
-        CHECK_THROWS_NAME(json::parse("\"\\uD80C\\u0000\""), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""),
                           "missing or wrong low surrogate");
-        CHECK_THROWS_NAME(json::parse("\"\\uD80C\\uFFFF\""), std::invalid_argument,
+        CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""),
                           "missing or wrong low surrogate");
     }
 
@@ -9805,8 +9736,7 @@ TEST_CASE("algorithms")
             {
                 json j({{"one", 1}, {"two", 2}});
                 CHECK_THROWS_AS(std::sort(j.begin(), j.end()), std::domain_error);
-                CHECK_THROWS_NAME(std::sort(j.begin(), j.end()), std::domain_error,
-                                  "cannot use offsets with object iterators");
+                CHECK_THROWS_WITH(std::sort(j.begin(), j.end()), "cannot use offsets with object iterators");
             }
         }