rosa/inc/tmp/traits.h
2021-05-10 18:14:24 +02:00

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