Started on implementing error handler chaining

* Namespace fixups
This commit is contained in:
Denis Blank 2017-09-29 15:38:41 +02:00
parent 98936f6972
commit 6481b5454d
8 changed files with 89 additions and 17 deletions

View File

@ -687,6 +687,6 @@ struct continuable_trait {
continuable_base<continuation,
detail::hints::signature_hint_tag<Args...>>;
};
} // end namespace cti
} // namespace cti
#endif // CONTINUABLE_BASE_HPP_INCLUDED__

View File

@ -82,6 +82,6 @@ public:
data_(detail::base::dispatch_error_tag{}, std::move(error));
}
};
} // end namespace cti
} // namespace cti
#endif // CONTINUABLE_PROMISE_BASE_HPP_INCLUDED__

View File

@ -120,9 +120,9 @@ void assert_async_types(C&& continuable, traits::identity<Args...> expected) {
"The called arguments don't match with the expected ones!");
});
}
} // end namespace testing
} // end namespace detail
} // end namespace cti
} // namespace testing
} // namespace detail
} // namespace cti
/// Asserts that the final callback of the given continuable was called
/// with any result.

View File

@ -52,7 +52,7 @@ using unique_trait_of = continuable_trait<
fu2::unique_function,
Args...
>;
} // end namespace detail
} // namespace detail
/// Defines a copyable continuation type which uses the
/// function2 backend for type erasure.
@ -94,6 +94,6 @@ using unique_callback = typename detail::unique_trait_of<
// TODO sink
// clang-format on
} // end namespace cti
} // namespace cti
#endif // CONTINUABLE_HPP_INCLUDED__

View File

@ -243,7 +243,7 @@ template <typename... Args>
constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
}
} // end namespace decoration
} // namespace decoration
/// Invoke the callback immediately
template <typename Invoker, typename Callback, typename NextCallback,
@ -390,6 +390,79 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
next_hint, ownership_);
}
template <typename Hint, typename Callback, typename Executor,
typename NextCallback>
struct error_proxy;
template <typename... Args, typename Callback, typename Executor,
typename NextCallback>
struct error_proxy<hints::signature_hint_tag<Args...>, Callback, Executor,
NextCallback> {
Callback callback_;
Executor executor_;
NextCallback next_callback_;
/// The operator which is called when the result was provided
void operator()(Args... args) {
// Forward the arguments to the next callback
std::move(next_callback_)(std::move(args)...);
}
/// The operator which is called when an error occurred
void operator()(dispatch_error_tag /*tag*/, error_type error) {
// Forwárd the error to the error handler
// TODO
}
};
/// Chains an error handler together with a continuation and
/// returns a continuation. The current future result of the continuation
//// stays unchanged.
///
template <typename Continuation, typename Callback, typename Executor>
auto chain_error_handler(Continuation&& continuation, Callback&& callback,
Executor&& executor) {
static_assert(is_continuation<std::decay_t<Continuation>>{},
"Expected a continuation!");
// The current hint will also be the next one
auto hint = hint_of(traits::identity_of(continuation));
// TODO consume only the data here so the freeze isn't needed
auto ownership_ = attorney::ownership_of(continuation);
continuation.freeze();
return attorney::create(
[
continuation = std::forward<Continuation>(continuation),
callback = std::forward<Callback>(callback),
executor = std::forward<Executor>(executor)
](auto&& next_callback) mutable {
// Invokes a continuation with a given callback.
// Passes the next callback to the resulting continuable or
// invokes the next callback directly if possible.
//
// For example given:
// - Continuation: continuation<[](auto&& callback) { callback("hi");
// }>
// - Callback: [](std::string) { }
// - NextCallback: []() { }
/*using Hint = decltype(hint_of(traits::identity_of(continuation)));
result_proxy<Hint, std::decay_t<decltype(partial_callable)>,
std::decay_t<decltype(executor)>,
std::decay_t<decltype(next_callback)>>
proxy{std::move(partial_callable), std::move(executor),
std::forward<decltype(next_callback)>(next_callback)};*/
// Invoke the continuation with a proxy callback.
// The proxy callback is responsible for passing
// the result to the callback as well as decorating it.
/*attorney::invoke_continuation(std::forward<Continuation>(continuation),
std::move(proxy));*/
},
hint, ownership_);
}
/// Workaround for GCC bug:
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
struct empty_callback {
@ -431,8 +504,7 @@ auto wrap_continuation(Continuation&& continuation) {
return supplier_callback<std::decay_t<Continuation>>(
std::forward<Continuation>(continuation));
}
} // end namespace base
} // namespace base
} // namespace detail
} // namespace cti

View File

@ -70,7 +70,7 @@ template <typename... HintArgs>
constexpr auto make_hint_of(traits::identity<HintArgs...> args) noexcept {
return args; // Identity is equal to signature_hint_tag
}
} // end namespace detail
} // namespace detail
/// Extracts the signature hint of a given continuation and it's optional
/// present hint arguments.
@ -101,7 +101,7 @@ constexpr auto extract(traits::identity<T> /*type*/,
return detail::make_hint_of(hint);
});
}
} // end namespace annotating
} // namespace annotating
namespace detail {
template <std::size_t Pos, typename T>
@ -198,7 +198,7 @@ private:
std::call_once(flag_, std::move(callback_), std::forward<Args>(args)...);
}
};
} // end namespace detail
} // namespace detail
/// Adds the given continuation tuple to the left composition
template <typename... LeftArgs, typename... RightArgs>

View File

@ -165,7 +165,7 @@ namespace detail {
// See http://stackoverflow.com/questions/35753920 for details.
template <typename...>
struct deduce_to_void : std::common_type<void> {};
} // end namespace detail
} // namespace detail
/// C++17 like void_t type
template <typename... T>
@ -204,7 +204,7 @@ constexpr auto static_if_impl(std::false_type, Type&& type,
FalseCallback&& falseCallback) {
return std::forward<FalseCallback>(falseCallback)(std::forward<Type>(type));
}
} // end namespace detail
} // namespace detail
/// Returns the pack size of the given type
template <typename... Args>

View File

@ -64,7 +64,7 @@ struct is_invokable_impl<
T, std::tuple<Args...>,
traits::void_t<decltype(std::declval<T>()(std::declval<Args>()...))>>
: std::common_type<std::true_type> {};
} // end namespace detail
} // namespace detail
/// Deduces to a std::true_type if the given type is callable with the arguments
/// inside the given tuple.
@ -148,7 +148,7 @@ auto partial_invoke_impl_shortcut(std::false_type failed, T&& callable,
failed, std::forward<T>(callable),
std::forward_as_tuple(std::forward<Args>(args)...));
}
} // end namespace detail
} // namespace detail
/// Partially invokes the given callable with the given arguments.
///