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

Loading...
Searching...
No Matches
tf::MultiConditionTaskLike Concept Reference

determines if a callable is a multi-condition task More...

`#include <taskflow/core/task.hpp>`

## Concept definition

template<typename C>
concept tf::MultiConditionTaskLike = std::invocable<C> &&
std::same_as<std::invoke_result_t<C>, SmallVector<int>>
tf::MultiConditionTaskLike
determines if a callable is a multi-condition task
Definition task.hpp:494

## Detailed Description

determines if a callable is a multi-condition task

A multi-condition task is a callable object that takes no arguments and returns a tf::SmallVector<int>. The returned vector contains branch indices for multiple successor branches, enabling complex control flow patterns where a single task can activate multiple branches simultaneously.

Requirements
  - Must be invocable with no arguments
  - Must return exactly tf::SmallVector<int>

Examples

// Valid multi-condition tasks (satisfy MultiConditionTaskLike)
// Multi-condition returning indices for multiple branches
auto multi_condition1 = []() {
tf::SmallVector<int> branches;
branches.push_back(0); // Take first branch
branches.push_back(2); // Also take third branch
return branches;
};
static_assert(MultiConditionTaskLike<decltype(multi_condition1)>);
// Dynamic branch selection
int branch_mask = 5; // binary: 101 → take branches 0 and 2
auto select_branches = [branch_mask]() {
tf::SmallVector<int> result;
for(int i = 0; i < 3; ++i) {
if(branch_mask & (1 << i)) {
result.push_back(i);
}
}
return result;
};
static_assert(MultiConditionTaskLike<decltype(select_branches)>);
// Function object
struct MultiConditionTask {
tf::SmallVector<int> operator()() const {
return {0, 1}; // Execute branches 0 and 1
}
};
static_assert(MultiConditionTaskLike<MultiConditionTask>);
// Use in taskflow
tf::Taskflow taskflow;
auto [init, mcond, branch_0, branch_1, branch_2] = taskflow.emplace(
[](){ std::cout << "init\n"; },
select_branches,
[](){ std::cout << "branch 0\n"; },
[](){ std::cout << "branch 1\n"; },
[](){ std::cout << "branch 2\n"; }
);
init.precede(mcond);
// All three branches become successors (only those returned in SmallVector will execute)
mcond.precede(branch_0, branch_1, branch_2);
tf::FlowBuilder::emplace
Task emplace(C &&callable)
creates a static task
Definition flow_builder.hpp:1738
tf::SmallVector
class to define a vector optimized for small array
Definition small_vector.hpp:931
tf::Task::precede
Task & precede(Ts &&... tasks)
adds precedence links from this to other tasks
Definition task.hpp:1258
tf::Taskflow
class to create a taskflow object
Definition taskflow.hpp:64

Invalid Examples

// Invalid: takes parameters
auto not_multi1 = [](int x) {
tf::SmallVector<int> v; v.push_back(x); return v;
};
// static_assert(MultiConditionTaskLike<decltype(not_multi1)>); // FAILS
// Invalid: returns wrong container type
auto not_multi2 = []() { return std::vector<int>{0, 1}; };
// static_assert(MultiConditionTaskLike<decltype(not_multi2)>); // FAILS
// Invalid: returns single int instead of SmallVector
auto not_multi3 = []() { return 0; };
// static_assert(MultiConditionTaskLike<decltype(not_multi3)>); // FAILS
// Invalid: returns void
auto not_multi4 = []() { std::cout << "task\n"; };
// static_assert(MultiConditionTaskLike<decltype(not_multi4)>); // FAILS