OGS 6.2.1-372-g67eca524a.dirty.20190919230349
ConfigTree.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <typeindex>
14 #include <map>
15 
16 #include <functional>
17 #include <memory>
18 #include <utility>
19 #include <vector>
20 
21 #include <boost/property_tree/ptree.hpp>
22 
23 extern template class boost::property_tree::basic_ptree<
24  std::string, std::string, std::less<>>;
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  {
162  _parent.error("The requested parameter <" + _tagname +
163  "> has child elements.");
164  }
165  return st;
166  }
167  };
168 
169 
176  template<typename ValueType>
178  : public std::iterator<std::input_iterator_tag, ValueType>
179  {
180  public:
181  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
182 
183  explicit ValueIterator(Iterator it, std::string root,
184  ConfigTree const& parent)
185  : _it(it), _tagname(std::move(root)), _parent(parent)
186  {}
187 
189  ++_it;
190  _has_incremented = true;
191  return *this;
192  }
193 
194  ValueType operator*() {
195  // if this iterator has been incremented since the last dereference,
196  // tell the _parent instance that a setting now has been parsed.
197  if (_has_incremented) {
198  _has_incremented = false;
199  _parent.markVisited<ValueType>(_tagname, Attr::TAG, false);
200  }
201  return ConfigTree(_it->second, _parent, _tagname).getValue<ValueType>();
202  }
203 
204  bool operator==(ValueIterator<ValueType> const& other) const {
205  return _it == other._it;
206  }
207 
208  bool operator!=(ValueIterator<ValueType> const& other) const {
209  return _it != other._it;
210  }
211 
212  private:
213  bool _has_incremented = true;
215  std::string const _tagname;
217  };
218 
220  using PTree = boost::property_tree::ptree;
221 
229  using Callback = std::function<void(const std::string& filename,
230  const std::string& path,
231  const std::string& message)>;
232 
248  explicit ConfigTree(PTree const& tree,
249  std::string filename,
250  Callback error_cb,
251  Callback warning_cb);
252 
257  explicit ConfigTree(PTree&&, std::string const&,
258  Callback const&, Callback const&) = delete;
259 
261  ConfigTree(ConfigTree const&) = delete;
262 
265  ConfigTree(ConfigTree && other);
266 
268  ConfigTree& operator=(ConfigTree const&) = delete;
269 
272  ConfigTree& operator=(ConfigTree&& other);
273 
275  std::string const& getProjectFileName() const { return _filename; }
276 
280 
288  template<typename T> T
289  getConfigParameter(std::string const& param) const;
290 
300  template<typename T> T
301  getConfigParameter(std::string const& param, T const& default_value) const;
302 
311  template<typename T> boost::optional<T>
312  getConfigParameterOptional(std::string const& param) const;
313 
320  template<typename T> Range<ValueIterator<T> >
321  getConfigParameterList(std::string const& param) const;
322 
324 
334 
342  ConfigTree getConfigParameter(std::string const& root) const;
343 
350  boost::optional<ConfigTree> getConfigParameterOptional(
351  std::string const& root) 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 
442 
450  ConfigTree
451  getConfigSubtree(std::string const& root) const;
452 
457  boost::optional<ConfigTree>
458  getConfigSubtreeOptional(std::string const& root) const;
459 
467  getConfigSubtreeList(std::string const& root) const;
468 
470 
473 
481  void ignoreConfigParameter(std::string const& param) const;
482 
489  void ignoreConfigParameterAll(std::string const& param) const;
490 
497  void ignoreConfigAttribute(std::string const& attr) const;
498 
500 
505  ~ConfigTree();
506 
509  static void onerror(std::string const& filename, std::string const& path,
510  std::string const& message);
511 
514  static void onwarning(std::string const& filename, std::string const& path,
515  std::string const& message);
516 
518  static void assertNoSwallowedErrors();
519 
520 private:
522  template <typename T>
523  boost::optional<T> getConfigParameterOptionalImpl(std::string const& param,
524  T* /*unused*/) const;
525 
527  template <typename T>
528  boost::optional<std::vector<T>> getConfigParameterOptionalImpl(
529  std::string const& param, std::vector<T>* /*unused*/) 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:130
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:239
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:109
std::string _path
A path printed in error/warning messages.
Definition: ConfigTree.h:608
void error(std::string const &message) const
Definition: ConfigTree.cpp:218
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:206
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:275
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:308
void warning(std::string const &message) const
Definition: ConfigTree.cpp:226
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:276
Callback _onerror
Custom error callback.
Definition: ConfigTree.h:628
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:220
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:317
void checkAndInvalidate(ConfigTree &conf)
Definition: ConfigTree.cpp:453
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:263
ValueIterator(Iterator it, std::string root, ConfigTree const &parent)
Definition: ConfigTree.h:183
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:357
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:231
ConfigTree(PTree const &tree, std::string filename, Callback error_cb, Callback warning_cb)
Definition: ConfigTree.cpp:35
Functionality to build different search length algorithm objects from given config.
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:246
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:204
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:151
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:232
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:175
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:208
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:181
Range< ValueIterator< T > > getConfigParameterList(std::string const &param) const
boost::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:161
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:195
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:187
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:188
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:294
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:638
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:371