mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Start to port the async traversal
This commit is contained in:
parent
73927516c6
commit
16dd2b0cb9
@ -41,6 +41,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <continuable/detail/container-category.hpp>
|
#include <continuable/detail/container-category.hpp>
|
||||||
|
#include <continuable/detail/traits.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -66,13 +67,16 @@ struct async_traverse_in_place_tag {};
|
|||||||
template <std::size_t Offset, typename Pack>
|
template <std::size_t Offset, typename Pack>
|
||||||
struct relocate_index_pack;
|
struct relocate_index_pack;
|
||||||
template <std::size_t Offset, std::size_t... Sequence>
|
template <std::size_t Offset, std::size_t... Sequence>
|
||||||
struct relocate_index_pack<Offset, pack_c<std::size_t, Sequence...>>
|
struct relocate_index_pack<Offset,
|
||||||
: std::common_type<pack_c<std::size_t, (Sequence + Offset)...>> {};
|
std::integer_sequence<std::size_t, Sequence...>>
|
||||||
|
: std::common_type<
|
||||||
|
std::integer_sequence<std::size_t, (Sequence + Offset)...>> {};
|
||||||
|
|
||||||
/// Creates a sequence from begin to end explicitly
|
/// Creates a sequence from begin to end explicitly
|
||||||
template <std::size_t Begin, std::size_t End>
|
template <std::size_t Begin, std::size_t End>
|
||||||
using explicit_range_sequence_of_t = typename relocate_index_pack<
|
using explicit_range_sequence_of_t =
|
||||||
Begin, typename make_index_pack<End - Begin>::type>::type;
|
typename relocate_index_pack<Begin,
|
||||||
|
std::make_index_sequence<End - Begin>>::type;
|
||||||
|
|
||||||
/// Continues the traversal when the object is called
|
/// Continues the traversal when the object is called
|
||||||
template <typename Frame, typename State>
|
template <typename Frame, typename State>
|
||||||
@ -104,7 +108,7 @@ auto make_resume_traversal_callable(Frame&& frame, State&& state)
|
|||||||
/// Stores the visitor and the arguments to traverse
|
/// Stores the visitor and the arguments to traverse
|
||||||
template <typename Visitor, typename... Args>
|
template <typename Visitor, typename... Args>
|
||||||
class async_traversal_frame : public Visitor {
|
class async_traversal_frame : public Visitor {
|
||||||
tuple<Args...> args_;
|
std::tuple<Args...> args_;
|
||||||
|
|
||||||
#ifndef _NDEBUG
|
#ifndef _NDEBUG
|
||||||
std::atomic<bool> finished_;
|
std::atomic<bool> finished_;
|
||||||
@ -120,7 +124,7 @@ class async_traversal_frame : public Visitor {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit async_traversal_frame(Visitor visitor, Args... args)
|
explicit async_traversal_frame(Visitor visitor, Args... args)
|
||||||
: Visitor(std::move(visitor)), args_(util::make_tuple(std::move(args)...))
|
: Visitor(std::move(visitor)), args_(std::make_tuple(std::move(args)...))
|
||||||
#ifndef _NDEBUG
|
#ifndef _NDEBUG
|
||||||
,
|
,
|
||||||
finished_(false)
|
finished_(false)
|
||||||
@ -137,21 +141,19 @@ public:
|
|||||||
explicit async_traversal_frame(async_traverse_in_place_tag<Visitor>,
|
explicit async_traversal_frame(async_traverse_in_place_tag<Visitor>,
|
||||||
MapperArg&& mapper_arg, Args... args)
|
MapperArg&& mapper_arg, Args... args)
|
||||||
: Visitor(std::forward<MapperArg>(mapper_arg)),
|
: Visitor(std::forward<MapperArg>(mapper_arg)),
|
||||||
args_(util::make_tuple(std::move(args)...)), finished_(false) {
|
args_(std::make_tuple(std::move(args)...)), finished_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the arguments of the frame
|
/// Returns the arguments of the frame
|
||||||
tuple<Args...>& head() noexcept {
|
std::tuple<Args...>& head() noexcept {
|
||||||
return args_;
|
return args_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the visitor with the given element
|
/// Calls the visitor with the given element
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto traverse(T&& value) -> decltype(util::invoke(std::declval<Visitor&>(),
|
auto traverse(T&& value) -> decltype(visitor()(async_traverse_visit_tag{},
|
||||||
async_traverse_visit_tag{},
|
|
||||||
std::forward<T>(value))) {
|
std::forward<T>(value))) {
|
||||||
return util::invoke(visitor(), async_traverse_visit_tag{},
|
return visitor()(async_traverse_visit_tag{}, std::forward<T>(value));
|
||||||
std::forward<T>(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the visitor with the given element and a continuation
|
/// Calls the visitor with the given element and a continuation
|
||||||
@ -169,7 +171,7 @@ public:
|
|||||||
|
|
||||||
// Invoke the visitor with the current value and the
|
// Invoke the visitor with the current value and the
|
||||||
// callable object to resume the control flow.
|
// callable object to resume the control flow.
|
||||||
util::invoke(visitor(), async_traverse_detach_tag{}, std::forward<T>(value),
|
visitor()(async_traverse_detach_tag{}, std::forward<T>(value),
|
||||||
std::move(resumable));
|
std::move(resumable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +211,8 @@ struct static_async_range {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto operator*() const noexcept
|
constexpr auto operator*() const noexcept
|
||||||
-> decltype(util::get<Begin>(*target_)) {
|
-> decltype(std::get<Begin>(*target_)) {
|
||||||
return util::get<Begin>(*target_);
|
return std::get<Begin>(*target_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t Position>
|
template <std::size_t Position>
|
||||||
@ -340,7 +342,7 @@ public:
|
|||||||
/// Async traverse a single element, and do nothing.
|
/// Async traverse a single element, and do nothing.
|
||||||
/// This function is matched last.
|
/// This function is matched last.
|
||||||
template <typename Matcher, typename Current>
|
template <typename Matcher, typename Current>
|
||||||
void async_traverse_one_impl(Matcher, Current&& current) {
|
void async_traverse_one_impl(Matcher, Current&& /*current*/) {
|
||||||
// Do nothing if the visitor doesn't accept the type
|
// Do nothing if the visitor doesn't accept the type
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,13 +354,12 @@ public:
|
|||||||
Current&& current)
|
Current&& current)
|
||||||
/// SFINAE this out if the visitor doesn't accept
|
/// SFINAE this out if the visitor doesn't accept
|
||||||
/// the given element
|
/// the given element
|
||||||
-> typename always_void<
|
-> traits::void_t<decltype(std::declval<Frame>()->traverse(*current))> {
|
||||||
decltype(std::declval<Frame>()->traverse(*current))>::type {
|
|
||||||
if (!frame_->traverse(*current)) {
|
if (!frame_->traverse(*current)) {
|
||||||
// Store the current call hierarchy into a tuple for
|
// Store the current call hierarchy into a tuple for
|
||||||
// later re-entrance.
|
// later re-entrance.
|
||||||
auto hierarchy =
|
auto hierarchy =
|
||||||
std::tuple_cat(util::make_tuple(current.next()), hierarchy_);
|
std::tuple_cat(std::make_tuple(current.next()), hierarchy_);
|
||||||
|
|
||||||
// First detach the current execution context
|
// First detach the current execution context
|
||||||
detach();
|
detach();
|
||||||
@ -406,8 +407,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t... Sequence, typename Current>
|
template <std::size_t... Sequence, typename Current>
|
||||||
void async_traverse_static_async_range(pack_c<std::size_t, Sequence...>,
|
void async_traverse_static_async_range(
|
||||||
Current&& current) {
|
std::integer_sequence<std::size_t, Sequence...>, Current&& current) {
|
||||||
int dummy[] = {0, ((void)async_traverse_one_checked(
|
int dummy[] = {0, ((void)async_traverse_one_checked(
|
||||||
current.template relocate<Sequence>()),
|
current.template relocate<Sequence>()),
|
||||||
0)...};
|
0)...};
|
||||||
@ -484,7 +485,7 @@ struct resume_state_callable {
|
|||||||
// Don't forward the arguments here, since we still need
|
// Don't forward the arguments here, since we still need
|
||||||
// the objects in a valid state later.
|
// the objects in a valid state later.
|
||||||
traversal_point_of_t<Frame, Parent, Hierarchy...> point(
|
traversal_point_of_t<Frame, Parent, Hierarchy...> point(
|
||||||
frame, util::make_tuple(parent, hierarchy...), detached);
|
frame, std::make_tuple(parent, hierarchy...), detached);
|
||||||
|
|
||||||
point.async_traverse(std::forward<Current>(current));
|
point.async_traverse(std::forward<Current>(current));
|
||||||
|
|
||||||
@ -505,7 +506,7 @@ struct resume_state_callable {
|
|||||||
template <typename Frame, typename State>
|
template <typename Frame, typename State>
|
||||||
void resume_traversal_callable<Frame, State>::operator()() {
|
void resume_traversal_callable<Frame, State>::operator()() {
|
||||||
auto hierarchy = std::tuple_cat(std::make_tuple(frame_), state_);
|
auto hierarchy = std::tuple_cat(std::make_tuple(frame_), state_);
|
||||||
util::invoke_fused(resume_state_callable{}, std::move(hierarchy));
|
traits::unpack(std::move(hierarchy), resume_state_callable{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gives access to types related to the traversal frame
|
/// Gives access to types related to the traversal frame
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user