This commit is contained in:
Denis Blank 2016-11-15 17:44:58 +01:00
parent 6bd0b49064
commit 32f990068e
2 changed files with 56 additions and 19 deletions

View File

@ -120,6 +120,9 @@ auto appendHandlerToContinuation(Continuation&& cont, Handler&& handler) {
#include <string> #include <string>
#include <memory> #include <memory>
template<typename T>
struct fail : std::enable_if_t<std::is_same<T, void>::value, std::true_type> { };
// Equivalent to C++17's std::void_t which is targets a bug in GCC, // Equivalent to C++17's std::void_t which is targets a bug in GCC,
// that prevents correct SFINAE behavior. // that prevents correct SFINAE behavior.
// See http://stackoverflow.com/questions/35753920 for details. // See http://stackoverflow.com/questions/35753920 for details.
@ -144,7 +147,7 @@ class ContinuableBase;
inline auto emptyContinuation() { inline auto emptyContinuation() {
return [](auto&& callback) { return [](auto&& callback) {
std::forward<decltype(callback)>(callback)(); /*std::forward<decltype(callback)>(*/callback/*)*/();
}; };
} }
@ -152,6 +155,11 @@ inline auto emptyCallback() {
return [](auto&&...) { }; return [](auto&&...) { };
} }
struct FinalCallback {
template<typename... Args>
void operator() (Args&&...) const { }
};
template<typename S, unsigned... I, typename T, typename F> template<typename S, unsigned... I, typename T, typename F>
auto applyTuple(std::integer_sequence<S, I...>, T&& tuple, F&& function) { auto applyTuple(std::integer_sequence<S, I...>, T&& tuple, F&& function) {
return std::forward<F>(function)(std::get<I>(std::forward<T>(tuple))...); return std::forward<F>(function)(std::get<I>(std::forward<T>(tuple))...);
@ -220,11 +228,12 @@ struct ArgumentsHint<OnlyArgument> : std::true_type {
using only_argument_type = OnlyArgument; using only_argument_type = OnlyArgument;
}; };
struct AbsentArgumentsTag { };
template<> template<>
struct ArgumentsHint<void> : std::false_type { }; struct ArgumentsHint<AbsentArgumentsTag> : std::false_type { };
using AbsentArgumentsHint = ArgumentsHint<void>;
using AbsentArgumentsHint = ArgumentsHint<AbsentArgumentsTag>;
using EmptyArgumentsHint = ArgumentsHint<>; using EmptyArgumentsHint = ArgumentsHint<>;
template<typename Function> template<typename Function>
@ -334,10 +343,10 @@ struct CallbackResultDecorator {
}; };
/// No decoration is needed for continuables /// No decoration is needed for continuables
template<typename Decorator> template<typename Decoration>
struct CallbackResultDecorator<ContinuableBase<Decorator>>{ struct CallbackResultDecorator<ContinuableBase<Decoration>>{
template<typename Callback> template<typename Callback>
static auto decorate(Callback&& callback) -> std::decay_t<Callback> { static auto decorate(Callback&& callback) {
return std::forward<Callback>(callback); return std::forward<Callback>(callback);
} }
}; };
@ -375,6 +384,14 @@ struct CallbackResultDecorator<std::tuple<Results...>> {
} }
}; };
template<typename Result, typename Next>
void finalInvoke(std::true_type, Result&&, Next&&) { }
template<typename Result, typename Next>
void finalInvoke(std::false_type, Result&& result, Next&& next) {
std::forward<Result>(result)(std::forward<Next>(next));
}
/// Create the proxy callback that is responsible for invoking /// Create the proxy callback that is responsible for invoking
/// the real callback and passing the next continuation into /// the real callback and passing the next continuation into
/// the result of the following callback. /// the result of the following callback.
@ -387,8 +404,10 @@ auto createProxyCallback(Callback&& callback,
// if not, we need to decorate it. // if not, we need to decorate it.
using Result = decltype(callback(std::forward<decltype(args)>(args)...)); using Result = decltype(callback(std::forward<decltype(args)>(args)...));
using Decorator = CallbackResultDecorator<Result>; using Decorator = CallbackResultDecorator<Result>;
Decorator::decorate(std::move(callback)) auto callable = Decorator::decorate(std::move(callback));
(std::forward<decltype(args)>(args)...)(std::move(next)); auto result = std::move(callable)(std::forward<decltype(args)>(args)...);
finalInvoke(std::is_same<FinalCallback, std::decay_t<Next>>{},
std::move(result), std::move(next));
}; };
} }
@ -408,7 +427,14 @@ void invokeUndecorated(Data data) {
// Check whether the ownership is acquired and start the continuation call // Check whether the ownership is acquired and start the continuation call
if (data.ownership.hasOwnership()) { if (data.ownership.hasOwnership()) {
// Pass an empty callback to the continuation to invoke it // Pass an empty callback to the continuation to invoke it
std::move(data.continuation)(emptyCallback()); auto cont = std::move(data.continuation); // (emptyCallback());
// auto fn = &decltype(cont)::operator();
// cont([](auto&&...) { });
cont(FinalCallback{});
int i = 0;
} }
} }
@ -495,12 +521,12 @@ private:
template<typename... TargetArgs, typename... CombinedData> template<typename... TargetArgs, typename... CombinedData>
auto undecorateCombined(Identity<TargetArgs...>, auto undecorateCombined(Identity<TargetArgs...>,
std::tuple<CombinedData...> combined) { std::tuple<CombinedData...> /*combined*/) {
} }
template<typename Callback, typename... CombinedData> template<typename Callback, typename... CombinedData>
auto undecorateCombined(std::tuple<CombinedData...> combined) { auto undecorateCombined(std::tuple<CombinedData...> /*combined*/) {
// using TargetArgs = typename do_undecorate<Callback>::argument_type; // using TargetArgs = typename do_undecorate<Callback>::argument_type;
// return undecorateCombined(TargetArgs{}, std::move(combined)); // return undecorateCombined(TargetArgs{}, std::move(combined));
} }

View File

@ -45,27 +45,38 @@ struct Debugable {
template<typename C> template<typename C>
void operator() (C&& c) { void operator() (C&& c) {
// fail<C> cc;
std::forward<C>(c)(true); std::forward<C>(c)(true);
} }
}; };
static auto moveTo() { static auto moveTo() {
/*return make_continuable([](auto&& callback) { return make_continuable([](auto&& callback) {
callback(true); callback(true);
});*/ });
return make_continuable(Debugable{}); // return make_continuable(Debugable{});
} }
int main(int, char**) { int main(int, char**) {
Debugable deb; Debugable deb;
// moveTo().then([](bool) {}); auto empty = [](auto&&...) {};
deb(empty);
moveTo()
.then([](bool) {
return make_continuable(Debugable{});
})
.then([](bool) {
});
// continuable<int, int> c; // continuable<int, int> c;
auto dispatcher = SelfDispatcher{}; // auto dispatcher = SelfDispatcher{};
/*(makeTestContinuation() && makeTestContinuation()) /*(makeTestContinuation() && makeTestContinuation())
.undecorateFor([]() .undecorateFor([]()
@ -85,7 +96,7 @@ int main(int, char**) {
// auto combined = makeTestContinuation() && makeTestContinuation(); // auto combined = makeTestContinuation() && makeTestContinuation();
int res = 0; int res = 0;
makeTestContinuation() /*makeTestContinuation()
.then([](std::string) { .then([](std::string) {
return std::make_tuple(47, 46, 45); return std::make_tuple(47, 46, 45);
}) })
@ -102,7 +113,7 @@ int main(int, char**) {
.then(makeTestContinuation()) .then(makeTestContinuation())
.then([] (std::string arg) { .then([] (std::string arg) {
arg.clear(); arg.clear();
}); });*/
return res; return res;
} }