Back to Taskflow

Taskflow: A General

docs/task_8hpp_source.html

4.1.049.8 KB
Original Source

| | Taskflow: A General-purpose Task-parallel Programming System |

Loading...

Searching...

No Matches

task.hpp

1#pragma once

2

3#include "graph.hpp"

4

9

10namespace tf {

11

12// ----------------------------------------------------------------------------

13// Task Types

14// ----------------------------------------------------------------------------

15

21enum class TaskType : int {

23PLACEHOLDER = 0,

25STATIC,

27RUNTIME,

29SUBFLOW,

31CONDITION,

33MODULE,

35ASYNC,

37UNDEFINED

38};

39

44inline constexpr std::array<TaskType, 7> TASK_TYPES = {

45TaskType::PLACEHOLDER,

46TaskType::STATIC,

47TaskType::RUNTIME,

48TaskType::SUBFLOW,

49TaskType::CONDITION,

50TaskType::MODULE,

51TaskType::ASYNC,

52};

53

66inline const char* to_string(TaskType type) {

67

68const char* val;

69

70switch(type) {

71case TaskType::PLACEHOLDER: val = "placeholder"; break;

72case TaskType::STATIC: val = "static"; break;

73case TaskType::RUNTIME: val = "runtime"; break;

74case TaskType::SUBFLOW: val = "subflow"; break;

75case TaskType::CONDITION: val = "condition"; break;

76case TaskType::MODULE: val = "module"; break;

77case TaskType::ASYNC: val = "async"; break;

78default: val = "undefined"; break;

79 }

80

81return val;

82}

83

84// ----------------------------------------------------------------------------

85// Static Task Trait

86// ----------------------------------------------------------------------------

87

139template <typename C>

140concept StaticTaskLike = std::invocable<C> &&

141 std::same_as<std::invoke_result_t<C>, void>;

142

150template <typename C>

151constexpr bool is_static_task_v = StaticTaskLike<C>;

152

153// ----------------------------------------------------------------------------

154// Subflow Task Trait

155// ----------------------------------------------------------------------------

156

219template <typename C>

220concept SubflowTaskLike = std::invocable<C, tf::Subflow&> &&

221 std::same_as<std::invoke_result_t<C, tf::Subflow&>, void>;

222

230template <typename C>

231constexpr bool is_subflow_task_v = SubflowTaskLike<C>;

232

233// ----------------------------------------------------------------------------

234// Runtime Task Trait

235// ----------------------------------------------------------------------------

236

302template <typename C>

303concept RuntimeTaskLike =

304 (std::invocable<C, tf::Runtime&> &&

305 std::same_as<std::invoke_result_t<C, tf::Runtime&>, void>) ||

306 (std::invocable<C, tf::NonpreemptiveRuntime&> &&

307 std::same_as<std::invoke_result_t<C, tf::NonpreemptiveRuntime&>, void>);

308

316template <typename C>

317constexpr bool is_runtime_task_v = RuntimeTaskLike<C>;

318

319

320// ----------------------------------------------------------------------------

321// Condition Task Trait

322// ----------------------------------------------------------------------------

323

396template <typename C>

397concept ConditionTaskLike = std::invocable<C> &&

398 std::convertible_to<std::invoke_result_t<C>, int>;

399

407template <typename C>

408constexpr bool is_condition_task_v = ConditionTaskLike<C>;

409

493template <typename C>

494concept MultiConditionTaskLike = std::invocable<C> &&

495 std::same_as<std::invoke_result_t<C>, SmallVector<int>>;

496

504template <typename C>

505constexpr bool is_multi_condition_task_v = MultiConditionTaskLike<C>;

506

507

508// ----------------------------------------------------------------------------

509// Task

510// ----------------------------------------------------------------------------

511

569class Task {

570

571friend class FlowBuilder;

572friend class Runtime;

573friend class NonpreemptiveRuntime;

574friend class Taskflow;

575friend class TaskView;

576friend class Executor;

577

578public:

579

585Task() = default;

586

599Task(const Task& other);

600

612Task& operator =(const Task& other);

613

622Task& operator =(std::nullptr_t);

623

636bool operator ==(const Task& rhs) const;

637

650bool operator !=(const Task& rhs) const;

651

663const std::string& name() const;

664

677size_t num_successors() const;

678

691size_t num_predecessors() const;

692

720size_t num_strong_dependencies() const;

721

749size_t num_weak_dependencies() const;

750

763Task& name(const std::string& name);

764

787template <typename C>

788Task& work(C&& callable);

789

807template <GraphLike T>

808Task& composed_of(T& object);

809

831Task& adopt(tf::Graph&& graph);

832

852template <typename... Ts>

853Task& precede(Ts&&... tasks);

854

874template <typename... Ts>

875Task& succeed(Ts&&... tasks);

876

904template <typename... Ts>

905Task& remove_predecessors(Ts&&... tasks);

906

934template <typename... Ts>

935Task& remove_successors(Ts&&... tasks);

936

943Task& release(Semaphore& semaphore);

944

951template <typename I>

952Task& release(I first, I last);

953

960Task& acquire(Semaphore& semaphore);

961

968template <typename I>

969Task& acquire(I first, I last);

970

1000Task& data(void* data);

1001

1014void reset();

1015

1019void reset_work();

1020

1035bool empty() const;

1036

1050bool has_work() const;

1051

1074template <typename V>

1075void for_each_successor(V&& visitor) const;

1076

1098template <typename V>

1099void for_each_predecessor(V&& visitor) const;

1100

1121template <typename V>

1122void for_each_subflow_task(V&& visitor) const;

1123

1136size_t hash_value() const;

1137

1150TaskType type() const;

1151

1161void dump(std::ostream& ostream) const;

1162

1190void* data() const;

1191

1232 std::exception_ptr exception_ptr() const;

1233

1239bool has_exception_ptr() const;

1240

1241private:

1242

1243Task(Node*);

1244

1245 Node* _node {nullptr};

1246};

1247

1248// Constructor

1249inline Task::Task(Node* node) : _node {node} {

1250}

1251

1252// Constructor

1253inline Task::Task(const Task& rhs) : _node {rhs._node} {

1254}

1255

1256// Function: precede

1257template <typename... Ts>

1258Task& Task::precede(Ts&&... tasks) {

1259 (_node->_precede(tasks._node), ...);

1260//_precede(std::forward<Ts>(tasks)...);

1261return *this;

1262}

1263

1264// Function: succeed

1265template <typename... Ts>

1266Task& Task::succeed(Ts&&... tasks) {

1267 (tasks._node->_precede(_node), ...);

1268//_succeed(std::forward<Ts>(tasks)...);

1269return *this;

1270}

1271

1272// Function: remove_predecessors

1273template <typename... Ts>

1274Task& Task::remove_predecessors(Ts&&... tasks) {

1275 (tasks._node->_remove_successors(_node), ...);

1276 (_node->_remove_predecessors(tasks._node), ...);

1277return *this;

1278}

1279

1280// Function: remove_successors

1281template <typename... Ts>

1282Task& Task::remove_successors(Ts&&... tasks) {

1283 (_node->_remove_successors(tasks._node), ...);

1284 (tasks._node->_remove_predecessors(_node), ...);

1285return *this;

1286}

1287

1288// Function: composed_of

1289template <GraphLike T>

1290Task& Task::composed_of(T& target) {

1291 _node->_handle.emplace<Node::Module>(retrieve_graph(target));

1292return *this;

1293}

1294

1295// Function: adopt

1296inline Task& Task::adopt(Graph&& graph) {

1297 _node->_handle.emplace<Node::AdoptedModule>(std::move(graph));

1298return *this;

1299}

1300

1301// Operator =

1302inline Task& Task::operator =(const Task& rhs) {

1303 _node = rhs._node;

1304return *this;

1305}

1306

1307// Operator =

1308inline Task& Task::operator =(std::nullptr_t ptr) {

1309 _node = ptr;

1310return *this;

1311}

1312

1313// Operator ==

1314inline bool Task::operator ==(const Task& rhs) const {

1315return _node == rhs._node;

1316}

1317

1318// Operator !=

1319inline bool Task::operator !=(const Task& rhs) const {

1320return _node != rhs._node;

1321}

1322

1323// Function: name

1324inline Task& Task::name(const std::string& name) {

1325 _node->_name = name;

1326return *this;

1327}

1328

1329// Function: acquire

1330inline Task& Task::acquire(Semaphore& s) {

1331if(!_node->_semaphores) {

1332 _node->_semaphores = std::make_unique<Node::Semaphores>();

1333 }

1334 _node->_semaphores->to_acquire.push_back(&s);

1335return *this;

1336}

1337

1338// Function: acquire

1339template <typename I>

1340Task& Task::acquire(I first, I last) {

1341if(!_node->_semaphores) {

1342 _node->_semaphores = std::make_unique<Node::Semaphores>();

1343 }

1344 _node->_semaphores->to_acquire.reserve(

1345 _node->_semaphores->to_acquire.size() + std::distance(first, last)

1346 );

1347for(auto s = first; s != last; ++s){

1348 _node->_semaphores->to_acquire.push_back(&(*s));

1349 }

1350return *this;

1351}

1352

1353// Function: release

1354inline Task& Task::release(Semaphore& s) {

1355if(!_node->_semaphores) {

1356 _node->_semaphores = std::make_unique<Node::Semaphores>();

1357 }

1358 _node->_semaphores->to_release.push_back(&s);

1359return *this;

1360}

1361

1362// Function: release

1363template <typename I>

1364Task& Task::release(I first, I last) {

1365if(!_node->_semaphores) {

1366 _node->_semaphores = std::make_unique<Node::Semaphores>();

1367 }

1368 _node->_semaphores->to_release.reserve(

1369 _node->_semaphores->to_release.size() + std::distance(first, last)

1370 );

1371for(auto s = first; s != last; ++s) {

1372 _node->_semaphores->to_release.push_back(&(*s));

1373 }

1374return *this;

1375}

1376

1377// Procedure: reset

1378inline void Task::reset() {

1379 _node = nullptr;

1380}

1381

1382// Procedure: reset_work

1383inline void Task::reset_work() {

1384 _node->_handle.emplace<std::monostate>();

1385}

1386

1387// Function: name

1388inline const std::string& Task::name() const {

1389return _node->_name;

1390}

1391

1392// Function: num_predecessors

1393inline size_t Task::num_predecessors() const {

1394return _node->num_predecessors();

1395}

1396

1397// Function: num_strong_dependencies

1398inline size_t Task::num_strong_dependencies() const {

1399return _node->num_strong_dependencies();

1400}

1401

1402// Function: num_weak_dependencies

1403inline size_t Task::num_weak_dependencies() const {

1404return _node->num_weak_dependencies();

1405}

1406

1407// Function: num_successors

1408inline size_t Task::num_successors() const {

1409return _node->num_successors();

1410}

1411

1412// Function: empty

1413inline bool Task::empty() const {

1414return _node == nullptr;

1415}

1416

1417// Function: has_work

1418inline bool Task::has_work() const {

1419return _node ? _node->_handle.index() != 0 : false;

1420}

1421

1422// Function: exception

1423inline std::exception_ptr Task::exception_ptr() const {

1424return _node ? _node->_exception_ptr : nullptr;

1425}

1426

1427// Function: has_exception

1428inline bool Task::has_exception_ptr() const {

1429return _node ? (_node->_exception_ptr != nullptr) : false;

1430}

1431

1432// Function: task_type

1433inline TaskType Task::type() const {

1434switch(_node->_handle.index()) {

1435case Node::PLACEHOLDER: return TaskType::PLACEHOLDER;

1436case Node::STATIC: return TaskType::STATIC;

1437case Node::RUNTIME: return TaskType::RUNTIME;

1438case Node::NONPREEMPTIVE_RUNTIME: return TaskType::RUNTIME;

1439case Node::SUBFLOW: return TaskType::SUBFLOW;

1440case Node::CONDITION: return TaskType::CONDITION;

1441case Node::MULTI_CONDITION: return TaskType::CONDITION;

1442case Node::MODULE: return TaskType::MODULE;

1443case Node::ADOPTED_MODULE: return TaskType::MODULE;

1444case Node::ASYNC: return TaskType::ASYNC;

1445case Node::DEPENDENT_ASYNC: return TaskType::ASYNC;

1446default: return TaskType::UNDEFINED;

1447 }

1448}

1449

1450// Function: for_each_successor

1451template <typename V>

1452void Task::for_each_successor(V&& visitor) const {

1453for(size_t i=0; i<_node->_num_successors; ++i) {

1454 visitor(Task(_node->_edges[i]));

1455 }

1456}

1457

1458// Function: for_each_predecessor

1459template <typename V>

1460void Task::for_each_predecessor(V&& visitor) const {

1461for(size_t i=_node->_num_successors; i<_node->_edges.size(); ++i) {

1462 visitor(Task(_node->_edges[i]));

1463 }

1464}

1465

1466// Function: for_each_subflow_task

1467template <typename V>

1468void Task::for_each_subflow_task(V&& visitor) const {

1469if(auto ptr = std::get_if<Node::Subflow>(&_node->_handle); ptr) {

1470for(auto itr = ptr->subgraph.begin(); itr != ptr->subgraph.end(); ++itr) {

1471 visitor(Task(*itr));

1472 }

1473 }

1474}

1475

1476// Function: hash_value

1477inline size_t Task::hash_value() const {

1478return std::hash<Node*>{}(_node);

1479}

1480

1481// Procedure: dump

1482inline void Task::dump(std::ostream& os) const {

1483 os << "task ";

1484if(name().empty()) os << _node;

1485else os << name();

1486 os << " [type=" << to_string(type()) << ']';

1487}

1488

1489// Function: work

1490template <typename C>

1491Task& Task::work(C&& c) {

1492

1493if constexpr(is_static_task_v<C>) {

1494 _node->_handle.emplace<Node::Static>(std::forward<C>(c));

1495 }

1496else if constexpr(is_runtime_task_v<C>) {

1497 _node->_handle.emplace<Node::Runtime>(std::forward<C>(c));

1498 }

1499else if constexpr(is_subflow_task_v<C>) {

1500 _node->_handle.emplace<Node::Subflow>(std::forward<C>(c));

1501 }

1502else if constexpr(is_condition_task_v<C>) {

1503 _node->_handle.emplace<Node::Condition>(std::forward<C>(c));

1504 }

1505else if constexpr(is_multi_condition_task_v<C>) {

1506 _node->_handle.emplace<Node::MultiCondition>(std::forward<C>(c));

1507 }

1508else {

1509static_assert(dependent_false_v<C>, "invalid task callable");

1510 }

1511return *this;

1512}

1513

1514// Function: data

1515inline void* Task::data() const {

1516return _node->_data;

1517}

1518

1519// Function: data

1520inline Task& Task::data(void* data) {

1521 _node->_data = data;

1522return *this;

1523}

1524

1525// ----------------------------------------------------------------------------

1526// global ostream

1527// ----------------------------------------------------------------------------

1528

1532inline std::ostream& operator <<(std::ostream& os, const Task& task) {

1533 task.dump(os);

1534return os;

1535}

1536

1537// ----------------------------------------------------------------------------

1538// Task View

1539// ----------------------------------------------------------------------------

1540

1546class TaskView {

1547

1548friend class Executor;

1549

1550public:

1551

1555const std::string& name() const;

1556

1560size_t num_successors() const;

1561

1565size_t num_predecessors() const;

1566

1570size_t num_strong_dependencies() const;

1571

1575size_t num_weak_dependencies() const;

1576

1585template <typename V>

1586void for_each_successor(V&& visitor) const;

1587

1596template <typename V>

1597void for_each_predecessor(V&& visitor) const;

1598

1602TaskType type() const;

1603

1607size_t hash_value() const;

1608

1609private:

1610

1611 TaskView(const Node&);

1612 TaskView(const TaskView&) = default;

1613

1614const Node& _node;

1615};

1616

1617// Constructor

1618inline TaskView::TaskView(const Node& node) : _node {node} {

1619}

1620

1621// Function: name

1622inline const std::string& TaskView::name() const {

1623return _node._name;

1624}

1625

1626// Function: num_predecessors

1627inline size_t TaskView::num_predecessors() const {

1628return _node.num_predecessors();

1629}

1630

1631// Function: num_strong_dependencies

1632inline size_t TaskView::num_strong_dependencies() const {

1633return _node.num_strong_dependencies();

1634}

1635

1636// Function: num_weak_dependencies

1637inline size_t TaskView::num_weak_dependencies() const {

1638return _node.num_weak_dependencies();

1639}

1640

1641// Function: num_successors

1642inline size_t TaskView::num_successors() const {

1643return _node.num_successors();

1644}

1645

1646// Function: type

1647inline TaskType TaskView::type() const {

1648switch(_node._handle.index()) {

1649case Node::PLACEHOLDER: return TaskType::PLACEHOLDER;

1650case Node::STATIC: return TaskType::STATIC;

1651case Node::RUNTIME: return TaskType::RUNTIME;

1652case Node::NONPREEMPTIVE_RUNTIME: return TaskType::RUNTIME;

1653case Node::SUBFLOW: return TaskType::SUBFLOW;

1654case Node::CONDITION: return TaskType::CONDITION;

1655case Node::MULTI_CONDITION: return TaskType::CONDITION;

1656case Node::MODULE: return TaskType::MODULE;

1657case Node::ADOPTED_MODULE: return TaskType::MODULE;

1658case Node::ASYNC: return TaskType::ASYNC;

1659case Node::DEPENDENT_ASYNC: return TaskType::ASYNC;

1660default: return TaskType::UNDEFINED;

1661 }

1662}

1663

1664// Function: hash_value

1665inline size_t TaskView::hash_value() const {

1666return std::hash<const Node*>{}(&_node);

1667}

1668

1669// Function: for_each_successor

1670template <typename V>

1671void TaskView::for_each_successor(V&& visitor) const {

1672for(size_t i=0; i<_node._num_successors; ++i) {

1673 visitor(TaskView(*_node._edges[i]));

1674 }

1675//for(size_t i=0; i<_node._successors.size(); ++i) {

1676// visitor(TaskView(*_node._successors[i]));

1677//}

1678}

1679

1680// Function: for_each_predecessor

1681template <typename V>

1682void TaskView::for_each_predecessor(V&& visitor) const {

1683for(size_t i=_node._num_successors; i<_node._edges.size(); ++i) {

1684 visitor(TaskView(*_node._edges[i]));

1685 }

1686//for(size_t i=0; i<_node._predecessors.size(); ++i) {

1687// visitor(TaskView(*_node._predecessors[i]));

1688//}

1689}

1690

1691} // end of namespace tf. ----------------------------------------------------

1692

1693namespace std {

1694

1745template <>

1746struct hash<tf::Task> {

1747auto operator() (const tf::Task& task) const noexcept {

1748return task.hash_value();

1749 }

1750};

1751

1752

1753

1807template <>

1808struct hash<tf::TaskView> {

1809auto operator() (const tf::TaskView& task_view) const noexcept {

1810return task_view.hash_value();

1811 }

1812};

1813

1814} // end of namespace std ----------------------------------------------------

tf::Graph

class to create a graph object

Definition graph.hpp:47

tf::Semaphore

class to create a semophore object for building a concurrency constraint

Definition semaphore.hpp:68

tf::SmallVector

class to define a vector optimized for small array

Definition small_vector.hpp:931

tf::TaskView

class to access task information from the observer interface

Definition task.hpp:1546

tf::TaskView::num_predecessors

size_t num_predecessors() const

queries the number of predecessors of the task

Definition task.hpp:1627

tf::TaskView::for_each_predecessor

void for_each_predecessor(V &&visitor) const

applies an visitor callable to each predecessor of the task

Definition task.hpp:1682

tf::TaskView::for_each_successor

void for_each_successor(V &&visitor) const

applies an visitor callable to each successor of the task

Definition task.hpp:1671

tf::TaskView::type

TaskType type() const

queries the task type

Definition task.hpp:1647

tf::TaskView::num_weak_dependencies

size_t num_weak_dependencies() const

queries the number of weak dependencies of the task

Definition task.hpp:1637

tf::TaskView::hash_value

size_t hash_value() const

obtains a hash value of the underlying node

Definition task.hpp:1665

tf::TaskView::name

const std::string & name() const

queries the name of the task

Definition task.hpp:1622

tf::TaskView::num_strong_dependencies

size_t num_strong_dependencies() const

queries the number of strong dependencies of the task

Definition task.hpp:1632

tf::TaskView::num_successors

size_t num_successors() const

queries the number of successors of the task

Definition task.hpp:1642

tf::Task

class to create a task handle over a taskflow node

Definition task.hpp:569

tf::Task::acquire

Task & acquire(Semaphore &semaphore)

makes the task acquire the given semaphore

Definition task.hpp:1330

tf::Task::name

const std::string & name() const

queries the name of the task

Definition task.hpp:1388

tf::Task::num_strong_dependencies

size_t num_strong_dependencies() const

queries the number of strong dependencies of the task

Definition task.hpp:1398

tf::Task::remove_successors

Task & remove_successors(Ts &&... tasks)

removes successor links from this to other tasks

Definition task.hpp:1282

tf::Task::num_successors

size_t num_successors() const

queries the number of successors of the task

Definition task.hpp:1408

tf::Task::hash_value

size_t hash_value() const

obtains a hash value of the underlying node

Definition task.hpp:1477

tf::Task::for_each_subflow_task

void for_each_subflow_task(V &&visitor) const

applies an visitor callable to each subflow task

Definition task.hpp:1468

tf::Task::release

Task & release(Semaphore &semaphore)

makes the task release the given semaphore

Definition task.hpp:1354

tf::Task::work

Task & work(C &&callable)

assigns a callable

Definition task.hpp:1491

tf::Task::exception_ptr

std::exception_ptr exception_ptr() const

retrieves the exception pointer of this task

Definition task.hpp:1423

tf::Task::reset

void reset()

resets the task handle to null

Definition task.hpp:1378

tf::Task::for_each_predecessor

void for_each_predecessor(V &&visitor) const

applies an visitor callable to each predecessor of the task

Definition task.hpp:1460

tf::Task::data

void * data() const

queries pointer to user data

Definition task.hpp:1515

tf::Task::dump

void dump(std::ostream &ostream) const

dumps the task through an output stream

Definition task.hpp:1482

tf::Task::succeed

Task & succeed(Ts &&... tasks)

adds precedence links from other tasks to this

Definition task.hpp:1266

tf::Task::operator=

Task & operator=(const Task &other)

replaces the contents with a copy of the other task

Definition task.hpp:1302

tf::Task::Task

Task()=default

constructs an empty task

tf::Task::empty

bool empty() const

queries if the task handle is associated with a taskflow node

Definition task.hpp:1413

tf::Task::precede

Task & precede(Ts &&... tasks)

adds precedence links from this to other tasks

Definition task.hpp:1258

tf::Task::has_exception_ptr

bool has_exception_ptr() const

queries if the task has an exception pointer

Definition task.hpp:1428

tf::Task::adopt

Task & adopt(tf::Graph &&graph)

creates a module task from a graph by taking over its ownership

Definition task.hpp:1296

tf::Task::composed_of

Task & composed_of(T &object)

creates a module task from a taskflow

Definition task.hpp:1290

tf::Task::remove_predecessors

Task & remove_predecessors(Ts &&... tasks)

removes predecessor links from other tasks to this

Definition task.hpp:1274

tf::Task::num_weak_dependencies

size_t num_weak_dependencies() const

queries the number of weak dependencies of the task

Definition task.hpp:1403

tf::Task::operator==

bool operator==(const Task &rhs) const

compares if two tasks are associated with the same taskflow node

Definition task.hpp:1314

tf::Task::num_predecessors

size_t num_predecessors() const

queries the number of predecessors of the task

Definition task.hpp:1393

tf::Task::reset_work

void reset_work()

resets the associated work to a placeholder

Definition task.hpp:1383

tf::Task::type

TaskType type() const

returns the task type

Definition task.hpp:1433

tf::Task::operator!=

bool operator!=(const Task &rhs) const

compares if two tasks are not associated with the same taskflow node

Definition task.hpp:1319

tf::Task::has_work

bool has_work() const

queries if the task has a work assigned

Definition task.hpp:1418

tf::Task::data

Task & data(void *data)

assigns pointer to user data

Definition task.hpp:1520

tf::Task::for_each_successor

void for_each_successor(V &&visitor) const

applies an visitor callable to each successor of the task

Definition task.hpp:1452

tf::ConditionTaskLike

determines if a callable is a condition task

Definition task.hpp:397

tf::MultiConditionTaskLike

determines if a callable is a multi-condition task

Definition task.hpp:494

tf::RuntimeTaskLike

determines if a callable is a runtime task

Definition task.hpp:303

tf::StaticTaskLike

determines if a callable is a static task

Definition task.hpp:140

tf::SubflowTaskLike

determines if a callable is a subflow task

Definition task.hpp:220

tf

taskflow namespace

Definition small_vector.hpp:20

tf::is_condition_task_v

constexpr bool is_condition_task_v

determines if a callable is a condition task (variable template)

Definition task.hpp:408

tf::is_static_task_v

constexpr bool is_static_task_v

determines if a callable is a static task (variable template)

Definition task.hpp:151

tf::TaskType

TaskType

enumeration of all task types

Definition task.hpp:21

tf::TaskType::UNDEFINED

@ UNDEFINED

undefined task type (for internal use only)

Definition task.hpp:37

tf::TaskType::MODULE

@ MODULE

module task type

Definition task.hpp:33

tf::TaskType::SUBFLOW

@ SUBFLOW

dynamic (subflow) task type

Definition task.hpp:29

tf::TaskType::CONDITION

@ CONDITION

condition task type

Definition task.hpp:31

tf::TaskType::ASYNC

@ ASYNC

asynchronous task type

Definition task.hpp:35

tf::TaskType::PLACEHOLDER

@ PLACEHOLDER

placeholder task type

Definition task.hpp:23

tf::TaskType::RUNTIME

@ RUNTIME

runtime task type

Definition task.hpp:27

tf::TaskType::STATIC

@ STATIC

static task type

Definition task.hpp:25

tf::to_string

const char * to_string(TaskType type)

convert a task type to a human-readable string

Definition task.hpp:66

tf::is_multi_condition_task_v

constexpr bool is_multi_condition_task_v

determines if a callable is a multi-condition task (variable template)

Definition task.hpp:505

tf::retrieve_graph

Graph & retrieve_graph(T &target)

retrieves a reference to the underlying tf::Graph from an object

Definition graph.hpp:1067

tf::operator<<

std::ostream & operator<<(std::ostream &os, const Task &task)

overload of ostream inserter operator for Task

Definition task.hpp:1532

tf::is_subflow_task_v

constexpr bool is_subflow_task_v

determines if a callable is a subflow task (variable template)

Definition task.hpp:231

tf::is_runtime_task_v

constexpr bool is_runtime_task_v

determines if a callable is a runtime task (variable template)

Definition task.hpp:317

hash

hash specialization for std::hash<tf::Task>