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};
219 const std::shared_ptr<std::string>& name = node.
get_name();
221 s +=
"<" + *name +
">" + seperator;
224 s +=
" id=" + std::to_string(node.
get_id());
225 s +=
" lev=" + std::to_string(node.
get_level());
226 const std::shared_ptr<std::string>& exec = node.
get_executor();
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;
287 virtual std::string
get_name()
const = 0;
294 virtual void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&
node) = 0;
330 virtual ~
itask() =
default;
332 virtual void set_executor(std::shared_ptr<transwarp::executor>
executor) = 0;
333 virtual void set_executor_all(std::shared_ptr<transwarp::executor> executor) = 0;
334 virtual void remove_executor() = 0;
335 virtual void remove_executor_all() = 0;
336 virtual void set_priority(std::size_t priority) = 0;
337 virtual void set_priority_all(std::size_t priority) = 0;
338 virtual void reset_priority() = 0;
339 virtual void reset_priority_all() = 0;
340 virtual void set_custom_data(std::shared_ptr<void> custom_data) = 0;
341 virtual void set_custom_data_all(std::shared_ptr<void> custom_data) = 0;
342 virtual void remove_custom_data() = 0;
343 virtual void remove_custom_data_all() = 0;
344 virtual const std::shared_ptr<transwarp::node>& get_node()
const noexcept = 0;
345 virtual void add_listener(std::shared_ptr<transwarp::listener>
listener) = 0;
346 virtual void add_listener(
transwarp::event_type event, std::shared_ptr<transwarp::listener> listener) = 0;
347 virtual void remove_listener(
const std::shared_ptr<transwarp::listener>& listener) = 0;
348 virtual void remove_listener(
transwarp::event_type event,
const std::shared_ptr<transwarp::listener>& listener) = 0;
350 virtual void remove_listeners() = 0;
351 virtual void schedule() = 0;
353 virtual void schedule(
bool reset) = 0;
355 virtual void schedule_all() = 0;
357 virtual void schedule_all(
bool reset_all) = 0;
363 virtual void set_exception(std::exception_ptr exception) = 0;
364 virtual bool was_scheduled()
const noexcept = 0;
365 virtual void wait()
const = 0;
366 virtual bool is_ready()
const = 0;
367 virtual bool has_result()
const = 0;
368 virtual void reset() = 0;
369 virtual void reset_all() = 0;
370 virtual void cancel(
bool enabled) noexcept = 0;
371 virtual void cancel_all(
bool enabled) noexcept = 0;
372 virtual std::vector<transwarp::edge> get_graph()
const = 0;
383 virtual void visit_depth(
const std::function<
void(
itask&)>& visitor) = 0;
384 virtual void unvisit() noexcept = 0;
385 virtual void set_node_id(std::size_t
id) noexcept = 0;
392 using type =
typename std::remove_const<typename std::remove_reference<T>::type>::type;
399 using type =
typename std::result_of<decltype(&std::shared_future<T>::get)(std::shared_future<T>)>::type;
404 template<
typename ResultType>
407 using result_type = ResultType;
409 virtual ~
task() =
default;
411 virtual void set_value(
const typename transwarp::decay<result_type>::type& value) = 0;
412 virtual void set_value(
typename transwarp::decay<result_type>::type&& value) = 0;
413 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
414 virtual typename transwarp::result<result_type>::type
get()
const = 0;
418 template<
typename ResultType>
421 using result_type = ResultType&;
423 virtual ~
task() =
default;
425 virtual void set_value(
typename transwarp::decay<result_type>::type& value) = 0;
426 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
427 virtual typename transwarp::result<result_type>::type
get()
const = 0;
434 using result_type = void;
436 virtual ~
task() =
default;
438 virtual void set_value() = 0;
439 virtual const std::shared_future<result_type>& get_future()
const noexcept = 0;
440 virtual result_type
get()
const = 0;
455 return transwarp_node_;
461 if (transwarp_node_->is_canceled()) {
470 std::shared_ptr<transwarp::node> transwarp_node_;
485 static void set_level(
transwarp::node& node, std::size_t level) noexcept {
493 static void set_name(
transwarp::node& node, std::shared_ptr<std::string> name) noexcept {
499 node.executor_ = std::move(executor);
501 node.executor_.reset();
505 static void add_parent(
transwarp::node& node, std::shared_ptr<transwarp::node> parent) {
506 node.parents_.push_back(std::move(parent));
509 static void set_priority(
transwarp::node& node, std::size_t priority) noexcept {
510 node.priority_ = priority;
513 static void set_custom_data(
transwarp::node& node, std::shared_ptr<void> custom_data) {
515 node.custom_data_ = std::move(custom_data);
517 node.custom_data_.reset();
521 static void set_canceled(
transwarp::node& node,
bool enabled) noexcept {
522 node.canceled_ = enabled;
535 if (n_threads == 0) {
538 const std::size_t n_target = threads_.size() + n_threads;
539 while (threads_.size() < n_target) {
542 thread = std::thread(&thread_pool::worker,
this);
548 threads_.push_back(std::move(thread));
567 void push(
const std::function<
void()>&
functor) {
569 std::lock_guard<std::mutex> lock(mutex_);
572 cond_var_.notify_one();
581 std::unique_lock<std::mutex> lock(mutex_);
582 cond_var_.wait(lock, [
this]{
583 return done_ || !functors_.empty();
585 if (done_ && functors_.empty()) {
588 functor = functors_.front();
597 std::lock_guard<std::mutex> lock(mutex_);
600 cond_var_.notify_all();
601 for (std::thread& thread : threads_) {
608 std::vector<std::thread> threads_;
609 std::queue<std::function<void()>> functors_;
610 std::condition_variable cond_var_;
615 template<
int offset,
typename... ParentResults>
617 static void work(
const std::tuple<std::shared_ptr<
transwarp::task<ParentResults>>...>& source, std::tuple<std::shared_future<ParentResults>...>& target) {
618 std::get<offset>(target) = std::get<offset>(source)->get_future();
623 template<
typename... ParentResults>
629 template<
typename... ParentResults>
631 std::tuple<std::shared_future<ParentResults>...>
result;
637 template<
typename ParentResultType>
639 std::vector<std::shared_future<ParentResultType>>
result;
640 result.reserve(input.size());
642 result.emplace_back(
task->get_future());
649 template<
typename Result,
typename Task,
typename... Args>
650 Result
run_task(std::size_t node_id,
const std::weak_ptr<Task>&
task, Args&&... args) {
651 const std::shared_ptr<Task> t = task.lock();
655 if (t->node_->is_canceled()) {
659 return t->functor_(std::forward<Args>(args)...);
663 inline void wait_for_all() {}
666 template<
typename ParentResult,
typename... ParentResults>
668 parent->get_future().wait();
674 template<
typename ParentResultType>
677 parent->get_future().wait();
682 template<
typename Parent>
683 Parent wait_for_any_impl() {
687 template<
typename Parent,
typename ParentResult,
typename... ParentResults>
689 const std::future_status status = parent->get_future().wait_for(std::chrono::microseconds(1));
690 if (status == std::future_status::ready) {
693 return transwarp::detail::wait_for_any_impl<Parent>(parents...);
697 template<
typename Parent,
typename... ParentResults>
700 Parent parent = transwarp::detail::wait_for_any_impl<Parent>(
parents...);
709 template<
typename ParentResultType>
713 const std::future_status status = parent->get_future().wait_for(std::chrono::microseconds(1));
714 if (status == std::future_status::ready) {
722 template<
typename OneResult>
726 template<
typename OneResult,
typename ParentResult,
typename... ParentResults>
729 parent->cancel(
true);
736 template<
typename OneResult,
typename ParentResultType>
740 parent->cancel(
true);
746 template<
typename TaskType,
bool done,
int total,
int... n>
748 template<
typename Result,
typename Task,
typename... ParentResults>
751 work<Result>(node_id, task,
parents);
755 template<
typename TaskType>
758 template<
int total,
int... n>
760 template<
typename Result,
typename Task,
typename... ParentResults>
762 return transwarp::detail::run_task<Result>(node_id, task);
768 template<
typename Result,
typename Task,
typename ParentResultType>
770 return transwarp::detail::run_task<Result>(node_id, task);
774 template<
int total,
int... n>
776 template<
typename Result,
typename Task,
typename... ParentResults>
780 return transwarp::detail::run_task<Result>(node_id, task, std::get<n>(futures)...);
786 template<
typename Result,
typename Task,
typename ParentResultType>
793 template<
int total,
int... n>
795 template<
typename Result,
typename Task,
typename... ParentResults>
797 using parent_t =
typename std::remove_reference<decltype(std::get<0>(
parents))>::type;
798 parent_t parent = transwarp::detail::wait_for_any<parent_t>(std::get<n>(
parents)...);
800 return transwarp::detail::run_task<Result>(node_id, task, parent->get_future());
806 template<
typename Result,
typename Task,
typename ParentResultType>
810 return transwarp::detail::run_task<Result>(node_id, task, parent->get_future());
814 template<
int total,
int... n>
816 template<
typename Result,
typename Task,
typename... ParentResults>
819 return transwarp::detail::run_task<Result>(node_id, task, std::get<n>(
parents)->get_future().get()...);
825 template<
typename Result,
typename Task,
typename ParentResultType>
828 std::vector<ParentResultType> results;
829 results.reserve(
parents.size());
831 results.emplace_back(parent->get_future().get());
833 return transwarp::detail::run_task<Result>(node_id, task, std::move(results));
837 template<
int total,
int... n>
839 template<
typename Result,
typename Task,
typename... ParentResults>
841 using parent_t =
typename std::remove_reference<decltype(std::get<0>(
parents))>::type;
842 parent_t parent = transwarp::detail::wait_for_any<parent_t>(std::get<n>(
parents)...);
844 return transwarp::detail::run_task<Result>(node_id, task, parent->get_future().get());
850 template<
typename Result,
typename Task,
typename ParentResultType>
854 return transwarp::detail::run_task<Result>(node_id, task, parent->get_future().get());
858 template<
int total,
int... n>
860 template<
typename Result,
typename Task,
typename... ParentResults>
863 get_all(std::get<n>(
parents)...);
864 return transwarp::detail::run_task<Result>(node_id, task);
866 template<
typename T,
typename... Args>
867 static void get_all(
const T& arg,
const Args& ...args) {
868 arg->get_future().get();
871 static void get_all() {}
876 template<
typename Result,
typename Task,
typename ParentResultType>
880 parent->get_future().get();
882 return transwarp::detail::run_task<Result>(node_id, task);
886 template<
int total,
int... n>
888 template<
typename Result,
typename Task,
typename... ParentResults>
890 using parent_t =
typename std::remove_reference<decltype(std::get<0>(
parents))>::type;
891 parent_t parent = transwarp::detail::wait_for_any<parent_t>(std::get<n>(
parents)...);
893 parent->get_future().get();
894 return transwarp::detail::run_task<Result>(node_id, task);
900 template<
typename Result,
typename Task,
typename ParentResultType>
904 parent->get_future().get();
905 return transwarp::detail::run_task<Result>(node_id, task);
912 template<
typename TaskType,
typename Result,
typename Task,
typename... ParentResults>
914 constexpr std::size_t n = std::tuple_size<std::tuple<std::shared_future<ParentResults>...>>::value;
916 work<Result>(node_id, task,
parents);
922 template<
typename TaskType,
typename Result,
typename Task,
typename ParentResultType>
925 work<Result>(node_id, task,
parents);
932 template<std::size_t end, std::size_t idx, std::size_t... i>
935 template<std::size_t end, std::size_t... i>
940 template<std::
size_t b, std::
size_t e>
945 template<
typename Functor,
typename... ParentResults>
948 template<std::size_t i, std::size_t... j,
typename Functor,
typename... ParentResults>
950 auto ptr = std::get<i>(t);
959 template<
typename Functor,
typename... ParentResults>
961 constexpr std::size_t n = std::tuple_size<std::tuple<std::shared_ptr<transwarp::task<ParentResults>>...>>::value;
962 using index_t =
typename transwarp::detail::index_range<0, n>::type;
963 transwarp::detail::call_with_each_index(index_t(), f, t);
967 template<
typename Functor,
typename ParentResultType>
984 transwarp::detail::node_manip::add_parent(node_, task.get_node());
985 if (node_.
get_level() <= task.get_node()->get_level()) {
987 transwarp::detail::node_manip::set_level(node_, task.get_node()->get_level() + 1);
1000 task.set_node_id(id_++);
1008 explicit graph_visitor(std::vector<transwarp::edge>& graph) noexcept
1012 const std::shared_ptr<transwarp::node>&
node = task.get_node();
1013 for (
const std::shared_ptr<transwarp::node>& parent : node->get_parents()) {
1014 graph_.emplace_back(parent, node);
1018 std::vector<transwarp::edge>& graph_;
1024 : reset_(reset), executor_(executor) {}
1027 task.schedule_impl(reset_, executor_);
1045 : enabled_(enabled) {}
1048 task.cancel(enabled_);
1057 : executor_(std::move(executor)) {}
1060 task.set_executor(executor_);
1063 std::shared_ptr<transwarp::executor> executor_;
1070 task.remove_executor();
1077 : priority_(priority) {}
1080 task.set_priority(priority_);
1083 std::size_t priority_;
1090 task.reset_priority();
1097 : custom_data_(std::move(custom_data)) {}
1100 task.set_custom_data(custom_data_);
1103 std::shared_ptr<void> custom_data_;
1110 task.remove_custom_data();
1120 tasks_.push_back(&task);
1123 std::vector<transwarp::itask*>& tasks_;
1129 : visitor_(visitor) {}
1132 task.visit_depth(visitor_);
1135 const std::function<void(transwarp::itask&)>& visitor_;
1147 template<
typename TaskType,
typename Functor,
typename... ParentResults>
1149 static_assert(std::is_same<TaskType, transwarp::root_type>::value ||
1150 std::is_same<TaskType, transwarp::accept_type>::value ||
1151 std::is_same<TaskType, transwarp::accept_any_type>::value ||
1152 std::is_same<TaskType, transwarp::consume_type>::value ||
1153 std::is_same<TaskType, transwarp::consume_any_type>::value ||
1154 std::is_same<TaskType, transwarp::wait_type>::value ||
1155 std::is_same<TaskType, transwarp::wait_any_type>::value,
1156 "Invalid task type, must be one of: root, accept, accept_any, consume, consume_any, wait, wait_any");
1159 template<
typename Functor,
typename... ParentResults>
1161 static_assert(
sizeof...(ParentResults) == 0,
"A root task cannot have parent tasks");
1162 using type = decltype(std::declval<Functor>()());
1165 template<
typename Functor,
typename... ParentResults>
1167 static_assert(
sizeof...(ParentResults) > 0,
"An accept task must have at least one parent");
1168 using type = decltype(std::declval<Functor>()(std::declval<std::shared_future<ParentResults>>()...));
1171 template<
typename Functor,
typename ParentResultType>
1173 using type = decltype(std::declval<Functor>()(std::declval<std::vector<std::shared_future<ParentResultType>>>()));
1176 template<
typename Functor,
typename... ParentResults>
1178 static_assert(
sizeof...(ParentResults) > 0,
"An accept_any task must have at least one parent");
1179 using arg_t =
typename std::tuple_element<0, std::tuple<ParentResults...>>::type;
1180 using type = decltype(std::declval<Functor>()(std::declval<std::shared_future<arg_t>>()));
1183 template<
typename Functor,
typename ParentResultType>
1185 using type = decltype(std::declval<Functor>()(std::declval<std::shared_future<ParentResultType>>()));
1188 template<
typename Functor,
typename... ParentResults>
1190 static_assert(
sizeof...(ParentResults) > 0,
"A consume task must have at least one parent");
1191 using type = decltype(std::declval<Functor>()(std::declval<ParentResults>()...));
1194 template<
typename Functor,
typename ParentResultType>
1196 using type = decltype(std::declval<Functor>()(std::declval<std::vector<ParentResultType>>()));
1199 template<
typename Functor,
typename... ParentResults>
1201 static_assert(
sizeof...(ParentResults) > 0,
"A consume_any task must have at least one parent");
1202 using arg_t =
typename std::tuple_element<0, std::tuple<ParentResults...>>::type;
1203 using type = decltype(std::declval<Functor>()(std::declval<arg_t>()));
1206 template<
typename Functor,
typename ParentResultType>
1208 using type = decltype(std::declval<Functor>()(std::declval<ParentResultType>()));
1211 template<
typename Functor,
typename... ParentResults>
1213 static_assert(
sizeof...(ParentResults) > 0,
"A wait task must have at least one parent");
1214 using type = decltype(std::declval<Functor>()());
1217 template<
typename Functor,
typename ParentResultType>
1219 using type = decltype(std::declval<Functor>()());
1222 template<
typename Functor,
typename... ParentResults>
1224 static_assert(
sizeof...(ParentResults) > 0,
"A wait_any task must have at least one parent");
1225 using type = decltype(std::declval<Functor>()());
1228 template<
typename Functor,
typename ParentResultType>
1230 using type = decltype(std::declval<Functor>()());
1233 template<
bool is_transwarp_functor>
1238 template<
typename Functor>
1239 void operator()(Functor&
functor, std::shared_ptr<transwarp::node>
node)
const noexcept {
1240 functor.transwarp_node_ = std::move(node);
1246 template<
typename Functor>
1247 void operator()(Functor&, std::shared_ptr<transwarp::node>)
const noexcept {}
1251 template<
typename Functor>
1257 template<
typename ResultType,
typename Value>
1259 std::promise<ResultType> promise;
1260 promise.set_value(std::forward<Value>(value));
1261 return promise.get_future();
1266 std::promise<void> promise;
1267 promise.set_value();
1268 return promise.get_future();
1272 template<
typename ResultType>
1277 std::promise<ResultType> promise;
1278 promise.set_exception(exception);
1279 return promise.get_future();
1284 template<
typename... ParentResults>
1286 using type = std::tuple<std::shared_ptr<transwarp::task<ParentResults>>...>;
1290 template<
typename ParentResultType>
1291 struct parents<std::vector<std::shared_ptr<transwarp::task<ParentResultType>>>> {
1292 using type = std::vector<std::shared_ptr<transwarp::task<ParentResultType>>>;
1296 template<
typename ResultType,
typename TaskType>
1300 template<
typename Task,
typename Parents>
1301 void call(std::size_t node_id,
1302 const std::weak_ptr<Task>&
task,
1304 promise_.set_value(transwarp::detail::call<TaskType, ResultType>(node_id, task, parents));
1307 std::promise<ResultType> promise_;
1310 template<
typename TaskType>
1314 template<
typename Task,
typename Parents>
1315 void call(std::size_t node_id,
1316 const std::weak_ptr<Task>&
task,
1318 transwarp::detail::call<TaskType, void>(node_id, task, parents);
1319 promise_.set_value();
1322 std::promise<void> promise_;
1326 template<
typename ResultType,
typename TaskType,
typename Task,
typename Parents>
1330 runner(std::size_t node_id,
1331 const std::weak_ptr<Task>&
task,
1332 const typename transwarp::decay<Parents>::type&
parents)
1333 : node_id_(node_id),
1338 std::future<ResultType> get_future() {
1339 return this->promise_.get_future();
1343 if (
const std::shared_ptr<Task> t = task_.lock()) {
1347 this->call(node_id_, task_, parents_);
1349 this->promise_.set_exception(std::current_exception());
1350 if (
const std::shared_ptr<Task> t = task_.lock()) {
1354 this->promise_.set_exception(std::current_exception());
1356 if (
const std::shared_ptr<Task> t = task_.lock()) {
1362 const std::size_t node_id_;
1363 const std::weak_ptr<Task> task_;
1364 const typename transwarp::decay<Parents>::type parents_;
1385 return "transwarp::sequential";
1389 void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&)
override {
1399 explicit parallel(std::size_t n_threads)
1411 return "transwarp::parallel";
1415 void execute(
const std::function<
void()>&
functor,
const std::shared_ptr<transwarp::node>&)
override {
1429 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
1431 public std::enable_shared_from_this<task_impl_base<ResultType, TaskType, Functor, ParentResults...>> {
1437 using result_type = ResultType;
1446 executor_ = std::move(executor);
1447 transwarp::detail::node_manip::set_executor(*node_, std::shared_ptr<std::string>(
new std::string(executor_->get_name())));
1455 visit_depth_all(visitor);
1462 transwarp::detail::node_manip::set_executor(*node_,
nullptr);
1469 visit_depth_all(visitor);
1476 transwarp::detail::node_manip::set_priority(*node_, priority);
1484 visit_depth_all(visitor);
1490 transwarp::detail::node_manip::set_priority(*node_, 0);
1497 visit_depth_all(visitor);
1507 transwarp::detail::node_manip::set_custom_data(*node_, std::move(custom_data));
1515 visit_depth_all(visitor);
1521 transwarp::detail::node_manip::set_custom_data(*node_,
nullptr);
1528 visit_depth_all(visitor);
1532 const std::shared_future<result_type>&
get_future() const noexcept
override {
1537 const std::shared_ptr<transwarp::node>&
get_node() const noexcept
override {
1544 check_listener(listener);
1545 for (std::vector<std::shared_ptr<transwarp::listener>>& l : listeners_) {
1546 l.push_back(listener);
1553 check_listener(listener);
1554 listeners_[get_event_index(event)].push_back(std::move(listener));
1560 check_listener(listener);
1561 for (std::vector<std::shared_ptr<transwarp::listener>>& l : listeners_) {
1562 l.erase(std::remove(l.begin(), l.end(), listener), l.end());
1569 check_listener(listener);
1570 std::vector<std::shared_ptr<transwarp::listener>>& l = listeners_[get_event_index(event)];
1571 l.erase(std::remove(l.begin(), l.end(), listener), l.end());
1577 listeners_[get_event_index(event)].clear();
1583 for (std::vector<std::shared_ptr<transwarp::listener>>& l : listeners_) {
1593 this->schedule_impl(
true);
1602 this->schedule_impl(reset);
1610 this->schedule_impl(
true, &executor);
1619 this->schedule_impl(reset, &executor);
1661 schedule_all_impl(
true, type);
1669 schedule_all_impl(
true, type, &executor);
1678 schedule_all_impl(reset_all, type);
1687 schedule_all_impl(reset_all, type, &executor);
1694 future_ = transwarp::detail::make_future_with_exception<result_type>(exception);
1695 schedule_mode_ =
false;
1701 return future_.valid();
1715 return future_.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
1726 future_ = std::shared_future<result_type>();
1727 transwarp::detail::node_manip::set_canceled(*node_,
false);
1728 schedule_mode_ =
true;
1735 visit_depth_all(visitor);
1741 void cancel(
bool enabled) noexcept
override {
1742 transwarp::detail::node_manip::set_canceled(*node_, enabled);
1750 visit_depth_all(visitor);
1757 std::vector<transwarp::edge> graph;
1765 template<
typename F>
1768 : node_(new transwarp::
node),
1769 functor_(std::forward<F>(
functor)),
1770 parents_(std::move(
parents)...)
1772 init(has_name, std::move(name));
1775 template<
typename F,
typename P>
1778 : node_(new transwarp::
node),
1779 functor_(std::forward<F>(
functor)),
1780 parents_(std::move(parents))
1782 if (parents_.empty()) {
1785 init(has_name, std::move(name));
1788 void init(
bool has_name, std::string name) {
1789 transwarp::detail::node_manip::set_type(*node_, task_type::value);
1790 transwarp::detail::node_manip::set_name(*node_, (has_name ? std::shared_ptr<std::string>(
new std::string(std::move(name))) :
nullptr));
1794 visit_depth(visitor);
1800 if (future_.valid() && future_.wait_for(std::chrono::seconds(0)) != std::future_status::ready) {
1807 if (!future_.valid()) {
1812 bool schedule_mode_ =
true;
1813 std::shared_future<result_type> future_;
1817 template<
typename R,
typename Y,
typename T,
typename P>
1820 template<
typename R,
typename T,
typename... A>
1824 void set_node_id(std::size_t
id) noexcept
override {
1825 transwarp::detail::node_manip::set_id(*node_,
id);
1833 if (schedule_mode_ && (reset || !future_.valid())) {
1835 transwarp::detail::node_manip::set_canceled(*node_,
false);
1837 std::weak_ptr<task_impl_base>
self = this->shared_from_this();
1839 std::shared_ptr<runner_t> runner = std::shared_ptr<runner_t>(
new runner_t(node_->get_id(),
self, parents_));
1841 future_ = runner->get_future();
1843 executor_->execute([runner]{ (*runner)(); }, node_);
1844 }
else if (executor) {
1845 executor->execute([runner]{ (*runner)(); }, node_);
1860 visit_breadth_all(visitor);
1863 visit_depth_all(visitor);
1871 template<
typename Visitor>
1872 void visit_breadth_all(Visitor& visitor) {
1873 if (breadth_tasks_.empty()) {
1874 breadth_tasks_.reserve(node_->get_id() + 1);
1878 const std::size_t l_level = l->get_node()->get_level();
1879 const std::size_t l_id = l->get_node()->get_id();
1880 const std::size_t r_level = r->get_node()->get_level();
1881 const std::size_t r_id = r->get_node()->get_id();
1882 return std::tie(l_level, l_id) < std::tie(r_level, r_id);
1884 std::sort(breadth_tasks_.begin(), breadth_tasks_.end(), compare);
1892 template<
typename Visitor>
1893 void visit_depth_all(Visitor& visitor) {
1894 if (depth_tasks_.empty()) {
1895 depth_tasks_.reserve(node_->get_id() + 1);
1905 void visit_depth(
const std::function<
void(
transwarp::itask&)>& visitor)
override {
1914 void unvisit() noexcept
override {
1923 const std::size_t index =
static_cast<std::size_t
>(event);
1924 if (index >= static_cast<std::size_t>(transwarp::event_type::count)) {
1932 for (
const std::shared_ptr<transwarp::listener>& listener : listeners_[static_cast<std::size_t>(event)]) {
1933 listener->handle_event(event, node_);
1938 void check_listener(
const std::shared_ptr<transwarp::listener>& listener)
const {
1944 std::shared_ptr<transwarp::node> node_;
1947 bool visited_ =
false;
1948 std::shared_ptr<transwarp::executor> executor_;
1949 std::vector<std::shared_ptr<transwarp::listener>> listeners_[
static_cast<std::size_t
>(transwarp::event_type::count)];
1950 std::vector<transwarp::itask*> depth_tasks_;
1951 std::vector<transwarp::itask*> breadth_tasks_;
1956 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
1963 using result_type = ResultType;
1967 void set_value(
const typename transwarp::decay<result_type>::type& value)
override {
1969 this->future_ = transwarp::detail::make_future_with_value<result_type>(value);
1970 this->schedule_mode_ =
false;
1975 void set_value(
typename transwarp::decay<result_type>::type&& value)
override {
1977 this->future_ = transwarp::detail::make_future_with_value<result_type>(std::move(value));
1978 this->schedule_mode_ =
false;
1984 typename transwarp::result<result_type>::type
get()
const override {
1986 return this->future_.get();
1991 template<
typename F>
1998 template<
typename F,
typename P>
2002 : transwarp::detail::task_impl_base<
result_type,
task_type, Functor, ParentResults...>(has_name, std::move(name), std::forward<F>(
functor), std::move(parents))
2008 template<
typename ResultType,
typename TaskType,
typename Functor,
typename... ParentResults>
2015 using result_type = ResultType&;
2019 void set_value(
typename transwarp::decay<result_type>::type& value)
override {
2020 this->ensure_task_not_running();
2021 this->future_ = transwarp::detail::make_future_with_value<result_type>(value);
2022 this->schedule_mode_ =
false;
2028 typename transwarp::result<result_type>::type
get()
const override {
2029 this->ensure_task_was_scheduled();
2030 return this->future_.get();
2035 template<
typename F>
2042 template<
typename F,
typename P>
2046 : transwarp::detail::task_impl_base<result_type,
task_type, Functor, ParentResults...>(has_name, std::move(name), std::forward<F>(
functor), std::move(parents))
2052 template<
typename TaskType,
typename Functor,
typename... ParentResults>
2059 using result_type = void;
2066 this->schedule_mode_ =
false;
2072 void get()
const override {
2074 this->future_.get();
2079 template<
typename F>
2086 template<
typename F,
typename P>
2090 : transwarp::detail::task_impl_base<
result_type,
task_type, Functor, ParentResults...>(has_name, std::move(name), std::forward<F>(
functor), std::move(parents))
2101 template<
typename TaskType,
typename Functor,
typename... ParentResults>
2112 template<
typename F>
2116 : transwarp::detail::task_impl_proxy<
result_type,
task_type, Functor, ParentResults...>(has_name, std::move(name), std::forward<F>(
functor), std::move(parents)...)
2121 template<
typename F,
typename P>
2124 : transwarp::detail::task_impl_proxy<
result_type,
task_type, Functor, ParentResults...>(has_name, std::move(name), std::forward<F>(
functor), std::move(parents))
2134 template<
typename TaskType_,
typename Functor_>
2135 std::shared_ptr<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>
2138 return std::shared_ptr<task_t>(
new task_t(
true, std::move(name), std::forward<Functor_>(
functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<task_impl*>(
this)->shared_from_this())));
2142 template<
typename TaskType_,
typename Functor_>
2143 std::shared_ptr<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>
2146 return std::shared_ptr<task_t>(
new task_t(
false,
"", std::forward<Functor_>(
functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<task_impl*>(
this)->shared_from_this())));
2154 template<
typename ResultType>
2156 public std::enable_shared_from_this<value_task<ResultType>> {
2166 template<
typename T>
2170 : node_(new transwarp::
node),
2171 future_(transwarp::detail::make_future_with_value<
result_type>(std::forward<T>(value)))
2173 transwarp::detail::node_manip::set_type(*node_, task_type::value);
2174 transwarp::detail::node_manip::set_name(*node_, (has_name ? std::shared_ptr<std::string>(
new std::string(std::move(name))) :
nullptr));
2184 template<
typename TaskType_,
typename Functor_>
2185 std::shared_ptr<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>
2188 return std::shared_ptr<task_t>(
new task_t(
true, std::move(name), std::forward<Functor_>(
functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<value_task*>(
this)->shared_from_this())));
2192 template<
typename TaskType_,
typename Functor_>
2193 std::shared_ptr<transwarp::task_impl<TaskType_, typename std::decay<Functor_>::type,
result_type>>
2196 return std::shared_ptr<task_t>(
new task_t(
false,
"", std::forward<Functor_>(
functor), std::dynamic_pointer_cast<
transwarp::task<result_type>>(const_cast<value_task*>(
this)->shared_from_this())));
2214 transwarp::detail::node_manip::set_priority(*node_, priority);
2225 transwarp::detail::node_manip::set_priority(*node_, 0);
2239 transwarp::detail::node_manip::set_custom_data(*node_, std::move(custom_data));
2250 transwarp::detail::node_manip::set_custom_data(*node_,
nullptr);
2259 const std::shared_future<result_type>&
get_future() const noexcept
override {
2264 const std::shared_ptr<transwarp::node>&
get_node() const noexcept
override {
2323 void set_value(
const typename transwarp::decay<result_type>::type& value)
override {
2324 future_ = transwarp::detail::make_future_with_value<result_type>(value);
2328 void set_value(
typename transwarp::decay<result_type>::type&& value)
override {
2329 future_ = transwarp::detail::make_future_with_value<result_type>(std::move(value));
2334 future_ = transwarp::detail::make_future_with_exception<result_type>(exception);
2356 typename transwarp::result<result_type>::type
get()
const override {
2357 return future_.get();
2380 void set_node_id(std::size_t
id) noexcept
override {
2381 transwarp::detail::node_manip::set_id(*node_,
id);
2388 void visit_depth(
const std::function<
void(
transwarp::itask&)>& visitor)
override {
2396 void unvisit() noexcept
override {
2400 std::shared_ptr<transwarp::node> node_;
2401 std::shared_future<result_type> future_;
2402 bool visited_ =
false;
2407 template<
typename TaskType,
typename Functor,
typename... Parents>
2408 std::shared_ptr<transwarp::task_impl<TaskType, typename std::decay<Functor>::type,
typename Parents::result_type...>>
2409 make_task(TaskType, std::string name, Functor&&
functor, std::shared_ptr<Parents>... parents) {
2411 return std::shared_ptr<task_t>(
new task_t(
true, std::move(name), std::forward<Functor>(
functor), std::move(parents)...));
2415 template<
typename TaskType,
typename Functor,
typename... Parents>
2416 std::shared_ptr<transwarp::task_impl<TaskType, typename std::decay<Functor>::type,
typename Parents::result_type...>>
2419 return std::shared_ptr<task_t>(
new task_t(
false,
"", std::forward<Functor>(
functor), std::move(parents)...));
2424 template<
typename TaskType,
typename Functor,
typename ParentType>
2425 std::shared_ptr<transwarp::task_impl<TaskType, typename std::decay<Functor>::type, std::vector<ParentType>>>
2428 return std::shared_ptr<task_t>(
new task_t(
true, std::move(name), std::forward<Functor>(
functor), std::move(parents)));
2432 template<
typename TaskType,
typename Functor,
typename ParentType>
2433 std::shared_ptr<transwarp::task_impl<TaskType, typename std::decay<Functor>::type, std::vector<ParentType>>>
2436 return std::shared_ptr<task_t>(
new task_t(
false,
"", std::forward<Functor>(
functor), std::move(parents)));
2441 template<
typename Value>
2442 std::shared_ptr<transwarp::value_task<typename transwarp::decay<Value>::type>>
2445 return std::shared_ptr<task_t>(
new task_t(
true, std::move(name), std::forward<Value>(value)));
2449 template<
typename Value>
2450 std::shared_ptr<transwarp::value_task<typename transwarp::decay<Value>::type>>
2453 return std::shared_ptr<task_t>(
new task_t(
false,
"", 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:1512
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:2254
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:529
void cancel_all(bool) noexceptoverride
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2370
void operator()(const transwarp::itask &task) const
Definition: transwarp.h:983
Node manipulation.
Definition: transwarp.h:479
TaskType task_type
The task type.
Definition: transwarp.h:2012
void remove_listeners(transwarp::event_type) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2281
Generates a graph.
Definition: transwarp.h:1007
The consume type. Used for tag dispatch.
Definition: transwarp.h:114
Determines the result type of the Functor dispatching on the task type.
Definition: transwarp.h:1148
void schedule_all(transwarp::executor &) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2302
Removes the executor from the given task.
Definition: transwarp.h:1067
Definition: transwarp.h:930
void reset_priority_all() override
Resets the priority of all tasks to 0.
Definition: transwarp.h:1494
Definition: transwarp.h:139
Just after a task was canceled (handle_event called on thread that task is run on) ...
TaskType task_type
The task type.
Definition: transwarp.h:2056
A callable to run a task given its parents.
Definition: transwarp.h:1327
void set_exception(std::exception_ptr exception) override
Assigns an exception to this task.
Definition: transwarp.h:2333
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:1642
void ensure_task_was_scheduled() const
Checks if the task was scheduled and throws transwarp::control_error if it's not. ...
Definition: transwarp.h:1806
Sets parents and level of the node.
Definition: transwarp.h:979
std::shared_ptr< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type > > then(TaskType_, std::string name, Functor_ &&functor) const
Creates a continuation to this task.
Definition: transwarp.h:2136
std::shared_ptr< transwarp::value_task< typename transwarp::decay< Value >::type > > make_value_task(std::string name, Value &&value)
A factory function to create a new value task.
Definition: transwarp.h:2443
Definition: transwarp.h:1297
void set_executor(std::shared_ptr< transwarp::executor >) override
No-op because a value task never runs.
Definition: transwarp.h:2200
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:1452
bool was_scheduled() const noexceptoverride
Returns whether the task was scheduled and not reset afterwards. This means that the underlying futur...
Definition: transwarp.h:1700
void cancel(bool) noexceptoverride
No-op because a value task never runs.
Definition: transwarp.h:2367
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:2299
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:1651
std::string get_name() const override
Returns the name of the executor.
Definition: transwarp.h:1410
Assigns a priority to the given task.
Definition: transwarp.h:1075
void set_value(const typename transwarp::decay< result_type >::type &value) override
Assigns a value to this task.
Definition: transwarp.h:2323
void schedule(transwarp::executor &executor) override
Schedules this task for execution using the provided executor. The task-specific executor gets preced...
Definition: transwarp.h:1608
Assigns an executor to the given task.
Definition: transwarp.h:1055
Unvisits the given task.
Definition: transwarp.h:1139
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:2213
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:1748
void remove_custom_data() override
Removes custom data from this task.
Definition: transwarp.h:1519
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:2244
std::tuple< std::shared_future< ParentResults >...> get_futures(const std::tuple< std::shared_ptr< transwarp::task< ParentResults >>...> &input)
Returns the futures from the given tuple of tasks.
Definition: transwarp.h:630
void set_value(typename transwarp::decay< result_type >::type &&value) override
Assigns a value to this task.
Definition: transwarp.h:2328
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:1676
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:1625
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:1441
value_task(bool has_name, std::string name, T &&value)
A value task is defined by name and value. Note: Don't use this constructor directly, use transwarp::make_value_task.
Definition: transwarp.h:2169
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:2235
The task class.
Definition: transwarp.h:405
Definition: transwarp.h:941
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:1685
void reset_priority_all() override
Resets the priority of all tasks to 0.
Definition: transwarp.h:2229
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:1967
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:1474
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:1252
void reset() override
Resets this task.
Definition: transwarp.h:1724
const std::vector< std::shared_ptr< node > > & get_parents() const noexcept
The task's parents (may be empty)
Definition: transwarp.h:182
Just before a task's functor is invoked (handle_event called on thread that task is run on) ...
Definition: transwarp.h:928
The task's functor accepts the first parent future that becomes ready.
std::shared_ptr< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type > > then(TaskType_, Functor_ &&functor) const
Creates a continuation to this task. Overload for omitting for task name.
Definition: transwarp.h:2144
The consume_any type. Used for tag dispatch.
Definition: transwarp.h:118
ResultType result_type
The result type of this task.
Definition: transwarp.h:1963
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:1502
bool was_scheduled() const noexceptoverride
Returns true because a value task is scheduled once on construction.
Definition: transwarp.h:2338
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:1415
void wait_for_all(const std::vector< std::shared_ptr< transwarp::task< ParentResultType >>> &parents)
Waits for all parents to finish.
Definition: transwarp.h:675
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:1532
constexpr transwarp::accept_type accept
The accept task tag.
Definition: transwarp.h:107
TaskType task_type
The task type.
Definition: transwarp.h:1434
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:2320
void remove_listeners() override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2284
bool has_result() const noexceptoverride
Returns whether this task contains a result.
Definition: transwarp.h:1719
The listener interface to listen to events raised by tasks.
Definition: transwarp.h:310
Exception thrown when a task is canceled.
Definition: transwarp.h:51
TaskType task_type
The task type.
Definition: transwarp.h:2105
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:1706
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:1551
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:1258
std::string get_name() const override
Returns the name of the executor.
Definition: transwarp.h:1384
void schedule() override
Schedules this task for execution on the caller thread. The task-specific executor gets precedence if...
Definition: transwarp.h:1591
void add_listener(std::shared_ptr< transwarp::listener >) override
No-op because a value task doesn't raise events.
Definition: transwarp.h:2269
void add_listener(std::shared_ptr< transwarp::listener > listener) override
Adds a new listener for all event types.
Definition: transwarp.h:1542
void ensure_task_not_running() const
Checks if the task is currently running and throws transwarp::control_error if it is...
Definition: transwarp.h:1799
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:1107
void schedule_all(transwarp::executor &, bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2308
Resets the given task.
Definition: transwarp.h:1035
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:446
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
Exception thrown when a task is used in unintended ways.
Definition: transwarp.h:78
Resets the priority of the given task.
Definition: transwarp.h:1087
void schedule() override
No-op because a value task never runs.
Definition: transwarp.h:2287
Returns the result type of a std::shared_future<T>
Definition: transwarp.h:398
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:2272
void wait() const override
No-op because a value task never runs.
Definition: transwarp.h:2343
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:1667
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.
Definition: transwarp.h:1957
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:460
The base task class that contains the functionality that can be used with all result types (void and ...
Definition: transwarp.h:1430
Definition: transwarp.h:616
The task's functor consumes all parent results.
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:2275
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:2219
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:2311
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:2296
A value task that stores a single value and doesn't require scheduling. Value tasks should be created...
Definition: transwarp.h:2155
void reset_priority() override
Resets the task priority to 0.
Definition: transwarp.h:2224
void remove_listeners(transwarp::event_type event) override
Removes all listeners for the given event type.
Definition: transwarp.h:1575
void remove_listener(const std::shared_ptr< transwarp::listener > &listener) override
Removes the listener for all event types.
Definition: transwarp.h:1558
Determines the type of the parents.
Definition: transwarp.h:1285
const std::shared_ptr< transwarp::node > & transwarp_node() const noexcept
The node associated to the task.
Definition: transwarp.h:454
Parent wait_for_any(const std::shared_ptr< transwarp::task< ParentResults >> &...parents)
Waits for the first parent to finish.
Definition: transwarp.h:698
void reset_all() override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2364
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:1567
Assigns custom data to the given task.
Definition: transwarp.h:1095
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:1692
void cancel_all_but_one(const std::shared_ptr< transwarp::task< OneResult >> &one, const std::vector< std::shared_ptr< transwarp::task< ParentResultType >>> &parents)
Cancels all tasks but one.
Definition: transwarp.h:737
Definition: transwarp.h:756
Removes reference and const from a type.
Definition: transwarp.h:391
void remove_listeners() override
Removes all listeners.
Definition: transwarp.h:1581
const std::shared_ptr< void > & get_custom_data() const noexcept
The custom task data (may be null)
Definition: transwarp.h:192
std::shared_ptr< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type > > then(TaskType_, std::string name, Functor_ &&functor) const
Creates a continuation to this task.
Definition: transwarp.h:2186
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.
Definition: transwarp.h:960
void reset_priority() override
Resets the task priority to 0.
Definition: transwarp.h:1488
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:2314
void schedule_all(transwarp::schedule_type, bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2317
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:1659
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:1756
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:2019
void schedule(transwarp::executor &) override
No-op because a value task never runs.
Definition: transwarp.h:2290
void reset_all() override
Resets all tasks in the graph.
Definition: transwarp.h:1732
Definition: transwarp.h:747
ResultType result_type
The result type of this task.
Definition: transwarp.h:2162
Executor for parallel execution. Uses a simple thread pool.
Definition: transwarp.h:1396
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:1481
void schedule(bool reset) override
Schedules this task for execution on the caller thread. The task-specific executor gets precedence if...
Definition: transwarp.h:1600
virtual std::string get_name() const =0
Returns the name of the executor.
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
Runs a task which is wrapped by the given functor. The functor only captures one shared pointer and c...
void execute(const std::function< void()> &functor, const std::shared_ptr< transwarp::node > &) override
Runs the functor on the current thread.
Definition: transwarp.h:1389
void remove_executor() override
Removes the executor from this task.
Definition: transwarp.h:1459
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
std::shared_ptr< transwarp::task_impl< TaskType, typename std::decay< Functor >::type, typename Parents::result_type...> > make_task(TaskType, std::string name, Functor &&functor, std::shared_ptr< Parents >...parents)
A factory function to create a new task.
Definition: transwarp.h:2409
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). The implementer needs to ensure that this never throws exceptions.
bool is_ready() const override
Returns true because a value task is always ready.
Definition: transwarp.h:2346
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:2102
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:2278
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:1741
Schedules using the given executor.
Definition: transwarp.h:1022
Result call(std::size_t node_id, const Task &task, const std::tuple< std::shared_ptr< transwarp::task< ParentResults >>...> &parents)
Calls the functor of the given task with the results from the tuple of parents. Throws transwarp::tas...
Definition: transwarp.h:913
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:2249
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:1975
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:1633
static Result work(std::size_t node_id, const Task &task, const std::tuple< std::shared_ptr< transwarp::task< ParentResults >>...> &parents)
Definition: transwarp.h:840
schedule_type
Determines in which order tasks are scheduled in the graph.
Definition: transwarp.h:321
The task's functor accepts all parent futures.
Applies final bookkeeping to the task.
Definition: transwarp.h:995
void remove_executor_all() override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2209
typename transwarp::detail::functor_result< TaskType, Functor, ParentResults...>::type result_type
The result type of this task.
Definition: transwarp.h:2108
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:1617
std::vector< transwarp::edge > get_graph() const override
Returns an empty graph because a value task doesn't have parents.
Definition: transwarp.h:2373
const std::shared_ptr< transwarp::node > & get_node() const noexceptoverride
Returns the associated node.
Definition: transwarp.h:1537
task_impl(bool has_name, std::string name, F &&functor, std::vector< std::shared_ptr< transwarp::task< P >>> parents)
A task is defined by name, functor, and parent tasks. Note: Don't use this constructor directly...
Definition: transwarp.h:2123
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:2063
std::shared_ptr< transwarp::task_impl< TaskType_, typename std::decay< Functor_ >::type, result_type > > then(TaskType_, Functor_ &&functor) const
Creates a continuation to this task. Overload for omitting the task name.
Definition: transwarp.h:2194
event_type
The task events that can be subscribed to using the listener interface.
Definition: transwarp.h:299
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:1525
void reset() override
No-op because a value task never runs.
Definition: transwarp.h:2361
std::shared_future< void > make_ready_future()
Returns a ready future.
Definition: transwarp.h:1265
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:2203
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:2259
Cancels or resumes the given task.
Definition: transwarp.h:1043
void remove_executor() override
No-op because a value task never runs.
Definition: transwarp.h:2206
void schedule(bool) override
No-op because a value task never runs.
Definition: transwarp.h:2293
void schedule_all(bool) override
No-op because a value task never runs and doesn't have parents.
Definition: transwarp.h:2305
Visits the given task using the visitor given in the constructor.
Definition: transwarp.h:1127
Pushes the given task into the vector of tasks.
Definition: transwarp.h:1115
Executor for sequential execution. Runs functors sequentially on the same thread. ...
Definition: transwarp.h:1372
bool has_result() const noexceptoverride
Returns true because a value task always contains a result.
Definition: transwarp.h:2351
task_impl(bool has_name, std::string name, F &&functor, std::shared_ptr< transwarp::task< ParentResults >>...parents)
A task is defined by name, functor, and parent tasks. Note: Don't use this constructor directly...
Definition: transwarp.h:2115
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:1273
void remove_executor_all() override
Removes the executor from all tasks.
Definition: transwarp.h:1466
const std::shared_ptr< transwarp::node > & get_node() const noexceptoverride
Returns the associated node.
Definition: transwarp.h:2264
bool is_ready() const override
Returns whether the task has finished processing. Should only be called if was_scheduled() is true...
Definition: transwarp.h:1713
An interface for the task class.
Definition: transwarp.h:328
Result run_task(std::size_t node_id, const std::weak_ptr< Task > &task, Args &&...args)
Runs the task with the given arguments, hence, invoking the task's functor.
Definition: transwarp.h:650