@@ -247,7 +247,9 @@ class INIReader
247247 int ParseError () const ;
248248
249249 // Return the list of sections found in ini file
250- const std::set<std::string>& Sections () const ;
250+ const std::set<std::string> Sections () const ;
251+
252+ const std::unordered_map<std::string, std::string> Get (std::string section) const ;
251253
252254 template <typename T = std::string>
253255 T Get (std::string section, std::string name) const ;
@@ -263,9 +265,7 @@ class INIReader
263265
264266protected:
265267 int _error;
266- std::map<std::string, std::string> _values;
267- std::set<std::string> _sections;
268- static std::string MakeKey (std::string section, std::string name);
268+ std::unordered_map<std::string, std::unordered_map<std::string, std::string>> _values;
269269 static int ValueHandler (void * user, const char * section, const char * name, const char * value);
270270
271271 template <typename T>
@@ -310,20 +310,36 @@ inline int INIReader::ParseError() const
310310 return _error;
311311}
312312
313- inline const std::set<std::string>& INIReader::Sections () const
313+ inline const std::set<std::string> INIReader::Sections () const
314314{
315- return _sections;
315+ std::set<std::string> retval;
316+ for (auto const & element : _values) {
317+ retval.insert (element.first );
318+ }
319+ return retval;
320+ }
321+
322+ inline const std::unordered_map<std::string, std::string> INIReader::Get (std::string section) const {
323+ auto const _section = _values.find (section);
324+ if (_section == _values.end ()) {
325+ throw std::runtime_error (" section '" + section + " ' not found." );
326+ }
327+ return _section->second ;
316328}
317329
318- template <typename T = std::string >
330+ template <typename T>
319331inline T INIReader::Get (std::string section, std::string name) const {
320- std::string key = MakeKey (section, name);
321- if (!_values.count (key)) {
322- throw std::runtime_error (" key " + key + " not found." );
332+ auto const _section = Get (section);
333+ auto const _value = _section.find (name);
334+
335+ if (_value == _section.end ()) {
336+ throw std::runtime_error (" key '" + name + " ' not found in section '" + section + " '." );
323337 }
324-
338+
339+ std::string value = _value->second ;
340+
325341 if constexpr (std::is_same<T, std::string>()) {
326- return _values. at (key) ;
342+ return value ;
327343 } else if constexpr (std::is_same<T, bool >()) {
328344 std::string s{_values.at (key)};
329345 std::transform (s.begin (), s.end (), s.begin (), ::tolower);
@@ -344,23 +360,20 @@ inline T INIReader::Get(std::string section, std::string name) const {
344360
345361template <typename T>
346362inline T INIReader::Get (std::string section, std::string name, T&& default_v) const {
347- std::string key = MakeKey (section, name);
348- if (!_values.count (key)) {
363+ try {
364+ return Get<T>(section, name);
365+ } catch (std::runtime_error &e) {
349366 return default_v;
350367 }
351- return Get<T>(section, name);
352368}
353369
354- template <typename T = std::string >
370+ template <typename T>
355371inline std::vector<T> INIReader::GetVector (std::string section, std::string name) const {
356- std::string key = MakeKey (section, name);
357- if (!_values.count (key)) {
358- throw std::runtime_error (" key " + key + " not found." );
359- }
372+ std::string value = Get (section, name);
360373
361- std::istringstream out{_values. at (key) };
374+ std::istringstream out{value };
362375 const std::vector<std::string> strs{
363- std::istream_iterator<std::string>{out},
376+ std::istream_iterator<std::string>{out},
364377 std::istream_iterator<std::string>()
365378 };
366379 try {
@@ -370,17 +383,17 @@ inline std::vector<T> INIReader::GetVector(std::string section, std::string name
370383 }
371384 return vs;
372385 } catch (std::exception& e) {
373- throw std::runtime_error (" cannot parse value in " + key + " to vector<T>." );
386+ throw std::runtime_error (" cannot parse value " + value + " to vector<T>." );
374387 }
375388}
376389
377390template <typename T>
378391inline std::vector<T> INIReader::GetVector (std::string section, std::string name, std::vector<T> default_v) const {
379- std::string key = MakeKey (section, name);
380- if (!_values.count (key)) {
392+ try {
393+ return GetVector<T>(section, name);
394+ } catch (std::runtime_error &e) {
381395 return default_v;
382- }
383- return GetVector<T>(section, name);
396+ };
384397}
385398
386399
@@ -398,20 +411,14 @@ inline T INIReader::Converter(std::string s) const {
398411 return v;
399412}
400413
401- inline std::string INIReader::MakeKey (const std::string section, const std::string name)
402- {
403- std::string key = section + " =" + name;
404- return key;
405414}
406415
407416inline int INIReader::ValueHandler (void * user, const char * section, const char * name, const char * value)
408417{
409418 INIReader* reader = (INIReader*)user;
410- std::string key = MakeKey (section, name);
411- if (reader->_values [key].size () > 0 )
412- reader->_values [key] += " \n " ;
413- reader->_values [key] += value;
414- reader->_sections .insert (section);
419+ if (reader->_values [section][name].size () > 0 )
420+ reader->_values [section][name] += " \n " ;
421+ reader->_values [section][name] += value;
415422 return 1 ;
416423}
417424}
0 commit comments