21 #include <type_traits>
45 : std::runtime_error(message)
102 struct root_type : std::integral_constant<transwarp::task_type, transwarp::task_type::root> {};
106 struct accept_type : std::integral_constant<transwarp::task_type, transwarp::task_type::accept> {};
110 struct accept_any_type : std::integral_constant<transwarp::task_type, transwarp::task_type::accept_any> {};
114 struct consume_type : std::integral_constant<transwarp::task_type, transwarp::task_type::consume> {};
118 struct consume_any_type : std::integral_constant<transwarp::task_type, transwarp::task_type::consume_any> {};
122 struct wait_type : std::integral_constant<transwarp::task_type, transwarp::task_type::wait> {};
126 struct wait_any_type : std::integral_constant<transwarp::task_type, transwarp::task_type::wait_any> {};
152 node& operator=(
const node&) =
delete;
172 const std::shared_ptr<std::string>&
get_name() const noexcept {
182 const std::vector<std::shared_ptr<node>>&
get_parents() const noexcept {
198 return canceled_.load();
205 std::size_t level_ = 0;
207 std::shared_ptr<std::string> name_;
208 std::shared_ptr<std::string> executor_;
209 std::vector<std::shared_ptr<node>> parents_;
210 std::size_t priority_ = 0;
211 std::shared_ptr<void> custom_data_;
212 std::atomic_bool canceled_{
false};
221 s +=
"<" + *name +
">" + seperator;
224 s +=
" id=" + std::to_string(node.
get_id());
225 s +=
" lev=" + std::to_string(node.
get_level());
228 s += seperator +
"<" + *exec +
">";
239 edge(std::shared_ptr<transwarp::node> parent, std::shared_ptr<transwarp::node> child) noexcept
240 : parent_(std::move(parent)), child_(std::move(child))
245 edge& operator=(
const edge&) =
default;
250 const std::shared_ptr<transwarp::node>&
get_parent() const noexcept {
255 const std::shared_ptr<transwarp::node>&
get_child() const noexcept {
260 std::shared_ptr<transwarp::node> parent_;
261 std::shared_ptr<transwarp::node> child_;
271 inline std::string
to_string(
const std::vector<transwarp::edge>& graph,
const std::string& separator=
"\n") {
272 std::string dot =
"digraph {" + separator;
273 for (
const auto&
edge : graph) {
287 virtual std::string
get_name()
const = 0;
293 virtual void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&
node) = 0;
326 virtual ~
itask() =
default;
328 virtual void set_executor(std::shared_ptr<transwarp::executor>
executor) = 0;
329 virtual void set_executor_all(std::shared_ptr<transwarp::executor> executor) = 0;
330 virtual void remove_executor() = 0;
331 virtual void remove_executor_all() = 0;
332 virtual void set_priority(std::size_t priority) = 0;
333 virtual void set_priority_all(std::size_t priority) = 0;
334 virtual void reset_priority() = 0;
335 virtual void reset_priority_all() = 0;
336 virtual void set_custom_data(std::shared_ptr<void> custom_data) = 0;
337 virtual void set_custom_data_all(std::shared_ptr<void> custom_data) = 0;
338 virtual void remove_custom_data() = 0;
339 virtual void remove_custom_data_all() = 0;
340 virtual const std::shared_ptr<transwarp::node>& get_node()
const noexcept = 0;
341 virtual void add_listener(std::shared_ptr<transwarp::listener>
listener) = 0;
342 virtual void add_listener(
transwarp::event_type event, std::shared_ptr<transwarp::listener> listener) = 0;
343 virtual void remove_listener(
const std::shared_ptr<transwarp::listener>& listener) = 0;
344 virtual void remove_listener(
transwarp::event_type event,
const std::shared_ptr<transwarp::listener>& listener) = 0;
346 virtual void remove_listeners() = 0;
347 virtual void schedule() = 0;
349 virtual void schedule(
bool reset) = 0;
351 virtual void schedule_all() = 0;
353 virtual void schedule_all(
bool reset_all) = 0;
359 virtual void set_exception(std::exception_ptr exception) = 0;
360 virtual bool was_scheduled()
const noexcept = 0;
361 virtual void wait()
const = 0;
362 virtual bool is_ready()
const = 0;
363 virtual bool has_result()
const = 0;
364 virtual void reset() = 0;
365 virtual void reset_all() = 0;
366 virtual void cancel(
bool enabled) noexcept = 0;
367 virtual void cancel_all(
bool enabled) noexcept = 0;
368 virtual std::vector<transwarp::edge> get_graph()
const = 0;
379 virtual void visit_depth(
const std::function<
void(
itask&)>& visitor) = 0;
380 virtual void unvisit() noexcept = 0;
381 virtual void set_node_id(std::size_t
id) noexcept = 0;
388 using type =
typename std::remove_const<typename std::remove_reference<T>::type>::type;
395 using type =
typename std::result_of<decltype(&std::shared_future<T>::get)(std::shared_future<T>)>::type;
400 template<
typename ResultType>
403 using result_type = ResultType;
405 virtual ~
task() =
default;
407 virtual void set_value(
const typename transwarp::decay<result_type>::type& value) = 0;
408 virtual void set_value(
typename transwarp::decay<result_type>::type&& value) = 0;
409 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
410 virtual typename transwarp::result_info<result_type>::type
get()
const = 0;
414 template<
typename ResultType>
417 using result_type = ResultType&;
419 virtual ~
task() =
default;
421 virtual void set_value(
typename transwarp::decay<result_type>::type& value) = 0;
422 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
423 virtual typename transwarp::result_info<result_type>::type
get()
const = 0;
430 using result_type = void;
432 virtual ~
task() =
default;
434 virtual void set_value() = 0;
435 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
436 virtual result_type
get()
const = 0;
451 return transwarp_node_;
457 if (transwarp_node_->is_canceled()) {
466 std::shared_ptr<transwarp::node> transwarp_node_;
481 static void set_level(
transwarp::node& node, std::size_t level) noexcept {
489 static void set_name(
transwarp::node& node, std::shared_ptr<std::string> name) noexcept {
495 node.executor_ = std::move(executor);
497 node.executor_.reset();
501 static void add_parent(
transwarp::node& node, std::shared_ptr<transwarp::node> parent) {
502 node.parents_.push_back(std::move(parent));
505 static void set_priority(
transwarp::node& node, std::size_t priority) noexcept {
506 node.priority_ = priority;
509 static void set_custom_data(
transwarp::node& node, std::shared_ptr<void> custom_data) {
511 node.custom_data_ = std::move(custom_data);
513 node.custom_data_.reset();
517 static void set_canceled(
transwarp::node& node,
bool enabled) noexcept {
518 node.canceled_ = enabled;
531 if (n_threads == 0) {
534 const auto n_target = threads_.size() + n_threads;
535 while (threads_.size() < n_target) {
538 thread = std::thread(&thread_pool::worker,
this);
544 threads_.push_back(std::move(thread));
563 void push(
const std::function<
void()>&
functor) {
565 std::lock_guard<std::mutex> lock(mutex_);
568 cond_var_.notify_one();
577 std::unique_lock<std::mutex> lock(mutex_);
578 cond_var_.wait(lock, [
this]{
579 return done_ || !functors_.empty();
581 if (done_ && functors_.empty()) {
584 functor = functors_.front();
593 std::lock_guard<std::mutex> lock(mutex_);
596 cond_var_.notify_all();
597 for (
auto& thread : threads_) {
604 std::vector<std::thread> threads_;
605 std::queue<std::function<void()>> functors_;
606 std::condition_variable cond_var_;
611 template<
typename Result,
typename Task,
typename... Args>
612 Result run_task(std::size_t node_id,
const Task&
task, Args&&... args) {
613 auto t = task.lock();
617 if (t->node_->is_canceled()) {
620 return t->functor_(std::forward<Args>(args)...);
624 inline void wait_for_all() {}
627 template<
typename Future,
typename... ParentResults>
628 void wait_for_all(
const Future& future,
const std::shared_future<ParentResults>& ...futures) {
634 template<
typename FutureResult>
635 FutureResult wait_for_any_impl() {
639 template<
typename FutureResult,
typename Future,
typename... ParentResults>
640 FutureResult wait_for_any_impl(
const Future& future,
const std::shared_future<ParentResults>& ...futures) {
641 const auto status = future.wait_for(std::chrono::microseconds(1));
642 if (status == std::future_status::ready) {
645 return transwarp::detail::wait_for_any_impl<FutureResult>(futures...);
649 template<
typename FutureResult,
typename... ParentResults>
650 FutureResult
wait_for_any(
const std::shared_future<ParentResults>& ...futures) {
652 auto future = transwarp::detail::wait_for_any_impl<FutureResult>(futures...);
653 if (future.valid()) {
660 template<
typename TaskType,
bool done,
int total,
int... n>
662 template<
typename Result,
typename Task,
typename... ParentResults>
663 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
665 work<Result>(node_id, task, futures);
669 template<
int total,
int... n>
671 template<
typename Result,
typename Task,
typename... ParentResults>
672 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>&) {
673 return transwarp::detail::run_task<Result>(node_id, task);
677 template<
int total,
int... n>
679 template<
typename Result,
typename Task,
typename... ParentResults>
680 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
682 return transwarp::detail::run_task<Result>(node_id, task, std::get<n>(futures)...);
686 template<
int total,
int... n>
688 template<
typename Result,
typename Task,
typename... ParentResults>
689 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
690 using future_t =
typename std::remove_reference<decltype(std::get<0>(futures))>::type;
691 auto future = transwarp::detail::wait_for_any<future_t>(std::get<n>(futures)...);
692 return transwarp::detail::run_task<Result>(node_id, task, future);
696 template<
int total,
int... n>
698 template<
typename Result,
typename Task,
typename... ParentResults>
699 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
701 return transwarp::detail::run_task<Result>(node_id, task, std::get<n>(futures).
get()...);
705 template<
int total,
int... n>
707 template<
typename Result,
typename Task,
typename... ParentResults>
708 static Result
work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
709 using future_t =
typename std::remove_reference<decltype(std::get<0>(futures))>::type;
710 auto future = transwarp::detail::wait_for_any<future_t>(std::get<n>(futures)...);
711 return transwarp::detail::run_task<Result>(node_id, task, future.get());
715 template<
int total,
int... n>
717 template<
typename Result,
typename Task,
typename... ParentResults>
718 static Result
work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
720 get_all(std::get<n>(futures)...);
721 return transwarp::detail::run_task<Result>(node_id, task);
723 template<
typename T,
typename... Args>
724 static void get_all(
const T& arg,
const Args& ...args) {
728 static void get_all() {}
731 template<
int total,
int... n>
733 template<
typename Result,
typename Task,
typename... ParentResults>
734 static Result work(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
735 while (!
wait(std::get<n>(futures)...));
736 return transwarp::detail::run_task<Result>(node_id, task);
738 template<
typename T,
typename... Args>
739 static bool wait(
const T& arg,
const Args& ...args) {
740 const auto status = arg.wait_for(std::chrono::microseconds(1));
741 if (status == std::future_status::ready) {
745 return wait(args...);
755 template<
typename TaskType,
typename Result,
typename Task,
typename... ParentResults>
756 Result
call_with_futures(std::size_t node_id,
const Task& task,
const std::tuple<std::shared_future<ParentResults>...>& futures) {
757 constexpr std::size_t n = std::tuple_size<std::tuple<std::shared_future<ParentResults>...>>::value;
759 work<Result>(node_id, task, futures);
766 template<std::size_t end, std::size_t idx, std::size_t... i>
769 template<std::size_t end, std::size_t... i>
774 template<std::
size_t b, std::
size_t e>
779 template<
typename Functor,
typename... ParentResults>
782 template<std::size_t i, std::size_t... j,
typename Functor,
typename... ParentResults>
784 auto ptr = std::get<i>(t);
794 template<
typename Functor,
typename... ParentResults>
796 constexpr std::size_t n = std::tuple_size<std::tuple<std::shared_ptr<transwarp::task<ParentResults>>...>>::value;
797 using index_t =
typename transwarp::detail::index_range<0, n>::type;
798 transwarp::detail::call_with_each_index(index_t(), f, t);
801 template<
int offset,
typename... ParentResults>
803 static void work(
const std::tuple<std::shared_ptr<
transwarp::task<ParentResults>>...>& source, std::tuple<std::shared_future<ParentResults>...>& target) {
804 std::get<offset>(target) = std::get<offset>(source)->get_future();
809 template<
typename... ParentResults>
815 template<
typename... ParentResults>
817 std::tuple<std::shared_future<ParentResults>...>
result;
828 transwarp::detail::node_manip::add_parent(*node_, task.get_node());
829 if (node_->get_level() <= task.get_node()->get_level()) {
831 transwarp::detail::node_manip::set_level(*node_, task.get_node()->get_level() + 1);
835 std::shared_ptr<transwarp::node>& node_;
844 task.set_node_id(id_++);
852 explicit graph_visitor(std::vector<transwarp::edge>& graph) noexcept
856 const auto&
node = task.get_node();
858 graph_.emplace_back(parent,
node);
862 std::vector<transwarp::edge>& graph_;
868 : reset_(reset), executor_(executor) {}
871 task.schedule_impl(reset_, executor_);
881 template<
typename Task>
882 void operator()(Task& task)
const {
890 : enabled_(enabled) {}
893 task.cancel(enabled_);
902 : executor_(std::move(executor)) {}
905 task.set_executor(executor_);
908 std::shared_ptr<transwarp::executor> executor_;
915 task.remove_executor();
922 : priority_(priority) {}
925 task.set_priority(priority_);
928 std::size_t priority_;
935 task.reset_priority();
942 : custom_data_(std::move(custom_data)) {}
945 task.set_custom_data(custom_data_);
948 std::shared_ptr<void> custom_data_;
955 task.remove_custom_data();
965 tasks_.push_back(&task);
968 std::vector<transwarp::itask*>& tasks_;
974 : visitor_(visitor) {}
977 task.visit_depth(visitor_);
980 const std::function<void(transwarp::itask&)>& visitor_;
992 template<
typename TaskType,
typename Functor,
typename... ParentResults>
994 static_assert(std::is_same<TaskType, transwarp::root_type>::value ||
995 std::is_same<TaskType, transwarp::accept_type>::value ||
996 std::is_same<TaskType, transwarp::accept_any_type>::value ||
997 std::is_same<TaskType, transwarp::consume_type>::value ||
998 std::is_same<TaskType, transwarp::consume_any_type>::value ||
999 std::is_same<TaskType, transwarp::wait_type>::value ||
1000 std::is_same<TaskType, transwarp::wait_any_type>::value,
1001 "Invalid task type, must be one of: root, accept, accept_any, consume, consume_any, wait, wait_any");
1004 template<
typename Functor,
typename... ParentResults>
1006 static_assert(
sizeof...(ParentResults) == 0,
"A root task cannot have parent tasks");
1007 using type = decltype(std::declval<Functor>()());
1010 template<
typename Functor,
typename... ParentResults>
1012 static_assert(
sizeof...(ParentResults) > 0,
"An accept task must have at least one parent");
1013 using type = decltype(std::declval<Functor>()(std::declval<std::shared_future<ParentResults>>()...));
1016 template<
typename Functor,
typename... ParentResults>
1018 static_assert(
sizeof...(ParentResults) > 0,
"An accept_any task must have at least one parent");
1019 using arg_t =
typename std::tuple_element<0, std::tuple<ParentResults...>>
::type;
1020 using type = decltype(std::declval<Functor>()(std::declval<std::shared_future<arg_t>>()));
1023 template<
typename Functor,
typename... ParentResults>
1025 static_assert(
sizeof...(ParentResults) > 0,
"A consume task must have at least one parent");
1026 using type = decltype(std::declval<Functor>()(std::declval<ParentResults>()...));
1029 template<
typename Functor,
typename... ParentResults>
1031 static_assert(
sizeof...(ParentResults) > 0,
"A consume_any task must have at least one parent");
1032 using arg_t =
typename std::tuple_element<0, std::tuple<ParentResults...>>
::type;
1033 using type = decltype(std::declval<Functor>()(std::declval<arg_t>()));
1036 template<
typename Functor,
typename... ParentResults>
1038 static_assert(
sizeof...(ParentResults) > 0,
"A wait task must have at least one parent");
1039 using type = decltype(std::declval<Functor>()());
1042 template<
typename Functor,
typename... ParentResults>
1044 static_assert(
sizeof...(ParentResults) > 0,
"A wait_any task must have at least one parent");
1045 using type = decltype(std::declval<Functor>()());
1048 template<
bool is_transwarp_functor>
1053 template<
typename Functor>
1054 void operator()(Functor&
functor, std::shared_ptr<transwarp::node>
node)
const noexcept {
1055 functor.transwarp_node_ = std::move(node);
1061 template<
typename Functor>
1062 void operator()(Functor&, std::shared_ptr<transwarp::node>)
const noexcept {}
1066 template<
typename Functor>
1072 template<
typename ResultType,
typename Value>
1074 std::promise<ResultType> promise;
1075 promise.set_value(std::forward<Value>(value));
1076 return promise.get_future();
1081 std::promise<void> promise;
1082 promise.set_value();
1083 return promise.get_future();
1087 template<
typename ResultType>
1092 std::promise<ResultType> promise;
1093 promise.set_exception(exception);
1094 return promise.get_future();
1114 return "transwarp::sequential";
1118 void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&)
override {
1128 explicit parallel(std::size_t n_threads)
1140 return "transwarp::parallel";
1144 void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&)
override {
1158 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
1160 public std::enable_shared_from_this<task_impl_base<ResultType, TaskType, Functor, ParentResults...>> {
1166 using result_type = ResultType;
1175 executor_ = std::move(executor);
1176 transwarp::detail::node_manip::set_executor(*node_, std::make_shared<std::string>(executor_->get_name()));
1184 visit_depth_all(visitor);
1191 transwarp::detail::node_manip::set_executor(*node_,
nullptr);
1198 visit_depth_all(visitor);
1205 transwarp::detail::node_manip::set_priority(*node_, priority);
1213 visit_depth_all(visitor);
1219 transwarp::detail::node_manip::set_priority(*node_, 0);
1226 visit_depth_all(visitor);
1236 transwarp::detail::node_manip::set_custom_data(*node_, std::move(custom_data));
1244 visit_depth_all(visitor);
1250 transwarp::detail::node_manip::set_custom_data(*node_,
nullptr);
1257 visit_depth_all(visitor);
1261 const std::shared_future<result_type>&
get_future() const noexcept
override {
1266 const std::shared_ptr<transwarp::node>&
get_node() const noexcept
override {
1273 check_listener(listener);
1274 for (
auto& l : listeners_) {
1275 l.push_back(listener);
1282 check_listener(listener);
1283 listeners_[get_event_index(event)].push_back(std::move(listener));
1289 check_listener(listener);
1290 for (
auto& l : listeners_) {
1291 l.erase(std::remove(l.begin(), l.end(), listener), l.end());
1298 check_listener(listener);
1299 auto& l = listeners_[get_event_index(event)];
1300 l.erase(std::remove(l.begin(), l.end(), listener), l.end());
1306 listeners_[get_event_index(event)].clear();
1312 for (
auto& l : listeners_) {
1322 this->schedule_impl(
true);
1331 this->schedule_impl(reset);
1339 this->schedule_impl(
true, &executor);
1348 this->schedule_impl(reset, &executor);
1390 schedule_all_impl(
true, type);
1398 schedule_all_impl(
true, type, &executor);
1407 schedule_all_impl(reset_all, type);
1416 schedule_all_impl(reset_all, type, &executor);
1423 future_ = transwarp::detail::make_future_with_exception<result_type>(exception);
1424 schedule_mode_ =
false;
1430 return future_.valid();
1444 return future_.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
1455 future_ = std::shared_future<result_type>();
1456 schedule_mode_ =
true;
1463 visit_depth_all(visitor);
1470 void cancel(
bool enabled) noexcept
override {
1471 transwarp::detail::node_manip::set_canceled(*node_, enabled);
1480 visit_depth_all(visitor);
1487 std::vector<transwarp::edge> graph;
1495 template<
typename F>
1498 : node_(std::make_shared<transwarp::
node>()),
1499 functor_(std::forward<F>(
functor)),
1500 parents_(std::make_tuple(std::move(parents)...)),
1501 listeners_(static_cast<std::size_t>(transwarp::
event_type::count))
1503 transwarp::detail::node_manip::set_type(*node_, task_type::value);
1504 transwarp::detail::node_manip::set_name(*node_, (has_name ? std::make_shared<std::string>(std::move(name)) :
nullptr));
1514 if (future_.valid() && future_.wait_for(std::chrono::seconds(0)) != std::future_status::ready) {
1521 if (!future_.valid()) {
1526 bool schedule_mode_ =
true;
1527 std::shared_future<result_type> future_;
1531 template<
typename R,
typename T,
typename... A>
1532 friend R transwarp::detail::run_task(std::size_t,
const T&, A&&...);
1535 void set_node_id(std::size_t
id) noexcept
override {
1536 transwarp::detail::node_manip::set_id(*node_,
id);
1544 if (schedule_mode_ && !node_->is_canceled() && (reset || !future_.valid())) {
1545 std::weak_ptr<task_impl_base>
self = this->shared_from_this();
1547 auto pack_task = std::make_shared<std::packaged_task<result_type()>>(
1550 node_->get_id(),
self, std::move(futures)));
1552 future_ = pack_task->get_future();
1553 auto callable = [pack_task,
self] {
1554 if (
const auto t =
self.lock()) {
1558 if (
const auto t =
self.lock()) {
1563 executor_->execute(callable, node_);
1564 }
else if (executor) {
1565 executor->execute(callable, node_);
1577 if (!node_->is_canceled()) {
1581 visit_breadth_all(visitor);
1584 visit_depth_all(visitor);
1593 template<
typename Visitor>
1594 void visit_breadth_all(Visitor& visitor) {
1595 if (breadth_tasks_.empty()) {
1596 breadth_tasks_.reserve(node_->get_id() + 1);
1600 const auto l_level = l->get_node()->get_level();
1601 const auto l_id = l->get_node()->get_id();
1602 const auto r_level = r->get_node()->get_level();
1603 const auto r_id = r->get_node()->get_id();
1604 return std::tie(l_level, l_id) < std::tie(r_level, r_id);
1606 std::sort(breadth_tasks_.begin(), breadth_tasks_.end(), compare);
1608 for (
auto task : breadth_tasks_) {
1614 template<
typename Visitor>
1615 void visit_depth_all(Visitor& visitor) {
1616 if (depth_tasks_.empty()) {
1617 depth_tasks_.reserve(node_->get_id() + 1);
1621 for (
auto task : depth_tasks_) {
1627 void visit_depth(
const std::function<
void(
transwarp::itask&)>& visitor)
override {
1636 void unvisit() noexcept
override {
1645 const auto index =
static_cast<std::size_t
>(event);
1646 if (index >= static_cast<std::size_t>(transwarp::event_type::count)) {
1654 for (
const auto& listener : listeners_[static_cast<std::size_t>(event)]) {
1655 listener->handle_event(event,
get_node());
1660 void check_listener(
const std::shared_ptr<transwarp::listener>& listener)
const {
1666 std::shared_ptr<transwarp::node> node_;
1668 std::tuple<std::shared_ptr<transwarp::task<ParentResults>>...> parents_;
1669 bool visited_ =
false;
1670 std::shared_ptr<transwarp::executor> executor_;
1671 std::vector<std::vector<std::shared_ptr<transwarp::listener>>> listeners_;
1672 std::vector<transwarp::itask*> depth_tasks_;
1673 std::vector<transwarp::itask*> breadth_tasks_;
1678 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
1685 using result_type = ResultType;
1689 void set_value(
const typename transwarp::decay<result_type>::type& value)
override {
1690 set_value_impl(value);
1695 void set_value(
typename transwarp::decay<result_type>::type&& value)
override {
1696 set_value_impl(value);
1702 typename transwarp::result_info<result_type>::type
get()
const override {
1704 return this->future_.get();
1709 template<
typename F>
1716 template<
typename F>
1719 : transwarp::detail::task_impl_base<
result_type,
task_type, Functor, ParentResults...>(false,
"", std::forward<F>(
functor), std::move(parents)...)
1724 template<
typename T>
1725 void set_value_impl(T&& value) {
1727 this->future_ = transwarp::detail::make_future_with_value<result_type>(std::forward<T>(value));
1728 this->schedule_mode_ =
false;
1734 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
1741 using result_type = ResultType&;
1745 void set_value(
typename transwarp::decay<result_type>::type& value)
override {
1746 set_value_impl(value);
1752 typename transwarp::result_info<result_type>::type
get()
const override {
1753 this->ensure_task_was_scheduled();
1754 return this->future_.get();
1759 template<
typename F>
1763 : transwarp::detail::
task_impl_base<result_type,
task_type, Functor, ParentResults...>(true, std::move(name), std::forward<F>(
functor), std::move(parents)...)
1766 template<
typename F>
1769 : transwarp::detail::task_impl_base<result_type,
task_type, Functor, ParentResults...>(false,
"", std::forward<F>(
functor), std::move(parents)...)
1774 template<
typename T>
1775 void set_value_impl(T&& value) {
1776 this->ensure_task_not_running();
1777 this->future_ = transwarp::detail::make_future_with_value<result_type>(std::forward<T>(value));
1778 this->schedule_mode_ =
false;
1784 template<
typename TaskType,
typename Functor,
typename... ParentResults>
1791 using result_type = void;
1798 this->schedule_mode_ =
false;
1804 void get()
const override {
1806 this->future_.get();
1811 template<
typename F>
1818 template<
typename F>
1821 : transwarp::detail::task_impl_base<
result_type,
task_type, Functor, ParentResults...>(false,
"", std::forward<F>(
functor), std::move(parents)...)
1832 template<
typename TaskType,
typename Functor,
typename... ParentResults>
1843 template<typename F, typename = typename std::enable_if<std::is_same<Functor, typename std::decay<F>::type>::value>::type>
1847 : transwarp::detail::task_impl_proxy<
result_type,
task_type, Functor, ParentResults...>(std::move(name), std::forward<F>(
functor), std::move(parents)...)
1852 template<typename F, typename = typename std::enable_if<std::is_same<Functor, typename std::decay<F>::type>::value>::type>
1855 : transwarp::detail::task_impl_proxy<
result_type,
task_type, Functor, ParentResults...>(std::forward<F>(
functor), std::move(parents)...)
1859 template<
typename TaskType_,
typename Functor_>
1861 -> decltype(std::make_shared<transwarp::
task_impl<TaskType_, typename std::
decay<Functor_>::type,
result_type>>(std::move(name), std::forward<Functor_>(
functor), std::dynamic_pointer_cast<transwarp::task<
result_type>>(const_cast<
task_impl*>(this)->shared_from_this()))) {
1862 return std::make_shared<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>(std::move(name), std::forward<Functor_>(functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<task_impl*>(
this)->shared_from_this()));
1866 template<
typename TaskType_,
typename Functor_>
1869 return std::make_shared<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>(std::forward<Functor_>(functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<task_impl*>(
this)->shared_from_this()));
1882 template<
typename ResultType>
1884 public std::enable_shared_from_this<value_task<ResultType>> {
1894 template<typename T, typename = typename std::enable_if<std::is_same<result_type, typename transwarp::decay<T>::type>::value>::type>
1898 :
value_task(true, std::move(name), std::forward<T>(value))
1903 template<typename T, typename = typename std::enable_if<std::is_same<result_type, typename transwarp::decay<T>::type>::value>::type>
1906 :
value_task(false,
"", std::forward<T>(value))
1918 template<
typename TaskType_,
typename Functor_>
1920 -> decltype(std::make_shared<transwarp::
task_impl<TaskType_, typename std::
decay<Functor_>::type,
result_type>>(std::move(name), std::forward<Functor_>(
functor), std::dynamic_pointer_cast<transwarp::task<
result_type>>(const_cast<
value_task*>(this)->shared_from_this()))) {
1921 return std::make_shared<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>(std::move(name), std::forward<Functor_>(functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<value_task*>(
this)->shared_from_this()));
1925 template<
typename TaskType_,
typename Functor_>
1928 return std::make_shared<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>(std::forward<Functor_>(functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<value_task*>(
this)->shared_from_this()));
1946 transwarp::detail::node_manip::set_priority(*node_, priority);
1957 transwarp::detail::node_manip::set_priority(*node_, 0);
1971 transwarp::detail::node_manip::set_custom_data(*node_, std::move(custom_data));
1982 transwarp::detail::node_manip::set_custom_data(*node_,
nullptr);
1991 const std::shared_future<result_type>&
get_future() const noexcept
override {
1996 const std::shared_ptr<transwarp::node>&
get_node() const noexcept
override {
2055 void set_value(
const typename transwarp::decay<result_type>::type& value)
override {
2056 future_ = transwarp::detail::make_future_with_value<result_type>(value);
2060 void set_value(
typename transwarp::decay<result_type>::type&& value)
override {
2061 future_ = transwarp::detail::make_future_with_value<result_type>(value);
2066 future_ = transwarp::detail::make_future_with_exception<result_type>(exception);
2088 typename transwarp::result_info<result_type>::type
get()
const override {
2089 return future_.get();
2111 template<
typename T>
2113 value_task(
bool has_name, std::string name, T&& value)
2114 : node_(std::make_shared<transwarp::
node>()),
2115 future_(transwarp::detail::make_future_with_value<
result_type>(std::forward<T>(value)))
2117 transwarp::detail::node_manip::set_type(*node_, task_type::value);
2118 transwarp::detail::node_manip::set_name(*node_, (has_name ? std::make_shared<std::string>(std::move(name)) :
nullptr));
2122 void set_node_id(std::size_t
id) noexcept
override {
2123 transwarp::detail::node_manip::set_id(*node_,
id);
2130 void visit_depth(
const std::function<
void(
transwarp::itask&)>& visitor)
override {
2138 void unvisit() noexcept
override {
2142 std::shared_ptr<transwarp::node> node_;
2143 std::shared_future<result_type> future_;
2144 bool visited_ =
false;
2149 template<
typename TaskType,
typename Functor,
typename... Parents>
2150 auto make_task(TaskType, std::string name, Functor&&
functor, std::shared_ptr<Parents>... parents)
2151 -> decltype(std::make_shared<
transwarp::task_impl<TaskType,
typename std::decay<Functor>::type,
typename Parents::result_type...>>(std::move(name), std::forward<Functor>(
functor), std::move(parents)...)) {
2152 return std::make_shared<transwarp::task_impl<TaskType, typename std::decay<Functor>::type,
typename Parents::result_type...>>(std::move(name), std::forward<Functor>(
functor), std::move(parents)...);
2156 template<
typename TaskType,
typename Functor,
typename... Parents>
2158 -> decltype(std::make_shared<
transwarp::task_impl<TaskType,
typename std::decay<Functor>::type,
typename Parents::result_type...>>(std::forward<Functor>(
functor), std::move(parents)...)) {
2159 return std::make_shared<transwarp::task_impl<TaskType, typename std::decay<Functor>::type,
typename Parents::result_type...>>(std::forward<Functor>(
functor), std::move(parents)...);
2164 template<
typename Value>
2166 -> decltype(std::make_shared<
transwarp::value_task<
typename transwarp::decay<Value>::type>>(std::move(name), std::forward<Value>(value))) {
2167 return std::make_shared<transwarp::value_task<typename transwarp::decay<Value>::type>>(std::move(name), std::forward<Value>(value));
2171 template<
typename Value>
2173 -> decltype(std::make_shared<
transwarp::value_task<
typename transwarp::decay<Value>::type>>(std::forward<Value>(value))) {
2174 return std::make_shared<transwarp::value_task<typename transwarp::decay<Value>::type>>(std::forward<Value>(value));
void set_custom_data_all(std::shared_ptr< void > custom_data) override
Assigns custom data to all tasks. transwarp will not directly use this. This is only useful if someth...
Definition: transwarp.h:1241
constexpr transwarp::wait_any_type wait_any
The wait_any task tag.
Definition: transwarp.h:127
void remove_custom_data_all() override
Removes custom data from all tasks.
Definition: transwarp.h:1986
The executor interface used to perform custom task execution.
Definition: transwarp.h:282
Exception thrown when a task was destroyed prematurely.
Definition: transwarp.h:60
A simple thread pool used to execute tasks in parallel.
Definition: transwarp.h:525
void cancel_all(bool) noexceptoverride
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2102
void operator()(const transwarp::itask &task) const
Definition: transwarp.h:827
Node manipulation.
Definition: transwarp.h:475
TaskType task_type
The task type.
Definition: transwarp.h:1738
void remove_listeners(transwarp::event_type) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2013
Generates a graph.
Definition: transwarp.h:851
The consume type. Used for tag dispatch.
Definition: transwarp.h:114
void schedule_all(transwarp::executor &) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2034
Removes the executor from the given task.
Definition: transwarp.h:912
Definition: transwarp.h:764
void reset_priority_all() override
Resets the priority of all tasks to 0.
Definition: transwarp.h:1223
Definition: transwarp.h:139
TaskType task_type
The task type.
Definition: transwarp.h:1788
void set_exception(std::exception_ptr exception) override
Assigns an exception to this task.
Definition: transwarp.h:2065
void schedule_all(bool reset_all) override
Schedules all tasks in the graph for execution on the caller thread. The task-specific executors get ...
Definition: transwarp.h:1371
void ensure_task_was_scheduled() const
Checks if the task was scheduled and throws transwarp::control_error if it's not. ...
Definition: transwarp.h:1520
Sets parents and level of the node.
Definition: transwarp.h:823
value_task(std::string name, T &&value)
A value task is defined by name and value. name is optional, see overload Note: A value task must be ...
Definition: transwarp.h:1897
void set_executor(std::shared_ptr< transwarp::executor >) override
No-op because a value task never runs.
Definition: transwarp.h:1932
void set_executor_all(std::shared_ptr< transwarp::executor > executor) override
Assigns an executor to all tasks which takes precedence over the executor provided in schedule() or s...
Definition: transwarp.h:1181
bool was_scheduled() const noexceptoverride
Returns whether the task was scheduled and not reset afterwards. This means that the underlying futur...
Definition: transwarp.h:1429
void wait_for_all(const Future &future, const std::shared_future< ParentResults > &...futures)
Waits for all futures to finish.
Definition: transwarp.h:628
void cancel(bool) noexceptoverride
No-op because a value task never runs.
Definition: transwarp.h:2099
just before a task is scheduled (handle_event called on thread of caller to schedule()) ...
void schedule_all() override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2031
void schedule_all(transwarp::executor &executor, bool reset_all) override
Schedules all tasks in the graph for execution using the provided executor. The task-specific executo...
Definition: transwarp.h:1380
std::string get_name() const override
Returns the name of the executor.
Definition: transwarp.h:1139
Assigns a priority to the given task.
Definition: transwarp.h:920
void set_value(const typename transwarp::decay< result_type >::type &value) override
Assigns a value to this task.
Definition: transwarp.h:2055
void schedule(transwarp::executor &executor) override
Schedules this task for execution using the provided executor. The task-specific executor gets preced...
Definition: transwarp.h:1337
Assigns an executor to the given task.
Definition: transwarp.h:900
Unvisits the given task.
Definition: transwarp.h:984
void set_priority(std::size_t priority) override
Sets a task priority (defaults to 0). transwarp will not directly use this. This is only useful if so...
Definition: transwarp.h:1945
void cancel_all(bool enabled) noexceptoverride
If enabled then all pending tasks in the graph are canceled which will throw transwarp::task_canceled...
Definition: transwarp.h:1478
void remove_custom_data() override
Removes custom data from this task.
Definition: transwarp.h:1248
void set_custom_data_all(std::shared_ptr< void > custom_data) override
Assigns custom data to all tasks. transwarp will not directly use this. This is only useful if someth...
Definition: transwarp.h:1976
std::tuple< std::shared_future< ParentResults >...> get_futures(const std::tuple< std::shared_ptr< transwarp::task< ParentResults >>...> &input)
Returns the futures from the given tasks.
Definition: transwarp.h:816
void set_value(typename transwarp::decay< result_type >::type &&value) override
Assigns a value to this task.
Definition: transwarp.h:2060
void schedule_all(transwarp::schedule_type type, bool reset_all) override
Schedules all tasks in the graph for execution on the caller thread. The task-specific executors get ...
Definition: transwarp.h:1405
Scheduling according to a breadth-first search (default)
void schedule_all() override
Schedules all tasks in the graph for execution on the caller thread. The task-specific executors get ...
Definition: transwarp.h:1354
void set_executor(std::shared_ptr< transwarp::executor > executor) override
Assigns an executor to this task which takes precedence over the executor provided in schedule() or s...
Definition: transwarp.h:1170
static Result work(std::size_t node_id, const Task &task, const std::tuple< std::shared_future< ParentResults >...> &futures)
Definition: transwarp.h:708
void set_custom_data(std::shared_ptr< void > custom_data) override
Assigns custom data to this task. transwarp will not directly use this. This is only useful if someth...
Definition: transwarp.h:1967
The task class (non-void result type)
Definition: transwarp.h:401
value_task(T &&value)
This overload is for omitting the task name Note: A value task must be created using shared_ptr (beca...
Definition: transwarp.h:1905
Definition: transwarp.h:775
void schedule_all(transwarp::executor &executor, transwarp::schedule_type type, bool reset_all) override
Schedules all tasks in the graph for execution using the provided executor. The task-specific executo...
Definition: transwarp.h:1414
decltype(std::declval< Functor >()(std::declval< std::shared_future< arg_t >>())) type
using first type as reference
Definition: transwarp.h:1020
void reset_priority_all() override
Resets the priority of all tasks to 0.
Definition: transwarp.h:1961
void set_value(const typename transwarp::decay< result_type >::type &value) override
Assigns a value to this task. Scheduling will have no effect after a value has been set...
Definition: transwarp.h:1689
void set_priority(std::size_t priority) override
Sets a task priority (defaults to 0). transwarp will not directly use this. This is only useful if so...
Definition: transwarp.h:1203
const std::shared_ptr< std::string > & get_executor() const noexcept
The optional, task-specific executor (may be null)
Definition: transwarp.h:177
void assign_node_if(Functor &functor, std::shared_ptr< transwarp::node > node) noexcept
Assigns the node to the given functor if the functor is a subclass of transwarp::functor.
Definition: transwarp.h:1067
void reset() override
Resets the future of this task.
Definition: transwarp.h:1453
const std::vector< std::shared_ptr< node > > & get_parents() const noexcept
The task's parents (may be empty)
Definition: transwarp.h:182
decltype(std::declval< Functor >()(std::declval< arg_t >())) type
using first type as reference
Definition: transwarp.h:1033
Definition: transwarp.h:762
auto then(TaskType_, Functor_ &&functor) const -> decltype(std::make_shared< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type >>(std::forward< Functor_ >(functor), std::dynamic_pointer_cast< transwarp::task< result_type >>(const_cast< value_task * >(this) ->shared_from_this())))
Creates a continuation to this task. Overload for omitting for task name.
Definition: transwarp.h:1926
The task's functor accepts the first parent future that becomes ready.
Definition: transwarp.h:661
The consume_any type. Used for tag dispatch.
Definition: transwarp.h:118
ResultType result_type
The result type of this task.
Definition: transwarp.h:1685
void set_custom_data(std::shared_ptr< void > custom_data) override
Assigns custom data to this task. transwarp will not directly use this. This is only useful if someth...
Definition: transwarp.h:1231
bool was_scheduled() const noexceptoverride
Returns true because a value task is scheduled once on construction.
Definition: transwarp.h:2070
static Result work(std::size_t node_id, const Task &task, const std::tuple< std::shared_future< ParentResults >...> &futures)
Definition: transwarp.h:718
void execute(const std::function< void()> &functor, const std::shared_ptr< transwarp::node > &) override
Pushes the functor into the thread pool for asynchronous execution.
Definition: transwarp.h:1144
The accept type. Used for tag dispatch.
Definition: transwarp.h:106
const std::shared_future< result_type > & get_future() const noexceptoverride
Returns the future associated to the underlying execution.
Definition: transwarp.h:1261
constexpr transwarp::accept_type accept
The accept task tag.
Definition: transwarp.h:107
Determines the result type of the Functor dispatching on the task type.
Definition: transwarp.h:993
TaskType task_type
The task type.
Definition: transwarp.h:1163
void schedule_all(transwarp::executor &, transwarp::schedule_type, bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2052
void remove_listeners() override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2016
bool has_result() const noexceptoverride
Returns whether this task contains a result.
Definition: transwarp.h:1448
The listener interface to listen to events raised by tasks.
Definition: transwarp.h:307
Exception thrown when a task is canceled.
Definition: transwarp.h:51
TaskType task_type
The task type.
Definition: transwarp.h:1836
void wait() const override
Waits for the task to complete. Should only be called if was_scheduled() is true, throws transwarp::c...
Definition: transwarp.h:1435
Scheduling according to a depth-first search.
void add_listener(transwarp::event_type event, std::shared_ptr< transwarp::listener > listener) override
Adds a new listener for the given event type only.
Definition: transwarp.h:1280
std::size_t get_level() const noexcept
The task level.
Definition: transwarp.h:162
std::shared_future< ResultType > make_future_with_value(Value &&value)
Returns a ready future with the given value as its state.
Definition: transwarp.h:1073
std::string get_name() const override
Returns the name of the executor.
Definition: transwarp.h:1113
void schedule() override
Schedules this task for execution on the caller thread. The task-specific executor gets precedence if...
Definition: transwarp.h:1320
void add_listener(std::shared_ptr< transwarp::listener >) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2001
void add_listener(std::shared_ptr< transwarp::listener > listener) override
Adds a new listener for all event types.
Definition: transwarp.h:1271
void ensure_task_not_running() const
Checks if the task is currently running and throws transwarp::control_error if it is...
Definition: transwarp.h:1513
just before a task starts running (handle_event called on thread that task is run on) ...
Removes custom data from the given task.
Definition: transwarp.h:952
void schedule_all(transwarp::executor &, bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2040
Resets the given task.
Definition: transwarp.h:879
const std::shared_ptr< std::string > & get_name() const noexcept
The optional task name (may be null)
Definition: transwarp.h:172
A base class for a user-defined functor that needs access to the node associated to the task or a can...
Definition: transwarp.h:442
constexpr transwarp::consume_any_type consume_any
The consume_any task tag.
Definition: transwarp.h:119
bool is_canceled() const noexcept
Returns whether the associated task is canceled.
Definition: transwarp.h:197
A node carrying meta-data of a task.
Definition: transwarp.h:145
Result call_with_futures(std::size_t node_id, const Task &task, const std::tuple< std::shared_future< ParentResults >...> &futures)
Calls the functor of the given task with the results from the futures. Throws transwarp::task_cancele...
Definition: transwarp.h:756
Exception thrown when a task is used in unintended ways.
Definition: transwarp.h:78
ResultType result_type
The result type of this task.
Definition: transwarp.h:1166
Resets the priority of the given task.
Definition: transwarp.h:932
void schedule() override
No-op because a value task never runs.
Definition: transwarp.h:2019
void add_listener(transwarp::event_type, std::shared_ptr< transwarp::listener >) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2004
void wait() const override
No-op because a value task never runs.
Definition: transwarp.h:2075
void schedule_all(transwarp::executor &executor, transwarp::schedule_type type) override
Schedules all tasks in the graph for execution using the provided executor. The task-specific executo...
Definition: transwarp.h:1396
std::size_t get_priority() const noexcept
The task priority (defaults to 0)
Definition: transwarp.h:187
const std::shared_ptr< transwarp::node > & get_parent() const noexcept
Returns the parent node.
Definition: transwarp.h:250
A task proxy for non-void result type.
Definition: transwarp.h:1679
void transwarp_cancel_point() const
If the associated task is canceled then this will throw transwarp::task_canceled which will stop the ...
Definition: transwarp.h:456
Returns the result type of a std::shared_future<T>
Definition: transwarp.h:394
The base task class that contains the functionality that can be used with all result types (void and ...
Definition: transwarp.h:1159
Definition: transwarp.h:802
The task's functor consumes all parent results.
auto make_value_task(std::string name, Value &&value) -> decltype(std::make_shared< transwarp::value_task< typename transwarp::decay< Value >::type >>(std::move(name), std::forward< Value >(value)))
A factory function to create a new value task.
Definition: transwarp.h:2165
just after a task has finished running (handle_event called on thread that task is run on) ...
void remove_listener(const std::shared_ptr< transwarp::listener > &) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2007
void set_priority_all(std::size_t priority) override
Sets a priority to all tasks (defaults to 0). transwarp will not directly use this. This is only useful if something else is using the priority.
Definition: transwarp.h:1951
Base class for exceptions.
Definition: transwarp.h:42
void schedule_all(transwarp::schedule_type) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2043
task_impl(std::string name, F &&functor, std::shared_ptr< transwarp::task< ParentResults >>...parents)
A task is defined by name, functor, and parent tasks. name is optional, see overload Note: A task mus...
Definition: transwarp.h:1846
constexpr transwarp::consume_type consume
The consume task tag.
Definition: transwarp.h:115
std::size_t get_id() const noexcept
The task ID.
Definition: transwarp.h:157
void schedule(transwarp::executor &, bool) override
No-op because a value task never runs.
Definition: transwarp.h:2028
A value task that stores a single value and doesn't require scheduling. Value tasks should be created...
Definition: transwarp.h:1883
void reset_priority() override
Resets the task priority to 0.
Definition: transwarp.h:1956
void remove_listeners(transwarp::event_type event) override
Removes all listeners for the given event type.
Definition: transwarp.h:1304
void remove_listener(const std::shared_ptr< transwarp::listener > &listener) override
Removes the listener for all event types.
Definition: transwarp.h:1287
const std::shared_ptr< transwarp::node > & transwarp_node() const noexcept
The node associated to the task.
Definition: transwarp.h:450
void reset_all() override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2096
void remove_listener(transwarp::event_type event, const std::shared_ptr< transwarp::listener > &listener) override
Removes the listener for the given event type only.
Definition: transwarp.h:1296
Assigns custom data to the given task.
Definition: transwarp.h:940
The task's functor takes no arguments but waits for all parents to finish.
void set_exception(std::exception_ptr exception) override
Assigns an exception to this task. Scheduling will have no effect after an exception has been set...
Definition: transwarp.h:1421
Removes reference and const from a type.
Definition: transwarp.h:387
void remove_listeners() override
Removes all listeners.
Definition: transwarp.h:1310
const std::shared_ptr< void > & get_custom_data() const noexcept
The custom task data (may be null)
Definition: transwarp.h:192
void call_with_each(const Functor &f, const std::tuple< std::shared_ptr< transwarp::task< ParentResults >>...> &t)
Calls the functor with every element in the tuple. Expects the tuple to contain task pointers only an...
Definition: transwarp.h:795
void reset_priority() override
Resets the task priority to 0.
Definition: transwarp.h:1217
typename transwarp::detail::result< TaskType, Functor, ParentResults...>::type result_type
The result type of this task.
Definition: transwarp.h:1839
void schedule_all(transwarp::executor &, transwarp::schedule_type) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2046
void schedule_all(transwarp::schedule_type, bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2049
An edge between two nodes.
Definition: transwarp.h:236
const std::shared_ptr< transwarp::node > & get_child() const noexcept
Returns the child node.
Definition: transwarp.h:255
void schedule_all(transwarp::schedule_type type) override
Schedules all tasks in the graph for execution on the caller thread. The task-specific executors get ...
Definition: transwarp.h:1388
std::vector< transwarp::edge > get_graph() const override
Returns the graph of the task structure. This is mainly for visualizing the tasks and their interdepe...
Definition: transwarp.h:1486
void set_value(typename transwarp::decay< result_type >::type &value) override
Assigns a value to this task. Scheduling will have no effect after a value has been set...
Definition: transwarp.h:1745
void schedule(transwarp::executor &) override
No-op because a value task never runs.
Definition: transwarp.h:2022
void reset_all() override
Resets the futures of all tasks in the graph.
Definition: transwarp.h:1460
ResultType result_type
The result type of this task.
Definition: transwarp.h:1890
Executor for parallel execution. Uses a simple thread pool.
Definition: transwarp.h:1125
The wait_any type. Used for tag dispatch.
Definition: transwarp.h:126
void set_priority_all(std::size_t priority) override
Sets a priority to all tasks (defaults to 0). transwarp will not directly use this. This is only useful if something else is using the priority (e.g. a custom executor)
Definition: transwarp.h:1210
void schedule(bool reset) override
Schedules this task for execution on the caller thread. The task-specific executor gets precedence if...
Definition: transwarp.h:1329
virtual std::string get_name() const =0
Is supposed to return the name of the executor.
auto then(TaskType_, Functor_ &&functor) const -> decltype(std::make_shared< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type >>(std::forward< Functor_ >(functor), std::dynamic_pointer_cast< transwarp::task< result_type >>(const_cast< task_impl * >(this) ->shared_from_this())))
Creates a continuation to this task. Overload for omitting for task name.
Definition: transwarp.h:1867
std::string to_string(const transwarp::task_type &type)
String conversion for the task_type enumeration.
Definition: transwarp.h:87
virtual void execute(const std::function< void()> &functor, const std::shared_ptr< transwarp::node > &node)=0
Is supposed to run a task which is wrapped by the functor. The functor only captures a shared_ptr and...
void execute(const std::function< void()> &functor, const std::shared_ptr< transwarp::node > &) override
Runs the functor on the current thread.
Definition: transwarp.h:1118
void remove_executor() override
Removes the executor from this task.
Definition: transwarp.h:1188
The accept_any type. Used for tag dispatch.
Definition: transwarp.h:110
transwarp::task_type get_type() const noexcept
The task type.
Definition: transwarp.h:167
static bool wait(const T &arg, const Args &...args)
Definition: transwarp.h:739
virtual void handle_event(transwarp::event_type event, const std::shared_ptr< transwarp::node > &node)=0
This may be called from arbitrary threads depending on the event type (see transwarp::event_type) ...
bool is_ready() const override
Returns true because a value task is always ready.
Definition: transwarp.h:2078
constexpr transwarp::wait_type wait
The wait task tag.
Definition: transwarp.h:123
The root type. Used for tag dispatch.
Definition: transwarp.h:102
The task's functor consumes the first parent result that becomes ready.
A task representing a piece of work given by functor and parent tasks. By connecting tasks a directed...
Definition: transwarp.h:1833
void remove_listener(transwarp::event_type, const std::shared_ptr< transwarp::listener > &) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2010
The wait type. Used for tag dispatch.
Definition: transwarp.h:122
void cancel(bool enabled) noexceptoverride
If enabled then this task is canceled which will throw transwarp::task_canceled when retrieving the t...
Definition: transwarp.h:1470
Schedules using the given executor.
Definition: transwarp.h:866
constexpr transwarp::root_type root
The root task tag.
Definition: transwarp.h:103
void remove_custom_data() override
Removes custom data from this task.
Definition: transwarp.h:1981
void set_value(typename transwarp::decay< result_type >::type &&value) override
Assigns a value to this task. Scheduling will have no effect after a value has been set...
Definition: transwarp.h:1695
void schedule_all(transwarp::executor &executor) override
Schedules all tasks in the graph for execution using the provided executor. The task-specific executo...
Definition: transwarp.h:1362
schedule_type
Determines in which order tasks are scheduled in the graph.
Definition: transwarp.h:317
The task's functor accepts all parent futures.
Applies final bookkeeping to the task.
Definition: transwarp.h:839
void remove_executor_all() override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:1941
void schedule(transwarp::executor &executor, bool reset) override
Schedules this task for execution using the provided executor. The task-specific executor gets preced...
Definition: transwarp.h:1346
std::vector< transwarp::edge > get_graph() const override
Returns an empty graph because a value task doesn't have parents.
Definition: transwarp.h:2105
const std::shared_ptr< transwarp::node > & get_node() const noexceptoverride
Returns the associated node.
Definition: transwarp.h:1266
task_type
The possible task types.
Definition: transwarp.h:30
void set_value() override
Assigns a value to this task. Scheduling will have no effect after a call to this. Calling reset() will reset this and re-enable scheduling.
Definition: transwarp.h:1795
event_type
The task events that can be subscribed to using the below listener interface.
Definition: transwarp.h:298
The task's functor takes no arguments but waits for the first parent to finish.
Exception thrown when an invalid parameter was passed to a function.
Definition: transwarp.h:69
void remove_custom_data_all() override
Removes custom data from all tasks.
Definition: transwarp.h:1254
auto make_task(TaskType, std::string name, Functor &&functor, std::shared_ptr< Parents >...parents) -> decltype(std::make_shared< transwarp::task_impl< TaskType, typename std::decay< Functor >::type, typename Parents::result_type...>>(std::move(name), std::forward< Functor >(functor), std::move(parents)...))
A factory function to create a new task.
Definition: transwarp.h:2150
void reset() override
No-op because a value task never runs.
Definition: transwarp.h:2093
std::shared_future< void > make_ready_future()
Returns a ready future.
Definition: transwarp.h:1080
void set_executor_all(std::shared_ptr< transwarp::executor >) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:1935
constexpr transwarp::accept_any_type accept_any
The accept_any task tag.
Definition: transwarp.h:111
const std::shared_future< result_type > & get_future() const noexceptoverride
Returns the future associated to the underlying execution.
Definition: transwarp.h:1991
Cancels or resumes the given task.
Definition: transwarp.h:888
void remove_executor() override
No-op because a value task never runs.
Definition: transwarp.h:1938
void schedule(bool) override
No-op because a value task never runs.
Definition: transwarp.h:2025
void schedule_all(bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2037
Visits the given task using the visitor given in the constructor.
Definition: transwarp.h:972
Pushes the given task into the vector of tasks.
Definition: transwarp.h:960
Executor for sequential execution. Runs functors sequentially on the same thread. ...
Definition: transwarp.h:1101
auto then(TaskType_, std::string name, Functor_ &&functor) const -> decltype(std::make_shared< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type >>(std::move(name), std::forward< Functor_ >(functor), std::dynamic_pointer_cast< transwarp::task< result_type >>(const_cast< value_task * >(this) ->shared_from_this())))
Creates a continuation to this task.
Definition: transwarp.h:1919
FutureResult wait_for_any(const std::shared_future< ParentResults > &...futures)
Waits for the first future to finish.
Definition: transwarp.h:650
bool has_result() const noexceptoverride
Returns true because a value task always contains a result.
Definition: transwarp.h:2083
std::shared_future< ResultType > make_future_with_exception(std::exception_ptr exception)
Returns a ready future with the given exception as its state.
Definition: transwarp.h:1088
void remove_executor_all() override
Removes the executor from all tasks.
Definition: transwarp.h:1195
const std::shared_ptr< transwarp::node > & get_node() const noexceptoverride
Returns the associated node.
Definition: transwarp.h:1996
bool is_ready() const override
Returns whether the task has finished processing. Should only be called if was_scheduled() is true...
Definition: transwarp.h:1442
task_impl(F &&functor, std::shared_ptr< transwarp::task< ParentResults >>...parents)
This overload is for omitting the task name Note: A task must be created using shared_ptr (because of...
Definition: transwarp.h:1854
auto then(TaskType_, std::string name, Functor_ &&functor) const -> decltype(std::make_shared< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type >>(std::move(name), std::forward< Functor_ >(functor), std::dynamic_pointer_cast< transwarp::task< result_type >>(const_cast< task_impl * >(this) ->shared_from_this())))
Creates a continuation to this task.
Definition: transwarp.h:1860
An interface for the task class.
Definition: transwarp.h:324