mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56: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...>{});
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// continuable is passed into it.
|
||||
///
|
||||
/// \since 2.0.0
|
||||
/// \since 4.0.0
|
||||
template <typename T>
|
||||
auto apply(T&& transform) && {
|
||||
return std::forward<T>(transform)(std::move(*this).finish());
|
||||
@ -462,22 +463,6 @@ public:
|
||||
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
|
||||
/// callback with the result of both continuable_base objects.
|
||||
///
|
||||
|
||||
@ -31,8 +31,8 @@
|
||||
#ifndef CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||
#define CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||
|
||||
#include <continuable/detail/core/types.hpp>
|
||||
#include <continuable/detail/other/transforms.hpp>
|
||||
#include <continuable/transforms/wait.hpp>
|
||||
#include <continuable/transforms/future.hpp>
|
||||
|
||||
namespace cti {
|
||||
/// \defgroup Transforms Transforms
|
||||
@ -41,70 +41,12 @@ namespace cti {
|
||||
/// 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
|
||||
/// any continuable_base to an object or to a continuable_base itself.
|
||||
///
|
||||
/// Transforms can be applied to continuables through using
|
||||
/// the cti::continuable_base::apply method accordingly.
|
||||
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 transforms {}
|
||||
} // namespace cti
|
||||
|
||||
#endif // CONTINUABLE_TRANSFORMS_HPP_INCLUDED
|
||||
|
||||
@ -53,7 +53,6 @@ namespace cti {}
|
||||
#include <continuable/continuable-promise-base.hpp>
|
||||
#include <continuable/continuable-promisify.hpp>
|
||||
#include <continuable/continuable-result.hpp>
|
||||
#include <continuable/continuable-transforms.hpp>
|
||||
#include <continuable/continuable-traverse-async.hpp>
|
||||
#include <continuable/continuable-traverse.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
|
||||
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
|
||||
template <typename T>
|
||||
class plain_tag {
|
||||
|
||||
@ -28,8 +28,8 @@
|
||||
SOFTWARE.
|
||||
**/
|
||||
|
||||
#ifndef CONTINUABLE_DETAIL_TRANSFORMS_HPP_INCLUDED
|
||||
#define CONTINUABLE_DETAIL_TRANSFORMS_HPP_INCLUDED
|
||||
#ifndef CONTINUABLE_DETAIL_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||
#define CONTINUABLE_DETAIL_TRANSFORMS_FUTURE_HPP_INCLUDED
|
||||
|
||||
#include <future>
|
||||
#include <continuable/continuable-primitives.hpp>
|
||||
@ -115,7 +115,7 @@ public:
|
||||
|
||||
/// Transforms the continuation to a future
|
||||
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
|
||||
constexpr auto const hint =
|
||||
base::annotation_of(identify<decltype(continuable)>{});
|
||||
@ -135,4 +135,4 @@ auto as_future(continuable_base<Data, Annotation>&& continuable) {
|
||||
} // namespace detail
|
||||
} // 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.
|
||||
**/
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <continuable/continuable-transforms.hpp>
|
||||
#include <continuable/continuable.hpp>
|
||||
#include <continuable/external/asio.hpp>
|
||||
#include <asio.hpp>
|
||||
|
||||
using namespace cti;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
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.
|
||||
**/
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
|
||||
#include <continuable/continuable-transforms.hpp>
|
||||
|
||||
#include <test-continuable.hpp>
|
||||
|
||||
using namespace cti;
|
||||
using namespace cti::detail;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
template <typename T>
|
||||
bool is_ready(T& future) {
|
||||
// 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));
|
||||
future.get();
|
||||
}
|
||||
@ -47,7 +52,7 @@ TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
|
||||
// ...
|
||||
return 0xFD;
|
||||
})
|
||||
.apply(cti::transforms::futurize());
|
||||
.apply(cti::transforms::to_future());
|
||||
|
||||
ASSERT_TRUE(is_ready(future));
|
||||
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 future = this->supply().then([&] {
|
||||
// ...
|
||||
return canary;
|
||||
}) | cti::transforms::futurize();
|
||||
auto future = this->supply()
|
||||
.then([&] {
|
||||
// ...
|
||||
return canary;
|
||||
})
|
||||
.apply(cti::transforms::to_future());
|
||||
|
||||
ASSERT_TRUE(is_ready(future));
|
||||
EXPECT_EQ(future.get(), canary);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_flattable) {
|
||||
auto continuation = this->supply_exception(supply_test_exception())
|
||||
.apply(cti::transforms::flatten());
|
||||
|
||||
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
|
||||
TYPED_TEST(single_dimension_tests, to_wait_test) {
|
||||
{
|
||||
this->supply().apply(cti::transforms::wait()); //
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user