...
This commit is contained in:
83
common/adc_traits.h
Normal file
83
common/adc_traits.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
/*
|
||||
|
||||
ABSTRACT DEVICE COMPONENTS LIBRARY
|
||||
|
||||
*/
|
||||
|
||||
|
||||
namespace adc::traits
|
||||
{
|
||||
|
||||
// deduce returned type of callable
|
||||
template <typename T>
|
||||
using adc_retval_t = std::invoke_result_t<std::remove_cvref_t<T>>;
|
||||
|
||||
|
||||
// helper classes
|
||||
template <typename... Ts>
|
||||
struct adc_func_traits_helper_t;
|
||||
|
||||
template <typename R>
|
||||
struct adc_func_traits_helper_t<R> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<>;
|
||||
using arg1_t = void;
|
||||
};
|
||||
|
||||
template <typename R, typename Arg, typename... Args>
|
||||
struct adc_func_traits_helper_t<R, Arg, Args...> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<Arg, Args...>;
|
||||
using arg1_t = Arg;
|
||||
};
|
||||
|
||||
|
||||
// callable traits
|
||||
|
||||
template <typename F>
|
||||
struct adc_func_traits;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct adc_func_traits<R (*)(Args...)> : adc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct adc_func_traits<R(Args...)> : adc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct adc_func_traits<R (C::*)(Args...)> : adc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct adc_func_traits<R (C::*)(Args...) const> : adc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct adc_func_traits : adc_func_traits<decltype(&F::operator())> {
|
||||
};
|
||||
|
||||
|
||||
// deduce type
|
||||
template <typename T>
|
||||
using adc_deduced_type =
|
||||
std::conditional_t<std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>,
|
||||
T,
|
||||
std::remove_cvref_t<T>>;
|
||||
|
||||
|
||||
// perfect-forwarding wrapper
|
||||
template <typename T, typename... Ts>
|
||||
auto adc_pf_wrapper(T&& v, Ts&&... vs)
|
||||
{
|
||||
return std::tuple<adc_deduced_type<T>, adc_deduced_type<Ts>...>(std::forward<T>(v), std::forward<Ts>(vs)...);
|
||||
}
|
||||
|
||||
|
||||
} // namespace adc::traits
|
||||
Reference in New Issue
Block a user