58 lines
1.6 KiB
C
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
|