mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
For loops provide loop_result loop_break and loop_continue for better readability
This commit is contained in:
parent
76ecc3d26d
commit
20cd0191fc
@ -31,6 +31,7 @@
|
||||
#ifndef CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED
|
||||
#define CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <continuable/detail/features.hpp>
|
||||
#include <continuable/detail/utility/identity.hpp>
|
||||
@ -84,6 +85,10 @@ class plain_tag {
|
||||
T value_;
|
||||
|
||||
public:
|
||||
template <typename O, std::enable_if_t<std::is_constructible<
|
||||
T, std::decay_t<O>>::value>* = nullptr>
|
||||
/* implicit */ plain_tag(O&& value) : value_(std::forward<O>(value)) {
|
||||
}
|
||||
explicit plain_tag(T value) : value_(std::move(value)) {
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#define CONTINUABLE_OPERATIONS_LOOP_HPP_INCLUDED
|
||||
|
||||
#include <utility>
|
||||
#include <continuable/continuable-primitives.hpp>
|
||||
#include <continuable/continuable-result.hpp>
|
||||
#include <continuable/detail/operations/loop.hpp>
|
||||
|
||||
@ -42,11 +43,30 @@ namespace cti {
|
||||
/// Can be used to create an asynchronous loop.
|
||||
///
|
||||
/// The callable will be called repeatedly until it returns a
|
||||
/// cti::continuable_base which then resolves to present cti::result.
|
||||
/// cti::continuable_base which then resolves to a present cti::result.
|
||||
///
|
||||
/// For better readability cti::loop_result, cti::loop_break and
|
||||
/// cti::loop_continue are provided which can be used as following:
|
||||
/// ```cpp
|
||||
/// auto while_answer_not_yes() {
|
||||
/// return loop([] {
|
||||
/// return ask_something().then([](std::string answer) -> loop_result<> {
|
||||
/// if (answer == "yes") {
|
||||
/// return loop_break();
|
||||
/// } else {
|
||||
/// return loop_continue();
|
||||
/// }
|
||||
/// });
|
||||
/// });
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// \param callable The callable type which must return a cti::continuable_base
|
||||
/// which then resolves to a cti::result of arbitrary values.
|
||||
///
|
||||
/// \param args The arguments that are passed to the callable upon
|
||||
/// each invocation.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
///
|
||||
template <typename Callable, typename... Args>
|
||||
@ -55,6 +75,34 @@ auto loop(Callable&& callable, Args&&... args) {
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Can be used to indicate a specific result inside an asynchronous loop.
|
||||
///
|
||||
/// See cti::loop for details.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
template <typename... T>
|
||||
using loop_result = plain_t<result<T...>>;
|
||||
|
||||
/// Can be used to create a loop_result which causes the loop to be
|
||||
/// cancelled and resolved with the given arguments.
|
||||
///
|
||||
/// See cti::loop for details.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
template <typename... T>
|
||||
auto loop_break(T&&... args) {
|
||||
return make_plain(make_result(std::forward<T>(args)...));
|
||||
}
|
||||
|
||||
/// Can be used to create a loop_result which causes the loop to be repeated.
|
||||
///
|
||||
/// See cti::loop for details.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
inline auto loop_continue() noexcept {
|
||||
return empty_result{};
|
||||
}
|
||||
|
||||
///
|
||||
/// \since 4.0.0
|
||||
///
|
||||
@ -64,6 +112,7 @@ auto range_loop(Callable&& callable, Iterator begin, Iterator end) {
|
||||
detail::operations::make_range_looper(std::forward<Callable>(callable),
|
||||
begin, end));
|
||||
}
|
||||
|
||||
/// \}
|
||||
} // namespace cti
|
||||
|
||||
|
||||
@ -52,6 +52,22 @@ TYPED_TEST(single_dimension_tests, operations_loop_completion) {
|
||||
CANARY, 2, CANARY);
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, operations_loop_until) {
|
||||
int i = 0;
|
||||
|
||||
ASSERT_ASYNC_COMPLETION(loop([&i] {
|
||||
return make_ready_continuable(++i).then([](int i) -> loop_result<> {
|
||||
if (i == 3) {
|
||||
return loop_break();
|
||||
} else {
|
||||
return loop_continue();
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
ASSERT_EQ(i, 3);
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, operations_loop_looping) {
|
||||
int i = 0;
|
||||
|
||||
@ -61,7 +77,7 @@ TYPED_TEST(single_dimension_tests, operations_loop_looping) {
|
||||
++i;
|
||||
return make_ready_continuable();
|
||||
},
|
||||
0, 10));
|
||||
0, 3));
|
||||
|
||||
ASSERT_EQ(i, 10);
|
||||
ASSERT_EQ(i, 3);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user