tf::FlowBuilder tf::Subflow tf::Taskflow taskflow/core/flow_builder.hpp class friend class Executor Executor Executor Graph & Graph& tf::FlowBuilder::_graph _graph associated graph object tf::FlowBuilder::FlowBuilder (Graph &graph) FlowBuilder Graph & graph constructs a flow builder with a graph typename C std::enable_if_t< is_static_task_v< C >, void > * nullptr Task Task tf::FlowBuilder::emplace (C &&callable) emplace C && callable creates a static task C callable type constructible from std::function<void()> callable callable to construct a static task a tf::Task handle The following example creates a static task. tf::Taskstatic_task=taskflow.emplace([](){}); Please refer to Static Tasking for details. typename C std::enable_if_t< is_subflow_task_v< C >, void > * nullptr Task Task tf::FlowBuilder::emplace (C &&callable) emplace C && callable creates a dynamic task C callable type constructible from std::function<void(tf::Subflow&)> callable callable to construct a dynamic task a tf::Task handle The following example creates a dynamic task (tf::Subflow) that spawns two static tasks. tf::Taskdynamic_task=taskflow.emplace([](tf::Subflow&sf){ tf::Taskstatic_task1=sf.emplace([](){}); tf::Taskstatic_task2=sf.emplace([](){}); }); Please refer to Subflow Tasking for details. typename C std::enable_if_t< is_condition_task_v< C >, void > * nullptr Task Task tf::FlowBuilder::emplace (C &&callable) emplace C && callable creates a condition task C callable type constructible from std::function<int()> callable callable to construct a condition task a tf::Task handle The following example creates an if-else block using one condition task and three static tasks. tf::Taskflowtaskflow; auto[init,cond,yes,no]=taskflow.emplace( [](){}, [](){return0;}, [](){std::cout<<"yes\n";}, [](){std::cout<<"no\n";} ); //executesyesifcondreturns0,ornoifcondreturns1 cond.precede(yes,no); cond.succeed(init); Please refer to Conditional Tasking for details. typename C std::enable_if_t< is_multi_condition_task_v< C >, void > * nullptr Task Task tf::FlowBuilder::emplace (C &&callable) emplace C && callable creates a multi-condition task C callable type constructible from std::function<tf::SmallVector<int>()> callable callable to construct a multi-condition task a tf::Task handle The following example creates a multi-condition task that selectively jumps to two successor tasks. tf::Taskflowtaskflow; auto[init,cond,branch1,branch2,branch3]=taskflow.emplace( [](){}, [](){returntf::SmallVector{0,2};}, [](){std::cout<<"branch1\n";}, [](){std::cout<<"branch2\n";}, [](){std::cout<<"branch3\n";} ); //executesbranch1andbranch3whencondreturns0and2 cond.precede(branch1,branch2,branch3); cond.succeed(init); Please refer to Conditional Tasking for details. typename... C C std::enable_if_t<(sizeof...(C)>1), void > * nullptr auto auto tf::FlowBuilder::emplace (C &&... callables) emplace C &&... callables creates multiple tasks from a list of callable objects C callable types callables one or multiple callable objects constructible from each task category a tf::Task handle The method returns a tuple of tasks each corresponding to the given callable target. You can use structured binding to get the return tasks one by one. The following example creates four static tasks and assign them to A, B, C, and D using structured binding. auto[A,B,C,D]=taskflow.emplace( [](){std::cout<<"A";}, [](){std::cout<<"B";}, [](){std::cout<<"C";}, [](){std::cout<<"D";} ); void void tf::FlowBuilder::erase (Task task) erase Task task removes a task from a taskflow task task to remove Removes a task and its input and output dependencies from the graph associated with the flow builder. If the task does not belong to the graph, nothing will happen. tf::TaskA=taskflow.emplace([](){std::cout<<"A";}); tf::TaskB=taskflow.emplace([](){std::cout<<"B";}); tf::TaskC=taskflow.emplace([](){std::cout<<"C";}); tf::TaskD=taskflow.emplace([](){std::cout<<"D";}); A.precede(B,C,D); //eraseAfromthetaskflowanditsdependenciestoB,C,andD taskflow.erase(A); typename T Task Task tf::FlowBuilder::composed_of (T &object) composed_of T & object creates a module task for the target object T target object type object a custom object that defines the method T::graph() a tf::Task handle The example below demonstrates a taskflow composition using the composed_of method. tf::Taskflowt1,t2; t1.emplace([](){std::cout<<"t1";}); //t2ispartiallycomposedoft1 tf::Taskcomp=t2.composed_of(t1); tf::Taskinit=t2.emplace([](){std::cout<<"t2";}); init.precede(comp); The taskflow object t2 is composed of another taskflow object t1, preceded by another static task init. When taskflow t2 is submitted to an executor, init will run first and then comp which spawns its definition in taskflow t1. The target object being composed must define the method T::graph() that returns a reference to a graph object of type tf::Graph such that it can interact with the executor. For example: //customstruct structMyObj{ tf::Graphgraph; MyObj(){ tf::FlowBuilderbuilder(graph); tf::Tasktask=builder.emplace([](){ std::cout<<"atask\n";//statictask }); } Graph&graph(){returngraph;} }; MyObjobj; tf::Taskcomp=taskflow.composed_of(obj); Please refer to Composable Tasking for details. Task Task tf::FlowBuilder::placeholder () placeholder creates a placeholder task a tf::Task handle A placeholder task maps to a node in the taskflow graph, but it does not have any callable work assigned yet. A placeholder task is different from an empty task handle that does not point to any node in a graph. //createaplaceholdertaskwithnocallabletargetassigned tf::Taskplaceholder=taskflow.placeholder(); assert(placeholder.empty()==false&&placeholder.has_work()==false); //createanemptytaskhandle tf::Tasktask; assert(task.empty()==true); //assignthetaskhandletotheplaceholdertask task=placeholder; assert(task.empty()==false&&task.has_work()==false); void void tf::FlowBuilder::linearize (std::vector< Task > &tasks) linearize std::vector< Task > & tasks adds adjacent dependency links to a linear list of tasks tasks a vector of tasks This member function creates linear dependencies over a vector of tasks. tf::TaskA=taskflow.emplace([](){std::cout<<"A";}); tf::TaskB=taskflow.emplace([](){std::cout<<"B";}); tf::TaskC=taskflow.emplace([](){std::cout<<"C";}); tf::TaskD=taskflow.emplace([](){std::cout<<"D";}); std::vector<tf::Task>tasks{A,B,C,D} taskflow.linearize(tasks);//A->B->C->D void void tf::FlowBuilder::linearize (std::initializer_list< Task > tasks) linearize std::initializer_list< Task > tasks adds adjacent dependency links to a linear list of tasks tasks an initializer list of tasks This member function creates linear dependencies over a list of tasks. tf::TaskA=taskflow.emplace([](){std::cout<<"A";}); tf::TaskB=taskflow.emplace([](){std::cout<<"B";}); tf::TaskC=taskflow.emplace([](){std::cout<<"C";}); tf::TaskD=taskflow.emplace([](){std::cout<<"D";}); taskflow.linearize({A,B,C,D});//A->B->C->D typename B typename E typename C typename P DefaultPartitioner Task Task tf::FlowBuilder::for_each (B first, E last, C callable, P part=P()) for_each B first E last C callable P part P() constructs an STL-styled parallel-for task B beginning iterator type E ending iterator type C callable type P partitioner type (default tf::DefaultPartitioner) first iterator to the beginning (inclusive) last iterator to the end (exclusive) callable callable object to apply to the dereferenced iterator part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks that applies the callable object to each object obtained by dereferencing every iterator in the range [first, last). This method is equivalent to the parallel execution of the following loop: for(autoitr=first;itr!=last;itr++){ callable(*itr); } Iterators are templated to enable stateful range using std::reference_wrapper. The callable needs to take a single argument of the dereferenced iterator type. Please refer to Parallel Iterations for details. typename B typename E typename S typename C typename P DefaultPartitioner Task Task tf::FlowBuilder::for_each_index (B first, E last, S step, C callable, P part=P()) for_each_index B first E last S step C callable P part P() constructs an STL-styled index-based parallel-for task B beginning index type (must be integral) E ending index type (must be integral) S step type (must be integral) C callable type P partitioner type (default tf::DefaultPartitioner) first index of the beginning (inclusive) last index of the end (exclusive) step step size callable callable object to apply to each valid index part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks that applies the callable object to each index in the range [first, last) with the step size. This method is equivalent to the parallel execution of the following loop: //case1:stepsizeispositive for(autoi=first;i<last;i+=step){ callable(i); } //case2:stepsizeisnegative for(autoi=first,i>last;i+=step){ callable(i); } Iterators are templated to enable stateful range using std::reference_wrapper. The callable needs to take a single argument of the integral index type. Please refer to Parallel Iterations for details. typename B typename E typename O typename C typename P DefaultPartitioner std::enable_if_t< is_partitioner_v< std::decay_t< P >>, void > * nullptr Task Task tf::FlowBuilder::transform (B first1, E last1, O d_first, C c, P part=P()) transform B first1 E last1 O d_first C c P part P() constructs a parallel-transform task B beginning input iterator type E ending input iterator type O output iterator type C callable type P partitioner type (default tf::DefaultPartitioner) first1 iterator to the beginning of the first range last1 iterator to the end of the first range d_first iterator to the beginning of the output range c an unary callable to apply to dereferenced input elements part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks that applies the callable object to an input range and stores the result in another output range. This method is equivalent to the parallel execution of the following loop: while(first1!=last1){ *d_first++=c(*first1++); } Iterators are templated to enable stateful range using std::reference_wrapper. The callable needs to take a single argument of the dereferenced iterator type. Please refer to Parallel Transforms for details. typename B1 typename E1 typename B2 typename O typename C typename P DefaultPartitioner std::enable_if_t<!is_partitioner_v< std::decay_t< C >>, void > * nullptr Task Task tf::FlowBuilder::transform (B1 first1, E1 last1, B2 first2, O d_first, C c, P part=P()) transform B1 first1 E1 last1 B2 first2 O d_first C c P part P() constructs a parallel-transform task B1 beginning input iterator type for the first input range E1 ending input iterator type for the first input range B2 beginning input iterator type for the first second range O output iterator type C callable type P partitioner type (default tf::DefaultPartitioner) first1 iterator to the beginning of the first input range last1 iterator to the end of the first input range first2 iterator to the beginning of the second input range d_first iterator to the beginning of the output range c a binary operator to apply to dereferenced input elements part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks that applies the callable object to two input ranges and stores the result in another output range. This method is equivalent to the parallel execution of the following loop: while(first1!=last1){ *d_first++=c(*first1++,*first2++); } Iterators are templated to enable stateful range using std::reference_wrapper. The callable needs to take two arguments of dereferenced elements from the two input ranges. Please refer to Parallel Transforms for details. typename B typename E typename T typename O typename P DefaultPartitioner Task Task tf::FlowBuilder::reduce (B first, E last, T &init, O bop, P part=P()) reduce B first E last T & init O bop P part P() constructs an STL-styled parallel-reduce task B beginning iterator type E ending iterator type T result type O binary reducer type P partitioner type (default tf::DefaultPartitioner) first iterator to the beginning (inclusive) last iterator to the end (exclusive) init initial value of the reduction and the storage for the reduced result bop binary operator that will be applied part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks to perform parallel reduction over init and the elements in the range [first, last). The reduced result is store in init. This method is equivalent to the parallel execution of the following loop: for(autoitr=first;itr!=last;itr++){ init=bop(init,*itr); } Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Reduction for details. typename B typename E typename T typename BOP typename UOP typename P DefaultPartitioner std::enable_if_t< is_partitioner_v< std::decay_t< P >>, void > * nullptr Task Task tf::FlowBuilder::transform_reduce (B first, E last, T &init, BOP bop, UOP uop, P part=P()) transform_reduce B first E last T & init BOP bop UOP uop P part P() constructs an STL-styled parallel transform-reduce task B beginning iterator type E ending iterator type T result type BOP binary reducer type UOP unary transformation type P partitioner type (default tf::DefaultPartitioner) first iterator to the beginning (inclusive) last iterator to the end (exclusive) init initial value of the reduction and the storage for the reduced result bop binary operator that will be applied in unspecified order to the results of uop uop unary operator that will be applied to transform each element in the range to the result type part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks to perform parallel reduction over init and the transformed elements in the range [first, last). The reduced result is store in init. This method is equivalent to the parallel execution of the following loop: for(autoitr=first;itr!=last;itr++){ init=bop(init,uop(*itr)); } Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Reduction for details. typename B1 typename E1 typename B2 typename T typename BOP_R typename BOP_T typename P DefaultPartitioner std::enable_if_t<!is_partitioner_v< std::decay_t< BOP_T >>, void > * nullptr Task Task tf::FlowBuilder::transform_reduce (B1 first1, E1 last1, B2 first2, T &init, BOP_R bop_r, BOP_T bop_t, P part=P()) transform_reduce B1 first1 E1 last1 B2 first2 T & init BOP_R bop_r BOP_T bop_t P part P() constructs an STL-styled parallel transform-reduce task B1 first beginning iterator type E1 first ending iterator type B2 second beginning iterator type T result type BOP_R binary reducer type BOP_T binary transformation type P partitioner type (default tf::DefaultPartitioner) first1 iterator to the beginning of the first range (inclusive) last1 iterator to the end of the first range (exclusive) first2 iterator to the beginning of the second range init initial value of the reduction and the storage for the reduced result bop_r binary operator that will be applied in unspecified order to the results of bop_t bop_t binary operator that will be applied to transform each element in the range to the result type part partitioning algorithm to schedule parallel iterations a tf::Task handle The task spawns asynchronous tasks to perform parallel reduction over init and transformed elements in the range [first, last). The reduced result is store in init. This method is equivalent to the parallel execution of the following loop: for(autoitr1=first1,itr2=first2;itr1!=last1;itr1++,itr2++){ init=bop_r(init,bop_t(*itr1,*itr2)); } Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Reduction for details. typename B typename E typename D typename BOP typename P DefaultPartitioner std::enable_if_t< is_partitioner_v< std::decay_t< P >>, void > * nullptr Task Task tf::FlowBuilder::inclusive_scan (B first, E last, D d_first, BOP bop, P part=P()) inclusive_scan B first E last D d_first BOP bop P part P() creates an STL-styled parallel inclusive-scan task B beginning iterator type E ending iterator type D destination iterator type BOP summation operator type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) bop function to perform summation part partitioning algorithm to schedule parallel iterations Performs the cumulative sum (aka prefix sum, aka scan) of the input range and writes the result to the output range. Each element of the output range contains the running total of all earlier elements using the given binary operator for summation. This function generates an inclusive scan, meaning that the N-th element of the output range is the sum of the first N input elements, so the N-th input element is included. std::vector<int>input={1,2,3,4,5}; taskflow.inclusive_scan( input.begin(),input.end(),input.begin(),std::plus<int>{} ); executor.run(taskflow).wait(); //inputis{1,3,6,10,15} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename D typename BOP typename T typename P DefaultPartitioner std::enable_if_t<!is_partitioner_v< std::decay_t< T >>, void > * nullptr Task Task tf::FlowBuilder::inclusive_scan (B first, E last, D d_first, BOP bop, T init, P part=P()) inclusive_scan B first E last D d_first BOP bop T init P part P() creates an STL-styled parallel inclusive-scan task with an initial value B beginning iterator type E ending iterator type D destination iterator type BOP summation operator type T initial value type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) bop function to perform summation init initial value part partitioning algorithm to schedule parallel iterations Performs the cumulative sum (aka prefix sum, aka scan) of the input range and writes the result to the output range. Each element of the output range contains the running total of all earlier elements (and the initial value) using the given binary operator for summation. This function generates an inclusive scan, meaning the N-th element of the output range is the sum of the first N input elements, so the N-th input element is included. std::vector<int>input={1,2,3,4,5}; taskflow.inclusive_scan( input.begin(),input.end(),input.begin(),std::plus<int>{},-1 ); executor.run(taskflow).wait(); //inputis{0,2,5,9,14} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename D typename T typename BOP typename P DefaultPartitioner Task Task tf::FlowBuilder::exclusive_scan (B first, E last, D d_first, T init, BOP bop, P part=P()) exclusive_scan B first E last D d_first T init BOP bop P part P() creates an STL-styled parallel exclusive-scan task B beginning iterator type E ending iterator type D destination iterator type T initial value type BOP summation operator type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) init initial value bop function to perform summation part partitioning algorithm to schedule parallel iterations Performs the cumulative sum (aka prefix sum, aka scan) of the input range and writes the result to the output range. Each element of the output range contains the running total of all earlier elements (and the initial value) using the given binary operator for summation. This function generates an exclusive scan, meaning the N-th element of the output range is the sum of the first N-1 input elements, so the N-th input element is not included. std::vector<int>input={1,2,3,4,5}; taskflow.exclusive_scan( input.begin(),input.end(),input.begin(),-1,std::plus<int>{} ); executor.run(taskflow).wait(); //inputis{-1,0,2,5,9} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename D typename BOP typename UOP typename P DefaultPartitioner std::enable_if_t< is_partitioner_v< std::decay_t< P >>, void > * nullptr Task Task tf::FlowBuilder::transform_inclusive_scan (B first, E last, D d_first, BOP bop, UOP uop, P part=P()) transform_inclusive_scan B first E last D d_first BOP bop UOP uop P part P() creates an STL-styled parallel transform-inclusive scan task B beginning iterator type E ending iterator type D destination iterator type BOP summation operator type UOP transform operator type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) bop function to perform summation uop function to transform elements of the input range part partitioning algorithm to schedule parallel iterations Write the cumulative sum (aka prefix sum, aka scan) of the input range to the output range. Each element of the output range contains the running total of all earlier elements using uop to transform the input elements and using bop for summation. This function generates an inclusive scan, meaning the Nth element of the output range is the sum of the first N input elements, so the Nth input element is included. std::vector<int>input={1,2,3,4,5}; taskflow.transform_inclusive_scan( input.begin(),input.end(),input.begin(),std::plus<int>{}, [](intitem){return-item;} ); executor.run(taskflow).wait(); //inputis{-1,-3,-6,-10,-15} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename D typename BOP typename UOP typename T typename P DefaultPartitioner std::enable_if_t<!is_partitioner_v< std::decay_t< T >>, void > * nullptr Task Task tf::FlowBuilder::transform_inclusive_scan (B first, E last, D d_first, BOP bop, UOP uop, T init, P part=P()) transform_inclusive_scan B first E last D d_first BOP bop UOP uop T init P part P() creates an STL-styled parallel transform-inclusive scan task B beginning iterator type E ending iterator type D destination iterator type BOP summation operator type UOP transform operator type T initial value type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) bop function to perform summation uop function to transform elements of the input range init initial value part partitioning algorithm to schedule parallel iterations Write the cumulative sum (aka prefix sum, aka scan) of the input range to the output range. Each element of the output range contains the running total of all earlier elements (including an initial value) using uop to transform the input elements and using bop for summation. This function generates an inclusive scan, meaning the Nth element of the output range is the sum of the first N input elements, so the Nth input element is included. std::vector<int>input={1,2,3,4,5}; taskflow.transform_inclusive_scan( input.begin(),input.end(),input.begin(),std::plus<int>{}, [](intitem){return-item;}, -1 ); executor.run(taskflow).wait(); //inputis{-2,-4,-7,-11,-16} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename D typename T typename BOP typename UOP typename P DefaultPartitioner Task Task tf::FlowBuilder::transform_exclusive_scan (B first, E last, D d_first, T init, BOP bop, UOP uop, P part=P()) transform_exclusive_scan B first E last D d_first T init BOP bop UOP uop P part P() creates an STL-styled parallel transform-exclusive scan task B beginning iterator type E ending iterator type D destination iterator type BOP summation operator type UOP transform operator type T initial value type P partitioner type (default tf::DefaultPartitioner) first start of input range last end of input range d_first start of output range (may be the same as input range) bop function to perform summation uop function to transform elements of the input range init initial value part partitioning algorithm to schedule parallel iterations Write the cumulative sum (aka prefix sum, aka scan) of the input range to the output range. Each element of the output range contains the running total of all earlier elements (including an initial value) using uop to transform the input elements and using bop for summation. This function generates an exclusive scan, meaning the Nth element of the output range is the sum of the first N-1 input elements, so the Nth input element is not included. std::vector<int>input={1,2,3,4,5}; taskflow.transform_exclusive_scan( input.begin(),input.end(),input.begin(),-1,std::plus<int>{}, [](intitem){return-item;} ); executor.run(taskflow).wait(); //inputis{-1,-2,-4,-7,-11} Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Scan for details. typename B typename E typename T typename UOP typename P DefaultPartitioner Task Task tf::FlowBuilder::find_if (B first, E last, T &result, UOP predicate, P part=P()) find_if B first E last T & result UOP predicate P part P() constructs a task to perform STL-styled find-if algorithm B beginning iterator type E ending iterator type T resulting iterator type UOP unary predicate type P partitioner type first start of the input range last end of the input range result resulting iterator to the found element in the input range predicate unary predicate which returns true for the required element part partitioning algorithm (default tf::DefaultPartitioner) Returns an iterator to the first element in the range [first, last) that satisfies the given criteria (or last if there is no such iterator). This method is equivalent to the parallel execution of the following loop: autofind_if(InputItfirst,InputItlast,UnaryPredicatep){ for(;first!=last;++first){ if(predicate(*first)){ returnfirst; } } returnlast; } For example, the code below find the element that satisfies the given criteria (value plus one is equal to 23) from an input range of 10 elements: std::vector<int>input={1,6,9,10,22,5,7,8,9,11}; std::vector<int>::iteratorresult; taskflow.find_if( input.begin(),input.end(),[](inti){returni+1=23;},result ); executor.run(taskflow).wait(); assert(*result==22); Iterators are templated to enable stateful range using std::reference_wrapper. typename B typename E typename T typename UOP typename P DefaultPartitioner Task Task tf::FlowBuilder::find_if_not (B first, E last, T &result, UOP predicate, P part=P()) find_if_not B first E last T & result UOP predicate P part P() constructs a task to perform STL-styled find-if-not algorithm B beginning iterator type E ending iterator type T resulting iterator type UOP unary predicate type P partitioner type first start of the input range last end of the input range result resulting iterator to the found element in the input range predicate unary predicate which returns false for the required element part partitioning algorithm (default tf::DefaultPartitioner) Returns an iterator to the first element in the range [first, last) that satisfies the given criteria (or last if there is no such iterator). This method is equivalent to the parallel execution of the following loop: autofind_if(InputItfirst,InputItlast,UnaryPredicatep){ for(;first!=last;++first){ if(!predicate(*first)){ returnfirst; } } returnlast; } For example, the code below find the element that satisfies the given criteria (value is not equal to 1) from an input range of 10 elements: std::vector<int>input={1,1,1,1,22,1,1,1,1,1}; std::vector<int>::iteratorresult; taskflow.find_if_not( input.begin(),input.end(),[](inti){returni==1;},result ); executor.run(taskflow).wait(); assert(*result==22); Iterators are templated to enable stateful range using std::reference_wrapper. typename B typename E typename T typename C typename P Task Task tf::FlowBuilder::min_element (B first, E last, T &result, C comp, P part) min_element B first E last T & result C comp P part constructs a task to perform STL-styled min-element algorithm B beginning iterator type E ending iterator type T resulting iterator type C comparator type P partitioner type first start of the input range last end of the input range result resulting iterator to the found element in the input range comp comparison function object part partitioning algorithm (default tf::DefaultPartitioner) Finds the smallest element in the [first, last) using the given comparison function object. The iterator to that smallest element is stored in result. This method is equivalent to the parallel execution of the following loop: if(first==last){ returnlast; } autosmallest=first; ++first; for(;first!=last;++first){ if(comp(*first,*smallest)){ smallest=first; } } returnsmallest; For example, the code below find the smallest element from an input range of 10 elements. std::vector<int>input={1,1,1,1,1,-1,1,1,1,1}; std::vector<int>::iteratorresult; taskflow.min_element( input.begin(),input.end(),std::less<int>(),result ); executor.run(taskflow).wait(); assert(*result==-1); Iterators are templated to enable stateful range using std::reference_wrapper. typename B typename E typename T typename C typename P Task Task tf::FlowBuilder::max_element (B first, E last, T &result, C comp, P part) max_element B first E last T & result C comp P part constructs a task to perform STL-styled max-element algorithm B beginning iterator type E ending iterator type T resulting iterator type C comparator type P partitioner type first start of the input range last end of the input range result resulting iterator to the found element in the input range comp comparison function object part partitioning algorithm (default tf::DefaultPartitioner) Finds the largest element in the [first, last) using the given comparison function object. The iterator to that largest element is stored in result. This method is equivalent to the parallel execution of the following loop: if(first==last){ returnlast; } autolargest=first; ++first; for(;first!=last;++first){ if(comp(*largest,*first)){ largest=first; } } returnlargest; For example, the code below find the largest element from an input range of 10 elements. std::vector<int>input={1,1,1,1,1,2,1,1,1,1}; std::vector<int>::iteratorresult; taskflow.max_element( input.begin(),input.end(),std::less<int>(),result ); executor.run(taskflow).wait(); assert(*result==2); Iterators are templated to enable stateful range using std::reference_wrapper. typename B typename E typename C Task Task tf::FlowBuilder::sort (B first, E last, C cmp) sort B first E last C cmp constructs a dynamic task to perform STL-styled parallel sort B beginning iterator type (random-accessible) E ending iterator type (random-accessible) C comparator type first iterator to the beginning (inclusive) last iterator to the end (exclusive) cmp comparison operator The task spawns asynchronous tasks to sort elements in the range [first, last) in parallel. Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Sort for details. typename B typename E Task Task tf::FlowBuilder::sort (B first, E last) sort B first E last constructs a dynamic task to perform STL-styled parallel sort using the std::less<T> comparator, where T is the element type B beginning iterator type (random-accessible) E ending iterator type (random-accessible) first iterator to the beginning (inclusive) last iterator to the end (exclusive) The task spawns asynchronous tasks to parallel sort elements in the range [first, last) using the std::less<T> comparator, where T is the dereferenced iterator type. Iterators are templated to enable stateful range using std::reference_wrapper. Please refer to Parallel Sort for details. typename L void void tf::FlowBuilder::_linearize (L &) _linearize L & keys class to build a task dependency graph The class provides essential methods to construct a task dependency graph from which tf::Taskflow and tf::Subflow are derived. _graph tf::FlowBuilder_graph tf::FlowBuilder_linearize tf::FlowBuildercomposed_of tf::FlowBuilderemplace tf::FlowBuilderemplace tf::FlowBuilderemplace tf::FlowBuilderemplace tf::FlowBuilderemplace tf::FlowBuildererase tf::FlowBuilderexclusive_scan tf::FlowBuilderExecutor tf::FlowBuilderfind_if tf::FlowBuilderfind_if_not tf::FlowBuilderFlowBuilder tf::FlowBuilderfor_each tf::FlowBuilderfor_each_index tf::FlowBuilderinclusive_scan tf::FlowBuilderinclusive_scan tf::FlowBuilderlinearize tf::FlowBuilderlinearize tf::FlowBuildermax_element tf::FlowBuildermin_element tf::FlowBuilderplaceholder tf::FlowBuilderreduce tf::FlowBuildersort tf::FlowBuildersort tf::FlowBuildertransform tf::FlowBuildertransform tf::FlowBuildertransform_exclusive_scan tf::FlowBuildertransform_inclusive_scan tf::FlowBuildertransform_inclusive_scan tf::FlowBuildertransform_reduce tf::FlowBuildertransform_reduce