mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-09-06 14:52:54 +02:00
163 lines
4.9 KiB
C++
163 lines
4.9 KiB
C++
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
#pragma once
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
#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 <typename T>
|
|
struct is_reference_wrapper : std::false_type
|
|
{};
|
|
|
|
template <typename T>
|
|
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type
|
|
{};
|
|
|
|
template <bool, int>
|
|
struct Invoke;
|
|
|
|
template <>
|
|
struct Invoke<true /* pmf */, 0 /* is_base_of */>
|
|
{
|
|
template <typename R, typename T, typename Arg, typename... Args>
|
|
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args)
|
|
OPENTELEMETRY_RETURN((std::forward<Arg>(arg).*pmf)(std::forward<Args>(args)...))
|
|
};
|
|
|
|
template <>
|
|
struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */>
|
|
{
|
|
template <typename R, typename T, typename Arg, typename... Args>
|
|
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args)
|
|
OPENTELEMETRY_RETURN((std::forward<Arg>(arg).get().*pmf)(std::forward<Args>(args)...))
|
|
};
|
|
|
|
template <>
|
|
struct Invoke<true /* pmf */, 2 /* otherwise */>
|
|
{
|
|
template <typename R, typename T, typename Arg, typename... Args>
|
|
inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args)
|
|
OPENTELEMETRY_RETURN(((*std::forward<Arg>(arg)).*pmf)(std::forward<Args>(args)...))
|
|
};
|
|
|
|
template <>
|
|
struct Invoke<false /* pmo */, 0 /* is_base_of */>
|
|
{
|
|
template <typename R, typename T, typename Arg>
|
|
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
|
|
OPENTELEMETRY_RETURN(std::forward<Arg>(arg).*pmo)
|
|
};
|
|
|
|
template <>
|
|
struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */>
|
|
{
|
|
template <typename R, typename T, typename Arg>
|
|
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
|
|
OPENTELEMETRY_RETURN(std::forward<Arg>(arg).get().*pmo)
|
|
};
|
|
|
|
template <>
|
|
struct Invoke<false /* pmo */, 2 /* otherwise */>
|
|
{
|
|
template <typename R, typename T, typename Arg>
|
|
inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
|
|
OPENTELEMETRY_RETURN((*std::forward<Arg>(arg)).*pmo)
|
|
};
|
|
|
|
template <typename R, typename T, typename Arg, typename... Args>
|
|
inline constexpr auto invoke_impl(R T::*f, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN(
|
|
Invoke<std::is_function<R>::value,
|
|
(std::is_base_of<T, decay_t<Arg>>::value ? 0
|
|
: is_reference_wrapper<decay_t<Arg>>::value ? 1
|
|
: 2)>::invoke(f,
|
|
std::forward<Arg>(arg),
|
|
std::forward<Args>(args)...))
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning(push)
|
|
# pragma warning(disable : 4100)
|
|
#endif
|
|
template <typename F, typename... Args>
|
|
inline constexpr auto invoke_impl(F &&f, Args &&...args)
|
|
OPENTELEMETRY_RETURN(std::forward<F>(f)(std::forward<Args>(args)...))
|
|
#ifdef _MSC_VER
|
|
# pragma warning(pop)
|
|
#endif
|
|
} // namespace detail
|
|
|
|
/* clang-format off */
|
|
template <typename F, typename... Args>
|
|
inline constexpr auto invoke(F &&f, Args &&... args)
|
|
OPENTELEMETRY_RETURN(detail::invoke_impl(std::forward<F>(f), std::forward<Args>(args)...))
|
|
|
|
namespace detail
|
|
/* clang-format on */
|
|
{
|
|
|
|
template <typename Void, typename, typename...>
|
|
struct invoke_result
|
|
{};
|
|
|
|
template <typename F, typename... Args>
|
|
struct invoke_result<void_t<decltype(nostd::invoke(std::declval<F>(), std::declval<Args>()...))>,
|
|
F, Args...>
|
|
{
|
|
using type = decltype(nostd::invoke(std::declval<F>(), std::declval<Args>()...));
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template <typename F, typename... Args>
|
|
using invoke_result = detail::invoke_result<void, F, Args...>;
|
|
|
|
template <typename F, typename... Args>
|
|
using invoke_result_t = typename invoke_result<F, Args...>::type;
|
|
|
|
namespace detail
|
|
{
|
|
|
|
template <typename Void, typename, typename...>
|
|
struct is_invocable : std::false_type
|
|
{};
|
|
|
|
template <typename F, typename... Args>
|
|
struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...> : std::true_type
|
|
{};
|
|
|
|
template <typename Void, typename, typename, typename...>
|
|
struct is_invocable_r : std::false_type
|
|
{};
|
|
|
|
template <typename R, typename F, typename... Args>
|
|
struct is_invocable_r<void_t<invoke_result_t<F, Args...>>, R, F, Args...>
|
|
: std::is_convertible<invoke_result_t<F, Args...>, R>
|
|
{};
|
|
|
|
} // namespace detail
|
|
|
|
template <typename F, typename... Args>
|
|
using is_invocable = detail::is_invocable<void, F, Args...>;
|
|
|
|
template <typename R, typename F, typename... Args>
|
|
using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
|
|
} // namespace nostd
|
|
OPENTELEMETRY_END_NAMESPACE
|
|
|
|
#undef OPENTELEMETRY_RETURN
|