Configuration.hpp 11.1 KB
Newer Older
1
2
3
4
/**
 * @file
 * @brief Core object of the configuration system
 * @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
5
6
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
7
8
9
10
11
12
13
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#ifndef CORRYVRECKAN_CONFIGURATION_H
#define CORRYVRECKAN_CONFIGURATION_H

#include <map>
14
#include <memory>
15
16
17
18
#include <stdexcept>
#include <string>
#include <vector>

19
#include "core/utils/text.h"
20
21
22
23
#include "exceptions.h"

namespace corryvreckan {

24
25
    template <typename T> using Matrix = std::vector<std::vector<T>>;

26
27
28
    /**
     * @brief Generic configuration object storing keys
     *
29
30
     * The configuration holds a set of keys with arbitrary values that are internally stored as strings. It has special
     * logic for reading paths (relative to the configuration file). All types are converted to their appropriate type using
31
32
33
34
35
36
37
     * the library of \ref StringConversions.
     */
    class Configuration {
    public:
        /**
         * @brief Construct a configuration object
         * @param name Name of the section header (empty section if not specified)
38
         * @param path Path to the file containing the configuration (or empty if not stored in a file)
39
40
41
         */
        explicit Configuration(std::string name = "", std::string path = "");

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
        /// @{
        /**
         * @brief Allow copying the configuration
         */
        Configuration(const Configuration&) = default;
        Configuration& operator=(const Configuration&) = default;
        /// @}

        /// @{
        /**
         * @brief Allow moving the configuration
         */
        Configuration(Configuration&&) noexcept = default;
        Configuration& operator=(Configuration&&) noexcept = default;
        /// @}

58
59
60
61
62
63
64
        /**
         * @brief Check if key is defined
         * @param key Key to check for existence
         * @return True if key exists, false otherwise
         */
        bool has(const std::string& key) const;

65
66
67
68
69
70
71
        /**
         * @brief Check how many of the given keys are defined
         * @param keys Keys to check for existence
         * @return number of existing keys from the given list
         */
        unsigned int count(std::initializer_list<std::string> keys) const;

72
73
74
75
76
77
78
        /**
         * @brief Get value of a key in requested type
         * @param key Key to get value of
         * @return Value of the key in the type of the requested template parameter
         */
        template <typename T> T get(const std::string& key) const;
        /**
79
         * @brief Get value of a key in requested type or default value if it does not exists
80
81
82
83
84
85
86
87
88
89
90
91
         * @param key Key to get value of
         * @param def Default value to use if key is not defined
         * @return Value of the key in the type of the requested template parameter
         *         or the default value if the key does not exists
         */
        template <typename T> T get(const std::string& key, const T& def) const;

        /**
         * @brief Get values for a key containing an array
         * @param key Key to get values of
         * @return List of values in the array in the requested template parameter
         */
92
        // TODO [doc] Provide second template parameter to specify the vector type to return it in
93
        template <typename T> std::vector<T> getArray(const std::string& key) const;
94
95
96
97
98
99
100
101
102
103
104

        /**
         * @brief Get values for a key containing an array or default array if it does not exists
         * @param key Key to get values of
         * @param def Default value array to use if key is not defined
         * @return List of values in the array in the requested template parameter
         *         or the default array if the key does not exist
         */
        // TODO [doc] Provide second template parameter to specify the vector type to return it in
        template <typename T> std::vector<T> getArray(const std::string& key, const std::vector<T> def) const;

105
106
107
108
109
110
        /**
         * @brief Get values for a key containing a 2D matrix
         * @param key Key to get values of
         * @return Matrix of values from the requested template parameter
         */
        template <typename T> Matrix<T> getMatrix(const std::string& key) const;
111

112
113
114
115
116
117
118
119
        /**
         * @brief Get values for a key containing a 2D matrix
         * @param key Key to get values of
         * @param def Default value matrix to use if key is not defined
         * @return Matrix of values from the requested template parameter
         */
        template <typename T> Matrix<T> getMatrix(const std::string& key, const Matrix<T> def) const;

120
121
122
123
124
125
126
127
        /**
         * @brief Get literal value of a key as string
         * @param key Key to get values of
         * @return Literal value of the key
         * @note This function does also not remove quotation marks in strings
         */
        std::string getText(const std::string& key) const;
        /**
128
         * @brief Get literal value of a key as string or a default if it does not exists
129
130
         * @param key Key to get values of
         * @param def Default value to use if key is not defined
131
         * @return Literal value of the key or the default value if the key does not exists
132
133
134
135
136
137
138
         * @note This function does also not remove quotation marks in strings
         */
        std::string getText(const std::string& key, const std::string& def) const;

        /**
         * @brief Get absolute path to file with paths relative to the configuration
         * @param key Key to get path of
139
         * @param check_exists If the file should be checked for existence (if yes always returns a canonical path)
140
141
142
143
         * @return Absolute path to a file
         */
        std::string getPath(const std::string& key, bool check_exists = false) const;
        /**
144
         * @brief Get array of absolute paths to files with paths relative to the configuration
145
         * @param key Key to get path of
146
         * @param check_exists If the files should be checked for existence (if yes always returns a canonical path)
147
148
         * @return List of absolute path to all the requested files
         */
149
        // TODO [doc] Provide second template parameter to specify the vector type to return it in
150
151
        std::vector<std::string> getPathArray(const std::string& key, bool check_exists = false) const;

152
        /**
153
         * @brief Set value for a key in a given type
154
155
156
         * @param key Key to set value of
         * @param val Value to assign to the key
         */
157
        template <typename T> void set(const std::string& key, const T& val);
158

159
        /**
160
         * @brief Store value for a key in a given type, including units
161
162
         * @param key Key to set value of
         * @param val Value to assign to the key
163
         * @param units List of possible output units
164
         */
165
        template <typename T> void set(const std::string& key, const T& val, std::initializer_list<std::string> units);
166

167
168
169
170
171
        /**
         * @brief Set list of values for a key in a given type
         * @param key Key to set values of
         * @param val List of values to assign to the key
         */
172
        // TODO [doc] Provide second template parameter to specify the vector type to return it in
173
174
        template <typename T> void setArray(const std::string& key, const std::vector<T>& val);

175
176
177
178
179
180
181
        /**
         * @brief Set matrix of values for a key in a given type
         * @param key Key to set values of
         * @param val List of values to assign to the key
         */
        template <typename T> void setMatrix(const std::string& key, const Matrix<T>& val);

182
183
184
185
186
187
188
189
190
        /**
         * @brief Set default value for a key only if it is not defined yet
         * @param key Key to possible set value of
         * @param val Value to assign if the key is not defined yet
         */
        template <typename T> void setDefault(const std::string& key, const T& val);
        /**
         * @brief Set default list of values for a key only if it is not defined yet
         * @param key Key to possible set values of
191
         * @param val List of values to assign to the key if the key is not defined yet
192
193
194
195
196
197
198
199
200
201
202
         */
        template <typename T> void setDefaultArray(const std::string& key, const std::vector<T>& val);

        /**
         * @brief Set literal value of a key as string
         * @param key Key to set value of
         * @param val Literal string to assign key to
         */
        void setText(const std::string& key, const std::string& val);

        /**
203
204
205
206
         * @brief Set alias name for an already existing key
         * @param new_key New alias to be created
         * @param old_key Key the alias is created for
         */
207
208
209
210
211
212
213
214
215
216
217
218
219
        void setAlias(const std::string& new_key, const std::string& old_key);

        /**
         * @brief Return total number of key / value pairs
         * @return Number of settings
         */
        unsigned int countSettings() const;

        /**
         * @brief Get name of the configuration header
         * @return Configuration name
         */
        std::string getName() const;
220

221
222
        /**
         * @brief Get path to the file containing the configuration if it has one
223
224
         * @return Absolute path to configuration file or empty if not linked to a file
         * @warning Parameter should be used with care as not all configurations are required to have a file
225
226
227
228
229
         */
        // TODO [doc] Fix name clash with getPath
        std::string getFilePath() const;

        /**
230
         * @brief Merge other configuration, only adding keys that are not yet defined in this configuration
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
         * @param other Configuration to merge this one with
         */
        void merge(const Configuration& other);

        /**
         * @brief Get all key value pairs
         * @return List of all key value pairs
         */
        // FIXME Better name for this function
        std::vector<std::pair<std::string, std::string>> getAll();

    private:
        /**
         * @brief Make relative paths absolute from this configuration file
         * @param path Path to make absolute (if it is not already absolute)
246
         * @param canonicalize_path If the path should be canonicalized (throws an error if the path does not exist)
247
248
249
         */
        std::string path_to_absolute(std::string path, bool canonicalize_path) const;

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
        /**
         * @brief Node in a parse tree
         */
        struct parse_node {
            std::string value;
            std::vector<std::unique_ptr<parse_node>> children;
        };
        /**
         * @brief Generate parse tree from configuration string
         * @param str String to parse
         * @param depth Current depth of the parsing (starts at zero)
         * @return Root node of the parsed tree
         */
        static std::unique_ptr<parse_node> parse_value(std::string str, int depth = 0);

265
266
267
268
269
270
271
272
273
274
275
276
        std::string name_;
        std::string path_;

        using ConfigMap = std::map<std::string, std::string>;
        ConfigMap config_;
    };
} // namespace corryvreckan

// Include template members
#include "Configuration.tpp"

#endif /* CORRYVRECKAN_CONFIGURATION_H */