79 lines
1.4 KiB
C++
79 lines
1.4 KiB
C++
#ifndef TMP_TRAITS_H
|
|
#define TMP_TRAITS_H
|
|
|
|
#include <type_traits>
|
|
#include "pack.h"
|
|
|
|
namespace tmp {
|
|
|
|
/**
|
|
* void_t
|
|
*
|
|
* as of C++17, use std::void_t instead
|
|
*/
|
|
template<typename...> using void_t = void;
|
|
|
|
/**
|
|
* Void
|
|
*
|
|
* use to replace `void` when an instance is required
|
|
*/
|
|
struct Void {};
|
|
|
|
// TODO: remove it?
|
|
template<typename Ostream>
|
|
Ostream &operator<<(Ostream &os, Void const&) {
|
|
return os << "Void{}";
|
|
}
|
|
|
|
/**
|
|
* ReturnType
|
|
*/
|
|
template<typename> struct ReturnTypeImpl;
|
|
template<typename R, typename... Ts>
|
|
struct ReturnTypeImpl<R(Ts...)> {
|
|
using type = R;
|
|
};
|
|
|
|
template<typename T>
|
|
using ReturnType = typename ReturnTypeImpl<T>::type;
|
|
|
|
/**
|
|
* Parameters
|
|
*/
|
|
template<typename> struct ParametersImpl;
|
|
template<typename R, typename... Ps>
|
|
struct ParametersImpl<R(Ps...)> {
|
|
using type = Pack<Ps...>;
|
|
};
|
|
|
|
template<typename T>
|
|
using Parameters = typename ParametersImpl<T>::type;
|
|
|
|
/**
|
|
* invoke_result
|
|
* as of C++17, use std::invoke_result instead
|
|
*/
|
|
template<typename F, typename... Args>
|
|
using invoke_result = std::result_of<F(Args...)>;
|
|
|
|
template<typename F, typename... Args>
|
|
using invoke_result_t = typename invoke_result<F, Args...>::type;
|
|
|
|
/**
|
|
* FunctionCat
|
|
*/
|
|
template<typename, typename> struct FunctionCatImpl;
|
|
|
|
template<typename Ret, typename... Ts, typename... Us>
|
|
struct FunctionCatImpl<Ret(Ts...), Ret(Us...)> {
|
|
using type = Ret(Ts..., Us...);
|
|
};
|
|
|
|
template<typename F1, typename F2>
|
|
using FunctionCat = typename FunctionCatImpl<F1, F2>::type;
|
|
|
|
}
|
|
|
|
#endif
|