@@ -15,176 +15,141 @@ using namespace std;
1515#include < boost/program_options.hpp>
1616namespace po = boost::program_options;
1717
18+ #include " logging.hpp"
19+
1820namespace pfasst
1921{
22+
2023 namespace config
2124 {
2225 /* *
2326 * @note This is using the Singleton Pattern.
24- * pfasst::Options ::get_instance() is thread-safe with C++11.
27+ * pfasst::options ::get_instance() is thread-safe with C++11.
2528 */
26- class Options
29+ class options
2730 {
2831 public:
2932 // ! Maximum width of a line in the help output
3033 static const size_t LINE_WIDTH = 100 ;
3134
3235 private:
3336 po::options_description all_options;
34- vector<string> group_names;
3537 map<string, po::options_description> option_groups;
36- map<string, function< void (po::options_description&)>> init_functions;
37- po::variables_map vars_map ;
38+
39+ po::variables_map variables_map ;
3840 vector<string> unrecognized_args;
3941 bool initialized = false ;
4042
4143 private:
42- // ! ctor is private to make it a singleton
43- Options ()
44- {}
45- Options (const Options&) = delete ;
46- void operator =(const Options&) = delete ;
44+ options () {}
45+ options (const options&) = delete ;
46+ void operator =(const options&) = delete ;
4747
4848 public:
49- static Options & get_instance ()
49+ static options & get_instance ()
5050 {
51- static Options instance;
51+ static options instance;
5252 return instance;
5353 }
5454
5555 po::variables_map& get_variables_map ()
56- { return this ->vars_map ; }
56+ {
57+ return this ->variables_map ;
58+ }
5759
5860 po::options_description& get_all_options ()
59- { return this ->all_options ; }
61+ {
62+ return this ->all_options ;
63+ }
6064
6165 vector<string>& get_unrecognized_args ()
62- { return this ->unrecognized_args ; }
63-
64- /* *
65- * @throws invalid_argument if there is already an init function or options group with the
66- * given name registered
67- */
68- void register_init_function (const string& name,
69- const function<void (po::options_description&)>& fnc,
70- int index = -1)
7166 {
72- assert (fnc);
73- if (!this ->option_groups .count (name) && !this ->init_functions .count (name)) {
74- this ->option_groups .emplace (make_pair<string,
75- po::options_description>(string (name),
76- po::options_description (name,
77- LINE_WIDTH)));
78- this ->init_functions [name] = fnc;
79- if (index == -1 ) {
80- this ->group_names .push_back (name);
81- } else {
82- this ->group_names .insert (this ->group_names .begin () + index, name);
83- }
84- } else {
85- throw invalid_argument (" There is already an init function named '" + name + " ' registered." );
86- }
67+ return this ->unrecognized_args ;
68+ }
69+
70+ void add_option (string group, string option, string help)
71+ {
72+ this ->option_groups .emplace (make_pair<string,
73+ po::options_description>(string (group),
74+ po::options_description (string (group), LINE_WIDTH)));
75+ this ->option_groups [group].add_options ()
76+ (option.c_str (), help.c_str ());
77+ }
78+
79+ template <typename T>
80+ void add_option (string group, string option, string help)
81+ {
82+ this ->option_groups .emplace (make_pair<string,
83+ po::options_description>(string (group),
84+ po::options_description (string (group), LINE_WIDTH)));
85+ this ->option_groups [group].add_options ()
86+ (option.c_str (), po::value<T>(), help.c_str ());
8787 }
8888
8989 void init ()
9090 {
9191 if (!this ->initialized ) {
92- for (string name : this ->group_names ) {
93- auto fnc = this ->init_functions [name];
94- // calling init function
95- fnc (this ->option_groups [name]);
96- this ->all_options .add (this ->option_groups [name]);
92+ for (auto const & kv : this ->option_groups ) {
93+ this ->all_options .add (kv.second );
9794 }
98- this ->initialized = true ;
9995 }
96+ this ->initialized = true ;
10097 }
101- };
10298
99+ };
103100
104101 template <typename T>
105102 inline static T get_value (const string& name, const T& default_val)
106103 {
107- return Options ::get_instance ().get_variables_map ().count (name)
108- ? Options ::get_instance ().get_variables_map ()[name].as <T>() : default_val;
104+ return options ::get_instance ().get_variables_map ().count (name)
105+ ? options ::get_instance ().get_variables_map ()[name].as <T>() : default_val;
109106 }
110107
111-
112108 template <typename T>
113109 inline static T get_value (const string& name)
114110 {
115- return Options::get_instance ().get_variables_map ()[name].as <T>();
116- }
117-
118-
119- inline static bool no_params_given ()
120- {
121- return Options::get_instance ().get_variables_map ().empty ();
122- }
123-
124-
125- inline static string pretty_print ()
126- {
127- stringstream s;
128- s << " Logging Options:" << endl
129- << " -v [ --verbose ] activates maximum verbosity" << endl
130- << " --v=arg activates verbosity upto verbose level 2" << endl
131- << " (valid range: 0-9)" << endl
132- << " -vmodule=arg actives verbose logging for specific module" << endl
133- << " (see [1] for details)" << endl;
134- s << Options::get_instance ().get_all_options () << endl;
135- s << " [1]: https://github.com/easylogging/easyloggingpp#vmodule" ;
136- return s.str ();
111+ return options::get_instance ().get_variables_map ()[name].as <T>();
137112 }
138113
139-
140114 /* *
141115 * @returns empty string if params are set and `if_no_params` is `true`
142116 */
143117 inline static string print_help (bool if_no_params = false )
144118 {
145- if (!if_no_params || (if_no_params && no_params_given ())) {
146- return pretty_print ();
119+ bool no_params_given = options::get_instance ().get_variables_map ().empty ();
120+
121+ if (!if_no_params || (if_no_params && no_params_given)) {
122+ stringstream s;
123+ s << options::get_instance ().get_all_options () << endl;
124+ s << " Logging options:" << endl
125+ << " -v [ --verbose ] activates maximum verbosity" << endl
126+ << " --v=arg activates verbosity upto verbose level 2" << endl
127+ << " (valid range: 0-9)" << endl
128+ << " -vmodule=arg actives verbose logging for specific module" << endl
129+ << " (see [1] for details)" << endl;
130+ s << " [1]: https://github.com/easylogging/easyloggingpp#vmodule" << endl;
131+ return s.str ();
147132 } else {
148133 return string ();
149134 }
150135 }
151136
152-
153- inline static void init_global_options (po::options_description& opts)
154- {
155- opts.add_options ()
156- (" help,h" , " display this help message" );
157- }
158-
159-
160- inline static void init_config ()
161- {
162- Options::get_instance ()
163- .register_init_function (" Global Options" ,
164- function<void (po::options_description&)>(init_global_options),
165- 0 );
166-
167- Options::get_instance ().init ();
168- }
169-
170-
171137 inline static void read_commandline (int argc, char * argv[], bool exit_on_help = true )
172138 {
173139 po::parsed_options parsed = po::command_line_parser (argc, argv)
174- .options (Options ::get_instance ().get_all_options ())
140+ .options (options ::get_instance ().get_all_options ())
175141 .allow_unregistered ().run ();
176- Options ::get_instance ().get_unrecognized_args () = po::collect_unrecognized (parsed.options ,
142+ options ::get_instance ().get_unrecognized_args () = po::collect_unrecognized (parsed.options ,
177143 po::exclude_positional);
178- po::store (parsed, Options ::get_instance ().get_variables_map ());
179- po::notify (Options ::get_instance ().get_variables_map ());
144+ po::store (parsed, options ::get_instance ().get_variables_map ());
145+ po::notify (options ::get_instance ().get_variables_map ());
180146
181- if (Options ::get_instance ().get_variables_map ().count (" help" )) {
147+ if (options ::get_instance ().get_variables_map ().count (" help" )) {
182148 cout << print_help () << endl;
183149 if (exit_on_help) exit (0 );
184150 }
185151 }
186152
187-
188153 /* *
189154 * @throws invalid_argument if the given file could not be opened
190155 */
@@ -194,13 +159,36 @@ namespace pfasst
194159 if (!ifs) {
195160 throw invalid_argument (" Config file '" + file_name + " ' not found." );
196161 } else {
197- po::store (po::parse_config_file (ifs, Options ::get_instance ().get_all_options ()),
198- Options ::get_instance ().get_variables_map ());
199- po::notify (Options ::get_instance ().get_variables_map ());
162+ po::store (po::parse_config_file (ifs, options ::get_instance ().get_all_options ()),
163+ options ::get_instance ().get_variables_map ());
164+ po::notify (options ::get_instance ().get_variables_map ());
200165 }
201166 }
202167
168+ static void add_option (string group, string name, string help)
169+ {
170+ options::get_instance ().add_option (group, name, help);
171+ }
172+
173+ template <typename T>
174+ static void add_option (string group, string name, string help)
175+ {
176+ options::get_instance ().add_option <T>(group, name, help);
177+ }
178+
179+ inline static void init ()
180+ {
181+ add_option (" Global" , " help,h" , " display this help message" );
182+
183+ add_option<double >(" Duration" , " dt" , " time step size" );
184+ add_option<double >(" Duration" , " tend" , " final time of simulation" );
185+ add_option<size_t >(" Duration" , " num_iters" , " number of iterations" );
186+
187+ options::get_instance ().init ();
188+ }
189+
203190 } // ::pfasst::config
191+
204192} // ::pfasst
205193
206194#endif // _PFASST__CONFIG_HPP_
0 commit comments