Started to implement promises and multi execution flow

This commit is contained in:
Denis Blank 2017-09-27 02:32:46 +02:00
parent 8d6c9ab895
commit b65eea8b1a
5 changed files with 156 additions and 4 deletions

View File

@ -225,6 +225,52 @@ public:
detail::base::wrap_continuation(std::move(continuation).materialize()));
}
/// Main method of the continuable_base to catch exceptions and error codes
///
/// \param callback The callback which is used to process the current
/// asynchronous error result on arrival.
/// In case the continuable_base is using exceptions, the usage is as
/// shown below:
///
/// ```cpp
/// http_request("github.com")
/// .then([](std::string github) { })
/// .catching([](std::exception_ptr ptr) {
/// // Handle the error here
/// try {
/// std::rethrow_exception(ptr);
/// } catch (std::exception& e) {
/// e.what(); // Handle the exception
/// }
/// });
/// ```
/// In case exceptions are disabled, `std::error_condition` is
/// used as error result instead of `std::exception_ptr`.
/// ```cpp
/// http_request("github.com")
/// .then([](std::string github) { })
/// .catching([](std::error_condition error) {
/// // Handle the error here
/// // ...
/// });
/// ```
///
/// \param executor The optional executor which is used to dispatch
/// the callback. See the description in `then` above.
///
/// \returns Returns a continuable_base with an asynchronous return type
/// depending on the current result type.
///
///
/// \since version 2.0.0
template <typename T, typename E = detail::base::this_thread_executor_tag>
auto catching(T&& callback,
E&& executor = detail::base::this_thread_executor_tag{}) && {
/*return detail::base::chain_continuation(std::move(*this).materialize(),
std::forward<T>(callback),
std::forward<E>(executor));*/
}
/// Invokes both continuable_base objects parallel and calls the
/// callback with the result of both continuable_base objects.
///

View File

@ -0,0 +1,87 @@
/**
/~` _ _ _|_. _ _ |_ | _
\_,(_)| | | || ||_|(_||_)|(/_
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_PROMISE_BASE_HPP_INCLUDED__
#define CONTINUABLE_PROMISE_BASE_HPP_INCLUDED__
#include <type_traits>
#include <utility>
#include <continuable/detail/api.hpp>
#include <continuable/detail/base.hpp>
namespace cti {
template <typename Data>
class promise_base {
/// \cond false
// The callback type
Data data_;
/// \endcond
public:
/// Constructor accepting the data object
explicit promise_base(Data data) : data_(std::move(data)) {
}
/// Constructor accepting any object convertible to the data object
template <typename OData, std::enable_if_t<std::is_convertible<
std::decay_t<OData>, Data>::value>* = nullptr>
promise_base(OData&& data) : data_(std::forward<OData>(data)) {
}
/// \cond false
promise_base(promise_base&&) = default;
promise_base(promise_base const&) = default;
promise_base& operator=(promise_base&&) = default;
promise_base& operator=(promise_base const&) = default;
/// \endcond
/// Resolves the continuation with the given values
template <typename... Args>
void set_value(Args&&... args) {
data_(detail::base::dispatch_result{}, std::forward<Args>(args)...);
}
/// Resolves the continuation with the given values
template <typename... Args>
void operator()(Args&&... args) {
data_(detail::base::dispatch_result{}, std::forward<Args>(args)...);
}
/// Resolves the continuation with the given error variable.
template <typename Arg>
void set_error(Arg&& arg) {
data_(detail::base::dispatch_error{}, std::forward<Arg>(arg));
}
};
} // end namespace cti
#endif // CONTINUABLE_PROMISE_BASE_HPP_INCLUDED__

View File

@ -57,7 +57,12 @@ namespace detail {
/// base::finalize_continuation(base::continuation<auto> continuation)
/// -> void
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 a real result
struct dispatch_result {};
/// A tag which is used to continue with an error
struct dispatch_error {};
/// Returns the signature hint of the given continuable
template <typename T>
@ -285,7 +290,7 @@ void invoke_proxy(hints::signature_hint_tag<Args...>,
Executor&& executor, NextCallback&& nextCallback) {
// Invoke the continuation with a proxy callback.
// The proxy callback is responsible for passing the
// The proxy callback is responsible for passing
// the result to the callback as well as decorating it.
attorney::invoke_continuation(std::forward<Continuation>(continuation), [
callback = std::forward<Callback>(callback),
@ -351,11 +356,11 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
continuation = std::forward<Continuation>(continuation),
partial_callable = std::move(partial_callable),
executor = std::forward<Executor>(executor)
](auto&& nextCallback) mutable {
](auto&& next_callback) mutable {
invoke_proxy(hint_of(traits::identity_of(continuation)),
std::move(continuation), std::move(partial_callable),
std::move(executor),
std::forward<decltype(nextCallback)>(nextCallback));
std::forward<decltype(next_callback)>(next_callback));
},
next_hint, ownership_);
}

View File

@ -30,7 +30,20 @@
#ifndef CONTINUABLE_DETAIL_FEATURES_HPP_INCLUDED__
#define CONTINUABLE_DETAIL_FEATURES_HPP_INCLUDED__
#include <continuable/detail/api.hpp>
// Defines CONTINUABLE_WITH_NO_EXCEPTIONS when exception support is disabled
#if defined(_MSC_VER)
#if !defined(_HAS_EXCEPTIONS) || (_HAS_EXCEPTIONS == 0)
#define CONTINUABLE_WITH_NO_EXCEPTIONS
#endif
#elif defined(__clang__)
#if !(__EXCEPTIONS && __has_feature(cxx_exceptions))
#define CONTINUABLE_WITH_NO_EXCEPTIONS
#endif
#elif defined(__GNUC__)
#if !__EXCEPTIONS
#define CONTINUABLE_WITH_NO_EXCEPTIONS
#endif
#endif
#undef CONTINUABLE_HAS_CXX17_CONSTEXPR_IF
#undef CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION

View File

@ -1,6 +1,7 @@
set(LIB_SOURCES
${CMAKE_SOURCE_DIR}/include/continuable/continuable.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-base.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.hpp
${CMAKE_SOURCE_DIR}/include/continuable/continuable-testing.hpp)
set(LIB_SOURCES_DETAIL
${CMAKE_SOURCE_DIR}/include/continuable/detail/base.hpp