From 1ea8cd128c11746d9ee18af1dc4b3d3d516b7296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Fri, 7 Sep 2018 12:15:35 +0200 Subject: [PATCH 01/12] fix void_t for older compilers --- include/nlohmann/detail/meta/void_t.hpp | 7 +++++-- single_include/nlohmann/json.hpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/nlohmann/detail/meta/void_t.hpp b/include/nlohmann/detail/meta/void_t.hpp index 66c4a359..2528ea84 100644 --- a/include/nlohmann/detail/meta/void_t.hpp +++ b/include/nlohmann/detail/meta/void_t.hpp @@ -4,7 +4,10 @@ namespace nlohmann { namespace detail { -template -using void_t = void; +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; } } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9984f14e..bb03b522 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3572,8 +3572,11 @@ namespace nlohmann { namespace detail { -template -using void_t = void; +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; } } From b59c3367c9cf4f0168ce7b7fc7314de80823f24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Wed, 5 Sep 2018 16:02:13 +0200 Subject: [PATCH 02/12] use detected instead of has_* traits --- include/nlohmann/detail/macro_scope.hpp | 19 -- include/nlohmann/detail/macro_unscope.hpp | 1 - include/nlohmann/detail/meta/type_traits.hpp | 77 +++--- single_include/nlohmann/json.hpp | 238 +++++++++---------- 4 files changed, 157 insertions(+), 178 deletions(-) diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 834ac241..80fbece7 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -102,22 +102,3 @@ basic_json - -/*! -@brief Helper to determine whether there's a key_type for T. - -This helper is used to tell associative containers apart from other containers -such as sequence containers. For instance, `std::map` passes the test as it -contains a `mapped_type`, whereas `std::vector` fails the test. - -@sa http://stackoverflow.com/a/7728728/266378 -@since version 1.0.0, overworked in version 2.0.6 -*/ -#define NLOHMANN_JSON_HAS_HELPER(type) \ - template struct has_##type { \ - template \ - static int detect(U &&); \ - static void detect(...); \ - static constexpr bool value = \ - std::is_integral()))>::value; \ - } diff --git a/include/nlohmann/detail/macro_unscope.hpp b/include/nlohmann/detail/macro_unscope.hpp index 032b1218..4c5aa915 100644 --- a/include/nlohmann/detail/macro_unscope.hpp +++ b/include/nlohmann/detail/macro_unscope.hpp @@ -20,4 +20,3 @@ #undef JSON_HAS_CPP_17 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION #undef NLOHMANN_BASIC_JSON_TPL -#undef NLOHMANN_JSON_HAS_HELPER diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index d3a6584d..63c0db96 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -7,6 +7,7 @@ #include #include +#include #include namespace nlohmann @@ -30,9 +31,31 @@ template struct is_basic_json : std::false_type {}; NLOHMANN_BASIC_JSON_TPL_DECLARATION struct is_basic_json : std::true_type {}; -//////////////////////// -// has_/is_ functions // -//////////////////////// +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using iterator_t = typename T::iterator; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +/////////////////// +// is_ functions // +/////////////////// // source: https://stackoverflow.com/a/37193089/4116453 @@ -42,11 +65,6 @@ struct is_complete_type : std::false_type {}; template struct is_complete_type : std::true_type {}; -NLOHMANN_JSON_HAS_HELPER(mapped_type); -NLOHMANN_JSON_HAS_HELPER(key_type); -NLOHMANN_JSON_HAS_HELPER(value_type); -NLOHMANN_JSON_HAS_HELPER(iterator); - template struct is_compatible_object_type_impl : std::false_type {}; @@ -74,8 +92,8 @@ struct is_compatible_object_type { static auto constexpr value = is_compatible_object_type_impl < conjunction>, - has_mapped_type, - has_key_type>::value, + is_detected, + is_detected>::value, typename BasicJsonType::object_t, CompatibleObjectType >::value; }; @@ -84,7 +102,7 @@ struct is_compatible_string_type { static auto constexpr value = is_compatible_string_type_impl < conjunction>, - has_value_type>::value, + is_detected>::value, typename BasicJsonType::string_t, CompatibleStringType >::value; }; @@ -107,8 +125,8 @@ struct is_compatible_array_type negation>, negation>, - has_value_type, - has_iterator>::value; + is_detected, + is_detected>::value; }; template @@ -141,14 +159,11 @@ struct is_compatible_integer_type template struct has_from_json { - // also check the return type of from_json - template::from_json( - std::declval(), std::declval()))>::value>> - static int detect(U&&); - static void detect(...); + using serializer = typename BasicJsonType::template json_serializer; - static constexpr bool value = std::is_integral>()))>::value; + static constexpr bool value = + is_detected_exact::value; }; // This trait checks if JSONSerializer::from_json(json const&) exists @@ -156,28 +171,22 @@ struct has_from_json template struct has_non_default_from_json { - template < - typename U, - typename = enable_if_t::from_json(std::declval()))>::value >> - static int detect(U&&); - static void detect(...); + using serializer = typename BasicJsonType::template json_serializer; - static constexpr bool value = std::is_integral>()))>::value; + static constexpr bool value = + is_detected_exact::value; }; // This trait checks if BasicJsonType::json_serializer::to_json exists template struct has_to_json { - template::to_json( - std::declval(), std::declval()))> - static int detect(U&&); - static void detect(...); + using serializer = typename BasicJsonType::template json_serializer; - static constexpr bool value = std::is_integral>()))>::value; + static constexpr bool value = + is_detected_exact::value; }; template diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index bb03b522..a9352128 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -218,25 +218,6 @@ using json = basic_json<>; NumberIntegerType, NumberUnsignedType, NumberFloatType, \ AllocatorType, JSONSerializer> -/*! -@brief Helper to determine whether there's a key_type for T. - -This helper is used to tell associative containers apart from other containers -such as sequence containers. For instance, `std::map` passes the test as it -contains a `mapped_type`, whereas `std::vector` fails the test. - -@sa http://stackoverflow.com/a/7728728/266378 -@since version 1.0.0, overworked in version 2.0.6 -*/ -#define NLOHMANN_JSON_HAS_HELPER(type) \ - template struct has_##type { \ - template \ - static int detect(U &&); \ - static void detect(...); \ - static constexpr bool value = \ - std::is_integral()))>::value; \ - } - // #include @@ -334,6 +315,78 @@ constexpr T static_const::value; // #include +// #include + + +#include + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; +} +} + + +// http://en.cppreference.com/w/cpp/experimental/is_detected +namespace nlohmann +{ +namespace detail +{ +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template