OGS 6.2.0-405-gb717f6088
ConfigTree.h
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include <typeindex>
13 #include <map>
14 
15 #include <functional>
16 #include <memory>
17 #include <utility>
18 #include <vector>
19 
20 #include <boost/property_tree/ptree.hpp>
21 
22 extern template class boost::property_tree::basic_ptree<
23  std::string, std::string, std::less<>>;
24 
25 namespace BaseLib
26 {
27 
28 class ConfigTree;
29 
36 void checkAndInvalidate(ConfigTree* const conf);
37 
39 void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
40 
42 void checkAndInvalidate(ConfigTree& conf);
43 
44 template<typename Iterator> class Range;
45 
94 class ConfigTree final
95 {
96 public:
103  : public std::iterator<std::input_iterator_tag, ConfigTree>
104  {
105  public:
106  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
107 
108  explicit SubtreeIterator(Iterator it, std::string root,
109  ConfigTree const& parent)
110  : _it(it), _tagname(std::move(root)), _parent(parent)
111  {}
112 
114  ++_it;
115  _has_incremented = true;
116  return *this;
117  }
118 
120  // if this iterator has been incremented since the last dereference,
121  // tell the _parent instance that a subtree now has been parsed.
122  if (_has_incremented) {
123  _has_incremented = false;
125  }
126  return ConfigTree(_it->second, _parent, _tagname);
127  }
128 
129  bool operator==(SubtreeIterator const& other) const {
130  return _it == other._it;
131  }
132 
133  bool operator!=(SubtreeIterator const& other) const {
134  return _it != other._it;
135  }
136 
137  private:
138  bool _has_incremented = true;
140 
141  protected:
142  std::string const _tagname;
144  };
145 
152  {
153  public:
156 
158  auto st = SubtreeIterator::operator*();
159  if (st.hasChildren())
160  {
161  _parent.error("The requested parameter <" + _tagname +
162  "> has child elements.");
163  }
164  return st;
165  }
166  };
167 
168 
175  template<typename ValueType>
177  : public std::iterator<std::input_iterator_tag, ValueType>
178  {
179  public:
180  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
181 
182  explicit ValueIterator(Iterator it, std::string root,
183  ConfigTree const& parent)
184  : _it(it), _tagname(std::move(root)), _parent(parent)
185  {}
186 
188  ++_it;
189  _has_incremented = true;
190  return *this;
191  }
192 
193  ValueType operator*() {
194  // if this iterator has been incremented since the last dereference,
195  // tell the _parent instance that a setting now has been parsed.
196  if (_has_incremented) {
197  _has_incremented = false;
198  _parent.markVisited<ValueType>(_tagname, Attr::TAG, false);
199  }
200  return ConfigTree(_it->second, _parent, _tagname).getValue<ValueType>();
201  }
202 
203  bool operator==(ValueIterator<ValueType> const& other) const {
204  return _it == other._it;
205  }
206 
207  bool operator!=(ValueIterator<ValueType> const& other) const {
208  return _it != other._it;
209  }
210 
211  private:
212  bool _has_incremented = true;
214  std::string const _tagname;
216  };
217 
219  using PTree = boost::property_tree::ptree;
220 
228  using Callback = std::function<void(const std::string& filename,
229  const std::string& path,
230  const std::string& message)>;
231 
247  explicit ConfigTree(PTree const& tree,
248  std::string filename,
249  Callback error_cb,
250  Callback warning_cb);
251 
256  explicit ConfigTree(PTree&&, std::string const&,
257  Callback const&, Callback const&) = delete;
258 
260  ConfigTree(ConfigTree const&) = delete;
261 
264  ConfigTree(ConfigTree && other);
265 
267  ConfigTree& operator=(ConfigTree const&) = delete;
268 
272 
274  std::string const& getProjectFileName() const { return _filename; }
275 
279 
287  template<typename T> T
288  getConfigParameter(std::string const& param) const;
289 
299  template<typename T> T
300  getConfigParameter(std::string const& param, T const& default_value) const;
301 
310  template<typename T> boost::optional<T>
311  getConfigParameterOptional(std::string const& param) const;
312 
319  template<typename T> Range<ValueIterator<T> >
320  getConfigParameterList(std::string const& param) const;
321 
323 
333 
341  ConfigTree
342  getConfigParameter(std::string const& param) const;
343 
350  boost::optional<ConfigTree>
351  getConfigParameterOptional(std::string const& param) const;
352 
360  getConfigParameterList(std::string const& param) const;
361 
368  template<typename T> T
369  getValue() const;
370 
377  template<typename T> T
378  getConfigAttribute(std::string const& attr) const;
379 
391  template <typename T>
392  T getConfigAttribute(std::string const& attr, T const& default_value) const;
393 
401  template<typename T> boost::optional<T>
402  getConfigAttributeOptional(std::string const& attr) const;
403 
405 
412 
424  template<typename T> T
425  peekConfigParameter(std::string const& param) const;
426 
431  template<typename T> void
432  checkConfigParameter(std::string const& param, T const& value) const;
433 
435  template<typename Ch> void
436  checkConfigParameter(std::string const& param, Ch const* value) const;
437 
439 
443 
451  ConfigTree
452  getConfigSubtree(std::string const& root) const;
453 
458  boost::optional<ConfigTree>
459  getConfigSubtreeOptional(std::string const& root) const;
460 
468  getConfigSubtreeList(std::string const& root) const;
469 
471 
475 
483  void ignoreConfigParameter(std::string const& param) const;
484 
491  void ignoreConfigParameterAll(std::string const& param) const;
492 
499  void ignoreConfigAttribute(std::string const& attr) const;
500 
502 
507  ~ConfigTree();
508 
511  static void onerror(std::string const& filename, std::string const& path,
512  std::string const& message);
513 
516  static void onwarning(std::string const& filename, std::string const& path,
517  std::string const& message);
518 
520  static void assertNoSwallowedErrors();
521 
522 private:
524  template<typename T> boost::optional<T>
525  getConfigParameterOptionalImpl(std::string const& param, T*) const;
526 
528  template<typename T> boost::optional<std::vector<T>>
529  getConfigParameterOptionalImpl(std::string const& param, std::vector<T>*) const;
530 
531  struct CountType
532  {
533  int count;
534  std::type_index type;
535  };
536 
538  enum class Attr : bool
539  {
540  TAG = false, ATTR = true
541  };
542 
544  explicit ConfigTree(PTree const& tree, ConfigTree const& parent, std::string const& root);
545 
550  [[noreturn]] void error(std::string const& message) const;
551 
554  void warning(std::string const& message) const;
555 
557  void checkKeyname(std::string const& key) const;
558 
560  std::string joinPaths(std::string const& p1, std::string const& p2) const;
561 
563  void checkUnique(std::string const& key) const;
564 
566  void checkUniqueAttr(std::string const& attr) const;
567 
574  template<typename T>
575  CountType& markVisited(std::string const& key, Attr const is_attr,
576  bool peek_only) const;
577 
584  CountType& markVisited(std::string const& key, Attr const is_attr,
585  bool const peek_only) const;
586 
589  void markVisitedDecrement(Attr const is_attr, std::string const& key) const;
590 
592  bool hasChildren() const;
593 
599  void checkAndInvalidate();
600 
602  static std::string shortString(std::string const& s);
603 
605  boost::property_tree::ptree const* _tree;
606 
608  std::string _path;
609 
611  std::string _filename;
612 
614  using KeyType = std::pair<Attr, std::string>;
615 
623  mutable std::map<KeyType, CountType> _visited_params;
624 
626  mutable bool _have_read_data = false;
627 
630 
632  static const char pathseparator;
633 
635  static const std::string key_chars_start;
636 
638  static const std::string key_chars;
639 
640  friend void checkAndInvalidate(ConfigTree* const conf);
641  friend void checkAndInvalidate(ConfigTree& conf);
642  friend void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
643 };
644 
645 } // namespace BaseLib
646 
647 #include "ConfigTree-impl.h"
bool operator==(SubtreeIterator const &other) const
Definition: ConfigTree.h:129
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:238
CountType & markVisited(std::string const &key, Attr const is_attr, bool peek_only) const
Attr
Used to indicate if dealing with XML tags or XML attributes.
Definition: ConfigTree.h:538
SubtreeIterator(Iterator it, std::string root, ConfigTree const &parent)
Definition: ConfigTree.h:108
std::string _path
A path printed in error/warning messages.
Definition: ConfigTree.h:608
void error(std::string const &message) const
Definition: ConfigTree.cpp:217
bool _have_read_data
Indicates if the plain data contained in this tree has already been read.
Definition: ConfigTree.h:626
void ignoreConfigParameterAll(std::string const &param) const
Definition: ConfigTree.cpp:205
boost::property_tree::ptree const * _tree
The wrapped tree.
Definition: ConfigTree.h:605
std::string const & getProjectFileName() const
Used to get the project file name.
Definition: ConfigTree.h:274
boost::optional< T > getConfigParameterOptionalImpl(std::string const &param, T *) const
Default implementation of reading a value of type T.
void checkUnique(std::string const &key) const
Asserts that the key has not been read yet.
Definition: ConfigTree.cpp:307
void warning(std::string const &message) const
Definition: ConfigTree.cpp:225
T getConfigParameter(std::string const &param) const
ConfigTree & operator=(ConfigTree const &)=delete
copying is not compatible with the semantics of this class
static const char pathseparator
Character separating two path components.
Definition: ConfigTree.h:632
std::map< KeyType, CountType > _visited_params
Definition: ConfigTree.h:623
std::string _filename
The path of the file from which this tree has been read.
Definition: ConfigTree.h:611
void checkKeyname(std::string const &key) const
Checks if key complies with the rules [a-z0-9_].
Definition: ConfigTree.cpp:275
Callback _onerror
Custom error callback.
Definition: ConfigTree.h:628
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:219
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:316
void checkAndInvalidate(ConfigTree &conf)
Definition: ConfigTree.cpp:449
bool operator!=(SubtreeIterator const &other) const
Definition: ConfigTree.h:133
void checkConfigParameter(std::string const &param, T const &value) const
static std::string shortString(std::string const &s)
returns a short string at suitable for error/warning messages
Definition: ConfigTree.cpp:262
ValueIterator(Iterator it, std::string root, ConfigTree const &parent)
Definition: ConfigTree.h:182
T peekConfigParameter(std::string const &param) const
Wraps a pair of iterators for use as a range in range-based for-loops.
void markVisitedDecrement(Attr const is_attr, std::string const &key) const
Definition: ConfigTree.cpp:353
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:230
ConfigTree(PTree const &tree, std::string filename, Callback error_cb, Callback warning_cb)
Definition: ConfigTree.cpp:34
Build information.
std::pair< Attr, std::string > KeyType
A pair (is attribute, tag/attribute name).
Definition: ConfigTree.h:614
T getConfigAttribute(std::string const &attr) const
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Definition: ConfigTree.cpp:245
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:203
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:150
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:231
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:174
Callback _onwarning
Custom warning callback.
Definition: ConfigTree.h:629
boost::optional< T > getConfigAttributeOptional(std::string const &attr) const
bool operator!=(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:207
boost::optional< T > getConfigParameterOptional(std::string const &param) const
static const std::string key_chars_start
Set of allowed characters as the first letter of a key name.
Definition: ConfigTree.h:635
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:180
Range< ValueIterator< T > > getConfigParameterList(std::string const &param) const
boost::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:160
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:194
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:186
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:187
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:293
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:106
static const std::string key_chars
Set of allowed characters in a key name.
Definition: ConfigTree.h:638
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:367