diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 568a65964..f915cbc0f 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -5219,6 +5219,41 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_error(); } + // workaround Clang <4 and GCC <5.2 not being able to construct tuples + // of basic_json by wrapping it using std::reference_wrapper +#if (defined(__clang__) && __clang_major__ < 4) || \ + (defined(__GNUC__) && !JSON_HEDLEY_GCC_VERSION_CHECK(5, 2, 0)) + using apply_basic_json_needs_to_be_wrapped = std::true_type; +#else + using apply_basic_json_needs_to_be_wrapped = std::false_type; +#endif + + template + using apply_arg_needs_to_be_wrapped = std::integral_constant < bool, + (apply_basic_json_needs_to_be_wrapped::value + && detail::is_basic_json>::value) >; + + template < typename Arg, + detail::enable_if_t < apply_arg_needs_to_be_wrapped::value&& std::is_const::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::cref(std::forward(arg))) + { + return std::cref(std::forward(arg)); // LCOV_EXCL_LINE + } + + template < typename Arg, + detail::enable_if_t < apply_arg_needs_to_be_wrapped::value&& !std::is_const::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::ref(std::forward(arg))) + { + return std::ref(std::forward(arg)); // LCOV_EXCL_LINE + } + + template < typename Arg, + detail::enable_if_t < !apply_arg_needs_to_be_wrapped::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::forward(arg)) + { + return std::forward(arg); + } + // convert arguments to tuple; insert basic_json_value placeholder if missing template < bool ConstThis, typename Value, typename ResultCallback, typename CallbackArg, typename Fn, typename FnArg, typename... Args, detail::enable_if_t < std::is_member_pointer::value @@ -5229,7 +5264,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(f_arg, ::nlohmann::placeholders::basic_json_value, args...), + std::forward(f), std::forward_as_tuple(f_arg, ::nlohmann::placeholders::basic_json_value, apply_maybe_wrap_arg(args)...), detail::make_index_sequence < 2 + sizeof...(args) > ()); } @@ -5241,7 +5276,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(::nlohmann::placeholders::basic_json_value, args...), + std::forward(f), std::forward_as_tuple(::nlohmann::placeholders::basic_json_value, apply_maybe_wrap_arg(args)...), detail::make_index_sequence < 1 + sizeof...(args) > ()); } @@ -5252,7 +5287,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(args...), + std::forward(f), std::forward_as_tuple(apply_maybe_wrap_arg(args)...), detail::make_index_sequence()); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index f8052897f..d8149a368 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -23599,6 +23599,41 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_error(); } + // workaround Clang <4 and GCC <5.2 not being able to construct tuples + // of basic_json by wrapping it using std::reference_wrapper +#if (defined(__clang__) && __clang_major__ < 4) || \ + (defined(__GNUC__) && !JSON_HEDLEY_GCC_VERSION_CHECK(5, 2, 0)) + using apply_basic_json_needs_to_be_wrapped = std::true_type; +#else + using apply_basic_json_needs_to_be_wrapped = std::false_type; +#endif + + template + using apply_arg_needs_to_be_wrapped = std::integral_constant < bool, + (apply_basic_json_needs_to_be_wrapped::value + && detail::is_basic_json>::value) >; + + template < typename Arg, + detail::enable_if_t < apply_arg_needs_to_be_wrapped::value&& std::is_const::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::cref(std::forward(arg))) + { + return std::cref(std::forward(arg)); // LCOV_EXCL_LINE + } + + template < typename Arg, + detail::enable_if_t < apply_arg_needs_to_be_wrapped::value&& !std::is_const::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::ref(std::forward(arg))) + { + return std::ref(std::forward(arg)); // LCOV_EXCL_LINE + } + + template < typename Arg, + detail::enable_if_t < !apply_arg_needs_to_be_wrapped::value, int > = 0 > + static auto apply_maybe_wrap_arg(Arg && arg) -> decltype(std::forward(arg)) + { + return std::forward(arg); + } + // convert arguments to tuple; insert basic_json_value placeholder if missing template < bool ConstThis, typename Value, typename ResultCallback, typename CallbackArg, typename Fn, typename FnArg, typename... Args, detail::enable_if_t < std::is_member_pointer::value @@ -23609,7 +23644,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(f_arg, ::nlohmann::placeholders::basic_json_value, args...), + std::forward(f), std::forward_as_tuple(f_arg, ::nlohmann::placeholders::basic_json_value, apply_maybe_wrap_arg(args)...), detail::make_index_sequence < 2 + sizeof...(args) > ()); } @@ -23621,7 +23656,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(::nlohmann::placeholders::basic_json_value, args...), + std::forward(f), std::forward_as_tuple(::nlohmann::placeholders::basic_json_value, apply_maybe_wrap_arg(args)...), detail::make_index_sequence < 1 + sizeof...(args) > ()); } @@ -23632,7 +23667,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec apply_invoke( std::forward(val), std::forward(cb), std::forward(cb_arg), - std::forward(f), std::forward_as_tuple(args...), + std::forward(f), std::forward_as_tuple(apply_maybe_wrap_arg(args)...), detail::make_index_sequence()); }