alsk/src/alsk/impl/implement.h

58 lines
1.6 KiB
C++

#ifndef ALSK_ALSK_IMPL_IMPLEMENT_H
#define ALSK_ALSK_IMPL_IMPLEMENT_H
#include <utility>
#include "callable.h"
#include "../context/context.h"
#include "../executor/traits.h"
namespace alsk {
/**
* @brief implement a skeleton
* @param TExecutor the executor template
* @param Skeleton the skeleton type
* @param Context [optional] the type of the context
*
* @return a callable
*/
template<template<typename> class TExecutor, typename Skeleton,
typename Context = DefaultContext,
std::enable_if_t<isSkeleton<Skeleton>>* = nullptr,
std::enable_if_t<isExecutor<TExecutor<Skeleton>>>* = nullptr
>
auto implement() {
using Executor = TExecutor<Skeleton>;
using State = CallableState<Context, Executor>;
using ImplType = Impl<Skeleton, typename Executor::Tag, Executor, State>;
return Callable<ImplType>(Skeleton{}, Executor{});
}
/**
* @brief implement a skeleton
* @param executor an instance of the executor
* @param skeleton an instance of the skeleton to implement
* @param Context [optional] the type of the context
*
* @return a callable
*/
template<typename Context = DefaultContext,
typename Executor, typename S,
std::enable_if_t<isSkeleton<S>>* = nullptr,
std::enable_if_t<isExecutor<Executor>>* = nullptr
>
auto implement(Executor&& executor, S&& skeleton) {
using ExecutorT = std::decay_t<Executor>;
using State = CallableState<Context, ExecutorT>;
using ImplType = Impl<std::decay_t<S>, typename ExecutorT::Tag, ExecutorT, State>;
return Callable<ImplType>(std::forward<S>(skeleton), std::forward<Executor>(executor));
}
}
#endif