comparison C++/Ini.h @ 327:78e8f9a3b233

Ini: - Add support for @include - Add more tests - Added lot of documentation TODO: - Add lots of test with errored files
author David Demelier <markand@malikania.fr>
date Tue, 03 Mar 2015 21:21:11 +0100
parents d52a69f9f029
children
comparison
equal deleted inserted replaced
326:fb6c42173634 327:78e8f9a3b233
17 */ 17 */
18 18
19 #ifndef _INI_H_ 19 #ifndef _INI_H_
20 #define _INI_H_ 20 #define _INI_H_
21 21
22 /**
23 * @file Ini.h
24 * @brief Configuration file parser
25 */
26
22 #include <algorithm> 27 #include <algorithm>
23 #include <deque> 28 #include <deque>
24 #include <fstream>
25 #include <istream>
26 #include <stdexcept> 29 #include <stdexcept>
27 #include <string> 30 #include <string>
31
32 /**
33 * @class IniError
34 * @brief Error in a file
35 */
36 class IniError : public std::exception {
37 private:
38 int m_line;
39 int m_position;
40 std::string m_error;
41
42 public:
43 /**
44 * Construct an error.
45 *
46 * @param line the line
47 * @param position the position
48 * @param error the error
49 */
50 inline IniError(int line, int position, std::string error)
51 : m_line(line)
52 , m_position(position)
53 , m_error(std::move(error))
54 {
55 }
56
57 /**
58 * Return the line number.
59 *
60 * @return the line
61 */
62 inline int line() const noexcept
63 {
64 return m_line;
65 }
66
67 /**
68 * Return the position in the current line.
69 *
70 * @return the position
71 */
72 inline int position() const noexcept
73 {
74 return m_position;
75 }
76
77 /**
78 * Get the error string.
79 *
80 * @return the string
81 */
82 inline const char *what() const noexcept
83 {
84 return m_error.c_str();
85 }
86 };
28 87
29 /** 88 /**
30 * @class IniOption 89 * @class IniOption
31 * @brief Option definition 90 * @brief Option definition
32 */ 91 */
34 private: 93 private:
35 std::string m_key; 94 std::string m_key;
36 std::string m_value; 95 std::string m_value;
37 96
38 public: 97 public:
98 /**
99 * Construct an option.
100 *
101 * @param key the key
102 * @param value the value
103 */
39 inline IniOption(std::string key, std::string value) 104 inline IniOption(std::string key, std::string value)
40 : m_key(std::move(key)) 105 : m_key(std::move(key))
41 , m_value(std::move(value)) 106 , m_value(std::move(value))
42 { 107 {
43 } 108 }
44 109
110 /**
111 * Get the option key.
112 *
113 * @return the key
114 */
45 inline const std::string &key() const noexcept 115 inline const std::string &key() const noexcept
46 { 116 {
47 return m_key; 117 return m_key;
48 } 118 }
49 119
120 /**
121 * Get the option value.
122 *
123 * @return the value
124 */
50 inline const std::string &value() const noexcept 125 inline const std::string &value() const noexcept
51 { 126 {
52 return m_value; 127 return m_value;
53 } 128 }
54 }; 129 };
74 149
75 return const_cast<T>(*it); 150 return const_cast<T>(*it);
76 } 151 }
77 152
78 public: 153 public:
154 /**
155 * Default constructor has no sections and no values.
156 */
79 IniSection() = default; 157 IniSection() = default;
80 158
81 inline IniSection(std::string key, std::deque<IniOption> options = {}) 159 /**
160 * Construct a section with a set of options.
161 *
162 * @param key the section name
163 * @param options the list of options
164 */
165 inline IniSection(std::string key, std::deque<IniOption> options = {}) noexcept
82 : m_key(std::move(key)) 166 : m_key(std::move(key))
83 , m_options(std::move(options)) 167 , m_options(std::move(options))
84 { 168 {
85 } 169 }
86 170
171 /**
172 * Get the section key.
173 *
174 * @return the key
175 */
87 inline const std::string &key() const noexcept 176 inline const std::string &key() const noexcept
88 { 177 {
89 return m_key; 178 return m_key;
90 } 179 }
91 180
181 /**
182 * Get an iterator to the beginning.
183 *
184 * @return the iterator
185 */
92 inline auto begin() noexcept 186 inline auto begin() noexcept
93 { 187 {
94 return m_options.begin(); 188 return m_options.begin();
95 } 189 }
96 190
191 /**
192 * Overloaded function.
193 *
194 * @return the iterator
195 */
97 inline auto begin() const noexcept 196 inline auto begin() const noexcept
98 { 197 {
99 return m_options.begin(); 198 return m_options.begin();
100 } 199 }
101 200
201 /**
202 * Overloaded function.
203 *
204 * @return the iterator
205 */
102 inline auto cbegin() const noexcept 206 inline auto cbegin() const noexcept
103 { 207 {
104 return m_options.cbegin(); 208 return m_options.cbegin();
105 } 209 }
106 210
211 /**
212 * Get an iterator to the end.
213 *
214 * @return the iterator
215 */
107 inline auto end() noexcept 216 inline auto end() noexcept
108 { 217 {
109 return m_options.end(); 218 return m_options.end();
110 } 219 }
111 220
221 /**
222 * Overloaded function.
223 *
224 * @return the iterator
225 */
112 inline auto end() const noexcept 226 inline auto end() const noexcept
113 { 227 {
114 return m_options.end(); 228 return m_options.end();
115 } 229 }
116 230
231 /**
232 * Overloaded function.
233 *
234 * @return the iterator
235 */
117 inline auto cend() const noexcept 236 inline auto cend() const noexcept
118 { 237 {
119 return m_options.cend(); 238 return m_options.cend();
120 } 239 }
121 240
241 /**
242 * Append an option.
243 *
244 * @param option the option to add
245 */
122 inline void push_back(IniOption option) 246 inline void push_back(IniOption option)
123 { 247 {
124 m_options.push_back(std::move(option)); 248 m_options.push_back(std::move(option));
125 } 249 }
126 250
251 /**
252 * Push an option to the beginning.
253 *
254 * @param option the option to add
255 */
127 inline void push_front(IniOption option) 256 inline void push_front(IniOption option)
128 { 257 {
129 m_options.push_front(std::move(option)); 258 m_options.push_front(std::move(option));
130 } 259 }
131 260
261 /**
262 * Get the number of options in that section.
263 *
264 * @return the size
265 */
132 inline unsigned size() const noexcept 266 inline unsigned size() const noexcept
133 { 267 {
134 return m_options.size(); 268 return m_options.size();
135 } 269 }
136 270
271 /**
272 * Access an option at the specified index.
273 *
274 * @param index the index
275 * @return the option
276 * @warning No bounds checking is performed
277 */
137 inline IniOption &operator[](int index) noexcept 278 inline IniOption &operator[](int index) noexcept
138 { 279 {
139 return m_options[index]; 280 return m_options[index];
140 } 281 }
141 282
283 /**
284 * Access an option at the specified index.
285 *
286 * @param index the index
287 * @return the option
288 * @warning No bounds checking is performed
289 */
142 inline const IniOption &operator[](int index) const noexcept 290 inline const IniOption &operator[](int index) const noexcept
143 { 291 {
144 return m_options[index]; 292 return m_options[index];
145 } 293 }
146 294
295 /**
296 * Access an option at the specified key.
297 *
298 * @param key the key
299 * @return the option
300 * @warning No bounds checking is performed
301 */
147 inline IniOption &operator[](const std::string &key) 302 inline IniOption &operator[](const std::string &key)
148 { 303 {
149 return find<IniOption &>(key); 304 return find<IniOption &>(key);
150 } 305 }
151 306
307 /**
308 * Access an option at the specified key.
309 *
310 * @param key the key
311 * @return the option
312 * @warning No bounds checking is performed
313 */
152 inline const IniOption &operator[](const std::string &key) const 314 inline const IniOption &operator[](const std::string &key) const
153 { 315 {
154 return find<const IniOption &>(key); 316 return find<const IniOption &>(key);
155 } 317 }
156 }; 318 };
175 337
176 return const_cast<T>(*it); 338 return const_cast<T>(*it);
177 } 339 }
178 340
179 public: 341 public:
342 /**
343 * Default constructor with an empty configuration.
344 */
180 Ini() = default; 345 Ini() = default;
181 346
182 Ini(std::istream &stream); 347 /**
183 348 * Open the path as the configuration file.
184 inline Ini(std::istream &&stream) 349 *
185 : Ini(stream) 350 * @param path the path
186 { 351 * @throw IniError on any error
187 } 352 */
188 353 Ini(const std::string &path);
354
355 /**
356 * Get an iterator to the beginning.
357 *
358 * @return the iterator
359 */
189 inline auto begin() noexcept 360 inline auto begin() noexcept
190 { 361 {
191 return m_sections.begin(); 362 return m_sections.begin();
192 } 363 }
193 364
365 /**
366 * Overloaded function.
367 *
368 * @return the iterator
369 */
194 inline auto begin() const noexcept 370 inline auto begin() const noexcept
195 { 371 {
196 return m_sections.begin(); 372 return m_sections.begin();
197 } 373 }
198 374
375 /**
376 * Overloaded function.
377 *
378 * @return the iterator
379 */
199 inline auto cbegin() const noexcept 380 inline auto cbegin() const noexcept
200 { 381 {
201 return m_sections.cbegin(); 382 return m_sections.cbegin();
202 } 383 }
203 384
385 /**
386 * Get an iterator to the end.
387 *
388 * @return the iterator
389 */
204 inline auto end() noexcept 390 inline auto end() noexcept
205 { 391 {
206 return m_sections.end(); 392 return m_sections.end();
207 } 393 }
208 394
395 /**
396 * Overloaded function.
397 *
398 * @return the iterator
399 */
209 inline auto end() const noexcept 400 inline auto end() const noexcept
210 { 401 {
211 return m_sections.end(); 402 return m_sections.end();
212 } 403 }
213 404
405 /**
406 * Overloaded function.
407 *
408 * @return the iterator
409 */
214 inline auto cend() const noexcept 410 inline auto cend() const noexcept
215 { 411 {
216 return m_sections.cend(); 412 return m_sections.cend();
217 } 413 }
218 414
415 /**
416 * Get the number of sections in the configuration.
417 *
418 * @return the size
419 */
219 inline unsigned size() const noexcept 420 inline unsigned size() const noexcept
220 { 421 {
221 return m_sections.size(); 422 return m_sections.size();
222 } 423 }
223 424
425 /**
426 * Append a section to the end.
427 *
428 * @param section the section to add
429 */
224 inline void push_back(IniSection section) 430 inline void push_back(IniSection section)
225 { 431 {
226 m_sections.push_back(std::move(section)); 432 m_sections.push_back(std::move(section));
227 } 433 }
228 434
435 /**
436 * Add a section to the beginning.
437 *
438 * @param section the section to add
439 */
229 inline void push_front(IniSection section) 440 inline void push_front(IniSection section)
230 { 441 {
231 m_sections.push_front(std::move(section)); 442 m_sections.push_front(std::move(section));
232 } 443 }
233 444
445 /**
446 * Access a section at the specified index.
447 *
448 * @param index the index
449 * @return the section
450 * @warning No bounds checking is performed
451 */
234 inline IniSection &operator[](int index) noexcept 452 inline IniSection &operator[](int index) noexcept
235 { 453 {
236 return m_sections[index]; 454 return m_sections[index];
237 } 455 }
238 456
457 /**
458 * Access a section at the specified index.
459 *
460 * @param index the index
461 * @return the section
462 * @warning No bounds checking is performed
463 */
239 inline const IniSection &operator[](int index) const noexcept 464 inline const IniSection &operator[](int index) const noexcept
240 { 465 {
241 return m_sections[index]; 466 return m_sections[index];
242 } 467 }
243 468
469 /**
470 * Access a section at the specified key.
471 *
472 * @param key the key
473 * @return the section
474 * @warning No bounds checking is performed
475 */
244 inline IniSection &operator[](const std::string &key) 476 inline IniSection &operator[](const std::string &key)
245 { 477 {
246 return find<IniSection &>(key); 478 return find<IniSection &>(key);
247 } 479 }
248 480
481 /**
482 * Access a section at the specified key.
483 *
484 * @param key the key
485 * @return the section
486 * @warning No bounds checking is performed
487 */
249 inline const IniSection &operator[](const std::string &key) const 488 inline const IniSection &operator[](const std::string &key) const
250 { 489 {
251 return find<IniSection &>(key); 490 return find<IniSection &>(key);
252 } 491 }
253 }; 492 };