thesis version
This commit is contained in:
32
inc/alsk/skeleton/link/args/placeholders.h
Normal file
32
inc/alsk/skeleton/link/args/placeholders.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef ALSK_ALSK_SKELETON_LINK_ARGS_PLACEHOLDERS_H
|
||||
#define ALSK_ALSK_SKELETON_LINK_ARGS_PLACEHOLDERS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <tmp/pack.h>
|
||||
|
||||
namespace alsk {
|
||||
namespace arg {
|
||||
|
||||
/**
|
||||
* @brief argument placeholder for parameters
|
||||
*/
|
||||
template<std::size_t I>
|
||||
struct P: std::integral_constant<std::size_t, I> {};
|
||||
|
||||
/**
|
||||
* @brief argument placeholder for returned values
|
||||
*/
|
||||
template<std::size_t I>
|
||||
struct R: std::integral_constant<std::size_t, I> {};
|
||||
|
||||
/**
|
||||
* @brief argument placeholder for contextual arguments
|
||||
*/
|
||||
template<std::size_t I>
|
||||
struct C: std::integral_constant<std::size_t, I> {};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
226
inc/alsk/skeleton/link/args/traits.h
Normal file
226
inc/alsk/skeleton/link/args/traits.h
Normal file
@ -0,0 +1,226 @@
|
||||
#ifndef ALSK_ALSK_SKELETON_LINK_ARGS_TRAITS_H
|
||||
#define ALSK_ALSK_SKELETON_LINK_ARGS_TRAITS_H
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <tmp/pack.h>
|
||||
#include <tmp/traits.h>
|
||||
|
||||
#include "placeholders.h"
|
||||
|
||||
namespace alsk {
|
||||
namespace arg {
|
||||
|
||||
/**
|
||||
* @brief true if the given type is a placeholder for a parameter
|
||||
*/
|
||||
template<typename T> struct IsP: std::false_type {};
|
||||
template<std::size_t I> struct IsP<P<I>>: std::true_type {};
|
||||
|
||||
template<typename T>
|
||||
constexpr bool isP = IsP<T>::value;
|
||||
|
||||
/**
|
||||
* @brief true if the given type is a placeholder for a returned value
|
||||
*/
|
||||
template<typename T> struct IsR: std::false_type {};
|
||||
template<std::size_t I> struct IsR<R<I>>: std::true_type {};
|
||||
|
||||
template<typename T>
|
||||
constexpr bool isR = IsR<T>::value;
|
||||
|
||||
/**
|
||||
* @brief true if the given type is a placeholder for a contextual argument
|
||||
*/
|
||||
template<typename T> struct IsC: std::false_type {};
|
||||
template<std::size_t I> struct IsC<C<I>>: std::true_type {};
|
||||
|
||||
template<typename T>
|
||||
constexpr bool isC = IsC<T>::value;
|
||||
|
||||
/**
|
||||
* @brief placeholders group
|
||||
*/
|
||||
template<typename P_, typename R_, typename C_>
|
||||
struct Placeholders {
|
||||
using P = tmp::AsPack<std::decay_t<P_>>;
|
||||
using R = tmp::AsPack<std::decay_t<R_>>;
|
||||
using C = tmp::AsPack<std::decay_t<C_>>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief apply type mods from A to B
|
||||
*/
|
||||
template<typename, typename B>
|
||||
struct ApplyTypeModsImpl {
|
||||
using type = B; // TODO: std::decay_t<B>
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct ApplyTypeModsImpl<A const&, B> {
|
||||
using type = std::decay_t<B> const&;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
using ApplyTypeMods = typename ApplyTypeModsImpl<A, B>::type;
|
||||
|
||||
/**
|
||||
* @brief ArgType
|
||||
*/
|
||||
template<typename T, typename, typename=void>
|
||||
struct ArgTypeImpl {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename A, typename Placeholders>
|
||||
struct ArgTypeImpl<A, Placeholders, std::enable_if_t<arg::isP<std::decay_t<A>>>> {
|
||||
using type = tmp::PackGet<typename Placeholders::P, std::decay_t<A>::value>;
|
||||
};
|
||||
|
||||
template<typename A, typename Placeholders>
|
||||
struct ArgTypeImpl<A, Placeholders, std::enable_if_t<arg::isR<std::decay_t<A>>>> {
|
||||
using type = tmp::PackGet<typename Placeholders::R, std::decay_t<A>::value>;
|
||||
};
|
||||
|
||||
template<typename A, typename Placeholders>
|
||||
struct ArgTypeImpl<A, Placeholders, std::enable_if_t<arg::isC<std::decay_t<A>>>> {
|
||||
using type = tmp::PackGet<typename Placeholders::C, std::decay_t<A>::value>;
|
||||
};
|
||||
|
||||
template<typename T, typename Placeholders>
|
||||
using ArgType = typename ArgTypeImpl<T, Placeholders>::type;
|
||||
|
||||
/**
|
||||
* @brief ArgGet
|
||||
*/
|
||||
template<typename, typename=void> struct ArgGet;
|
||||
|
||||
template<>
|
||||
struct ArgGet<void> {
|
||||
template<typename P, typename R, typename C>
|
||||
static void get(P&&, R&&, C&&) {}
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct ArgGet<A, std::enable_if_t<arg::isP<std::decay_t<A>>>> {
|
||||
template<typename P, typename R, typename C>
|
||||
static auto get(P&& p, R&&, C&&)
|
||||
-> /*ApplyTypeMods<A,*/ // TODO: does not work
|
||||
ArgType<A, arg::Placeholders<P, tmp::Pack<>, tmp::Pack<>>>
|
||||
/*>*/ {
|
||||
return std::get<std::decay_t<A>::value>(std::forward<P>(p));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct ArgGet<A, std::enable_if_t<arg::isR<std::decay_t<A>>>> {
|
||||
template<typename P, typename R, typename C>
|
||||
static auto get(P&&, R&& r, C&&)
|
||||
-> ApplyTypeMods<A,
|
||||
ArgType<A, arg::Placeholders<tmp::Pack<>, R, tmp::Pack<>>>
|
||||
> {
|
||||
return std::get<std::decay_t<A>::value>(std::forward<R>(r));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct ArgGet<A, std::enable_if_t<arg::isC<std::decay_t<A>>>> {
|
||||
template<typename P, typename R, typename C>
|
||||
static auto get(P&&, R&&, C&& x)
|
||||
-> ApplyTypeMods<A,
|
||||
ArgType<A, arg::Placeholders<tmp::Pack<>, tmp::Pack<>, C>>
|
||||
> {
|
||||
return std::get<std::decay_t<A>::value>(std::forward<C>(x));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IsPlaceholder
|
||||
*/
|
||||
namespace impl {
|
||||
|
||||
template<typename A>
|
||||
struct IsPlaceholder:
|
||||
std::integral_constant<bool,
|
||||
arg::isP<std::decay_t<A>> or arg::isR<std::decay_t<A>> or arg::isC<std::decay_t<A>>
|
||||
> {};
|
||||
|
||||
template<typename A>
|
||||
constexpr bool isPlaceholder = IsPlaceholder<A>::value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ArgFilter
|
||||
*/
|
||||
template<typename, typename = void> struct ArgFilterImpl;
|
||||
|
||||
template<typename Ret, typename T, typename... Ts>
|
||||
struct ArgFilterImpl<Ret(T, Ts...), std::enable_if_t<impl::isPlaceholder<T>>> {
|
||||
using type = tmp::FunctionCat<Ret(T), typename ArgFilterImpl<Ret(Ts...)>::type>;
|
||||
};
|
||||
|
||||
template<typename Ret, typename T, typename... Ts>
|
||||
struct ArgFilterImpl<Ret(T, Ts...), std::enable_if_t<!impl::isPlaceholder<T>>> {
|
||||
using type = typename ArgFilterImpl<Ret(Ts...)>::type;
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct ArgFilterImpl<Ret()> {
|
||||
using type = Ret();
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
using ArgFilter = typename ArgFilterImpl<F>::type;
|
||||
|
||||
/**
|
||||
* @brief RealTypeImpl
|
||||
* @param T a type to solve
|
||||
* @param Placeholders the placeholders list
|
||||
*/
|
||||
template<typename T, typename Placeholders>
|
||||
struct RealTypeImpl {
|
||||
using type = ArgType<T, Placeholders>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RealType
|
||||
* @param T a type to solve
|
||||
* @param Placeholders the placeholders list
|
||||
*/
|
||||
template<typename T, typename Placeholders>
|
||||
using RealType = typename RealTypeImpl<T, Placeholders>::type;
|
||||
|
||||
/**
|
||||
* @brief RealSignature
|
||||
*/
|
||||
template<typename, typename> struct RealSignatureImpl;
|
||||
|
||||
template<typename Ret, typename... Ps, typename Placeholders>
|
||||
struct RealSignatureImpl<Ret(Ps...), Placeholders> {
|
||||
// using type = Ret(*)(typename RealType<Ps, P, R>::type...); // issue with const& parameters
|
||||
using type = std::function<Ret(RealType<Ps, Placeholders>...)>;
|
||||
};
|
||||
|
||||
template<typename T, typename Placeholders>
|
||||
using RealSignature = typename RealSignatureImpl<T, Placeholders>::type;
|
||||
|
||||
/**
|
||||
* @brief Returns
|
||||
*/
|
||||
template<typename> struct ReturnsImpl;
|
||||
template<typename... Fs>
|
||||
struct ReturnsImpl<tmp::Pack<Fs...>> {
|
||||
using type = tmp::Pack<tmp::ReturnType<Fs>...>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using Returns = typename ReturnsImpl<T>::type;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user