diff --git a/src/json.hpp b/src/json.hpp index 3d4994e3..23709788 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -117,6 +117,17 @@ namespace nlohmann template struct json_traits; +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +template +using remove_cv_t = typename std::remove_cv::type; + +template +using remove_reference_t = typename std::remove_reference::type; + +// TODO update this doc /*! @brief unnamed namespace with internal helper functions @since version 1.0.0 @@ -1393,15 +1404,11 @@ class basic_json // auto j = json{{"a", json(not_equality_comparable{})}}; // // we can remove this constraint though, since lots of ctor are not explicit already - template < - typename T, - typename = - typename std::enable_if::type>::type>::value>::type> + template >>::value>> explicit basic_json(T &&val) - : basic_json(json_traits::type>::type>:: - to_json(std::forward(val))) {} + : basic_json(json_traits>>::to_json( + std::forward(val))) {} /*! @brief create a string (explicit) @@ -1418,14 +1425,15 @@ class basic_json @sa @ref basic_json(const typename string_t::value_type*) -- create a string value from a character pointer - @sa @ref basic_json(const CompatibleStringType&) -- create a string - value + @sa @ref basic_json(const CompatibleStringType&) -- create a string value from a compatible string container @since version 1.0.0 */ - basic_json(const string_t &val) : m_type(value_t::string), m_value(val) { - assert_invariant(); + basic_json(const string_t& val) + : m_type(value_t::string), m_value(val) + { + assert_invariant(); } /*! @@ -2763,17 +2771,12 @@ class basic_json // get_impl overload chosen if json_traits struct is specialized for type T // simply returns json_traits::from_json(*this); - // TODO add alias templates (enable_if_t etc) - template < - typename T, - typename = typename std::enable_if< - detail::has_json_traits::type>::type>::value>::type> - auto get_impl(T *) const -> decltype( - json_traits::type>::type>::from_json(std::declval())) { - return json_traits::type>::type>::from_json(*this); + template >>::value>> + auto get_impl(T *) const + -> decltype(json_traits>>::from_json( + std::declval())) { + return json_traits>>::from_json(*this); } // this one is quite atrocious @@ -2781,31 +2784,34 @@ class basic_json // I chose to prefer the json_traits specialization if it exists, since it's a more advanced use. // But we can of course change this behaviour template - auto get_impl(T *) const -> typename std::enable_if< - not detail::has_json_traits::type>::value, - typename std::remove_cv(), - std::declval()), - std::declval())>::type>::type>::type + auto get_impl(T *) const + -> enable_if_t>::value, + remove_cv_t(), + std::declval()), + std::declval())>>> { - typename std::remove_cv::type>::type - ret; + remove_cv_t ret; + // I guess this output parameter is the only way to get ADL + // Even if users can use the get method to have a more 'functional' behaviour + // i.e. having a return type, could there be a way to have the same behaviour with from_json? + // e.g. auto t = nlohmann::from_json(json{}); + // this seems to require variable templates though... (at least it did when I tried to implement it) ::nlohmann::from_json(*this, ret); return ret; } - /// get an object (explicit) - template ::value and - std::is_convertible::value, - int>::type = 0> - T get_impl(T *) const { - if (is_object()) { - return T(m_value.object->begin(), m_value.object->end()); - } else { + template::value and + std::is_convertible::value, int>::type = 0> + T get_impl(T*) const + { + if (is_object()) + { + return T(m_value.object->begin(), m_value.object->end()); + } + else + { JSON_THROW(std::domain_error("type must be object, but is " + type_name())); }