#pragma once #ifdef JSON_HAS_CPP_17 #include // invoke #endif #include // invoke_result, is_base_of, is_function, is_invocable, is_object, is_same, remove_reference #include // declval, forward #include #include #include namespace nlohmann { namespace detail { #ifdef JSON_HAS_CPP_17 // the following utilities are natively available in C++17 using std::invoke; using std::invoke_result; using std::is_invocable; #else // invoke_impl derived from the C++ standard draft [func.require] for qslib (proprietary) // modified to use standard library type traits and utilities where possible namespace internal { template()(std::forward(std::declval())...))> auto invoke_impl(Fn && f, Args && ...args) -> decltype(f(std::forward(args)...)) { return f(std::forward(args)...); }; template < typename T, typename U, typename V, typename... Args, enable_if_t < std::is_function::value && std::is_base_of::type>::value, int > = 0 > auto invoke_impl(T U::*f, V && v, Args && ...args) -> decltype((v.*f)(std::forward(args)...)) { return (v.*f)(std::forward(args)...); } template < typename T, typename U, typename V, typename... Args, enable_if_t < std::is_function::value && !std::is_base_of::type>::value, int > = 0 > auto invoke_impl(T U::*f, V && v, Args && ...args) -> decltype(((*v).*f)(std::forward(args)...)) { return ((*v).*f)(std::forward(args)...); } template < typename T, typename U, typename V, typename... Args, enable_if_t < std::is_object::value && sizeof...(Args) == 0, int > = 0 > auto invoke_impl(T U::*f, V && v, Args && ... /*unused*/) -> decltype((*v).*f) { return (*v).*f; } template using detect_invocable = decltype(invoke_impl(std::declval(), std::declval()...)); // https://en.cppreference.com/w/cpp/types/result_of template struct invoke_result {}; template struct invoke_result(), std::declval()...))), Fn, Args...> { using type = decltype(invoke_impl(std::declval(), std::declval()...)); }; } // namespace internal template auto invoke(Fn&& f, Args&& ... args) -> decltype(internal::invoke_impl(std::forward(f), std::forward(args)...)) { return internal::invoke_impl(std::forward(f), std::forward(args)...); } template using invoke_result = internal::invoke_result; template using is_invocable = typename is_detected::type; #endif // used as a dummy argument struct null_arg_t { explicit null_arg_t() = default; }; static constexpr null_arg_t null_arg{}; template using is_null_arg = typename std::is_same, null_arg_t>::type; template struct apply_value_or_arg { using element_type = typename std::tuple_element::type; using type = typename std::conditional::value, Value, element_type>::type; }; template using apply_invoke_result_t = typename detail::invoke_result::type...>::type; template using apply_is_invocable = typename detail::is_invocable::type...>::type; } // namespace detail } // namespace nlohmann