Introduce config traits

This commit is contained in:
Denis Blank 2016-09-14 22:53:14 +02:00
parent 4b31875c95
commit 6d0d0cfa94

View File

@ -120,7 +120,7 @@ struct SelfDispatcher {
} }
}; };
template<typename Continuation, typename Dispatcher = SelfDispatcher> template<typename Config>
class ContinuableBase; class ContinuableBase;
static auto createEmptyContinuation() { static auto createEmptyContinuation() {
@ -239,27 +239,49 @@ void invokeContinuation(Continuation&& continuation) {
std::forward<Continuation>(continuation)(createEmptyCallback()); std::forward<Continuation>(continuation)(createEmptyCallback());
} }
template<typename ContinuationType, typename DispatcherType>
struct ContinuableConfig {
using Continuation = ContinuationType;
using Dispatcher = DispatcherType;
template<typename NewType>
using ChangeContinuationTo = ContinuableConfig<
NewType, Dispatcher
>;
template<typename NewType>
using ChangeDispatcherTo = ContinuableConfig<
Continuation, NewType
>;
};
template<typename Continuation, typename Dispatcher = SelfDispatcher> template<typename Continuation, typename Dispatcher = SelfDispatcher>
auto make_continuable(Continuation&& continuation, auto make_continuable(Continuation&& continuation,
Dispatcher&& dispatcher = SelfDispatcher{}) noexcept { Dispatcher&& dispatcher = SelfDispatcher{}) noexcept {
return ContinuableBase<std::decay_t<Continuation>, std::decay_t<Dispatcher>> { using Config = ContinuableConfig<
std::forward<Continuation>(continuation), std::forward<Dispatcher>(dispatcher) std::decay_t<Continuation>,
std::decay_t<Dispatcher>
>;
return ContinuableBase<Config> {
std::forward<Continuation>(continuation),
std::forward<Dispatcher>(dispatcher)
}; };
} }
template<typename Continuation, typename Dispatcher> template<typename Config>
class ContinuableBase { class ContinuableBase {
template<typename, typename> template<typename>
friend class ContinuableBase; friend class ContinuableBase;
ContinuableBase(Continuation continuation_, Ownership ownership_, ContinuableBase(typename Config::Continuation continuation_,
Dispatcher dispatcher_) noexcept Ownership ownership_,
typename Config::Dispatcher dispatcher_) noexcept
: continuation(std::move(continuation_)), : continuation(std::move(continuation_)),
dispatcher(std::move(dispatcher_)), ownership(std::move(ownership_)) { } dispatcher(std::move(dispatcher_)), ownership(std::move(ownership_)) { }
public: public:
ContinuableBase(Continuation continuation_, ContinuableBase(typename Config::Continuation continuation_,
Dispatcher dispatcher_ = Dispatcher{}) noexcept typename Config::Dispatcher dispatcher_) noexcept
: continuation(std::move(continuation_)), : continuation(std::move(continuation_)),
dispatcher(std::move(dispatcher_)) { } dispatcher(std::move(dispatcher_)) { }
~ContinuableBase() { ~ContinuableBase() {
@ -274,7 +296,10 @@ public:
auto then(Callback&& callback)&& { auto then(Callback&& callback)&& {
auto next = appendHandlerToContinuation(std::move(continuation), auto next = appendHandlerToContinuation(std::move(continuation),
std::forward<Callback>(callback)); std::forward<Callback>(callback));
return ContinuableBase<std::decay_t<decltype(next)>, Dispatcher> { using Transformed = ContinuableBase<
typename Config::template ChangeContinuationTo<decltype(next)>
>;
return Transformed {
std::move(next), std::move(ownership), std::move(dispatcher) std::move(next), std::move(ownership), std::move(dispatcher)
}; };
} }
@ -283,51 +308,62 @@ public:
auto then(Callback&& callback) const& { auto then(Callback&& callback) const& {
auto next = appendHandlerToContinuation(continuation, auto next = appendHandlerToContinuation(continuation,
std::forward<Callback>(callback)); std::forward<Callback>(callback));
return ContinuableBase<std::decay_t<decltype(next)>, Dispatcher> { using Transformed = ContinuableBase<
typename Config::template ChangeContinuationTo<decltype(next)>
>;
return Transformed {
std::move(next), ownership, dispatcher std::move(next), ownership, dispatcher
}; };
} }
template<typename NewStrand> template<typename NewDispatcher>
auto post(NewStrand&& newStrand)&& { auto post(NewDispatcher&& newDispatcher)&& {
return ContinuableBase<Continuation, NewStrand> { using Transformed = ContinuableBase<
typename Config::template ChangeDispatcherTo<std::decay_t<NewDispatcher>>
>;
return Transformed {
std::move(continuation), std::move(ownership), std::move(continuation), std::move(ownership),
std::forward<NewStrand>(newStrand) std::forward<NewDispatcher>(newDispatcher)
}; };
} }
template<typename NewStrand> template<typename NewDispatcher>
auto post(NewStrand&& newStrand) const& { auto post(NewDispatcher&& newDispatcher) const& {
return ContinuableBase<Continuation, NewStrand> { using Transformed = ContinuableBase<
typename Config::template ChangeDispatcherTo<std::decay_t<NewDispatcher>>
>;
return Transformed {
continuation, ownership, continuation, ownership,
std::forward<NewStrand>(newStrand) std::forward<NewDispatcher>(newDispatcher)
}; };
} }
private: private:
Continuation continuation; typename Config::Continuation continuation;
Dispatcher dispatcher; typename Config::Dispatcher dispatcher;
Ownership ownership; Ownership ownership;
}; };
static auto makeTestContinuation() { static auto makeTestContinuation() {
return make_continuable([i = std::make_unique<int>(0)](auto&& callback) { return make_continuable([](auto&& callback) {
callback("<br>hi<br>"); callback("<br>hi<br>");
}); });
} }
int main(int, char**) { int main(int, char**) {
auto dispatcher = [](auto callable) { auto dispatcher = SelfDispatcher{};
};
int res = 0; int res = 0;
makeTestContinuation() makeTestContinuation()
.post(dispatcher) .post(dispatcher)
.then([](std::string) { .then([](std::string) {
return std::make_tuple(47, 46, 45); return std::make_tuple(47, 46, 45);
}) })
.then([&](int val1, int val2, int val3) { .then([&](int val1, int val2, int val3) {
res += val1 + val2 + val3; res += val1 + val2 + val3;
int i = 0; int i = 0;
}); });