Merge pull request #1138 from theodelrieu/feature/unordered_map_conversion
Feature/unordered map conversion
This commit is contained in:
commit
d505ed7b31
4 changed files with 384 additions and 182 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <string> // string
|
||||
#include <tuple> // tuple, make_tuple
|
||||
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
|
||||
#include <unordered_map> // unordered_map
|
||||
#include <utility> // pair, declval
|
||||
#include <valarray> // valarray
|
||||
|
||||
|
@ -278,10 +279,29 @@ void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
|
|||
from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename Key, typename Value,
|
||||
template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||
typename = enable_if_t<not std::is_constructible<
|
||||
typename BasicJsonType::string_t, Key>::value>>
|
||||
void from_json(const BasicJsonType& j, std::map<Key, Value>& m)
|
||||
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
||||
{
|
||||
if (JSON_UNLIKELY(not j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
}
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_UNLIKELY(not p.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
|
||||
}
|
||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
|
||||
typename = enable_if_t<not std::is_constructible<
|
||||
typename BasicJsonType::string_t, Key>::value>>
|
||||
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
||||
{
|
||||
if (JSON_UNLIKELY(not j.is_array()))
|
||||
{
|
||||
|
|
|
@ -414,7 +414,7 @@ class serializer
|
|||
else
|
||||
{
|
||||
// we finish reading, but do not accept: string was incomplete
|
||||
std::string sn(3,'\0');
|
||||
std::string sn(3, '\0');
|
||||
snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
||||
}
|
||||
|
|
|
@ -913,6 +913,7 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
|
|||
#include <string> // string
|
||||
#include <tuple> // tuple, make_tuple
|
||||
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
|
||||
#include <unordered_map> // unordered_map
|
||||
#include <utility> // pair, declval
|
||||
#include <valarray> // valarray
|
||||
|
||||
|
@ -1186,10 +1187,29 @@ void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
|
|||
from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename Key, typename Value,
|
||||
template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
|
||||
typename = enable_if_t<not std::is_constructible<
|
||||
typename BasicJsonType::string_t, Key>::value>>
|
||||
void from_json(const BasicJsonType& j, std::map<Key, Value>& m)
|
||||
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
|
||||
{
|
||||
if (JSON_UNLIKELY(not j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
}
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_UNLIKELY(not p.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
|
||||
}
|
||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
|
||||
typename = enable_if_t<not std::is_constructible<
|
||||
typename BasicJsonType::string_t, Key>::value>>
|
||||
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
|
||||
{
|
||||
if (JSON_UNLIKELY(not j.is_array()))
|
||||
{
|
||||
|
@ -1973,10 +1993,8 @@ class input_adapter
|
|||
#include <clocale> // localeconv
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
|
||||
#include <cstdio> // snprintf
|
||||
#include <initializer_list> // initializer_list
|
||||
#include <ios> // hex, uppercase
|
||||
#include <iomanip> // setw, setfill
|
||||
#include <sstream> // stringstream
|
||||
#include <string> // char_traits, string
|
||||
#include <vector> // vector
|
||||
|
||||
|
@ -3146,10 +3164,9 @@ scan_number_done:
|
|||
if ('\x00' <= c and c <= '\x1F')
|
||||
{
|
||||
// escape control characters
|
||||
std::stringstream ss;
|
||||
ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
|
||||
<< std::hex << static_cast<int>(c) << ">";
|
||||
result += ss.str();
|
||||
char cs[9];
|
||||
snprintf(cs, 9, "<U+%.4X>", c);
|
||||
result += cs;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5619,12 +5636,10 @@ class output_adapter
|
|||
#include <cmath> // ldexp
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
|
||||
#include <cstdio> // snprintf
|
||||
#include <cstring> // memcpy
|
||||
#include <iomanip> // setw, setfill
|
||||
#include <ios> // hex
|
||||
#include <iterator> // back_inserter
|
||||
#include <limits> // numeric_limits
|
||||
#include <sstream> // stringstream
|
||||
#include <string> // char_traits, string
|
||||
#include <utility> // make_pair, move
|
||||
|
||||
|
@ -7283,9 +7298,9 @@ class binary_reader
|
|||
*/
|
||||
std::string get_token_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
|
||||
return ss.str();
|
||||
char cr[3];
|
||||
snprintf(cr, 3, "%.2X", current);
|
||||
return std::string{cr};
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -8272,11 +8287,8 @@ class binary_writer
|
|||
#include <cstddef> // size_t, ptrdiff_t
|
||||
#include <cstdint> // uint8_t
|
||||
#include <cstdio> // snprintf
|
||||
#include <iomanip> // setfill
|
||||
#include <iterator> // next
|
||||
#include <limits> // numeric_limits
|
||||
#include <string> // string
|
||||
#include <sstream> // stringstream
|
||||
#include <type_traits> // is_same
|
||||
|
||||
// #include <nlohmann/detail/exceptions.hpp>
|
||||
|
@ -9753,9 +9765,9 @@ class serializer
|
|||
|
||||
case UTF8_REJECT: // decode found invalid UTF-8 byte
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
|
||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str()));
|
||||
std::string sn(3, '\0');
|
||||
snprintf(&sn[0], sn.size(), "%.2X", byte);
|
||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
||||
}
|
||||
|
||||
default: // decode found yet incomplete multi-byte code point
|
||||
|
@ -9781,9 +9793,9 @@ class serializer
|
|||
else
|
||||
{
|
||||
// we finish reading, but do not accept: string was incomplete
|
||||
std::stringstream ss;
|
||||
ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(static_cast<uint8_t>(s.back()));
|
||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str()));
|
||||
std::string sn(3, '\0');
|
||||
snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
|
||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,25 @@ using nlohmann::json;
|
|||
#include <unordered_set>
|
||||
#include <valarray>
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename MapType>
|
||||
void map_type_conversion_checks()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("value conversion")
|
||||
{
|
||||
SECTION("get an object (explicit)")
|
||||
{
|
||||
json::object_t o_reference = {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
||||
json::object_t o_reference = {{"object", json::object()},
|
||||
{"array", {1, 2, 3, 4}},
|
||||
{"number", 42},
|
||||
{"boolean", false},
|
||||
{"null", nullptr},
|
||||
{"string", "Hello world"}
|
||||
};
|
||||
json j(o_reference);
|
||||
|
||||
SECTION("json::object_t")
|
||||
|
@ -55,19 +69,22 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("std::map<json::string_t, json>")
|
||||
{
|
||||
std::map<json::string_t, json> o = j.get<std::map<json::string_t, json>>();
|
||||
std::map<json::string_t, json> o =
|
||||
j.get<std::map<json::string_t, json>>();
|
||||
CHECK(json(o) == j);
|
||||
}
|
||||
|
||||
SECTION("std::multimap<json::string_t, json>")
|
||||
{
|
||||
std::multimap<json::string_t, json> o = j.get<std::multimap<json::string_t, json>>();
|
||||
std::multimap<json::string_t, json> o =
|
||||
j.get<std::multimap<json::string_t, json>>();
|
||||
CHECK(json(o) == j);
|
||||
}
|
||||
|
||||
SECTION("std::unordered_map<json::string_t, json>")
|
||||
{
|
||||
std::unordered_map<json::string_t, json> o = j.get<std::unordered_map<json::string_t, json>>();
|
||||
std::unordered_map<json::string_t, json> o =
|
||||
j.get<std::unordered_map<json::string_t, json>>();
|
||||
CHECK(json(o) == j);
|
||||
}
|
||||
|
||||
|
@ -80,34 +97,55 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-object type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(
|
||||
json(json::value_t::number_unsigned).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::object_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::array).get<json::object_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::array).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is array");
|
||||
CHECK_THROWS_WITH(json(json::value_t::string).get<json::object_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::string).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is string");
|
||||
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is boolean");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, "
|
||||
"but is boolean");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_integer).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::object_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_unsigned).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::object_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_float).get<json::object_t>(),
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get an object (implicit)")
|
||||
{
|
||||
json::object_t o_reference = {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
||||
json::object_t o_reference = {{"object", json::object()},
|
||||
{"array", {1, 2, 3, 4}},
|
||||
{"number", 42},
|
||||
{"boolean", false},
|
||||
{"null", nullptr},
|
||||
{"string", "Hello world"}
|
||||
};
|
||||
json j(o_reference);
|
||||
|
||||
SECTION("json::object_t")
|
||||
|
@ -143,7 +181,8 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("get an array (explicit)")
|
||||
{
|
||||
json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
|
||||
json::array_t a_reference{json(1), json(1u), json(2.2),
|
||||
json(false), json("string"), json()};
|
||||
json j(a_reference);
|
||||
|
||||
SECTION("json::array_t")
|
||||
|
@ -163,8 +202,10 @@ TEST_CASE("value conversion")
|
|||
std::forward_list<json> a = j.get<std::forward_list<json>>();
|
||||
CHECK(json(a) == j);
|
||||
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<std::forward_list<json>>(),
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<std::forward_list<json>>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<std::forward_list<json>>(),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
|
@ -173,8 +214,10 @@ TEST_CASE("value conversion")
|
|||
std::vector<json> a = j.get<std::vector<json>>();
|
||||
CHECK(json(a) == j);
|
||||
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<std::vector<json>>(),
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<std::vector<json>>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<std::vector<json>>(),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
|
||||
#if not defined(JSON_NOEXCEPTION)
|
||||
|
@ -214,36 +257,52 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-array type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<std::vector<int>>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::object).get<std::vector<int>>(),
|
||||
"[json.exception.type_error.302] type must be array, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::object).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::string).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::string).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is string");
|
||||
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::boolean).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is boolean");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_integer).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_unsigned).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::array_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_float).get<json::array_t>(),
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get an array (implicit)")
|
||||
{
|
||||
json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
|
||||
json::array_t a_reference{json(1), json(1u), json(2.2),
|
||||
json(false), json("string"), json()};
|
||||
json j(a_reference);
|
||||
|
||||
SECTION("json::array_t")
|
||||
|
@ -279,7 +338,7 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("get a string (explicit)")
|
||||
{
|
||||
json::string_t s_reference {"Hello world"};
|
||||
json::string_t s_reference{"Hello world"};
|
||||
json j(s_reference);
|
||||
|
||||
SECTION("string_t")
|
||||
|
@ -296,34 +355,49 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-string type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(
|
||||
json(json::value_t::number_unsigned).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::string_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<json::string_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::object).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::array).get<json::string_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::array).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is array");
|
||||
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is boolean");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, "
|
||||
"but is boolean");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_integer).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::string_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_unsigned).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::string_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_float).get<json::string_t>(),
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get a string (implicit)")
|
||||
{
|
||||
json::string_t s_reference {"Hello world"};
|
||||
json::string_t s_reference{"Hello world"};
|
||||
json j(s_reference);
|
||||
|
||||
SECTION("string_t")
|
||||
|
@ -341,7 +415,7 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("get a boolean (explicit)")
|
||||
{
|
||||
json::boolean_t b_reference {true};
|
||||
json::boolean_t b_reference{true};
|
||||
json j(b_reference);
|
||||
|
||||
SECTION("boolean_t")
|
||||
|
@ -358,34 +432,53 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-string type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(
|
||||
json(json::value_t::number_integer).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(
|
||||
json(json::value_t::number_unsigned).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::boolean_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::array).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, "
|
||||
"but is object");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::array).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is array");
|
||||
CHECK_THROWS_WITH(json(json::value_t::string).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is string");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
CHECK_THROWS_WITH(json(json::value_t::number_float).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
"[json.exception.type_error.302] type must be boolean, "
|
||||
"but is string");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_integer).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is "
|
||||
"number");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_unsigned).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is "
|
||||
"number");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::number_float).get<json::boolean_t>(),
|
||||
"[json.exception.type_error.302] type must be boolean, but is "
|
||||
"number");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get a boolean (implicit)")
|
||||
{
|
||||
json::boolean_t b_reference {true};
|
||||
json::boolean_t b_reference{true};
|
||||
json j(b_reference);
|
||||
|
||||
SECTION("boolean_t")
|
||||
|
@ -403,9 +496,9 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("get an integer number (explicit)")
|
||||
{
|
||||
json::number_integer_t n_reference {42};
|
||||
json::number_integer_t n_reference{42};
|
||||
json j(n_reference);
|
||||
json::number_unsigned_t n_unsigned_reference {42u};
|
||||
json::number_unsigned_t n_unsigned_reference{42u};
|
||||
json j_unsigned(n_unsigned_reference);
|
||||
|
||||
SECTION("number_integer_t")
|
||||
|
@ -614,33 +707,47 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-number type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_integer_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_integer_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(
|
||||
json(json::value_t::boolean).get<json::number_integer_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_integer_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_integer_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::object).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_integer_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::array).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is array");
|
||||
CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_integer_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::string).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is string");
|
||||
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is boolean");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::boolean).get<json::number_integer_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is "
|
||||
"boolean");
|
||||
|
||||
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
|
||||
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_unsigned_t>());
|
||||
CHECK_NOTHROW(
|
||||
json(json::value_t::number_float).get<json::number_integer_t>());
|
||||
CHECK_NOTHROW(
|
||||
json(json::value_t::number_float).get<json::number_unsigned_t>());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get an integer number (implicit)")
|
||||
{
|
||||
json::number_integer_t n_reference {42};
|
||||
json::number_integer_t n_reference{42};
|
||||
json j(n_reference);
|
||||
json::number_unsigned_t n_unsigned_reference {42u};
|
||||
json::number_unsigned_t n_unsigned_reference{42u};
|
||||
json j_unsigned(n_unsigned_reference);
|
||||
|
||||
SECTION("number_integer_t")
|
||||
|
@ -850,7 +957,7 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("get a floating-point number (explicit)")
|
||||
{
|
||||
json::number_float_t n_reference {42.23};
|
||||
json::number_float_t n_reference{42.23};
|
||||
json j(n_reference);
|
||||
|
||||
SECTION("number_float_t")
|
||||
|
@ -873,31 +980,44 @@ TEST_CASE("value conversion")
|
|||
|
||||
SECTION("exception in case of a non-string type")
|
||||
{
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::null).get<json::number_float_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::object).get<json::number_float_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(),
|
||||
json::type_error&);
|
||||
|
||||
CHECK_THROWS_WITH(json(json::value_t::null).get<json::number_float_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::null).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is null");
|
||||
CHECK_THROWS_WITH(json(json::value_t::object).get<json::number_float_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::object).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is object");
|
||||
CHECK_THROWS_WITH(json(json::value_t::array).get<json::number_float_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::array).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is array");
|
||||
CHECK_THROWS_WITH(json(json::value_t::string).get<json::number_float_t>(),
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::string).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is string");
|
||||
CHECK_THROWS_WITH(json(json::value_t::boolean).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is boolean");
|
||||
CHECK_THROWS_WITH(
|
||||
json(json::value_t::boolean).get<json::number_float_t>(),
|
||||
"[json.exception.type_error.302] type must be number, but is "
|
||||
"boolean");
|
||||
|
||||
CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
|
||||
CHECK_NOTHROW(json(json::value_t::number_unsigned).get<json::number_float_t>());
|
||||
CHECK_NOTHROW(
|
||||
json(json::value_t::number_integer).get<json::number_float_t>());
|
||||
CHECK_NOTHROW(
|
||||
json(json::value_t::number_unsigned).get<json::number_float_t>());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("get a floating-point number (implicit)")
|
||||
{
|
||||
json::number_float_t n_reference {42.23};
|
||||
json::number_float_t n_reference{42.23};
|
||||
json j(n_reference);
|
||||
|
||||
SECTION("number_float_t")
|
||||
|
@ -954,7 +1074,7 @@ TEST_CASE("value conversion")
|
|||
j3.get<std::unordered_map<std::string, double>>();
|
||||
j4.get<std::unordered_map<std::string, bool>>();
|
||||
j5.get<std::unordered_map<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
// CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
SECTION("std::multimap")
|
||||
|
@ -964,7 +1084,7 @@ TEST_CASE("value conversion")
|
|||
j3.get<std::multimap<std::string, double>>();
|
||||
j4.get<std::multimap<std::string, bool>>();
|
||||
j5.get<std::multimap<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
// CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
SECTION("std::unordered_multimap")
|
||||
|
@ -974,13 +1094,16 @@ TEST_CASE("value conversion")
|
|||
j3.get<std::unordered_multimap<std::string, double>>();
|
||||
j4.get<std::unordered_multimap<std::string, bool>>();
|
||||
j5.get<std::unordered_multimap<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
// CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
SECTION("exception in case of a non-object type")
|
||||
{
|
||||
CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), json::type_error&);
|
||||
CHECK_THROWS_WITH((json().get<std::map<std::string, int>>()), "[json.exception.type_error.302] type must be object, but is null");
|
||||
CHECK_THROWS_AS((json().get<std::map<std::string, int>>()),
|
||||
json::type_error&);
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::map<std::string, int>>()),
|
||||
"[json.exception.type_error.302] type must be object, but is null");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1145,8 @@ TEST_CASE("value conversion")
|
|||
{
|
||||
std::array<int, 6> arr6 = {{1, 2, 3, 4, 5, 6}};
|
||||
CHECK_THROWS_AS(arr6 = j1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(arr6 = j1, "[json.exception.out_of_range.401] array index 4 is out of range");
|
||||
CHECK_THROWS_WITH(arr6 = j1, "[json.exception.out_of_range.401] "
|
||||
"array index 4 is out of range");
|
||||
}
|
||||
|
||||
SECTION("std::array is smaller than JSON")
|
||||
|
@ -1088,13 +1212,47 @@ TEST_CASE("value conversion")
|
|||
CHECK(m == m2);
|
||||
|
||||
json j7 = {0, 1, 2, 3};
|
||||
json j8 = 2;
|
||||
CHECK_THROWS_AS((j7.get<std::map<int, int>>()), json::type_error&);
|
||||
CHECK_THROWS_WITH((j7.get<std::map<int, int>>()), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS((j8.get<std::map<int, int>>()), json::type_error&);
|
||||
CHECK_THROWS_WITH((j7.get<std::map<int, int>>()),
|
||||
"[json.exception.type_error.302] type must be array, "
|
||||
"but is number");
|
||||
CHECK_THROWS_WITH((j8.get<std::map<int, int>>()),
|
||||
"[json.exception.type_error.302] type must be array, "
|
||||
"but is number");
|
||||
|
||||
SECTION("superfluous entries")
|
||||
{
|
||||
json j8 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
|
||||
m2 = j8.get<std::map<int, int>>();
|
||||
json j9 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
|
||||
m2 = j9.get<std::map<int, int>>();
|
||||
CHECK(m == m2);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::unordered_map (array of pairs)")
|
||||
{
|
||||
std::unordered_map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
|
||||
json j6 = m;
|
||||
|
||||
auto m2 = j6.get<std::unordered_map<int, int>>();
|
||||
CHECK(m == m2);
|
||||
|
||||
json j7 = {0, 1, 2, 3};
|
||||
json j8 = 2;
|
||||
CHECK_THROWS_AS((j7.get<std::unordered_map<int, int>>()), json::type_error&);
|
||||
CHECK_THROWS_AS((j8.get<std::unordered_map<int, int>>()), json::type_error&);
|
||||
CHECK_THROWS_WITH((j7.get<std::unordered_map<int, int>>()),
|
||||
"[json.exception.type_error.302] type must be array, "
|
||||
"but is number");
|
||||
CHECK_THROWS_WITH((j8.get<std::unordered_map<int, int>>()),
|
||||
"[json.exception.type_error.302] type must be array, "
|
||||
"but is number");
|
||||
|
||||
SECTION("superfluous entries")
|
||||
{
|
||||
json j9{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
|
||||
m2 = j9.get<std::unordered_map<int, int>>();
|
||||
CHECK(m == m2);
|
||||
}
|
||||
}
|
||||
|
@ -1109,12 +1267,24 @@ TEST_CASE("value conversion")
|
|||
|
||||
// does type really must be an array? or it rather must not be null?
|
||||
// that's what I thought when other test like this one broke
|
||||
CHECK_THROWS_WITH((json().get<std::list<int>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::vector<int>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::vector<json>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::list<json>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::valarray<int>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::map<int, int>>()), "[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::list<int>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::vector<int>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::vector<json>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::list<json>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::valarray<int>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
CHECK_THROWS_WITH(
|
||||
(json().get<std::map<int, int>>()),
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue