Attempt at adding unordered_map as a basic_json object type

NOTE: This does NOT compile due to unordered_map needing to have an
instance in the CompatibleObjectType CTOR for the basic_json object, and
basic_json being an incomplete type at that time.  For assistance
request only.
This commit is contained in:
Erich Keane 2015-12-30 11:12:58 -08:00
parent 3905406f9c
commit 90ab92ade1
2 changed files with 55 additions and 5 deletions

View File

@ -105,6 +105,49 @@ static bool approx(const T a, const T b)
{
return not (a > b or a < b);
}
/*!
@brief Type Trait to convert a type to a void for SFINAE purposes
*/
template<typename T>
struct void_converter
{
using type = void;
};
// Type to help determine between a map or unordered-map type for the
// object_t type alias. Takes advantage of the fact that a map has a
// key_comparer member type and unordered_map has a hasher member type
template<template<typename...> class ObjectType, class Key, class Value,
template<typename> class AllocatorType, typename Enable = void>
struct object_t_helper{};
// Specialization that works for the 'map' type
template<template<typename...> class ObjectType, class Key, class Value,
template<typename> class AllocatorType>
struct object_t_helper<ObjectType, Key, Value, AllocatorType,
typename void_converter<typename ObjectType<char,char>::key_compare>::type
>
{
using type = ObjectType<
Key,
Value,
std::less<Key>,
AllocatorType<std::pair<Key,Value>>>;
};
// Specialization that works for the 'unordered_map' type
template<template<typename...> class ObjectType, class Key, class Value,
template<typename> class AllocatorType>
struct object_t_helper<ObjectType, Key, Value, AllocatorType,
typename void_converter<typename ObjectType<char,char>::hasher>::type
>
{
using type = ObjectType<
Key,
Value,
std::hash<Key>,
std::equal_to<Key>,
AllocatorType<std::pair<Key,Value>>>;
};
}
/*!
@ -333,11 +376,12 @@ class basic_json
@since version 1.0.0
*/
using object_t = ObjectType<StringType,
basic_json,
std::less<StringType>,
AllocatorType<std::pair<const StringType,
basic_json>>>;
using object_t = typename object_t_helper<
ObjectType,
StringType,
basic_json,
AllocatorType
>::type;
/*!
@brief a type for an array

View File

@ -11314,6 +11314,12 @@ TEST_CASE("regression tests")
CHECK(s2 == "value");
}
SECTION("issue #164 - std::unordered_map cannot be used as ObjectType")
{
// create JSON class with std::unordered_map instead of a std::map
nlohmann::basic_json<std::unordered_map> unordered_json;
}
SECTION("character following a surrogate pair is skipped")
{
CHECK(json::parse("\"\\ud80c\\udc60abc\"").get<json::string_t>() == u8"\U00013060abc");