mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 09:16:46 +08:00
First building API of promises and error handling
* Currently not functional (yet)
This commit is contained in:
parent
8e8f5e982d
commit
37c70c3365
@ -42,6 +42,7 @@
|
|||||||
#include <continuable/detail/composition.hpp>
|
#include <continuable/detail/composition.hpp>
|
||||||
#include <continuable/detail/traits.hpp>
|
#include <continuable/detail/traits.hpp>
|
||||||
#include <continuable/detail/transforms.hpp>
|
#include <continuable/detail/transforms.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
#include <continuable/detail/util.hpp>
|
#include <continuable/detail/util.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
@ -192,9 +193,9 @@ public:
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// \since version 1.0.0
|
/// \since version 1.0.0
|
||||||
template <typename T, typename E = detail::base::this_thread_executor_tag>
|
template <typename T, typename E = detail::types::this_thread_executor_tag>
|
||||||
auto then(T&& callback,
|
auto then(T&& callback,
|
||||||
E&& executor = detail::base::this_thread_executor_tag{}) && {
|
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
||||||
return detail::base::chain_continuation(std::move(*this).materialize(),
|
return detail::base::chain_continuation(std::move(*this).materialize(),
|
||||||
std::forward<T>(callback),
|
std::forward<T>(callback),
|
||||||
std::forward<E>(executor));
|
std::forward<E>(executor));
|
||||||
@ -262,12 +263,12 @@ public:
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \since version 2.0.0
|
/// \since version 2.0.0
|
||||||
template <typename T, typename E = detail::base::this_thread_executor_tag>
|
template <typename T, typename E = detail::types::this_thread_executor_tag>
|
||||||
auto catching(T&& callback,
|
auto catching(T&& callback,
|
||||||
E&& executor = detail::base::this_thread_executor_tag{}) && {
|
E&& executor = detail::types::this_thread_executor_tag{}) && {
|
||||||
/*return detail::base::chain_continuation(std::move(*this).materialize(),
|
return detail::base::chain_error_handler(std::move(*this).materialize(),
|
||||||
std::forward<T>(callback),
|
std::forward<T>(callback),
|
||||||
std::forward<E>(executor));*/
|
std::forward<E>(executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invokes both continuable_base objects parallel and calls the
|
/// Invokes both continuable_base objects parallel and calls the
|
||||||
@ -627,33 +628,6 @@ auto when_seq(Continuables&&... continuables) {
|
|||||||
return detail::traits::fold(detail::traits::seq_folding(),
|
return detail::traits::fold(detail::traits::seq_folding(),
|
||||||
std::forward<Continuables>(continuables)...);
|
std::forward<Continuables>(continuables)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to retrieve a continuable_base type with a given type-erasure backend.
|
|
||||||
///
|
|
||||||
/// Every object may me used as type-erasure backend as long as the
|
|
||||||
/// requirements of a `std::function` like wrapper are satisfied.
|
|
||||||
///
|
|
||||||
/// \tparam CallbackWrapper The type which is used to erase the callback.
|
|
||||||
///
|
|
||||||
/// \tparam ContinuationWrapper The type which is used to erase the
|
|
||||||
/// continuation data.
|
|
||||||
///
|
|
||||||
/// \tparam Args The current signature of the continuable.
|
|
||||||
template <template <typename> class CallbackWrapper,
|
|
||||||
template <typename> class ContinuationWrapper, typename... Args>
|
|
||||||
struct continuable_trait {
|
|
||||||
/// The callback type which is passed to continuations
|
|
||||||
using callback = CallbackWrapper<void(Args...)>;
|
|
||||||
|
|
||||||
/// The continuation type which is used to erase the internal data.
|
|
||||||
using continuation =
|
|
||||||
ContinuationWrapper<void(CallbackWrapper<void(Args...)>)>;
|
|
||||||
|
|
||||||
/// The continuable type for the given parameters.
|
|
||||||
using continuable =
|
|
||||||
continuable_base<continuation,
|
|
||||||
detail::hints::signature_hint_tag<Args...>>;
|
|
||||||
};
|
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
#endif // CONTINUABLE_BASE_HPP_INCLUDED__
|
#endif // CONTINUABLE_BASE_HPP_INCLUDED__
|
||||||
|
|||||||
@ -35,14 +35,14 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <continuable/detail/api.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
#include <continuable/detail/base.hpp>
|
|
||||||
#include <continuable/detail/hints.hpp>
|
#include <continuable/detail/hints.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
template <typename Hint, typename Data>
|
template <typename Data, typename Hint>
|
||||||
class promise_base;
|
class promise_base;
|
||||||
template <typename... Args, typename Data>
|
template <typename Data, typename... Args>
|
||||||
class promise_base<detail::hints::signature_hint_tag<Args...>, Data> {
|
class promise_base<Data, detail::hints::signature_hint_tag<Args...>> {
|
||||||
/// \cond false
|
/// \cond false
|
||||||
// The callback type
|
// The callback type
|
||||||
Data data_;
|
Data data_;
|
||||||
@ -78,8 +78,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the continuation with the given error variable.
|
/// Resolves the continuation with the given error variable.
|
||||||
void set_error(detail::base::error_type error) {
|
void set_error(detail::types::error_type error) {
|
||||||
data_(detail::base::dispatch_error_tag{}, std::move(error));
|
data_(detail::types::dispatch_error_tag{}, std::move(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|||||||
76
include/continuable/continuable-trait.hpp
Normal file
76
include/continuable/continuable-trait.hpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v2.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef CONTINUABLE_TRAIT_HPP_INCLUDED__
|
||||||
|
#define CONTINUABLE_TRAIT_HPP_INCLUDED__
|
||||||
|
|
||||||
|
#include <continuable/continuable-base.hpp>
|
||||||
|
#include <continuable/continuable-promise-base.hpp>
|
||||||
|
#include <continuable/detail/api.hpp>
|
||||||
|
#include <continuable/detail/hints.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
/// Trait to retrieve a continuable_base type with a given type-erasure backend.
|
||||||
|
///
|
||||||
|
/// Every object may me used as type-erasure backend as long as the
|
||||||
|
/// requirements of a `std::function` like wrapper are satisfied.
|
||||||
|
///
|
||||||
|
/// \tparam CallbackWrapper The type which is used to erase the callback.
|
||||||
|
///
|
||||||
|
/// \tparam ContinuationWrapper The type which is used to erase the
|
||||||
|
/// continuation data.
|
||||||
|
///
|
||||||
|
/// \tparam Args The current signature of the continuable.
|
||||||
|
template <template <typename...> class CallbackWrapper,
|
||||||
|
template <typename...> class ContinuationWrapper, typename... Args>
|
||||||
|
struct continuable_trait {
|
||||||
|
/// The callback type which is passed to continuations
|
||||||
|
using callback =
|
||||||
|
CallbackWrapper<void(Args...), void(detail::types::dispatch_error_tag,
|
||||||
|
detail::types::error_type)>;
|
||||||
|
|
||||||
|
/// The continuation type which is used to erase the internal data.
|
||||||
|
using continuation = ContinuationWrapper<void(
|
||||||
|
CallbackWrapper<void(Args...), void(detail::types::dispatch_error_tag,
|
||||||
|
detail::types::error_type)>)>;
|
||||||
|
|
||||||
|
/// The promise type which is used to resolve continuations
|
||||||
|
using promise =
|
||||||
|
promise_base<callback, detail::hints::signature_hint_tag<Args...>>;
|
||||||
|
|
||||||
|
/// The continuable type for the given parameters.
|
||||||
|
using continuable =
|
||||||
|
continuable_base<continuation,
|
||||||
|
detail::hints::signature_hint_tag<Args...>>;
|
||||||
|
};
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_TRAIT_HPP_INCLUDED__
|
||||||
@ -31,10 +31,10 @@
|
|||||||
#ifndef CONTINUABLE_HPP_INCLUDED__
|
#ifndef CONTINUABLE_HPP_INCLUDED__
|
||||||
#define CONTINUABLE_HPP_INCLUDED__
|
#define CONTINUABLE_HPP_INCLUDED__
|
||||||
|
|
||||||
#include "function2/function2.hpp"
|
#include <function2/function2.hpp>
|
||||||
|
|
||||||
#include <continuable/continuable-base.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
#include <continuable/continuable-promise-base.hpp>
|
#include <continuable/continuable-trait.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -67,19 +67,20 @@ using continuable = typename detail::trait_of<
|
|||||||
/// function2 backend for the continuable type erasure.
|
/// function2 backend for the continuable type erasure.
|
||||||
///
|
///
|
||||||
/// Usable like: `callback<int, float>`
|
/// Usable like: `callback<int, float>`
|
||||||
template <typename... Args>
|
// TODO Decide whether promises are copyable
|
||||||
using callback = typename detail::trait_of<
|
// template <typename... Args>
|
||||||
Args...
|
// using promise = typename detail::trait_of<
|
||||||
>::callback;
|
// Args...
|
||||||
|
// >::promise;
|
||||||
|
|
||||||
/// Defines a non-copyable continuation type which uses the
|
/// Defines a non-copyable promise type which using the
|
||||||
/// function2 backend for type erasure.
|
/// function2 backend for type erasure.
|
||||||
///
|
///
|
||||||
/// Usable like: `unique_continuable<int, float>`
|
/// Usable like: `promise<int, float>`
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
using unique_continuable = typename detail::unique_trait_of<
|
using promise = typename detail::unique_trait_of<
|
||||||
Args...
|
Args...
|
||||||
>::continuable;
|
>::promise;
|
||||||
|
|
||||||
/// Defines a non-copyable callback type which uses the
|
/// Defines a non-copyable callback type which uses the
|
||||||
/// function2 backend for the continuable type erasure.
|
/// function2 backend for the continuable type erasure.
|
||||||
|
|||||||
@ -35,15 +35,10 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
#include <exception>
|
|
||||||
#else // CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
#include <error>
|
|
||||||
#endif // CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
|
|
||||||
#include <continuable/detail/api.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
#include <continuable/detail/hints.hpp>
|
#include <continuable/detail/hints.hpp>
|
||||||
#include <continuable/detail/traits.hpp>
|
#include <continuable/detail/traits.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
#include <continuable/detail/util.hpp>
|
#include <continuable/detail/util.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
@ -63,19 +58,6 @@ namespace detail {
|
|||||||
/// base::finalize_continuation(base::continuation<auto> continuation)
|
/// base::finalize_continuation(base::continuation<auto> continuation)
|
||||||
/// -> void
|
/// -> void
|
||||||
namespace base {
|
namespace base {
|
||||||
/// A tag which is used to execute the continuation inside the current thread
|
|
||||||
struct this_thread_executor_tag {};
|
|
||||||
/// A tag which is used to continue with an error
|
|
||||||
struct dispatch_error_tag {};
|
|
||||||
|
|
||||||
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
/// Represents the error type when exceptions are enabled
|
|
||||||
using error_type = std::exception_ptr;
|
|
||||||
#else // CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
/// Represents the error type when exceptions are disabled
|
|
||||||
using error_type = std::error_category;
|
|
||||||
#endif // CONTINUABLE_WITH_NO_EXCEPTIONS
|
|
||||||
|
|
||||||
/// Returns the signature hint of the given continuable
|
/// Returns the signature hint of the given continuable
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr auto hint_of(traits::identity<T>) {
|
constexpr auto hint_of(traits::identity<T>) {
|
||||||
@ -204,7 +186,7 @@ constexpr auto invoker_of(traits::identity<T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// - void -> next_callback()
|
/// - void -> next_callback()
|
||||||
constexpr auto invoker_of(traits::identity<void>) {
|
inline auto invoker_of(traits::identity<void>) {
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
std::forward<decltype(callback)>(callback)(
|
std::forward<decltype(callback)>(callback)(
|
||||||
@ -248,7 +230,7 @@ constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
|
|||||||
/// Invoke the callback immediately
|
/// Invoke the callback immediately
|
||||||
template <typename Invoker, typename Callback, typename NextCallback,
|
template <typename Invoker, typename Callback, typename NextCallback,
|
||||||
typename... Args>
|
typename... Args>
|
||||||
void packed_dispatch(this_thread_executor_tag, Invoker&& invoker,
|
void packed_dispatch(types::this_thread_executor_tag, Invoker&& invoker,
|
||||||
Callback&& callback, NextCallback&& next_callback,
|
Callback&& callback, NextCallback&& next_callback,
|
||||||
Args&&... args) {
|
Args&&... args) {
|
||||||
|
|
||||||
@ -276,7 +258,7 @@ void packed_dispatch(Executor&& executor, Invoker&& invoker,
|
|||||||
traits::unpack(std::move(args), [&](auto&&... captured_args) {
|
traits::unpack(std::move(args), [&](auto&&... captured_args) {
|
||||||
// Just use the packed dispatch method which dispatches the work on
|
// Just use the packed dispatch method which dispatches the work on
|
||||||
// the current thread.
|
// the current thread.
|
||||||
packed_dispatch(this_thread_executor_tag{}, std::move(invoker),
|
packed_dispatch(types::this_thread_executor_tag{}, std::move(invoker),
|
||||||
std::move(callback), std::move(next_callback),
|
std::move(callback), std::move(next_callback),
|
||||||
std::forward<decltype(captured_args)>(captured_args)...);
|
std::forward<decltype(captured_args)>(captured_args)...);
|
||||||
});
|
});
|
||||||
@ -286,13 +268,14 @@ void packed_dispatch(Executor&& executor, Invoker&& invoker,
|
|||||||
std::forward<Executor>(executor)(std::move(work));
|
std::forward<Executor>(executor)(std::move(work));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace callbacks {
|
||||||
template <typename Hint, typename Callback, typename Executor,
|
template <typename Hint, typename Callback, typename Executor,
|
||||||
typename NextCallback>
|
typename NextCallback>
|
||||||
struct result_proxy;
|
struct result_callback;
|
||||||
|
|
||||||
template <typename... Args, typename Callback, typename Executor,
|
template <typename... Args, typename Callback, typename Executor,
|
||||||
typename NextCallback>
|
typename NextCallback>
|
||||||
struct result_proxy<hints::signature_hint_tag<Args...>, Callback, Executor,
|
struct result_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
||||||
NextCallback> {
|
NextCallback> {
|
||||||
Callback callback_;
|
Callback callback_;
|
||||||
Executor executor_;
|
Executor executor_;
|
||||||
@ -315,12 +298,77 @@ struct result_proxy<hints::signature_hint_tag<Args...>, Callback, Executor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The operator which is called when an error occurred
|
/// The operator which is called when an error occurred
|
||||||
void operator()(dispatch_error_tag tag, error_type error) {
|
void operator()(types::dispatch_error_tag tag, types::error_type error) {
|
||||||
// Forward the error to the next callback
|
// Forward the error to the next callback
|
||||||
std::move(next_callback_)(tag, std::move(error));
|
std::move(next_callback_)(tag, std::move(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolves the continuation with the given values
|
||||||
|
void set_value(Args... args) {
|
||||||
|
std::move(next_callback_)(std::move(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves the continuation with the given error variable.
|
||||||
|
void set_error(types::error_type error) {
|
||||||
|
std::move(next_callback_)(types::dispatch_error_tag{}, std::move(error));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Hint, typename Callback, typename Executor,
|
||||||
|
typename NextCallback>
|
||||||
|
struct error_callback;
|
||||||
|
|
||||||
|
template <typename... Args, typename Callback, typename Executor,
|
||||||
|
typename NextCallback>
|
||||||
|
struct error_callback<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()(types::dispatch_error_tag /*tag*/, types::error_type error) {
|
||||||
|
auto invoker = [] {};
|
||||||
|
|
||||||
|
// Forward the error to the error handler
|
||||||
|
packed_dispatch(std::move(executor_), std::move(invoker),
|
||||||
|
std::move(callback_), std::move(next_callback_),
|
||||||
|
std::move(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves the continuation with the given values
|
||||||
|
void set_value(Args... args) {
|
||||||
|
std::move(next_callback_)(std::move(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves the continuation with the given error variable.
|
||||||
|
void set_error(types::error_type error) {
|
||||||
|
std::move(next_callback_)(types::dispatch_error_tag{}, std::move(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Workaround for GCC bug:
|
||||||
|
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
||||||
|
struct empty_callback {
|
||||||
|
template <typename... Args>
|
||||||
|
void operator()(Args... /*error*/) const {
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void set_value(Args... /*error*/) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_error(types::error_type /*error*/) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace callbacks
|
||||||
|
|
||||||
/// Returns the next hint when the callback is invoked with the given hint
|
/// Returns the next hint when the callback is invoked with the given hint
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
constexpr auto next_hint_of(traits::identity<T> /*callback*/,
|
constexpr auto next_hint_of(traits::identity<T> /*callback*/,
|
||||||
@ -375,7 +423,8 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
|
|||||||
// - Callback: [](std::string) { }
|
// - Callback: [](std::string) { }
|
||||||
// - NextCallback: []() { }
|
// - NextCallback: []() { }
|
||||||
using Hint = decltype(hint_of(traits::identity_of(continuation)));
|
using Hint = decltype(hint_of(traits::identity_of(continuation)));
|
||||||
result_proxy<Hint, std::decay_t<decltype(partial_callable)>,
|
callbacks::result_callback<Hint,
|
||||||
|
std::decay_t<decltype(partial_callable)>,
|
||||||
std::decay_t<decltype(executor)>,
|
std::decay_t<decltype(executor)>,
|
||||||
std::decay_t<decltype(next_callback)>>
|
std::decay_t<decltype(next_callback)>>
|
||||||
proxy{std::move(partial_callable), std::move(executor),
|
proxy{std::move(partial_callable), std::move(executor),
|
||||||
@ -390,31 +439,6 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
|
|||||||
next_hint, ownership_);
|
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
|
/// Chains an error handler together with a continuation and
|
||||||
/// returns a continuation. The current future result of the continuation
|
/// returns a continuation. The current future result of the continuation
|
||||||
//// stays unchanged.
|
//// stays unchanged.
|
||||||
@ -437,7 +461,7 @@ auto chain_error_handler(Continuation&& continuation, Callback&& callback,
|
|||||||
continuation = std::forward<Continuation>(continuation),
|
continuation = std::forward<Continuation>(continuation),
|
||||||
callback = std::forward<Callback>(callback),
|
callback = std::forward<Callback>(callback),
|
||||||
executor = std::forward<Executor>(executor)
|
executor = std::forward<Executor>(executor)
|
||||||
](auto&& next_callback) mutable {
|
](auto&& /*next_callback*/) mutable {
|
||||||
// Invokes a continuation with a given callback.
|
// Invokes a continuation with a given callback.
|
||||||
// Passes the next callback to the resulting continuable or
|
// Passes the next callback to the resulting continuable or
|
||||||
// invokes the next callback directly if possible.
|
// invokes the next callback directly if possible.
|
||||||
@ -448,7 +472,8 @@ auto chain_error_handler(Continuation&& continuation, Callback&& callback,
|
|||||||
// - Callback: [](std::string) { }
|
// - Callback: [](std::string) { }
|
||||||
// - NextCallback: []() { }
|
// - NextCallback: []() { }
|
||||||
/*using Hint = decltype(hint_of(traits::identity_of(continuation)));
|
/*using Hint = decltype(hint_of(traits::identity_of(continuation)));
|
||||||
result_proxy<Hint, std::decay_t<decltype(partial_callable)>,
|
callbacks::result_callback<Hint,
|
||||||
|
std::decay_t<decltype(partial_callable)>,
|
||||||
std::decay_t<decltype(executor)>,
|
std::decay_t<decltype(executor)>,
|
||||||
std::decay_t<decltype(next_callback)>>
|
std::decay_t<decltype(next_callback)>>
|
||||||
proxy{std::move(partial_callable), std::move(executor),
|
proxy{std::move(partial_callable), std::move(executor),
|
||||||
@ -463,14 +488,6 @@ auto chain_error_handler(Continuation&& continuation, Callback&& callback,
|
|||||||
hint, ownership_);
|
hint, ownership_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Workaround for GCC bug:
|
|
||||||
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
|
||||||
struct empty_callback {
|
|
||||||
template <typename... Args>
|
|
||||||
void operator()(Args...) const {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Final invokes the given continuation chain:
|
/// Final invokes the given continuation chain:
|
||||||
///
|
///
|
||||||
/// For example given:
|
/// For example given:
|
||||||
@ -478,7 +495,7 @@ struct empty_callback {
|
|||||||
template <typename Continuation>
|
template <typename Continuation>
|
||||||
void finalize_continuation(Continuation&& continuation) {
|
void finalize_continuation(Continuation&& continuation) {
|
||||||
attorney::invoke_continuation(std::forward<Continuation>(continuation),
|
attorney::invoke_continuation(std::forward<Continuation>(continuation),
|
||||||
empty_callback{});
|
callbacks::empty_callback{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Workaround for GCC bug:
|
/// Workaround for GCC bug:
|
||||||
|
|||||||
63
include/continuable/detail/types.hpp
Normal file
63
include/continuable/detail/types.hpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v2.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED__
|
||||||
|
#define CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED__
|
||||||
|
|
||||||
|
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
#include <exception>
|
||||||
|
#else // CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
#include <error>
|
||||||
|
#endif // CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
#include <continuable/detail/api.hpp>
|
||||||
|
#include <continuable/detail/features.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
namespace detail {
|
||||||
|
/// Contains types used globally across the library
|
||||||
|
namespace types {
|
||||||
|
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
/// Represents the error type when exceptions are enabled
|
||||||
|
using error_type = std::exception_ptr;
|
||||||
|
#else // CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
/// Represents the error type when exceptions are disabled
|
||||||
|
using error_type = std::error_condition;
|
||||||
|
#endif // CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
/// A tag which is used to execute the continuation inside the current thread
|
||||||
|
struct this_thread_executor_tag {};
|
||||||
|
/// A tag which is used to continue with an error
|
||||||
|
struct dispatch_error_tag {};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED__
|
||||||
@ -1,6 +1,7 @@
|
|||||||
set(LIB_SOURCES
|
set(LIB_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-base.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-base.hpp
|
||||||
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-trait.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-testing.hpp)
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-testing.hpp)
|
||||||
set(LIB_SOURCES_DETAIL
|
set(LIB_SOURCES_DETAIL
|
||||||
@ -11,6 +12,7 @@ set(LIB_SOURCES_DETAIL
|
|||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/features.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/features.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/transforms.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/transforms.hpp
|
||||||
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/types.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/util.hpp)
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/util.hpp)
|
||||||
set(TEST
|
set(TEST
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-playground.cpp)
|
${CMAKE_CURRENT_LIST_DIR}/test-playground.cpp)
|
||||||
|
|||||||
@ -26,11 +26,35 @@
|
|||||||
|
|
||||||
cti::continuable<std::string> http_request(std::string url) {
|
cti::continuable<std::string> http_request(std::string url) {
|
||||||
return [](cti::promise<std::string> promise) {
|
return [](cti::promise<std::string> promise) {
|
||||||
// ...
|
promise.set_error(nullptr);
|
||||||
promise.set_value("");
|
promise.set_value("");
|
||||||
|
promise("");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto http_request2(std::string url) {
|
||||||
|
return cti::make_continuable<std::string>([](auto&& promise) {
|
||||||
|
promise.set_error(nullptr);
|
||||||
|
promise.set_value("");
|
||||||
|
promise("");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
|
http_request("github.com")
|
||||||
|
.then([](std::string /*response*/) {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
.catching([](std::exception_ptr /*e*/) {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
|
||||||
|
http_request2("github.com")
|
||||||
|
.then([](std::string /*response*/) {
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
.catching([](std::exception_ptr /*e*/) {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user