OGS 6.1.0-1721-g6382411ad
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<std::string>>;
24 
25 
26 namespace BaseLib
27 {
28 
29 class ConfigTree;
30 
37 void checkAndInvalidate(ConfigTree* const conf);
38 
40 void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
41 
43 void checkAndInvalidate(ConfigTree& conf);
44 
45 template<typename Iterator> class Range;
46 
95 class ConfigTree final
96 {
97 public:
104  : public std::iterator<std::input_iterator_tag, ConfigTree>
105  {
106  public:
107  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
108 
109  explicit SubtreeIterator(Iterator it, std::string root,
110  ConfigTree const& parent)
111  : _it(it), _tagname(std::move(root)), _parent(parent)
112  {}
113 
115  ++_it;
116  _has_incremented = true;
117  return *this;
118  }
119 
121  // if this iterator has been incremented since the last dereference,
122  // tell the _parent instance that a subtree now has been parsed.
123  if (_has_incremented) {
124  _has_incremented = false;
126  }
127  return ConfigTree(_it->second, _parent, _tagname);
128  }
129 
130  bool operator==(SubtreeIterator const& other) const {
131  return _it == other._it;
132  }
133 
134  bool operator!=(SubtreeIterator const& other) const {
135  return _it != other._it;
136  }
137 
138  private:
139  bool _has_incremented = true;
141 
142  protected:
143  std::string const _tagname;
145  };
146 
153  {
154  public:
157 
159  auto st = SubtreeIterator::operator*();
160  if (st.hasChildren())
161  _parent.error("The requested parameter <" + _tagname + ">"
162  " has child elements.");
163  return st;
164  }
165  };
166 
167 
174  template<typename ValueType>
176  : public std::iterator<std::input_iterator_tag, ValueType>
177  {
178  public:
179  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
180 
181  explicit ValueIterator(Iterator it, std::string root,
182  ConfigTree const& parent)
183  : _it(it), _tagname(std::move(root)), _parent(parent)
184  {}
185 
187  ++_it;
188  _has_incremented = true;
189  return *this;
190  }
191 
192  ValueType operator*() {
193  // if this iterator has been incremented since the last dereference,
194  // tell the _parent instance that a setting now has been parsed.
195  if (_has_incremented) {
196  _has_incremented = false;
197  _parent.markVisited<ValueType>(_tagname, Attr::TAG, false);
198  }
199  return ConfigTree(_it->second, _parent, _tagname).getValue<ValueType>();
200  }
201 
202  bool operator==(ValueIterator<ValueType> const& other) const {
203  return _it == other._it;
204  }
205 
206  bool operator!=(ValueIterator<ValueType> const& other) const {
207  return _it != other._it;
208  }
209 
210  private:
211  bool _has_incremented = true;
213  std::string const _tagname;
215  };
216 
218  using PTree = boost::property_tree::ptree;
219 
227  using Callback = std::function<void(const std::string& filename,
228  const std::string& path,
229  const std::string& message)>;
230 
246  explicit ConfigTree(PTree const& tree,
247  std::string filename,
248  Callback error_cb,
249  Callback warning_cb);
250 
255  explicit ConfigTree(PTree&&, std::string const&,
256  Callback const&, Callback const&) = delete;
257 
259  ConfigTree(ConfigTree const&) = delete;
260 
263  ConfigTree(ConfigTree && other);
264 
266  ConfigTree& operator=(ConfigTree const&) = delete;
267 
271 
275 
283  template<typename T> T
284  getConfigParameter(std::string const& param) const;
285 
295  template<typename T> T
296  getConfigParameter(std::string const& param, T const& default_value) const;
297 
306  template<typename T> boost::optional<T>
307  getConfigParameterOptional(std::string const& param) const;
308 
315  template<typename T> Range<ValueIterator<T> >
316  getConfigParameterList(std::string const& param) const;
317 
319 
329 
337  ConfigTree
338  getConfigParameter(std::string const& param) const;
339 
346  boost::optional<ConfigTree>
347  getConfigParameterOptional(std::string const& param) const;
348 
356  getConfigParameterList(std::string const& param) const;
357 
364  template<typename T> T
365  getValue() const;
366 
373  template<typename T> T
374  getConfigAttribute(std::string const& attr) const;
375 
387  template <typename T>
388  T getConfigAttribute(std::string const& attr, T const& default_value) const;
389 
397  template<typename T> boost::optional<T>
398  getConfigAttributeOptional(std::string const& attr) const;
399 
401 
408 
420  template<typename T> T
421  peekConfigParameter(std::string const& param) const;
422 
427  template<typename T> void
428  checkConfigParameter(std::string const& param, T const& value) const;
429 
431  template<typename Ch> void
432  checkConfigParameter(std::string const& param, Ch const* value) const;
433 
435 
439 
447  ConfigTree
448  getConfigSubtree(std::string const& root) const;
449 
454  boost::optional<ConfigTree>
455  getConfigSubtreeOptional(std::string const& root) const;
456 
464  getConfigSubtreeList(std::string const& root) const;
465 
467 
471 
479  void ignoreConfigParameter(std::string const& param) const;
480 
487  void ignoreConfigParameterAll(std::string const& param) const;
488 
495  void ignoreConfigAttribute(std::string const& attr) const;
496 
498 
503  ~ConfigTree();
504 
507  static void onerror(std::string const& filename, std::string const& path,
508  std::string const& message);
509 
512  static void onwarning(std::string const& filename, std::string const& path,
513  std::string const& message);
514 
516  static void assertNoSwallowedErrors();
517 
518 private:
520  template<typename T> boost::optional<T>
521  getConfigParameterOptionalImpl(std::string const& param, T*) const;
522 
524  template<typename T> boost::optional<std::vector<T>>
525  getConfigParameterOptionalImpl(std::string const& param, std::vector<T>*) const;
526 
527  struct CountType
528  {
529  int count;
530  std::type_index type;
531  };
532 
534  enum class Attr : bool
535  {
536  TAG = false, ATTR = true
537  };
538 
540  explicit ConfigTree(PTree const& tree, ConfigTree const& parent, std::string const& root);
541 
546 #if defined(_MSC_VER) && _MSC_VER < 1500
547  __declspec(noreturn)
548 #else
549  [[noreturn]]
550 #endif
551  void error(std::string const& message) const;
552 
555  void warning(std::string const& message) const;
556 
558  void checkKeyname(std::string const& key) const;
559 
561  std::string joinPaths(std::string const& p1, std::string const& p2) const;
562 
564  void checkUnique(std::string const& key) const;
565 
567  void checkUniqueAttr(std::string const& attr) const;
568 
575  template<typename T>
576  CountType& markVisited(std::string const& key, Attr const is_attr,
577  bool peek_only) const;
578 
585  CountType& markVisited(std::string const& key, Attr const is_attr,
586  bool const peek_only) const;
587 
590  void markVisitedDecrement(Attr const is_attr, std::string const& key) const;
591 
593  bool hasChildren() const;
594 
600  void checkAndInvalidate();
601 
603  static std::string shortString(std::string const& s);
604 
606  boost::property_tree::ptree const* _tree;
607 
609  std::string _path;
610 
612  std::string _filename;
613 
615  using KeyType = std::pair<Attr, std::string>;
616 
624  mutable std::map<KeyType, CountType> _visited_params;
625 
627  mutable bool _have_read_data = false;
628 
631 
633  static const char pathseparator;
634 
636  static const std::string key_chars_start;
637 
639  static const std::string key_chars;
640 
641  friend void checkAndInvalidate(ConfigTree* const conf);
642  friend void checkAndInvalidate(ConfigTree& conf);
643  friend void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
644 };
645 
646 }
647 
648 #include "ConfigTree-impl.h"
bool operator==(SubtreeIterator const &other) const
Definition: ConfigTree.h:130
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:234
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:534
SubtreeIterator(Iterator it, std::string root, ConfigTree const &parent)
Definition: ConfigTree.h:109
std::string _path
A path printed in error/warning messages.
Definition: ConfigTree.h:609
void error(std::string const &message) const
Definition: ConfigTree.cpp:213
bool _have_read_data
Indicates if the plain data contained in this tree has already been read.
Definition: ConfigTree.h:627
void ignoreConfigParameterAll(std::string const &param) const
Definition: ConfigTree.cpp:201
boost::property_tree::ptree const * _tree
The wrapped tree.
Definition: ConfigTree.h:606
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:295
void warning(std::string const &message) const
Definition: ConfigTree.cpp:221
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:633
std::map< KeyType, CountType > _visited_params
Definition: ConfigTree.h:624
std::string _filename
The path of the file from which this tree has been read.
Definition: ConfigTree.h:612
void checkKeyname(std::string const &key) const
Checks if key complies with the rules [a-z0-9_].
Definition: ConfigTree.cpp:266
Callback _onerror
Custom error callback.
Definition: ConfigTree.h:629
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:218
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:304
void checkAndInvalidate(ConfigTree &conf)
Definition: ConfigTree.cpp:426
bool operator!=(SubtreeIterator const &other) const
Definition: ConfigTree.h:134
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:256
ValueIterator(Iterator it, std::string root, ConfigTree const &parent)
Definition: ConfigTree.h:181
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:338
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:229
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:615
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:241
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:202
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:146
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:227
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:170
Callback _onwarning
Custom warning callback.
Definition: ConfigTree.h:630
boost::optional< T > getConfigAttributeOptional(std::string const &attr) const
bool operator!=(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:206
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:636
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:179
Range< ValueIterator< T > > getConfigParameterList(std::string const &param) const
boost::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:156
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:190
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:182
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:186
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:284
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:107
static const std::string key_chars
Set of allowed characters in a key name.
Definition: ConfigTree.h:639
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:352