diff --git a/include/continuable/detail/traverse-async.hpp b/include/continuable/detail/traverse-async.hpp
index 08fb1f9..6f8998d 100644
--- a/include/continuable/detail/traverse-async.hpp
+++ b/include/continuable/detail/traverse-async.hpp
@@ -105,11 +105,56 @@ auto make_resume_traversal_callable(Frame&& frame, State&& state)
std::forward(frame), std::forward(state));
}
-/// Stores the visitor and the arguments to traverse
+template
+struct has_head : std::false_type {};
+template
+struct has_head().head())>>
+ : std::true_type {};
+
template
-class async_traversal_frame : public Visitor {
+class async_traversal_frame_data : public Visitor {
+
std::tuple args_;
+public:
+ explicit async_traversal_frame_data(Visitor visitor, Args... args)
+ : Visitor(std::move(visitor)),
+ args_(std::make_tuple(std::move(args)...)) {
+ }
+ template
+ explicit async_traversal_frame_data(async_traverse_in_place_tag,
+ MapperArg&& mapper_arg, Args... args)
+ : Visitor(std::forward(mapper_arg)),
+ args_(std::make_tuple(std::move(args)...)) {
+ }
+
+ /// Returns the arguments of the frame
+ std::tuple& head() noexcept {
+ return args_;
+ }
+};
+template
+class async_traversal_frame_no_data : public Visitor {
+public:
+ explicit async_traversal_frame_no_data(Visitor visitor)
+ : Visitor(std::move(visitor)) {
+ }
+ template
+ explicit async_traversal_frame_no_data(async_traverse_in_place_tag,
+ MapperArg&& mapper_arg)
+ : Visitor(std::forward(mapper_arg)) {
+ }
+};
+
+template
+using data_layout_t =
+ std::conditional_t::value,
+ async_traversal_frame_no_data,
+ async_traversal_frame_data>;
+
+/// Stores the visitor and the arguments to traverse
+template
+class async_traversal_frame : public data_layout_t {
#ifndef _NDEBUG
std::atomic finished_;
#endif // _NDEBUG
@@ -123,8 +168,9 @@ class async_traversal_frame : public Visitor {
}
public:
- explicit async_traversal_frame(Visitor visitor, Args... args)
- : Visitor(std::move(visitor)), args_(std::make_tuple(std::move(args)...))
+ template
+ explicit async_traversal_frame(T&&... args)
+ : data_layout_t(std::forward(args)...)
#ifndef _NDEBUG
,
finished_(false)
@@ -135,18 +181,6 @@ public:
/// We require a virtual base
virtual ~async_traversal_frame() override = default;
- template
- explicit async_traversal_frame(async_traverse_in_place_tag,
- MapperArg&& mapper_arg, Args... args)
- : Visitor(std::forward(mapper_arg)),
- args_(std::make_tuple(std::move(args)...)), finished_(false) {
- }
-
- /// Returns the arguments of the frame
- std::tuple& head() noexcept {
- return args_;
- }
-
/// Calls the visitor with the given element
template
auto traverse(T&& value) -> decltype(visitor()(async_traverse_visit_tag{},
@@ -184,7 +218,7 @@ public:
}
#endif // _NDEBUG
- visitor()(async_traverse_complete_tag{}, std::move(args_));
+ visitor()(async_traverse_complete_tag{}, std::move(this->head()));
}
};