// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "opentelemetry/nostd/detail/decay.h" #include "opentelemetry/nostd/detail/void.h" #include "opentelemetry/version.h" #define OPENTELEMETRY_RETURN(...) \ noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) \ { \ return __VA_ARGS__; \ } OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { namespace detail { template struct is_reference_wrapper : std::false_type {}; template struct is_reference_wrapper> : std::true_type {}; template struct Invoke; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN((std::forward(arg).*pmf)(std::forward(args)...)) }; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN((std::forward(arg).get().*pmf)(std::forward(args)...)) }; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN(((*std::forward(arg)).*pmf)(std::forward(args)...)) }; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmo, Arg &&arg) OPENTELEMETRY_RETURN(std::forward(arg).*pmo) }; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmo, Arg &&arg) OPENTELEMETRY_RETURN(std::forward(arg).get().*pmo) }; template <> struct Invoke { template inline static constexpr auto invoke(R T::*pmo, Arg &&arg) OPENTELEMETRY_RETURN((*std::forward(arg)).*pmo) }; template inline constexpr auto invoke_impl(R T::*f, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN( Invoke::value, (std::is_base_of>::value ? 0 : is_reference_wrapper>::value ? 1 : 2)>::invoke(f, std::forward(arg), std::forward(args)...)) #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable : 4100) #endif template inline constexpr auto invoke_impl(F &&f, Args &&...args) OPENTELEMETRY_RETURN(std::forward(f)(std::forward(args)...)) #ifdef _MSC_VER # pragma warning(pop) #endif } // namespace detail /* clang-format off */ template inline constexpr auto invoke(F &&f, Args &&... args) OPENTELEMETRY_RETURN(detail::invoke_impl(std::forward(f), std::forward(args)...)) namespace detail /* clang-format on */ { template struct invoke_result {}; template struct invoke_result(), std::declval()...))>, F, Args...> { using type = decltype(nostd::invoke(std::declval(), std::declval()...)); }; } // namespace detail template using invoke_result = detail::invoke_result; template using invoke_result_t = typename invoke_result::type; namespace detail { template struct is_invocable : std::false_type {}; template struct is_invocable>, F, Args...> : std::true_type {}; template struct is_invocable_r : std::false_type {}; template struct is_invocable_r>, R, F, Args...> : std::is_convertible, R> {}; } // namespace detail template using is_invocable = detail::is_invocable; template using is_invocable_r = detail::is_invocable_r; } // namespace nostd OPENTELEMETRY_END_NAMESPACE #undef OPENTELEMETRY_RETURN