Cpp-Taskflow  2.3.0
task.hpp
1 #pragma once
2 
3 #include "graph.hpp"
4 
5 namespace tf {
6 
7 // ----------------------------------------------------------------------------
8 // Task
9 // ----------------------------------------------------------------------------
10 
22 class Task {
23 
24  friend class FlowBuilder;
25  friend class Taskflow;
26  friend class TaskView;
27 
28  public:
29 
33  Task() = default;
34 
38  Task(const Task& other);
39 
43  Task& operator = (const Task&);
44 
49 
53  bool operator == (const Task& rhs) const;
54 
58  bool operator != (const Task& rhs) const;
59 
63  const std::string& name() const;
64 
68  size_t num_successors() const;
69 
73  size_t num_dependents() const;
74 
78  size_t num_strong_dependents() const;
79 
83  size_t num_weak_dependents() const;
84 
92  Task& name(const std::string& name);
93 
103  template <typename C>
104  Task& work(C&& callable);
105 
115  template <typename... Ts>
116  Task& precede(Ts&&... tasks);
117 
127  template <typename... Ts>
128  Task& succeed(Ts&&... tasks);
129 
135  Task& reset();
136 
140  bool empty() const;
141 
145  bool has_work() const;
146 
150  template <typename V>
151  void for_each_successor(V&& visitor) const;
152 
156  template <typename V>
157  void for_each_dependent(V&& visitor) const;
158 
159  private:
160 
161  Task(Node&);
162  Task(Node*);
163 
164  Node* _node {nullptr};
165 
166  template <typename S>
167  void _gather(S&);
168 
169  template <typename S>
170  void _precede(S&);
171 
172  template <typename S>
173  void _succeed(S&);
174 };
175 
176 // Constructor
177 inline Task::Task(Node& node) : _node {&node} {
178 }
179 
180 // Constructor
181 inline Task::Task(Node* node) : _node {node} {
182 }
183 
184 // Constructor
185 inline Task::Task(const Task& rhs) : _node {rhs._node} {
186 }
187 
188 // Function: precede
189 template <typename... Ts>
190 Task& Task::precede(Ts&&... tgts) {
191  (_node->_precede(tgts._node), ...);
192  return *this;
193 }
194 
195 // Function: succeed
196 template <typename... Bs>
197 Task& Task::succeed(Bs&&... tgts) {
198  (tgts._node->_precede(_node), ...);
199  return *this;
200 }
201 
202 // Operator =
203 inline Task& Task::operator = (const Task& rhs) {
204  _node = rhs._node;
205  return *this;
206 }
207 
208 // Operator =
210  _node = ptr;
211  return *this;
212 }
213 
214 // Operator ==
215 inline bool Task::operator == (const Task& rhs) const {
216  return _node == rhs._node;
217 }
218 
219 // Operator !=
220 inline bool Task::operator != (const Task& rhs) const {
221  return _node != rhs._node;
222 }
223 
224 // Function: name
225 inline Task& Task::name(const std::string& name) {
226  _node->_name = name;
227  return *this;
228 }
229 
230 // Procedure: reset
231 inline Task& Task::reset() {
232  _node = nullptr;
233  return *this;
234 }
235 
236 // Function: name
237 inline const std::string& Task::name() const {
238  return _node->_name;
239 }
240 
241 // Function: num_dependents
242 inline size_t Task::num_dependents() const {
243  return _node->num_dependents();
244 }
245 
246 // Function: num_strong_dependents
247 inline size_t Task::num_strong_dependents() const {
248  return _node->num_strong_dependents();
249 }
250 
251 // Function: num_weak_dependents
252 inline size_t Task::num_weak_dependents() const {
253  return _node->num_weak_dependents();
254 }
255 
256 // Function: num_successors
257 inline size_t Task::num_successors() const {
258  return _node->num_successors();
259 }
260 
261 // Function: empty
262 inline bool Task::empty() const {
263  return _node == nullptr;
264 }
265 
266 // Function: has_work
267 inline bool Task::has_work() const {
268  return _node ? _node->_work.index() != 0 : false;
269 }
270 
271 // Function: for_each_successor
272 template <typename V>
273 void Task::for_each_successor(V&& visitor) const {
274  for(size_t i=0; i<_node->_successors.size(); ++i) {
275  visitor(Task(_node->_successors[i]));
276  }
277 }
278 
279 // Function: for_each_dependent
280 template <typename V>
281 void Task::for_each_dependent(V&& visitor) const {
282  for(size_t i=0; i<_node->_dependents.size(); ++i) {
283  visitor(Task(_node->_dependents[i]));
284  }
285 }
286 
287 // ----------------------------------------------------------------------------
288 
296 class TaskView {
297 
298  friend class Executor;
299 
300  public:
301 
305  TaskView() = default;
306 
310  TaskView(const Task& task);
311 
315  TaskView(const TaskView& other);
316 
320  TaskView& operator = (const TaskView& other);
321 
325  TaskView& operator = (const Task& other);
326 
331 
335  bool operator == (const TaskView&) const;
336 
340  bool operator != (const TaskView&) const;
341 
345  const std::string& name() const;
346 
350  size_t num_successors() const;
351 
355  size_t num_dependents() const;
356 
360  size_t num_strong_dependents() const;
361 
365  size_t num_weak_dependents() const;
366 
370  void reset();
371 
375  bool empty() const;
376 
380  template <typename V>
381  void for_each_successor(V&& visitor) const;
382 
386  template <typename V>
387  void for_each_dependent(V&& visitor) const;
388 
389  private:
390 
391  TaskView(Node*);
392 
393  Node* _node {nullptr};
394 };
395 
396 // Constructor
397 inline TaskView::TaskView(Node* node) : _node {node} {
398 }
399 
400 // Constructor
401 inline TaskView::TaskView(const TaskView& rhs) : _node {rhs._node} {
402 }
403 
404 // Constructor
405 inline TaskView::TaskView(const Task& task) : _node {task._node} {
406 }
407 
408 // Operator =
410  _node = rhs._node;
411  return *this;
412 }
413 
414 // Operator =
415 inline TaskView& TaskView::operator = (const Task& rhs) {
416  _node = rhs._node;
417  return *this;
418 }
419 
420 // Operator =
422  _node = ptr;
423  return *this;
424 }
425 
426 // Function: name
427 inline const std::string& TaskView::name() const {
428  return _node->_name;
429 }
430 
431 // Function: num_dependents
432 inline size_t TaskView::num_dependents() const {
433  return _node->num_dependents();
434 }
435 
436 // Function: num_strong_dependents
437 inline size_t TaskView::num_strong_dependents() const {
438  return _node->num_strong_dependents();
439 }
440 
441 // Function: num_weak_dependents
442 inline size_t TaskView::num_weak_dependents() const {
443  return _node->num_weak_dependents();
444 }
445 
446 // Function: num_successors
447 inline size_t TaskView::num_successors() const {
448  return _node->num_successors();
449 }
450 
451 // Function: reset
452 inline void TaskView::reset() {
453  _node = nullptr;
454 }
455 
456 // Function: empty
457 inline bool TaskView::empty() const {
458  return _node == nullptr;
459 }
460 
461 // Operator ==
462 inline bool TaskView::operator == (const TaskView& rhs) const {
463  return _node == rhs._node;
464 }
465 
466 // Operator !=
467 inline bool TaskView::operator != (const TaskView& rhs) const {
468  return _node != rhs._node;
469 }
470 
471 // Function: for_each_successor
472 template <typename V>
473 void TaskView::for_each_successor(V&& visitor) const {
474  for(size_t i=0; i<_node->_successors.size(); ++i) {
475  visitor(TaskView(_node->_successors[i]));
476  }
477 }
478 
479 // Function: for_each_dependent
480 template <typename V>
481 void TaskView::for_each_dependent(V&& visitor) const {
482  for(size_t i=0; i<_node->_dependents.size(); ++i) {
483  visitor(TaskView(_node->_dependents[i]));
484  }
485 }
486 
487 } // end of namespace tf. ---------------------------------------------------
488 
489 
size_t num_dependents() const
queries the number of predecessors of the task
Definition: task.hpp:242
Task & reset()
resets the task handle to null
Definition: task.hpp:231
TaskView()=default
constructs an empty task view
bool operator!=(const TaskView &) const
compares if two taskviews are associated with different tasks
Definition: task.hpp:467
void for_each_dependent(V &&visitor) const
applies an visitor callable to each dependents of the task
Definition: task.hpp:481
size_t num_weak_dependents() const
queries the number of weak dependents of the task
Definition: task.hpp:442
size_t num_successors() const
queries the number of successors of the task
Definition: task.hpp:447
Definition: taskflow.hpp:5
bool operator==(const Task &rhs) const
compares if two tasks are associated with the same graph node
Definition: task.hpp:215
Task & succeed(Ts &&... tasks)
adds precedence links from other tasks to this
Definition: task.hpp:197
void for_each_successor(V &&visitor) const
applies an visitor callable to each successor of the task
Definition: task.hpp:473
bool operator!=(const Task &rhs) const
compares if two tasks are not associated with the same graph node
Definition: task.hpp:220
bool empty() const
queries if the task view is empty
Definition: task.hpp:457
size_t num_strong_dependents() const
queries the number of strong dependents of the task
Definition: task.hpp:437
Task & operator=(const Task &)
replaces the contents with a copy of the other task
Definition: task.hpp:203
void for_each_dependent(V &&visitor) const
applies an visitor callable to each dependents of the task
Definition: task.hpp:281
the class to create a task dependency graph
Definition: core/taskflow.hpp:18
const std::string & name() const
queries the name of the task
Definition: task.hpp:237
an immutable accessor class to a task node, mainly used in the tf::ExecutorObserver interface...
Definition: task.hpp:296
bool empty() const
queries if the task handle points to a task node
Definition: task.hpp:262
void reset()
resets to an empty view
Definition: task.hpp:452
size_t num_strong_dependents() const
queries the number of strong dependents of the task
Definition: task.hpp:247
Building blocks of a task dependency graph.
Definition: flow_builder.hpp:13
size_t num_successors() const
queries the number of successors of the task
Definition: task.hpp:257
size_t num_weak_dependents() const
queries the number of weak dependents of the task
Definition: task.hpp:252
task handle to a node in a task dependency graph
Definition: task.hpp:22
Task & precede(Ts &&... tasks)
adds precedence links from this to other tasks
Definition: task.hpp:190
void for_each_successor(V &&visitor) const
applies an visitor callable to each successor of the task
Definition: task.hpp:273
Task()=default
constructs an empty task
The executor class to run a taskflow graph.
Definition: executor.hpp:33
TaskView & operator=(const TaskView &other)
replaces the contents with a copy of the other task
Definition: task.hpp:409
bool operator==(const TaskView &) const
compares if two taskviews are associated with the same task
Definition: task.hpp:462
size_t num_dependents() const
queries the number of predecessors of the task
Definition: task.hpp:432
Task & work(C &&callable)
assigns a new callable object to the task
Definition: flow_builder.hpp:971
bool has_work() const
queries if the task has a work assigned
Definition: task.hpp:267
const std::string & name() const
queries the name of the task
Definition: task.hpp:427