mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
Start to revise transforms
This commit is contained in:
parent
957d3fa375
commit
df4d6ed971
@ -436,14 +436,15 @@ public:
|
|||||||
return std::move(*this).then(detail::base::convert_to<Args...>{});
|
return std::move(*this).then(detail::base::convert_to<Args...>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A method which allows to apply this continuable to the given callable.
|
/// A method which allows to apply a callable object to this continuable.
|
||||||
///
|
///
|
||||||
/// \param transform A transform which shall accept this continuable
|
/// \param transform A callable objects that transforms a continuable
|
||||||
|
/// to a different object.
|
||||||
///
|
///
|
||||||
/// \returns Returns the result of the given transform when this
|
/// \returns Returns the result of the given transform when this
|
||||||
/// continuable is passed into it.
|
/// continuable is passed into it.
|
||||||
///
|
///
|
||||||
/// \since 2.0.0
|
/// \since 4.0.0
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto apply(T&& transform) && {
|
auto apply(T&& transform) && {
|
||||||
return std::forward<T>(transform)(std::move(*this).finish());
|
return std::forward<T>(transform)(std::move(*this).finish());
|
||||||
@ -462,22 +463,6 @@ public:
|
|||||||
return std::move(*this).then(std::forward<T>(right));
|
return std::move(*this).then(std::forward<T>(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The pipe operator | is an alias for the continuable::apply method.
|
|
||||||
///
|
|
||||||
/// \param transform The transformer which is applied.
|
|
||||||
///
|
|
||||||
/// \returns See the corresponding continuable_base::apply method for the
|
|
||||||
/// explanation of the return type.
|
|
||||||
///
|
|
||||||
/// \note You may create your own transformation through
|
|
||||||
/// calling make_transformation.
|
|
||||||
///
|
|
||||||
/// \since 3.0.0
|
|
||||||
template <typename T>
|
|
||||||
auto operator|(detail::types::transform<T> transform) && {
|
|
||||||
return std::move(*this).apply(std::move(transform));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Invokes both continuable_base objects parallel and calls the
|
/// Invokes both continuable_base objects parallel and calls the
|
||||||
/// callback with the result of both continuable_base objects.
|
/// callback with the result of both continuable_base objects.
|
||||||
///
|
///
|
||||||
|
|||||||
@ -31,8 +31,8 @@
|
|||||||
#ifndef CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
#ifndef CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||||
#define CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
#define CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||||
|
|
||||||
#include <continuable/detail/core/types.hpp>
|
#include <continuable/transforms/wait.hpp>
|
||||||
#include <continuable/detail/other/transforms.hpp>
|
#include <continuable/transforms/future.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
/// \defgroup Transforms Transforms
|
/// \defgroup Transforms Transforms
|
||||||
@ -41,70 +41,12 @@ namespace cti {
|
|||||||
/// types such as (`std::future`).
|
/// types such as (`std::future`).
|
||||||
/// \{
|
/// \{
|
||||||
|
|
||||||
/// A callable tag object which marks a wrapped callable object
|
|
||||||
/// as continuable transformation which enables some useful overloads.
|
|
||||||
///
|
|
||||||
/// \since 3.0.0
|
|
||||||
template <typename T>
|
|
||||||
using transform = detail::types::transform<T>;
|
|
||||||
|
|
||||||
/// Wraps the given callable object into a transform class.
|
|
||||||
///
|
|
||||||
/// \since 3.0.0
|
|
||||||
template <typename T>
|
|
||||||
auto make_transform(T&& callable) {
|
|
||||||
return transform<std::decay_t<T>>(std::forward<T>(callable));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The namespace transforms declares callable objects that transform
|
/// The namespace transforms declares callable objects that transform
|
||||||
/// any continuable_base to an object or to a continuable_base itself.
|
/// any continuable_base to an object or to a continuable_base itself.
|
||||||
///
|
///
|
||||||
/// Transforms can be applied to continuables through using
|
/// Transforms can be applied to continuables through using
|
||||||
/// the cti::continuable_base::apply method accordingly.
|
/// the cti::continuable_base::apply method accordingly.
|
||||||
namespace transforms {
|
namespace transforms {}
|
||||||
/// Returns a transform that if applied to a continuable,
|
|
||||||
/// it will start the continuation chain and returns the asynchronous
|
|
||||||
/// result as `std::future<...>`.
|
|
||||||
///
|
|
||||||
/// \returns Returns a `std::future<...>` which becomes ready as soon
|
|
||||||
/// as the the continuation chain has finished.
|
|
||||||
/// The signature of the future depends on the result type:
|
|
||||||
/// | Continuation type | Return type |
|
|
||||||
/// | : ------------------------------- | : -------------------------------- |
|
|
||||||
/// | `continuable_base with <>` | `std::future<void>` |
|
|
||||||
/// | `continuable_base with <Arg>` | `std::future<Arg>` |
|
|
||||||
/// | `continuable_base with <Args...>` | `std::future<std::tuple<Args...>>` |
|
|
||||||
///
|
|
||||||
/// \attention If exceptions are used, exceptions that are thrown, are forwarded
|
|
||||||
/// to the returned future. If there are no exceptions supported,
|
|
||||||
/// you shall not pass any errors to the end of the asynchronous
|
|
||||||
/// call chain!
|
|
||||||
/// Otherwise this will yield a trap that causes application exit.
|
|
||||||
///
|
|
||||||
/// \since 2.0.0
|
|
||||||
inline auto futurize() {
|
|
||||||
return make_transform([](auto&& continuable) {
|
|
||||||
using detail::transforms::as_future;
|
|
||||||
return as_future(std::forward<decltype(continuable)>(continuable));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a transform that if applied to a continuable, it will ignores all
|
|
||||||
/// error which ocured until the point the transform was applied.
|
|
||||||
///
|
|
||||||
/// \returns Returns a continuable with the same signature as applied to.
|
|
||||||
///
|
|
||||||
/// \attention This can be used to create a continuable which doesn't resolve
|
|
||||||
/// the continuation on errors.
|
|
||||||
///
|
|
||||||
/// \since 2.0.0
|
|
||||||
inline auto flatten() {
|
|
||||||
return make_transform([](auto&& continuable) {
|
|
||||||
return std::forward<decltype(continuable)>(continuable).fail([](auto&&) {});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/// \}
|
|
||||||
} // namespace transforms
|
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
#endif // CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
#endif // CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||||
|
|||||||
@ -53,7 +53,6 @@ namespace cti {}
|
|||||||
#include <continuable/continuable-promise-base.hpp>
|
#include <continuable/continuable-promise-base.hpp>
|
||||||
#include <continuable/continuable-promisify.hpp>
|
#include <continuable/continuable-promisify.hpp>
|
||||||
#include <continuable/continuable-result.hpp>
|
#include <continuable/continuable-result.hpp>
|
||||||
#include <continuable/continuable-transforms.hpp>
|
|
||||||
#include <continuable/continuable-traverse-async.hpp>
|
#include <continuable/continuable-traverse-async.hpp>
|
||||||
#include <continuable/continuable-traverse.hpp>
|
#include <continuable/continuable-traverse.hpp>
|
||||||
#include <continuable/continuable-types.hpp>
|
#include <continuable/continuable-types.hpp>
|
||||||
|
|||||||
@ -66,16 +66,6 @@ using exception_t = std::error_condition;
|
|||||||
/// A tag which is used to execute the continuation inside the current thread
|
/// A tag which is used to execute the continuation inside the current thread
|
||||||
struct this_thread_executor_tag {};
|
struct this_thread_executor_tag {};
|
||||||
|
|
||||||
/// Marks a given callable object as transformation
|
|
||||||
template <typename T>
|
|
||||||
class transform : T {
|
|
||||||
public:
|
|
||||||
explicit transform(T callable) : T(std::move(callable)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
using T::operator();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Marks a given callable object as transformation
|
/// Marks a given callable object as transformation
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class plain_tag {
|
class plain_tag {
|
||||||
|
|||||||
@ -28,8 +28,8 @@
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef CONTINUABLE_DETAIL_TRANSFORMS_HPP_INCLUDED
|
#ifndef CONTINUABLE_DETAIL_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||||
#define CONTINUABLE_DETAIL_TRANSFORMS_HPP_INCLUDED
|
#define CONTINUABLE_DETAIL_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <continuable/continuable-primitives.hpp>
|
#include <continuable/continuable-primitives.hpp>
|
||||||
@ -115,7 +115,7 @@ public:
|
|||||||
|
|
||||||
/// Transforms the continuation to a future
|
/// Transforms the continuation to a future
|
||||||
template <typename Data, typename Annotation>
|
template <typename Data, typename Annotation>
|
||||||
auto as_future(continuable_base<Data, Annotation>&& continuable) {
|
auto to_future(continuable_base<Data, Annotation>&& continuable) {
|
||||||
// Create the promise which is able to supply the current arguments
|
// Create the promise which is able to supply the current arguments
|
||||||
constexpr auto const hint =
|
constexpr auto const hint =
|
||||||
base::annotation_of(identify<decltype(continuable)>{});
|
base::annotation_of(identify<decltype(continuable)>{});
|
||||||
@ -135,4 +135,4 @@ auto as_future(continuable_base<Data, Annotation>&& continuable) {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
#endif // CONTINUABLE_DETAIL_TRANSFORMS_HPP_INCLUDED
|
#endif // CONTINUABLE_DETAIL_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||||
134
include/continuable/detail/transforms/wait.hpp
Normal file
134
include/continuable/detail/transforms/wait.hpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
|
#define CONTINUABLE_DETAIL_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <chrono>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <continuable/continuable-primitives.hpp>
|
||||||
|
#include <continuable/detail/core/annotation.hpp>
|
||||||
|
#include <continuable/detail/core/base.hpp>
|
||||||
|
#include <continuable/detail/core/types.hpp>
|
||||||
|
#include <continuable/detail/features.hpp>
|
||||||
|
#include <continuable/detail/utility/util.hpp>
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
# include <exception>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
namespace detail {
|
||||||
|
namespace transforms {
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <typename... Args>
|
||||||
|
struct sync_trait {
|
||||||
|
/// The promise type used to create the future
|
||||||
|
using promise_t = std::tuple<Args...>;
|
||||||
|
/// Boxes the argument pack into a tuple
|
||||||
|
static void resolve(promise_t& promise, Args... args) {
|
||||||
|
promise.set_value(std::make_tuple(std::move(args)...));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct sync_trait<> {
|
||||||
|
/// The promise type used to create the future
|
||||||
|
using promise_t = result<Args...>;
|
||||||
|
/// Boxes the argument pack into void
|
||||||
|
static void resolve(promise_t& promise) {
|
||||||
|
promise.set_value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename First>
|
||||||
|
struct sync_trait<First> {
|
||||||
|
/// The promise type used to create the future
|
||||||
|
using promise_t = std::promise<First>;
|
||||||
|
/// Boxes the argument pack into nothing
|
||||||
|
static void resolve(promise_t& promise, First first) {
|
||||||
|
promise.set_value(std::move(first));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename Hint>
|
||||||
|
struct sync_trait;
|
||||||
|
template <typename... Args>
|
||||||
|
struct sync_trait<identity<Args...>> {
|
||||||
|
using result_t = result<Args...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Transforms the continuation to sync execution
|
||||||
|
template <typename Data, typename Annotation>
|
||||||
|
auto wait(continuable_base<Data, Annotation>&& continuable) {
|
||||||
|
constexpr auto hint = base::annotation_of(identify<decltype(continuable)>{});
|
||||||
|
using result_t = typename sync_trait<std::decay_t<decltype(hint)>>::result_t;
|
||||||
|
(void)hint;
|
||||||
|
|
||||||
|
std::recursive_mutex mutex;
|
||||||
|
std::condition_variable_any cv;
|
||||||
|
std::atomic_bool ready{false};
|
||||||
|
result_t sync_result;
|
||||||
|
|
||||||
|
std::move(continuable)
|
||||||
|
.next([&](auto&&... args) {
|
||||||
|
sync_result = result_t::from(std::forward<decltype(args)>(args)...);
|
||||||
|
|
||||||
|
ready.store(true, std::memory_order_release);
|
||||||
|
cv.notify_all();
|
||||||
|
})
|
||||||
|
.done();
|
||||||
|
|
||||||
|
if (!ready.load(std::memory_order_acquire)) {
|
||||||
|
std::unique_lock<std::recursive_mutex> lock(mutex);
|
||||||
|
cv.wait(lock, [&] {
|
||||||
|
return ready.load(std::memory_order_acquire);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
if (sync_result.is_value()) {
|
||||||
|
return std::move(sync_result).get_value();
|
||||||
|
} else {
|
||||||
|
assert(sync_result.is_exception());
|
||||||
|
std::rethrow_exception(sync_result.get_exception());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return sync_result;
|
||||||
|
#endif // CONTINUABLE_HAS_EXCEPTIONS
|
||||||
|
}
|
||||||
|
} // namespace transforms
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_DETAIL_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
72
include/continuable/transforms/future.hpp
Normal file
72
include/continuable/transforms/future.hpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||||
|
#define CONTINUABLE_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <continuable/detail/transforms/future.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
/// \ingroup Transforms
|
||||||
|
/// \{
|
||||||
|
|
||||||
|
namespace transforms {
|
||||||
|
/// Returns a transform that if applied to a continuable,
|
||||||
|
/// it will start the continuation chain and returns the asynchronous
|
||||||
|
/// result as `std::future<...>`.
|
||||||
|
///
|
||||||
|
/// \returns Returns a `std::future<...>` which becomes ready as soon
|
||||||
|
/// as the the continuation chain has finished.
|
||||||
|
/// The signature of the future depends on the result type:
|
||||||
|
/// | Continuation type | Return type |
|
||||||
|
/// | : ------------------------------- | : -------------------------------- |
|
||||||
|
/// | `continuable_base with <>` | `std::future<void>` |
|
||||||
|
/// | `continuable_base with <Arg>` | `std::future<Arg>` |
|
||||||
|
/// | `continuable_base with <Args...>` | `std::future<std::tuple<Args...>>` |
|
||||||
|
///
|
||||||
|
/// \attention If exceptions are used, exceptions that are thrown, are forwarded
|
||||||
|
/// to the returned future. If there are no exceptions supported,
|
||||||
|
/// you shall not pass any errors to the end of the asynchronous
|
||||||
|
/// call chain!
|
||||||
|
/// Otherwise this will yield a trap that causes application exit.
|
||||||
|
///
|
||||||
|
/// \since 2.0.0
|
||||||
|
inline auto to_future() {
|
||||||
|
return [](auto&& continuable) {
|
||||||
|
return detail::transforms::to_future(
|
||||||
|
std::forward<decltype(continuable)>(continuable));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace transforms
|
||||||
|
/// \}
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_OPERATIONS_SPLIT_HPP_INCLUDED
|
||||||
68
include/continuable/transforms/wait.hpp
Normal file
68
include/continuable/transforms/wait.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
|
#define CONTINUABLE_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <continuable/detail/transforms/wait.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
/// \ingroup Transforms
|
||||||
|
/// \{
|
||||||
|
|
||||||
|
namespace transforms {
|
||||||
|
/// Returns a transform that if applied to a continuable,
|
||||||
|
/// it will start the continuation chain and returns the result synchronously.
|
||||||
|
/// The current thread is blocked until the continuation chain is finished.
|
||||||
|
///
|
||||||
|
/// \returns Returns a value that is available immediately.
|
||||||
|
/// The signature of the future depends on the result type:
|
||||||
|
/// | Continuation type | Return type |
|
||||||
|
/// | : ------------------------------- | : -------------------------------- |
|
||||||
|
/// | `continuable_base with <>` | `void` |
|
||||||
|
/// | `continuable_base with <Arg>` | `Arg` |
|
||||||
|
/// | `continuable_base with <Args...>` | `std::tuple<Args...>` |
|
||||||
|
///
|
||||||
|
/// \attention If exceptions are used, exceptions that are thrown, are rethrown
|
||||||
|
/// synchronously.
|
||||||
|
///
|
||||||
|
/// \since 4.0.0
|
||||||
|
inline auto wait() {
|
||||||
|
return [](auto&& continuable) {
|
||||||
|
return detail::transforms::wait(
|
||||||
|
std::forward<decltype(continuable)>(continuable));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace transforms
|
||||||
|
/// \}
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_TRANSFORMS_WAIT_HPP_INCLUDED
|
||||||
@ -20,9 +20,37 @@
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <continuable/continuable-transforms.hpp>
|
||||||
#include <continuable/continuable.hpp>
|
#include <continuable/continuable.hpp>
|
||||||
|
#include <continuable/external/asio.hpp>
|
||||||
|
#include <asio.hpp>
|
||||||
|
|
||||||
using namespace cti;
|
using namespace cti;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
|
asio::io_context ioc(1);
|
||||||
|
asio::steady_timer t(ioc);
|
||||||
|
auto work = std::make_shared<asio::io_context::work>(ioc);
|
||||||
|
|
||||||
|
t.expires_after(1s);
|
||||||
|
|
||||||
|
std::thread th([&] {
|
||||||
|
ioc.run();
|
||||||
|
puts("io_context finished");
|
||||||
|
});
|
||||||
|
|
||||||
|
int res = t.async_wait(cti::use_continuable)
|
||||||
|
.then([] {
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
.apply(transforms::wait());
|
||||||
|
|
||||||
|
puts("async_wait finished");
|
||||||
|
work.reset();
|
||||||
|
|
||||||
|
th.join();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,22 +21,27 @@
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <continuable/continuable-transforms.hpp>
|
#include <continuable/continuable-transforms.hpp>
|
||||||
|
|
||||||
#include <test-continuable.hpp>
|
#include <test-continuable.hpp>
|
||||||
|
|
||||||
using namespace cti;
|
using namespace cti;
|
||||||
using namespace cti::detail;
|
using namespace cti::detail;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool is_ready(T& future) {
|
bool is_ready(T& future) {
|
||||||
// Check that the future is ready
|
// Check that the future is ready
|
||||||
return future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
|
return future.wait_for(0s) == std::future_status::ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
|
TYPED_TEST(single_dimension_tests, to_future_test) {
|
||||||
{
|
{
|
||||||
auto future = this->supply().apply(cti::transforms::futurize());
|
auto future = this->supply().apply(cti::transforms::to_future());
|
||||||
ASSERT_TRUE(is_ready(future));
|
ASSERT_TRUE(is_ready(future));
|
||||||
future.get();
|
future.get();
|
||||||
}
|
}
|
||||||
@ -47,7 +52,7 @@ TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
|
|||||||
// ...
|
// ...
|
||||||
return 0xFD;
|
return 0xFD;
|
||||||
})
|
})
|
||||||
.apply(cti::transforms::futurize());
|
.apply(cti::transforms::to_future());
|
||||||
|
|
||||||
ASSERT_TRUE(is_ready(future));
|
ASSERT_TRUE(is_ready(future));
|
||||||
EXPECT_EQ(future.get(), 0xFD);
|
EXPECT_EQ(future.get(), 0xFD);
|
||||||
@ -56,19 +61,20 @@ TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
|
|||||||
{
|
{
|
||||||
auto canary = std::make_tuple(0xFD, 0xF5);
|
auto canary = std::make_tuple(0xFD, 0xF5);
|
||||||
|
|
||||||
auto future = this->supply().then([&] {
|
auto future = this->supply()
|
||||||
// ...
|
.then([&] {
|
||||||
return canary;
|
// ...
|
||||||
}) | cti::transforms::futurize();
|
return canary;
|
||||||
|
})
|
||||||
|
.apply(cti::transforms::to_future());
|
||||||
|
|
||||||
ASSERT_TRUE(is_ready(future));
|
ASSERT_TRUE(is_ready(future));
|
||||||
EXPECT_EQ(future.get(), canary);
|
EXPECT_EQ(future.get(), canary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(single_dimension_tests, are_flattable) {
|
TYPED_TEST(single_dimension_tests, to_wait_test) {
|
||||||
auto continuation = this->supply_exception(supply_test_exception())
|
{
|
||||||
.apply(cti::transforms::flatten());
|
this->supply().apply(cti::transforms::wait()); //
|
||||||
|
}
|
||||||
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user