mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
appConfigurator.hpp
Go to the documentation of this file.
1 /** \file appConfigurator.hpp
2  * \author Jared R. Males
3  * \brief An application configuration manager
4  *
5  * \ingroup mxApp_files
6  *
7  */
8 
9 //***********************************************************************//
10 // Copyright 2015, 2016, 2017, 2018 Jared R. Males (jaredmales@gmail.com)
11 //
12 // This file is part of mxlib.
13 //
14 // mxlib is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 // mxlib is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
26 //***********************************************************************//
27 
28 #ifndef app_appConfigurator_hpp
29 #define app_appConfigurator_hpp
30 
31 #include <list>
32 #include <fstream>
33 
34 #include "../mxError.hpp"
35 
36 
37 #include "clOptions.hpp"
38 #include "iniFile.hpp"
39 #include "configTarget.hpp"
40 
41 
42 namespace mx
43 {
44 namespace app
45 {
46 
47 /// Class to manage a set of configurable values, and read their values from config/ini files and the command line.
48 /**
49  * The configuration files are TOML/ini-style, with sections. That is
50  \verbatim
51  key1=value1
52  key2=value2
53 
54  [section1]
55  key3=value3
56  key4=value4,value4.1, value4.2, value4.3
57 
58  [section2]
59  key3=value5
60  key3=value5.1
61  key4=value6_over_
62  multiple_lines
63 
64  \endverbatim
65  * such that section1.key3 is distinct from section2.key3 (they must have different config-target names though).
66  *
67  * Additional syntax rules:
68  * - Leading whitespace is stripped from the value, so `key=val` and `key= val` are equivalent.
69  * - Additional entries within one file with the same section and key are appended to the previous entry.
70  * So the value of section2.key3 is "value5value5.1".
71  * - Multi-line values are handled such that in the above example the result is key4=value6_over_multiple_lines.
72  * - Vectors are input as comma separated lists, as in section1.key4 above. Leading whitespace is stripped from each
73  * component of the vector.
74  *
75  * \todo add handling of += in subsequent files.
76  * \todo should just swith to strict TOML
77  *
78  * The command line parser handles both short-opt ("-h -vArg -n Arg") and long-opt ("--help --value=Arg --number=Arg") styles.
79  *
80  *
81  * \bug a config=value pair listed in a conf file twice seems to cause a failure, even if they are the same value.
82  *
83  * \ingroup mxApp
84  *
85  */
87 {
88  ///Iterator for the targets unordered_map
89  typedef std::unordered_map<std::string, configTarget>::iterator targetIterator;
90 
91  ///Iterator for the clOnlyTargets list.
92  typedef std::list<configTarget>::iterator clOnlyTargetIterator;
93 
94  ///The targets are stored in an unordered_map for fast access by key.
95  std::unordered_map<std::string, configTarget> m_targets;
96 
97  /// Config file entries present in the file(s), but not corresponding to a target when parsed. Set aside for possible analysis.
98  std::unordered_map<std::string, configTarget> m_unusedConfigs;
99 
100  ///Targets which are only for the command line are stored separately in a list.
101  std::list<configTarget> clOnlyTargets;
102 
103  /// Non-option arguments from the command line.
104  std::vector<std::string> nonOptions;
105 
106  /// Running count of options added, used to track order.
107  int nAdded {0};
108 
109  /// Flag controlling whether or not to record config sources
110  bool m_sources {false};
111 
112  /// Clear the containers and free up the associated memory.
113  void clear();
114 
115  /// Add a configTarget
116  /** Note that if name is a duplicate but the section and keyword are empty, it is handled as command-line only.
117  */
118  void add( const configTarget & tgt /**< [in] The configuration target to add */);
119 
120  /// Add a configTarget
121  /**
122  * \overload
123  */
124  void add( const std::string &n, ///< [in] The name of the target
125  const std::string &so, ///< [in] The command-line short option (e.g. "f" for -f)
126  const std::string &lo, ///< [in] The command-line long option (e.g. "file" for --file)
127  int clt, ///< [in] The command-line option type, argType::false, argType::true, argType::optional, argType::required
128  const std::string & s, ///< [in] The config file section name, can be empty ""
129  const std::string & kw, ///< [in] The config file keyword, read in a "keyword=value" pair
130  bool isReq = false, ///< [in] Whether or not this option is required to be set
131  const std::string & ht = "", ///< [in] The type to display in the help message
132  const std::string & he = "" ///< [in] The explanation to display in the help message
133  );
134 
135  ///Parse the command line, updating the targets
136  void parseCommandLine( int argc, ///< [in] standard command line result specifying number of argumetns in argv
137  char ** argv, ///< [in] standard command line result containing the arguments.
138  const std::string & oneTarget = "" ///< [in] [optional] if not empty, then only this target is extracted by the parser.
139  );
140 
141 
142  ///Read and parse a config/ini file, updating the targets
143  /** \todo handle += here, by appending to the last value as if a vector.
144  */
145  int readConfig( const std::string & fname, ///< [in] the config file name
146  bool reportFileNotFound = true ///< [in] [optiona] control whether a file not found is reported.
147  );
148 
149  /// Check if a target has been set by the configuration
150  /**
151  * \returns true if the configuration set at least one value for this target
152  * \returns false if no value was set.
153  */
154  bool isSet( const std::string & name, ///< [in] the target name
155  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
156  );
157 
158  /// Check if a target has been set by the configuration
159  /**
160  * \overload
161  *
162  * \returns true if the configuration set at least one value for this target
163  * \returns false if no value was set.
164  */
165  bool isSet(const std::string & name /**< [in] the target name */);
166 
167  ///Get the number of different values set for the specified config target
168  /**
169  * \returns the number of different values set for name.
170  */
171  int count( const std::string & name, ///< [in] the target name
172  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
173  );
174 
175  ///Get the number of different values set for the specified config target
176  /**
177  * \overload
178  *
179  * \returns the number of different values set for name.
180  */
181  int count( const std::string & name /**< [in] the target name */);
182 
183  ///Get the command line verbosity count for this option.
184  /** E.g., -v ==> 1, -vv ==> 2, -vvv ==> 3, etc. Note that for this to work
185  * properly, this must be of type mx::argType::True.
186  *
187  * \returns the verbosity count.
188  */
189  int verbosity( const std::string & name, ///< [in] the target name
190  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
191  );
192 
193  ///Get the command line verbosity count for this option.
194  /** E.g., -v ==> 1, -vv ==> 2, -vvv ==> 3, etc. Note that for this to work
195  * properly, this must be of type mx::argType::True.
196  *
197  * \overload
198  *
199  * \returns the verbosity count.
200  */
201  int verbosity( const std::string & name /**< [in] the target name */);
202 
203  /// Get the i-th value of the target, converted to the specified type
204  /** The supplied value is only altered if the config target was set, which preserves.
205  * default values.
206  *
207  * \retval 0 on success
208  * \retval -1 on error
209  */
210  template<typename typeT>
211  int get( typeT & v, ///< [out] the variable to store the value in, unaltered if not set.
212  const std::string & name, ///< [in] the config target name
213  size_t i, ///< [in] the number of config specification to get.
214  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
215  );
216 
217  /// Get the i-th value of the target from the used set, converted to the specified type
218  /** The supplied value is only altered if the config target was set, which preserves.
219  * default values.
220  *
221  * \overload
222  *
223  * \retval 0 on success
224  * \retval -1 on error
225  */
226  template<typename typeT>
227  int get( typeT & v, ///< [out] the variable to store the value in
228  const std::string & name, ///< [in] the config target name
229  size_t i ///< [in] the number of config specification to get.
230  );
231 
232  /// Get the final value of the target, converted to the specified type
233  /** The supplied value is only altered if the config target was set, which preserves.
234  * default values.
235  *
236  * \overload
237  *
238  * \retval 0 on success.
239  * \retval -1 on error.
240  */
241  template<typename typeT>
242  int get( typeT & v, ///< [out] the variable to store the value in
243  const std::string & name, ///< [in] the config target name
244  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
245  );
246 
247  /// Get the final value of the target from the used set, converted to the specified type
248  /** The supplied value is only altered if the config target was set, which preserves.
249  * default values.
250  *
251  * \overload
252  *
253  * \retval 0 on success.
254  * \retval -1 on error.
255  */
256  template<typename typeT>
257  int get( typeT & v, ///< [out] the variable to store the value in
258  const std::string & name ///< [in] the config target name
259  );
260 
261  /// Get the i-th value of the target, converted to the specified config target
262  /** The vector is only populated if the config target was set. If it is populated,
263  * it is cleared first. Thus if a vector filled with default values is passed
264  * in, it will only be overwritten if the user specified new values.
265  *
266  * \returns 0 on success
267  * \returns -1 on error
268  */
269  template<typename typeT>
270  int get( std::vector<typeT> & v, ///< [out] the vector to populate
271  const std::string & name, ///< [in] the config target name.
272  size_t i, ///< [in] the number of config specification to get.
273  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
274  );
275 
276  /// Get the i-th value of the target, converted to the specified config target
277  /** The vector is only populated if the config target was set. If it is populated,
278  * it is cleared first. Thus if a vector filled with default values is passed
279  * in, it will only be overwritten if the user specified new values.
280  *
281  * \returns 0 on success
282  * \returns -1 on error
283  */
284  template<typename typeT>
285  int get( std::vector<typeT> & v, ///< [out] the vector to populate
286  const std::string & name, ///< [in] the config target name.
287  size_t i ///< [in] the number of config specification to get.
288  );
289 
290  /// Get the i-th value of the target as a vector containing the specified type.
291  /** The vector is only populated if the config target was set. If it is populated,
292  * it is cleared first. Thus if a vector filled with default values is passed
293  * in, it will only be overwritten if the user specified new values.
294  *
295  * \retval 0 on success.
296  * \retval -1 on error.
297  */
298  template<typename typeT>
299  int get( std::vector<typeT> & v, ///< [out] the vector to populate
300  const std::string & name, ///< [in] the config target name.
301  std::unordered_map<std::string, configTarget> & targets ///< [in] the map of config targets to use
302  );
303 
304  /// Get the i-th value of the target in the used set, as a vector containing the specified type.
305  /** The vector is only populated if the config target was set. If it is populated,
306  * it is cleared first. Thus if a vector filled with default values is passed
307  * in, it will only be overwritten if the user specified new values.
308  *
309  * \retval 0 on success.
310  * \retval -1 on error.
311  */
312  template<typename typeT>
313  int get( std::vector<typeT> & v, ///< [out] the vector to populate
314  const std::string & name ///< [in] the config target name.
315  );
316 
317  /// Access operator, configures a value by calling get.
318  /**
319  * \retval 0 on success
320  * \retval -1 on error
321  */
322  template<typename typeT>
323  int operator()( typeT & v, ///< [out] the variable to populate (either scalar or vector), will be unaltered if not set.
324  const std::string & name ///< [in] the config target name.
325  );
326 
327  /// Configure a value from the unused map, using the iniFile key.
328  /**
329  * \retval 0 on success
330  * \retval -1 on error
331  */
332  template<typename typeT>
333  int configUnused( typeT & v, ///< [out] the variable to populate (either scalar or vector), will be unaltered if not set.
334  const std::string & key ///< [in] the iniFile key for this target.
335  );
336 
337  /// Configure a value from the unused map, using the section and keyword.
338  /**
339  * \retval 0 on success
340  * \retval -1 on error
341  */
342  template<typename typeT>
343  int configUnused( typeT & v, ///< [out] the variable to populate (either scalar or vector), will be unaltered if not set.
344  const std::string & section, ///< [in] the section name for this target
345  const std::string & keyword ///< [in] the keyword for this target.
346  );
347 
348  /// Get the unique sections in the unused config targets.
349  /**
350  * \retval 0 on success
351  * \retval -1 on error
352  */
353  int unusedSections( std::vector<std::string> & sections );
354 
355  /// Check if a target has been set in the unused configuration
356  /**
357  * \returns true if the unused configuration set at least one value for this target
358  * \returns false if no value was set.
359  */
360  int isSetUnused( const std::string & name /**< [in] the target name */);
361 
362 
363  /// Call an external logging function whenever a config value is accessed by get or operator().
364  /** Only called if this is not a nullptr (the default), otherwise no logging or reporting is done.
365  */
366  void (*configLog)( const std::string & name, ///< [in] The name of the config target.
367  const int & code, ///< [in] The type code from mx::typeDescription
368  const std::string & valueStr, ///< [in] The value in its string form as found in the configuration
369  const std::string & source ///< [in] The source of the value, either default, command line, or a path.
370  ) {nullptr};
371 
372  /// Get the number of unknown options found during config processing.
374 };
375 
376 template<typename typeT>
377 int appConfigurator::get( typeT & v,
378  const std::string & name,
379  size_t i,
380  std::unordered_map<std::string, configTarget> & targets
381  )
382 {
383  targets[name].used = true; //This means this was checked.
384 
385  if(!isSet(name, targets))
386  {
387  if(configLog)
388  {
390  }
391 
392  return 0;
393  }
394 
395  if( targets[name].values.size() <= i) return -1;
396 
397  v = ioutils::convertFromString<typeT>(targets[name].values[i]);
398 
399  //Log it here.
400  if(configLog)
401  {
402  if(m_sources)
403  {
404  configLog(name, meta::typeDescription<typeT>::code(), targets[name].values[i], targets[name].sources[i]);
405  }
406  else
407  {
408  configLog(name, meta::typeDescription<typeT>::code(), targets[name].values[i], "");
409  }
410  }
411 
412  return 0;
413 }
414 //explicits
415 extern template
416 int appConfigurator::get<char>( char & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
417 
418 extern template
419 int appConfigurator::get<char16_t>( char16_t & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
420 
421 extern template
422 int appConfigurator::get<char32_t>( char32_t & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
423 
424 extern template
425 int appConfigurator::get<wchar_t>( wchar_t & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
426 
427 extern template
428 int appConfigurator::get<signed char>( signed char & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
429 
430 extern template
431 int appConfigurator::get<short>( short & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
432 
433 extern template
434 int appConfigurator::get<int>( int & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
435 
436 extern template
437 int appConfigurator::get<long>( long & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
438 
439 extern template
440 int appConfigurator::get<long long>( long long & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
441 
442 extern template
443 int appConfigurator::get<unsigned char>( unsigned char & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
444 
445 extern template
446 int appConfigurator::get<unsigned short>( unsigned short & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
447 
448 extern template
449 int appConfigurator::get<unsigned int>( unsigned int & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
450 
451 extern template
452 int appConfigurator::get<unsigned long>( unsigned long & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
453 
454 extern template
455 int appConfigurator::get<unsigned long long>( unsigned long long & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
456 
457 extern template
458 int appConfigurator::get<float>( float & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
459 
460 extern template
461 int appConfigurator::get<double>( double & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
462 
463 extern template
464 int appConfigurator::get<long double>( long double & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
465 
466 #ifdef HASQUAD
467 extern template
468 int appConfigurator::get<__float128>( __float128 & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
469 #endif
470 
471 extern template
472 int appConfigurator::get<bool>( bool & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
473 
474 extern template
475 int appConfigurator::get<std::string>( std::string & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
476 
477 //+++++++++++++++++++++++++++++++++++++
478 
479 template<typename typeT>
480 int appConfigurator::get( typeT & v,
481  const std::string & name,
482  size_t i
483  )
484 {
485  return get(v, name, i, m_targets);
486 }
487 
488 //explicits
489 extern template
490 int appConfigurator::get<char>( char & v, const std::string & name, size_t i);
491 
492 extern template
493 int appConfigurator::get<char16_t>( char16_t & v, const std::string & name, size_t i);
494 
495 extern template
496 int appConfigurator::get<char32_t>( char32_t & v, const std::string & name, size_t i);
497 
498 extern template
499 int appConfigurator::get<wchar_t>( wchar_t & v, const std::string & name, size_t i);
500 
501 extern template
502 int appConfigurator::get<signed char>( signed char & v, const std::string & name, size_t i);
503 
504 extern template
505 int appConfigurator::get<short>( short & v, const std::string & name, size_t i);
506 
507 extern template
508 int appConfigurator::get<int>( int & v, const std::string & name, size_t i);
509 
510 extern template
511 int appConfigurator::get<long>( long & v, const std::string & name, size_t i);
512 
513 extern template
514 int appConfigurator::get<long long>( long long & v, const std::string & name, size_t i);
515 
516 extern template
517 int appConfigurator::get<unsigned char>( unsigned char & v, const std::string & name, size_t i);
518 
519 extern template
520 int appConfigurator::get<unsigned short>( unsigned short & v, const std::string & name, size_t i);
521 
522 extern template
523 int appConfigurator::get<unsigned int>( unsigned int & v, const std::string & name, size_t i);
524 
525 extern template
526 int appConfigurator::get<unsigned long>( unsigned long & v, const std::string & name, size_t i);
527 
528 extern template
529 int appConfigurator::get<unsigned long long>( unsigned long long & v, const std::string & name, size_t i);
530 
531 extern template
532 int appConfigurator::get<float>( float & v, const std::string & name, size_t i);
533 
534 extern template
535 int appConfigurator::get<double>( double & v, const std::string & name, size_t i);
536 
537 extern template
538 int appConfigurator::get<long double>( long double & v, const std::string & name, size_t i);
539 
540 #ifdef HASQUAD
541 extern template
542 int appConfigurator::get<__float128>( __float128 & v, const std::string & name, size_t i);
543 #endif
544 
545 extern template
546 int appConfigurator::get<bool>( bool & v, const std::string & name, size_t i);
547 
548 extern template
549 int appConfigurator::get<std::string>( std::string & v, const std::string & name, size_t i);
550 
551 //+++++++++++++++++++++++++++++++++++++
552 
553 template<typename typeT>
554 int appConfigurator::get( typeT & v,
555  const std::string & name,
556  std::unordered_map<std::string, configTarget> & targets
557  )
558 {
559  targets[name].used = true; //This means this was checked.
560 
561  if(!isSet(name, targets))
562  {
563  if(configLog)
564  {
566  }
567 
568  return 0;
569  }
570 
571  int i = targets[name].values.size() - 1;
572 
573  if(i < 0) return -1;
574 
575  return get(v, name, i, targets);
576 }
577 //explicits:
578 
579 extern template
580 int appConfigurator::get<char>( char & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
581 
582 extern template
583 int appConfigurator::get<char16_t>( char16_t & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
584 
585 extern template
586 int appConfigurator::get<char32_t>( char32_t & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
587 
588 extern template
589 int appConfigurator::get<wchar_t>( wchar_t & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
590 
591 extern template
592 int appConfigurator::get<signed char>( signed char & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
593 
594 extern template
595 int appConfigurator::get<short>( short & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
596 
597 extern template
598 int appConfigurator::get<int>( int & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
599 
600 extern template
601 int appConfigurator::get<long>( long & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
602 
603 extern template
604 int appConfigurator::get<long long>( long long & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
605 
606 extern template
607 int appConfigurator::get<unsigned char>( unsigned char & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
608 
609 extern template
610 int appConfigurator::get<unsigned short>( unsigned short & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
611 
612 extern template
613 int appConfigurator::get<unsigned int>( unsigned int & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
614 
615 extern template
616 int appConfigurator::get<unsigned long>( unsigned long & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
617 
618 extern template
619 int appConfigurator::get<unsigned long long>( unsigned long long & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
620 
621 extern template
622 int appConfigurator::get<float>( float & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
623 
624 extern template
625 int appConfigurator::get<double>( double & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
626 
627 extern template
628 int appConfigurator::get<long double>( long double & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
629 
630 #ifdef HASQUAD
631 extern template
632 int appConfigurator::get<__float128>( __float128 & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
633 #endif
634 
635 extern template
636 int appConfigurator::get<bool>( bool & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
637 
638 extern template
639 int appConfigurator::get<std::string>( std::string & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
640 
641 //+++++++++++++++++++++++++++++++++++++
642 
643 template<typename typeT>
644 int appConfigurator::get( typeT & v,
645  const std::string & name)
646 {
647  return get(v, name, m_targets);
648 }
649 //explicits:
650 
651 extern template
652 int appConfigurator::get<char>( char & v, const std::string & name);
653 
654 extern template
655 int appConfigurator::get<char16_t>( char16_t & v, const std::string & name);
656 
657 extern template
658 int appConfigurator::get<char32_t>( char32_t & v, const std::string & name);
659 
660 extern template
661 int appConfigurator::get<wchar_t>( wchar_t & v, const std::string & name);
662 
663 extern template
664 int appConfigurator::get<signed char>( signed char & v, const std::string & name);
665 
666 extern template
667 int appConfigurator::get<short>( short & v, const std::string & name);
668 
669 extern template
670 int appConfigurator::get<int>( int & v, const std::string & name);
671 
672 extern template
673 int appConfigurator::get<long>( long & v, const std::string & name);
674 
675 extern template
676 int appConfigurator::get<long long>( long long & v, const std::string & name);
677 
678 extern template
679 int appConfigurator::get<unsigned char>( unsigned char & v, const std::string & name);
680 
681 extern template
682 int appConfigurator::get<unsigned short>( unsigned short & v, const std::string & name);
683 
684 extern template
685 int appConfigurator::get<unsigned int>( unsigned int & v, const std::string & name);
686 
687 extern template
688 int appConfigurator::get<unsigned long>( unsigned long & v, const std::string & name);
689 
690 extern template
691 int appConfigurator::get<unsigned long long>( unsigned long long & v, const std::string & name);
692 
693 extern template
694 int appConfigurator::get<float>( float & v, const std::string & name);
695 
696 extern template
697 int appConfigurator::get<double>( double & v, const std::string & name);
698 
699 extern template
700 int appConfigurator::get<long double>( long double & v, const std::string & name);
701 
702 #ifdef HASQUAD
703 extern template
704 int appConfigurator::get<__float128>( __float128 & v, const std::string & name);
705 #endif
706 
707 extern template
708 int appConfigurator::get<bool>( bool & v, const std::string & name);
709 
710 extern template
711 int appConfigurator::get<std::string>( std::string & v, const std::string & name);
712 
713 //+++++++++++++++++++++++++++++++++++++
714 template<typename typeT>
715 int appConfigurator::get( std::vector<typeT> & v,
716  const std::string & name,
717  size_t i,
718  std::unordered_map<std::string, configTarget> & targets
719  )
720 {
721  targets[name].used = true; //This means this was checked.
722 
723  if(!isSet(name, targets))
724  {
725  if(configLog)
726  {
727  configLog(name, meta::typeDescription<typeT>::code(), "[need a vector to string]", "default");
728  }
729 
730  return 0;
731  }
732 
733  if( targets[name].values.size() <= i) return -1;
734 
735  std::string s;
736 
737 
738  s = ioutils::convertFromString<std::string>(targets[name].values[i]);
739 
740  //if( get<std::string>(s, name, i, targets) < 0) return -1;
741 
742  //Case that s was set to be empty.
743  if(s.size() == 0)
744  {
745  if(configLog)
746  {
747  if(m_sources)
748  {
749  configLog(name, meta::typeDescription<typeT>::code(), "", targets[name].sources[i]);
750  }
751  else
752  {
754  }
755  }
756 
757  v.clear(); //We clear the vector passed as default
758  return 0;
759  }
760 
761  size_t st;
762  size_t com;
763 
764  st = 0;
765 
766  while(::isspace(s[st]) && st < s.size()-1) ++st;
767 
768  com = s.find(',', st);
769 
770  v.clear();
771 
772  while(com != std::string::npos)
773  {
774  v.push_back( ioutils::convertFromString<typeT>(s.substr(st, com-st)) );
775  st = com + 1;
776  while(::isspace(s[st]) && st < s.size()-1) ++st;
777 
778  com = s.find(',', st);
779  }
780  v.push_back( ioutils::convertFromString<typeT>(s.substr(st, s.size()-st)));
781 
782  //Log it here.
783  if(configLog)
784  {
785  if(m_sources)
786  {
787  configLog(name, meta::typeDescription<typeT>::code(), targets[name].values[i], targets[name].sources[i]);
788  }
789  else
790  {
791  configLog(name, meta::typeDescription<typeT>::code(), targets[name].values[i], "");
792  }
793  }
794 
795  return 0;
796 }
797 //explicits:
798 
799 extern template
800 int appConfigurator::get<char>( std::vector<char> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
801 
802 extern template
803 int appConfigurator::get<char16_t>( std::vector<char16_t> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
804 
805 extern template
806 int appConfigurator::get<char32_t>( std::vector<char32_t> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
807 
808 extern template
809 int appConfigurator::get<wchar_t>( std::vector<wchar_t> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
810 
811 extern template
812 int appConfigurator::get<signed char>( std::vector<signed char> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
813 
814 extern template
815 int appConfigurator::get<short>( std::vector<short> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
816 
817 extern template
818 int appConfigurator::get<int>( std::vector<int> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
819 
820 extern template
821 int appConfigurator::get<long>( std::vector<long> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
822 
823 extern template
824 int appConfigurator::get<long long>( std::vector<long long> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
825 
826 extern template
827 int appConfigurator::get<unsigned char>( std::vector<unsigned char> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
828 
829 extern template
830 int appConfigurator::get<unsigned short>( std::vector<unsigned short> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
831 
832 extern template
833 int appConfigurator::get<unsigned int>( std::vector<unsigned int> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
834 
835 extern template
836 int appConfigurator::get<unsigned long>( std::vector<unsigned long> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
837 
838 extern template
839 int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
840 
841 extern template
842 int appConfigurator::get<float>( std::vector<float> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
843 
844 extern template
845 int appConfigurator::get<double>( std::vector<double> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
846 
847 extern template
848 int appConfigurator::get<long double>( std::vector<long double> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
849 
850 #ifdef HASQUAD
851 extern template
852 int appConfigurator::get<__float128>( std::vector<__float128> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
853 #endif
854 
855 extern template
856 int appConfigurator::get<bool>( std::vector<bool> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
857 
858 extern template
859 int appConfigurator::get<std::string>( std::vector<std::string> & v, const std::string & name, size_t i, std::unordered_map<std::string, configTarget> & targets);
860 
861 //+++++++++++++++++++++++++++++++++++++
862 
863 template<typename typeT>
864 int appConfigurator::get( std::vector<typeT> & v,
865  const std::string & name,
866  size_t i
867  )
868 {
869  return get(v, name, i, m_targets);
870 }
871 
872 //explicits:
873 
874 extern template
875 int appConfigurator::get<char>( std::vector<char> & v, const std::string & name, size_t i);
876 
877 extern template
878 int appConfigurator::get<char16_t>( std::vector<char16_t> & v, const std::string & name, size_t i);
879 
880 extern template
881 int appConfigurator::get<char32_t>( std::vector<char32_t> & v, const std::string & name, size_t i);
882 
883 extern template
884 int appConfigurator::get<wchar_t>( std::vector<wchar_t> & v, const std::string & name, size_t i);
885 
886 extern template
887 int appConfigurator::get<signed char>( std::vector<signed char> & v, const std::string & name, size_t i);
888 
889 extern template
890 int appConfigurator::get<short>( std::vector<short> & v, const std::string & name, size_t i);
891 
892 extern template
893 int appConfigurator::get<int>( std::vector<int> & v, const std::string & name, size_t i);
894 
895 extern template
896 int appConfigurator::get<long>( std::vector<long> & v, const std::string & name, size_t i);
897 
898 extern template
899 int appConfigurator::get<long long>( std::vector<long long> & v, const std::string & name, size_t i);
900 
901 extern template
902 int appConfigurator::get<unsigned char>( std::vector<unsigned char> & v, const std::string & name, size_t i);
903 
904 extern template
905 int appConfigurator::get<unsigned short>( std::vector<unsigned short> & v, const std::string & name, size_t i);
906 
907 extern template
908 int appConfigurator::get<unsigned int>( std::vector<unsigned int> & v, const std::string & name, size_t i);
909 
910 extern template
911 int appConfigurator::get<unsigned long>( std::vector<unsigned long> & v, const std::string & name, size_t i);
912 
913 extern template
914 int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> & v, const std::string & name, size_t i);
915 
916 extern template
917 int appConfigurator::get<float>( std::vector<float> & v, const std::string & name, size_t i);
918 
919 extern template
920 int appConfigurator::get<double>( std::vector<double> & v, const std::string & name, size_t i);
921 
922 extern template
923 int appConfigurator::get<long double>( std::vector<long double> & v, const std::string & name, size_t i);
924 
925 #ifdef HASQUAD
926 extern template
927 int appConfigurator::get<__float128>( std::vector<__float128> & v, const std::string & name, size_t i);
928 #endif
929 
930 extern template
931 int appConfigurator::get<bool>( std::vector<bool> & v, const std::string & name, size_t i);
932 
933 extern template
934 int appConfigurator::get<std::string>( std::vector<std::string> & v, const std::string & name, size_t i);
935 
936 //+++++++++++++++++++++++++++++++++++++
937 template<typename typeT>
938 int appConfigurator::get( std::vector<typeT> & v,
939  const std::string & name,
940  std::unordered_map<std::string, configTarget> & targets
941  )
942 {
943  targets[name].used = true; //This means this was checked.
944 
945  if(!isSet(name, targets))
946  {
947  if(configLog)
948  {
949  configLog(name, meta::typeDescription<typeT>::code(), "[need a vector to string]", "default");
950  }
951  return 0;
952  }
953  int i = targets[name].values.size() - 1;
954 
955  if(i < 0) return -1;
956 
957  return get(v, name, i, targets);
958 }
959 //explicits:
960 
961 extern template
962 int appConfigurator::get<char>( std::vector<char> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
963 
964 extern template
965 int appConfigurator::get<char16_t>( std::vector<char16_t> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
966 
967 extern template
968 int appConfigurator::get<char32_t>( std::vector<char32_t> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
969 
970 extern template
971 int appConfigurator::get<wchar_t>( std::vector<wchar_t> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
972 
973 extern template
974 int appConfigurator::get<signed char>( std::vector<signed char> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
975 
976 extern template
977 int appConfigurator::get<short>( std::vector<short> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
978 
979 extern template
980 int appConfigurator::get<int>( std::vector<int> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
981 
982 extern template
983 int appConfigurator::get<long>( std::vector<long> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
984 
985 extern template
986 int appConfigurator::get<long long>( std::vector<long long> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
987 
988 extern template
989 int appConfigurator::get<unsigned char>( std::vector<unsigned char> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
990 
991 extern template
992 int appConfigurator::get<unsigned short>( std::vector<unsigned short> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
993 
994 extern template
995 int appConfigurator::get<unsigned int>( std::vector<unsigned int> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
996 
997 extern template
998 int appConfigurator::get<unsigned long>( std::vector<unsigned long> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
999 
1000 extern template
1001 int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1002 
1003 extern template
1004 int appConfigurator::get<float>( std::vector<float> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1005 
1006 extern template
1007 int appConfigurator::get<double>( std::vector<double> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1008 
1009 extern template
1010 int appConfigurator::get<long double>( std::vector<long double> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1011 
1012 #ifdef HASQUAD
1013 extern template
1014 int appConfigurator::get<__float128>( std::vector<__float128> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1015 #endif
1016 
1017 extern template
1018 int appConfigurator::get<bool>( std::vector<bool> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1019 
1020 extern template
1021 int appConfigurator::get<std::string>( std::vector<std::string> & v, const std::string & name, std::unordered_map<std::string, configTarget> & targets);
1022 
1023 //+++++++++++++++++++++++++++++++++++++
1024 
1025 template<typename typeT>
1026 int appConfigurator::get( std::vector<typeT> & v,
1027  const std::string & name
1028  )
1029 {
1030  return get(v, name, m_targets);
1031 }
1032 //explicits:
1033 
1034 extern template
1035 int appConfigurator::get<char>( std::vector<char> & v, const std::string & name);
1036 
1037 extern template
1038 int appConfigurator::get<char16_t>( std::vector<char16_t> & v, const std::string & name);
1039 
1040 extern template
1041 int appConfigurator::get<char32_t>( std::vector<char32_t> & v, const std::string & name);
1042 
1043 extern template
1044 int appConfigurator::get<wchar_t>( std::vector<wchar_t> & v, const std::string & name);
1045 
1046 extern template
1047 int appConfigurator::get<signed char>( std::vector<signed char> & v, const std::string & name);
1048 
1049 extern template
1050 int appConfigurator::get<short>( std::vector<short> & v, const std::string & name);
1051 
1052 extern template
1053 int appConfigurator::get<int>( std::vector<int> & v, const std::string & name);
1054 
1055 extern template
1056 int appConfigurator::get<long>( std::vector<long> & v, const std::string & name);
1057 
1058 extern template
1059 int appConfigurator::get<long long>( std::vector<long long> & v, const std::string & name);
1060 
1061 extern template
1062 int appConfigurator::get<unsigned char>( std::vector<unsigned char> & v, const std::string & name);
1063 
1064 extern template
1065 int appConfigurator::get<unsigned short>( std::vector<unsigned short> & v, const std::string & name);
1066 
1067 extern template
1068 int appConfigurator::get<unsigned int>( std::vector<unsigned int> & v, const std::string & name);
1069 
1070 extern template
1071 int appConfigurator::get<unsigned long>( std::vector<unsigned long> & v, const std::string & name);
1072 
1073 extern template
1074 int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> & v, const std::string & name);
1075 
1076 extern template
1077 int appConfigurator::get<float>( std::vector<float> & v, const std::string & name);
1078 
1079 extern template
1080 int appConfigurator::get<double>( std::vector<double> & v, const std::string & name);
1081 
1082 extern template
1083 int appConfigurator::get<long double>( std::vector<long double> & v, const std::string & name);
1084 
1085 #ifdef HASQUAD
1086 extern template
1087 int appConfigurator::get<__float128>( std::vector<__float128> & v, const std::string & name);
1088 #endif
1089 
1090 extern template
1091 int appConfigurator::get<bool>( std::vector<bool> & v, const std::string & name);
1092 
1093 extern template
1094 int appConfigurator::get<std::string>( std::vector<std::string> & v, const std::string & name);
1095 
1096 //+++++++++++++++++++++++++++++++++++++
1097 
1098 template<typename typeT>
1100  const std::string & name
1101  )
1102 {
1103  return get(v, name, m_targets);
1104 }
1105 
1106 //explicits:
1107 
1108 extern template
1109 int appConfigurator::operator()<char>( char & v, const std::string & name);
1110 
1111 extern template
1112 int appConfigurator::operator()<char16_t>( char16_t & v, const std::string & name);
1113 
1114 extern template
1115 int appConfigurator::operator()<char32_t>( char32_t & v, const std::string & name);
1116 
1117 extern template
1118 int appConfigurator::operator()<wchar_t>( wchar_t & v, const std::string & name);
1119 
1120 extern template
1121 int appConfigurator::operator()<signed char>( signed char & v, const std::string & name);
1122 
1123 extern template
1124 int appConfigurator::operator()<short>( short & v, const std::string & name);
1125 
1126 extern template
1127 int appConfigurator::operator()<int>( int & v, const std::string & name);
1128 
1129 extern template
1130 int appConfigurator::operator()<long>( long & v, const std::string & name);
1131 
1132 extern template
1133 int appConfigurator::operator()<long long>( long long & v, const std::string & name);
1134 
1135 extern template
1136 int appConfigurator::operator()<unsigned char>( unsigned char & v, const std::string & name);
1137 
1138 extern template
1139 int appConfigurator::operator()<unsigned short>( unsigned short & v, const std::string & name);
1140 
1141 extern template
1142 int appConfigurator::operator()<unsigned int>( unsigned int & v, const std::string & name);
1143 
1144 extern template
1145 int appConfigurator::operator()<unsigned long>( unsigned long & v, const std::string & name);
1146 
1147 extern template
1148 int appConfigurator::operator()<unsigned long long>( unsigned long long & v, const std::string & name);
1149 
1150 extern template
1151 int appConfigurator::operator()<float>( float & v, const std::string & name);
1152 
1153 extern template
1154 int appConfigurator::operator()<double>( double & v, const std::string & name);
1155 
1156 extern template
1157 int appConfigurator::operator()<long double>( long double & v, const std::string & name);
1158 
1159 #ifdef HASQUAD
1160 extern template
1161 int appConfigurator::operator()<__float128>( __float128 & v, const std::string & name);
1162 #endif
1163 
1164 extern template
1165 int appConfigurator::operator()<bool>( bool & v, const std::string & name);
1166 
1167 extern template
1168 int appConfigurator::operator()<std::string>( std::string & v, const std::string & name);
1169 
1170 //+++++++++++++++++++++++++++++++++++++
1171 
1172 template<typename typeT>
1174  const std::string & key
1175  )
1176 {
1177  return get(v, key, m_unusedConfigs);
1178 }
1179 
1180 extern template
1181 int appConfigurator::configUnused<char>( char & v, const std::string & key);
1182 
1183 extern template
1184 int appConfigurator::configUnused<char16_t>( char16_t & v, const std::string & key);
1185 
1186 extern template
1187 int appConfigurator::configUnused<char32_t>( char32_t & v, const std::string & key);
1188 
1189 extern template
1190 int appConfigurator::configUnused<wchar_t>( wchar_t & v, const std::string & key);
1191 
1192 extern template
1193 int appConfigurator::configUnused<signed char>( signed char & v, const std::string & key);
1194 
1195 extern template
1196 int appConfigurator::configUnused<short>( short & v, const std::string & key);
1197 
1198 extern template
1199 int appConfigurator::configUnused<int>( int & v, const std::string & key);
1200 
1201 extern template
1202 int appConfigurator::configUnused<long>( long & v, const std::string & key);
1203 
1204 extern template
1205 int appConfigurator::configUnused<long long>( long long & v, const std::string & key);
1206 
1207 extern template
1208 int appConfigurator::configUnused<unsigned char>( unsigned char & v, const std::string & key);
1209 
1210 extern template
1211 int appConfigurator::configUnused<unsigned short>( unsigned short & v, const std::string & key);
1212 
1213 extern template
1214 int appConfigurator::configUnused<unsigned int>( unsigned int & v, const std::string & key);
1215 
1216 extern template
1217 int appConfigurator::configUnused<unsigned long>( unsigned long & v, const std::string & key);
1218 
1219 extern template
1220 int appConfigurator::configUnused<unsigned long long>( unsigned long long & v, const std::string & key);
1221 
1222 extern template
1223 int appConfigurator::configUnused<float>( float & v, const std::string & key);
1224 
1225 extern template
1226 int appConfigurator::configUnused<double>( double & v, const std::string & key);
1227 
1228 extern template
1229 int appConfigurator::configUnused<long double>( long double & v, const std::string & key);
1230 
1231 #ifdef HASQUAD
1232 extern template
1233 int appConfigurator::configUnused<__float128>( __float128 & v, const std::string & key);
1234 #endif
1235 
1236 extern template
1237 int appConfigurator::configUnused<bool>( bool & v, const std::string & key);
1238 
1239 extern template
1240 int appConfigurator::configUnused<std::string>( std::string & v, const std::string & key);
1241 //+++++++++++++++++++++++++++++++++++++
1242 
1243 template<typename typeT>
1245  const std::string & section,
1246  const std::string & keyword
1247  )
1248 {
1249  return configUnused(v, iniFile::makeKey(section,keyword));
1250 }
1251 
1252 extern template
1253 int appConfigurator::configUnused<char>( char & v, const std::string & section, const std::string & keyword);
1254 
1255 extern template
1256 int appConfigurator::configUnused<char16_t>( char16_t & v, const std::string & section, const std::string & keyword);
1257 
1258 extern template
1259 int appConfigurator::configUnused<char32_t>( char32_t & v, const std::string & section, const std::string & keyword);
1260 
1261 extern template
1262 int appConfigurator::configUnused<wchar_t>( wchar_t & v, const std::string & section, const std::string & keyword);
1263 
1264 extern template
1265 int appConfigurator::configUnused<signed char>( signed char & v, const std::string & section, const std::string & keyword);
1266 
1267 extern template
1268 int appConfigurator::configUnused<short>( short & v, const std::string & section, const std::string & keyword);
1269 
1270 extern template
1271 int appConfigurator::configUnused<int>( int & v, const std::string & section, const std::string & keyword);
1272 
1273 extern template
1274 int appConfigurator::configUnused<long>( long & v, const std::string & section, const std::string & keyword);
1275 
1276 extern template
1277 int appConfigurator::configUnused<long long>( long long & v, const std::string & section, const std::string & keyword);
1278 
1279 extern template
1280 int appConfigurator::configUnused<unsigned char>( unsigned char & v, const std::string & section, const std::string & keyword);
1281 
1282 extern template
1283 int appConfigurator::configUnused<unsigned short>( unsigned short & v, const std::string & section, const std::string & keyword);
1284 
1285 extern template
1286 int appConfigurator::configUnused<unsigned int>( unsigned int & v, const std::string & section, const std::string & keyword);
1287 
1288 extern template
1289 int appConfigurator::configUnused<unsigned long>( unsigned long & v, const std::string & section, const std::string & keyword);
1290 
1291 extern template
1292 int appConfigurator::configUnused<unsigned long long>( unsigned long long & v, const std::string & section, const std::string & keyword);
1293 
1294 extern template
1295 int appConfigurator::configUnused<float>( float & v, const std::string & section, const std::string & keyword);
1296 
1297 extern template
1298 int appConfigurator::configUnused<double>( double & v, const std::string & section, const std::string & keyword);
1299 
1300 extern template
1301 int appConfigurator::configUnused<long double>( long double & v, const std::string & section, const std::string & keyword);
1302 
1303 #ifdef HASQUAD
1304 extern template
1305 int appConfigurator::configUnused<__float128>( __float128 & v, const std::string & section, const std::string & keyword);
1306 #endif
1307 
1308 extern template
1309 int appConfigurator::configUnused<bool>( bool & v, const std::string & section, const std::string & keyword);
1310 
1311 extern template
1312 int appConfigurator::configUnused<std::string>( std::string & v, const std::string & section, const std::string & keyword);
1313 
1314 //+++++++++++++++++++++++++++++++++++++
1315 
1316 /// A simple config file writing function, useful for testing.
1317 /** Write a config file to the path specified by `fname`. Each of the parameters
1318  * is a vector, and each component is required of each vector.
1319  *
1320  * Example:
1321  *\code
1322  writeConfigFile( "/tmp/test.conf", {"", "", "sect1", "sect1", "sect2", "sect2"},
1323  {"key0", "key1", "key2", "key3", "key4", "key5"},
1324  {"val0", "val1", "val2", "val3", "val4", "val5"} );
1325 
1326  *\endcode
1327  *results in the file `/tmp/test.conf' containing
1328  * \verbatim
1329  key0=val0
1330  key1=val1
1331 
1332  [sect1]
1333  key2=val2
1334  key3=val3
1335 
1336  [sect2]
1337  key4=val4
1338  key5=val5
1339 
1340  * \endverbatim
1341  *
1342  * No error checking is done.
1343  */
1344 void writeConfigFile( const std::string & fname, ///< [in] the complete path for the output file.
1345  const std::vector<std::string> & sections, ///< [in] sections, one per config value
1346  const std::vector<std::string> & keywords, ///< [in] keywords, one per config value
1347  const std::vector<std::string> & values ///< [in] the values
1348  );
1349 
1350 } //namespace app
1351 } //namespace mx
1352 
1353 #endif // app_appConfigurator_hpp
void writeConfigFile(const std::string &fname, const std::vector< std::string > &sections, const std::vector< std::string > &keywords, const std::vector< std::string > &values)
A simple config file writing function, useful for testing.
A command line parser.
Targets for the configuration manager, and utiltities.
std::string convertToString(const typeT &value, int precision=0)
Convert a numerical value to a string.
Definition: stringUtils.hpp:82
Declares and defines an ini-style (toml) file parser.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Class to manage a set of configurable values, and read their values from config/ini files and the com...
std::unordered_map< std::string, configTarget > m_targets
The targets are stored in an unordered_map for fast access by key.
int readConfig(const std::string &fname, bool reportFileNotFound=true)
Read and parse a config/ini file, updating the targets.
int operator()(typeT &v, const std::string &name)
Access operator, configures a value by calling get.
void add(const configTarget &tgt)
Add a configTarget.
bool m_sources
Flag controlling whether or not to record config sources.
int get(typeT &v, const std::string &name, size_t i, std::unordered_map< std::string, configTarget > &targets)
Get the i-th value of the target, converted to the specified type.
std::vector< std::string > nonOptions
Non-option arguments from the command line.
int configUnused(typeT &v, const std::string &key)
Configure a value from the unused map, using the iniFile key.
void(* configLog)(const std::string &name, const int &code, const std::string &valueStr, const std::string &source)
Call an external logging function whenever a config value is accessed by get or operator().
int verbosity(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Get the command line verbosity count for this option.
int isSetUnused(const std::string &name)
Check if a target has been set in the unused configuration.
bool isSet(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Check if a target has been set by the configuration.
void clear()
Clear the containers and free up the associated memory.
int unusedSections(std::vector< std::string > &sections)
Get the unique sections in the unused config targets.
int numUnknownOptions()
Get the number of unknown options found during config processing.
std::list< configTarget > clOnlyTargets
Targets which are only for the command line are stored separately in a list.
int count(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Get the number of different values set for the specified config target.
void parseCommandLine(int argc, char **argv, const std::string &oneTarget="")
Parse the command line, updating the targets.
std::unordered_map< std::string, configTarget >::iterator targetIterator
Iterator for the targets unordered_map.
int nAdded
Running count of options added, used to track order.
std::unordered_map< std::string, configTarget > m_unusedConfigs
Config file entries present in the file(s), but not corresponding to a target when parsed....
std::list< configTarget >::iterator clOnlyTargetIterator
Iterator for the clOnlyTargets list.
A configuration target.
static std::string makeKey(const std::string &section, const std::string &name)
Return a key generated from the section and name.
Definition: iniFile.hpp:57
Struct which contains static members describing a type.