LCOV - code coverage report
Current view: top level - include/app - appConfigurator.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 100.0 % 86 86
Test Date: 2026-08-30 22:23:37 Functions: 100.0 % 11 11

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

Generated by: LCOV version 2.0-1