Cpp-Taskflow  2.2.0
task.hpp
1 #pragma once
2 
3 #include "graph.hpp"
4 
5 namespace tf {
6 
18 class Task {
19 
20  friend class FlowBuilder;
21  friend class Taskflow;
22  friend class TaskView;
23 
24  public:
25 
29  Task() = default;
30 
34  Task(const Task& other);
35 
39  Task& operator = (const Task&);
40 
45 
49  const std::string& name() const;
50 
54  size_t num_successors() const;
55 
59  size_t num_dependents() const;
60 
68  Task& name(const std::string& name);
69 
79  template <typename C>
80  Task& work(C&& callable);
81 
91  template <typename... Ts>
92  Task& precede(Ts&&... tasks);
93 
101  Task& precede(std::vector<Task>& tasks);
102 
111 
121  template <typename... Ts>
122  Task& succeed(Ts&&... tasks);
123 
131  Task& succeed(std::vector<Task>& tasks);
132 
141 
151  template <typename... Ts>
152  Task& gather(Ts&&... tasks);
153 
161  Task& gather(std::vector<Task>& tasks);
162 
171 
177  Task& reset();
178 
182  bool empty() const;
183 
187  bool has_work() const;
188 
189  private:
190 
191  Task(Node&);
192  Task(Node*);
193 
194  Node* _node {nullptr};
195 
196  template <typename S>
197  void _gather(S&);
198 
199  template <typename S>
200  void _precede(S&);
201 
202  template <typename S>
203  void _succeed(S&);
204 };
205 
206 // Constructor
207 inline Task::Task(Node& node) : _node {&node} {
208 }
209 
210 // Constructor
211 inline Task::Task(Node* node) : _node {node} {
212 }
213 
214 // Constructor
215 inline Task::Task(const Task& rhs) : _node {rhs._node} {
216 }
217 
218 // Function: precede
219 template <typename... Ts>
220 Task& Task::precede(Ts&&... tgts) {
221  (_node->precede(*(tgts._node)), ...);
222  return *this;
223 }
224 
225 // Function: precede
227  _precede(tgts);
228  return *this;
229 }
230 
231 // Function: precede
233  _precede(tgts);
234  return *this;
235 }
236 
237 // Procedure: _precede
238 template <typename S>
239 void Task::_precede(S& tgts) {
240  for(auto& to : tgts) {
241  _node->precede(*(to._node));
242  }
243 }
244 
245 // Function: gather
246 template <typename... Bs>
247 Task& Task::gather(Bs&&... tgts) {
248  (tgts._node->precede(*_node), ...);
249  return *this;
250 }
251 
252 // Procedure: _gather
253 template <typename S>
254 void Task::_gather(S& tgts) {
255  for(auto& from : tgts) {
256  from._node->precede(*_node);
257  }
258 }
259 
260 // Function: gather
262  _gather(tgts);
263  return *this;
264 }
265 
266 // Function: gather
268  _gather(tgts);
269  return *this;
270 }
271 
272 // Function: succeed
273 template <typename... Bs>
274 Task& Task::succeed(Bs&&... tgts) {
275  (tgts._node->precede(*_node), ...);
276  return *this;
277 }
278 
279 // Procedure: _succeed
280 template <typename S>
281 void Task::_succeed(S& tgts) {
282  for(auto& from : tgts) {
283  from._node->precede(*_node);
284  }
285 }
286 
287 // Function: succeed
289  _succeed(tgts);
290  return *this;
291 }
292 
293 // Function: succeed
295  _succeed(tgts);
296  return *this;
297 }
298 
299 // Operator =
300 inline Task& Task::operator = (const Task& rhs) {
301  _node = rhs._node;
302  return *this;
303 }
304 
305 // Operator =
307  _node = ptr;
308  return *this;
309 }
310 
311 // Function: work
312 template <typename C>
313 inline Task& Task::work(C&& c) {
314 
315  if(_node->_module) {
316  TF_THROW(Error::TASKFLOW, "can't assign work to a module task");
317  }
318 
319  _node->_work = std::forward<C>(c);
320 
321  return *this;
322 }
323 
324 // Function: name
325 inline Task& Task::name(const std::string& name) {
326  _node->_name = name;
327  return *this;
328 }
329 
330 // Procedure: reset
331 inline Task& Task::reset() {
332  _node = nullptr;
333  return *this;
334 }
335 
336 // Function: name
337 inline const std::string& Task::name() const {
338  return _node->_name;
339 }
340 
341 // Function: num_dependents
342 inline size_t Task::num_dependents() const {
343  return _node->num_dependents();
344 }
345 
346 // Function: num_successors
347 inline size_t Task::num_successors() const {
348  return _node->num_successors();
349 }
350 
351 // Function: empty
352 inline bool Task::empty() const {
353  return _node == nullptr;
354 }
355 
356 // Function: has_work
357 inline bool Task::has_work() const {
358  return _node ? _node->_work.index() != 0 : false;
359 }
360 
361 // ----------------------------------------------------------------------------
362 
370 class TaskView {
371 
372  friend class Executor;
373 
374  public:
375 
379  TaskView() = default;
380 
384  TaskView(const Task& task);
385 
389  TaskView(const TaskView& other);
390 
394  TaskView& operator = (const TaskView& other);
395 
399  TaskView& operator = (const Task& other);
400 
405 
409  const std::string& name() const;
410 
414  size_t num_successors() const;
415 
419  size_t num_dependents() const;
420 
424  void reset();
425 
429  bool empty() const;
430 
431  private:
432 
433  TaskView(Node&);
434  TaskView(Node*);
435 
436  Node* _node {nullptr};
437 };
438 
439 // Constructor
440 inline TaskView::TaskView(Node& node) : _node {&node} {
441 }
442 
443 // Constructor
444 inline TaskView::TaskView(Node* node) : _node {node} {
445 }
446 
447 // Constructor
448 inline TaskView::TaskView(const TaskView& rhs) : _node {rhs._node} {
449 }
450 
451 // Constructor
452 inline TaskView::TaskView(const Task& task) : _node {task._node} {
453 }
454 
455 // Operator =
457  _node = rhs._node;
458  return *this;
459 }
460 
461 // Operator =
462 inline TaskView& TaskView::operator = (const Task& rhs) {
463  _node = rhs._node;
464  return *this;
465 }
466 
467 // Operator =
469  _node = ptr;
470  return *this;
471 }
472 
473 // Function: name
474 inline const std::string& TaskView::name() const {
475  return _node->_name;
476 }
477 
478 // Function: num_dependents
479 inline size_t TaskView::num_dependents() const {
480  return _node->num_dependents();
481 }
482 
483 // Function: num_successors
484 inline size_t TaskView::num_successors() const {
485  return _node->num_successors();
486 }
487 
488 // Function: reset
489 inline void TaskView::reset() {
490  _node = nullptr;
491 }
492 
493 // Function: empty
494 inline bool TaskView::empty() const {
495  return _node == nullptr;
496 }
497 
498 } // end of namespace tf. ---------------------------------------------------
499 
size_t num_dependents() const
queries the number of predecessors of the task
Definition: task.hpp:342
Task & reset()
resets the task handle to null
Definition: task.hpp:331
TaskView()=default
constructs an empty task view
Task & gather(Ts &&... tasks)
adds precedence links from other tasks to this (same as succeed)
Definition: task.hpp:247
size_t num_successors() const
queries the number of successors of the task
Definition: task.hpp:484
Definition: taskflow.hpp:5
Task & succeed(Ts &&... tasks)
adds precedence links from other tasks to this
Definition: task.hpp:274
bool empty() const
queries if the task view is empty
Definition: task.hpp:494
Task & operator=(const Task &)
replaces the contents with a copy of the other task
Definition: task.hpp:300
the class to create a task dependency graph
Definition: core/taskflow.hpp:15
const std::string & name() const
queries the name of the task
Definition: task.hpp:337
A constant wrapper class to a task node, mainly used in the tf::ExecutorObserver interface.
Definition: task.hpp:370
bool empty() const
queries if the task handle points to a task node
Definition: task.hpp:352
void reset()
resets to an empty view
Definition: task.hpp:489
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:347
Handle to modify and access a task.
Definition: task.hpp:18
Task & precede(Ts &&... tasks)
adds precedence links from this to other tasks
Definition: task.hpp:220
Task()=default
constructs an empty task
The executor class to run a taskflow graph.
Definition: executor.hpp:88
TaskView & operator=(const TaskView &other)
replaces the contents with a copy of the other task
Definition: task.hpp:456
size_t num_dependents() const
queries the number of predecessors of the task
Definition: task.hpp:479
Task & work(C &&callable)
assigns a new callable object to the task
Definition: task.hpp:313
bool has_work() const
queries if the task has a work assigned
Definition: task.hpp:357
const std::string & name() const
queries the name of the task
Definition: task.hpp:474