summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/task/task-register.hh
blob: 6608e02d9bd1fd436bc38a42b4c03bf13d933647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
 ** \file task/task-register.hh
 ** \brief Declare the task::TaskRegister class.
 **
 */

#pragma once

#include <iosfwd>
#include <map>
#include <string>
#include <vector>

#include <boost/program_options.hpp>

#include <misc/timer.hh>
#include <task/fwd.hh>

namespace task
{
  /** \brief Register Tasks.

  The purpose of the TaskRegister class is to collect tasks
  and organize their execution using their dependencies (like 'make').
  For modeling details, see Design Patterns: singleton.
  */
  class TaskRegister
  {
    // Make it non-copyable.
    TaskRegister(const TaskRegister&) = delete;
    TaskRegister& operator=(const TaskRegister&) = delete;

    /// \name Ctor & dtor.
  private:
    /// Construct a TaskRegister.
    TaskRegister() = default;

  public:
    /// Access to the unique TaskRegister.
    static TaskRegister& instance();

    /** \name Tasks registering.
     ** \{ */
    /// Register task \a task.
    void register_task(const SimpleTask& task);
    void register_task(const ArgumentTask& task);
    /// Register the task \a task_name for execution.
    void enable_task(const std::string& task_name);

    /// Return the number of tasks to execute.
    int nb_of_task_to_execute_get();
    /** \} */

    /// \name Task reordering.
  private:
    /** \brief Resolve dependencies between tasks.
     **
     ** Resolve dependencies on tasks registered for execution.
     ** Make a depth first search of implicit tasks graph,
     ** check cycles and build an ordered list of tasks. */
    void resolve_dependencies(const Task& task);

  public:
    /** \brief Parse \a argv and determine which tasks to execute.
     **
     ** Use boost::program_options. */
    char* parse_arg(int argc, char* argv[]);

    /** \name Display TaskRegister content.
     ** \{ */
    /// Display registered Tasks.
    std::ostream& print_task_list(std::ostream& ostr);
    /// Display task graph.
    std::ostream& print_task_graph(std::ostream& ostr);
    /// Display registered Tasks execution order.
    std::ostream& print_task_order(std::ostream& ostr);

    /** \name Using registered Tasks.
     ** \{ */
    /// Execute tasks, checking dependencies.
    void execute();
    /** \} */

    /** \name Time management.
     ** \{ */
    /// Access to the tasks timer.
    const misc::timer& timer_get() const;
    /** \} */

    /// Ordered vector of tasks.
    using tasks_list_type = std::vector<const Task*>;

  private:
    /// Associate a task name to a task.
    using tasks_by_name_type = std::map<const std::string, Task const*>;
    /// Associate a module name to a task module.
    using indexed_module_type =
      std::map<const std::string, boost::program_options::options_description>;

    // Common code between the two overload of `register_task'.
    indexed_module_type::iterator register_task_(const Task& task);

    /// 'string to task' map.
    tasks_by_name_type task_list_;

    /// 'ordered for execution' tasks list.
    tasks_list_type task_order_;

    /// Tasks timer.
    misc::timer timer_;

    /// Task modules.
    indexed_module_type modules_;
  };

} // namespace task

#include <task/task-register.hxx>