Executor class
          #include <src/taskflow/core/executor.hpp>
        
        execution interface for running a taskflow graph
Contents
An executor object manages a set of worker threads to run taskflow(s) using an efficient work-stealing scheduling algorithm.
Constructors, destructors, conversion operators
Public functions
- 
              auto run(Taskflow& taskflow) -> tf::
Future<void>  - runs the taskflow once
 - 
              template<typename C>auto run(Taskflow& taskflow, C&& callable) -> tf::
Future<void>  - runs the taskflow once and invoke a callback upon completion
 - 
              auto run_n(Taskflow& taskflow,
              size_t N) -> tf::
Future<void>  - runs the taskflow for N times
 - 
              template<typename C>auto run_n(Taskflow& taskflow, size_t N, C&& callable) -> tf::
Future<void>  - runs the taskflow for N times and then invokes a callback
 - 
              template<typename P>auto run_until(Taskflow& taskflow, P&& pred) -> tf::
Future<void>  - runs the taskflow multiple times until the predicate becomes true and then invokes a callback
 - 
              template<typename P, typename C>auto run_until(Taskflow& taskflow, P&& pred, C&& callable) -> tf::
Future<void>  - runs the taskflow multiple times until the predicate becomes true and then invokes the callback
 - void wait_for_all()
 - wait for all pending graphs to complete
 - auto num_workers() const -> size_t
 - queries the number of worker threads (can be zero)
 - auto num_topologies() const -> size_t
 - queries the number of running topologies at the time of this call
 - auto this_worker_id() const -> int
 - queries the id of the caller thread in this executor
 - 
              template<typename F, typename... ArgsT>auto async(F&& f, ArgsT && ... args) -> auto
 - runs a given function asynchronously
 - 
              template<typename F, typename... ArgsT>void silent_async(F&& f, ArgsT && ... args)
 - similar to tf::
Executor:: async but does not return a future object  - 
              template<typename Observer, typename... ArgsT>auto make_observer(ArgsT && ... args) -> std::shared_ptr<Observer>
 - constructs an observer to inspect the activities of worker threads
 - 
              template<typename Observer>void remove_observer(std::shared_ptr<Observer> observer)
 - removes the associated observer
 - auto num_observers() const -> size_t
 - queries the number of observers
 
Function documentation
              tf:: Future<void> tf:: Executor:: run(Taskflow& taskflow)
            
            runs the taskflow once
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| Returns | a tf:: | 
                
              
                template<typename C>
              
              tf:: Future<void> tf:: Executor:: run(Taskflow& taskflow,
              C&& callable)
            
            runs the taskflow once and invoke a callback upon completion
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| callable | a callable object to be invoked after this run | 
| Returns | a tf:: | 
                
              tf:: Future<void> tf:: Executor:: run_n(Taskflow& taskflow,
              size_t N)
            
            runs the taskflow for N times
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| N | number of runs | 
| Returns | a tf:: | 
                
              
                template<typename C>
              
              tf:: Future<void> tf:: Executor:: run_n(Taskflow& taskflow,
              size_t N,
              C&& callable)
            
            runs the taskflow for N times and then invokes a callback
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| N | number of runs | 
| callable | a callable object to be invoked after this run | 
| Returns | a tf:: | 
                
              
                template<typename P>
              
              tf:: Future<void> tf:: Executor:: run_until(Taskflow& taskflow,
              P&& pred)
            
            runs the taskflow multiple times until the predicate becomes true and then invokes a callback
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| pred | a boolean predicate to return true for stop | 
| Returns | a tf:: | 
                
              
                template<typename P, typename C>
              
              tf:: Future<void> tf:: Executor:: run_until(Taskflow& taskflow,
              P&& pred,
              C&& callable)
            
            runs the taskflow multiple times until the predicate becomes true and then invokes the callback
| Parameters | |
|---|---|
| taskflow | a tf:: | 
                
| pred | a boolean predicate to return true for stop | 
| callable | a callable object to be invoked after this run | 
| Returns | a tf:: | 
                
              size_t tf:: Executor:: num_topologies() const
            
            queries the number of running topologies at the time of this call
When a taskflow is submitted to an executor, a topology is created to store runtime metadata of the running taskflow.
              int tf:: Executor:: this_worker_id() const
            
            queries the id of the caller thread in this executor
Each worker has an unique id from 0 to N-1 exclusive to the associated executor. If the caller thread does not belong to the executor, -1 is returned.
              
                template<typename F, typename... ArgsT>
              
              auto tf:: Executor:: async(F&& f,
              ArgsT && ... args)
            
            runs a given function asynchronously
| Template parameters | |
|---|---|
| F | callable type | 
| ArgsT | parameter types | 
| Parameters | |
| f | callable object to call | 
| args | parameters to pass to the callable | 
| Returns | a tf:: | 
                
This method is thread-safe. Multiple threads can launch asynchronous tasks at the same time.
              
                template<typename Observer, typename... ArgsT>
              
              std::shared_ptr<Observer> tf:: Executor:: make_observer(ArgsT && ... args)
            
            constructs an observer to inspect the activities of worker threads
| Template parameters | |
|---|---|
| Observer | observer type derived from tf:: | 
                
| ArgsT | argument parameter pack | 
| Parameters | |
| args | arguments to forward to the constructor of the observer | 
| Returns | a shared pointer to the created observer | 
Each executor manage a list of observers in shared ownership with callers.