OGS
ConfigTree.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <boost/property_tree/ptree.hpp>
14 #include <functional>
15 #include <map>
16 #include <memory>
17 #include <optional>
18 #include <typeindex>
19 #include <utility>
20 #include <vector>
21 
22 extern template class boost::property_tree::basic_ptree<
23  std::string, std::string, std::less<>>;
24 
25 namespace BaseLib
26 {
27 class ConfigTree;
28 
35 void checkAndInvalidate(ConfigTree* const conf);
36 
38 void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
39 
41 void checkAndInvalidate(ConfigTree& conf);
42 
43 template <typename Iterator>
44 class Range;
45 
102 class ConfigTree final
103 {
104 public:
111  : public std::iterator<std::input_iterator_tag, ConfigTree>
112  {
113  public:
114  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
115 
116  explicit SubtreeIterator(Iterator const& it, std::string const& root,
117  ConfigTree const& parent)
118  : it_(it), tagname_(root), parent_(parent)
119  {
120  }
121 
123  {
124  ++it_;
125  has_incremented_ = true;
126  return *this;
127  }
128 
130  {
131  // if this iterator has been incremented since the last dereference,
132  // tell the parent_ instance that a subtree now has been parsed.
133  if (has_incremented_)
134  {
135  has_incremented_ = false;
137  }
138  return ConfigTree(it_->second, parent_, tagname_);
139  }
140 
141  bool operator==(SubtreeIterator const& other) const
142  {
143  return it_ == other.it_;
144  }
145 
146  bool operator!=(SubtreeIterator const& other) const
147  {
148  return it_ != other.it_;
149  }
150 
151  private:
152  bool has_incremented_ = true;
154 
155  protected:
156  std::string const tagname_;
158  };
159 
167  {
168  public:
171 
173  {
174  auto st = SubtreeIterator::operator*();
175  if (st.hasChildren())
176  {
177  parent_.error("The requested parameter <" + tagname_ +
178  "> has child elements.");
179  }
180  return st;
181  }
182  };
183 
190  template <typename ValueType>
192  : public std::iterator<std::input_iterator_tag, ValueType>
193  {
194  public:
195  using Iterator = boost::property_tree::ptree::const_assoc_iterator;
196 
197  explicit ValueIterator(Iterator const& it, std::string const& root,
198  ConfigTree const& parent)
199  : it_(it), tagname_(root), parent_(parent)
200  {
201  }
202 
204  {
205  ++it_;
206  has_incremented_ = true;
207  return *this;
208  }
209 
210  ValueType operator*()
211  {
212  // if this iterator has been incremented since the last dereference,
213  // tell the parent_ instance that a setting now has been parsed.
214  if (has_incremented_)
215  {
216  has_incremented_ = false;
217  parent_.markVisited<ValueType>(tagname_, Attr::TAG, false);
218  }
219  return ConfigTree(it_->second, parent_, tagname_)
220  .getValue<ValueType>();
221  }
222 
223  bool operator==(ValueIterator<ValueType> const& other) const
224  {
225  return it_ == other.it_;
226  }
227 
228  bool operator!=(ValueIterator<ValueType> const& other) const
229  {
230  return it_ != other.it_;
231  }
232 
233  private:
234  bool has_incremented_ = true;
236  std::string const tagname_;
238  };
239 
241  using PTree = boost::property_tree::ptree;
242 
250  using Callback = std::function<void(const std::string& filename,
251  const std::string& path,
252  const std::string& message)>;
253 
269  explicit ConfigTree(PTree const& tree,
270  std::string filename,
271  Callback error_cb,
272  Callback warning_cb);
273 
279  explicit ConfigTree(PTree&&, std::string const&, Callback const&,
280  Callback const&) = delete;
281 
283  ConfigTree(ConfigTree const&) = delete;
284 
287  ConfigTree(ConfigTree&& other);
288 
290  ConfigTree& operator=(ConfigTree const&) = delete;
291 
294  ConfigTree& operator=(ConfigTree&& other);
295 
297  std::string const& getProjectFileName() const { return filename_; }
298 
303 
310  template <typename T>
311  T getConfigParameter(std::string const& param) const;
312 
322  template <typename T>
323  T getConfigParameter(std::string const& param,
324  T const& default_value) const;
325 
335  template <typename T>
336  std::optional<T> getConfigParameterOptional(std::string const& param) const;
337 
345  template <typename T>
347  std::string const& param) const;
348 
350 
363 
370  ConfigTree getConfigParameter(std::string const& root) const;
371 
378  std::optional<ConfigTree> getConfigParameterOptional(
379  std::string const& root) const;
380 
389  std::string const& param) const;
390 
397  template <typename T>
398  T getValue() const;
399 
406  template <typename T>
407  T getConfigAttribute(std::string const& attr) const;
408 
420  template <typename T>
421  T getConfigAttribute(std::string const& attr, T const& default_value) const;
422 
430  template <typename T>
431  std::optional<T> getConfigAttributeOptional(std::string const& attr) const;
432 
434 
442 
455  template <typename T>
456  T peekConfigParameter(std::string const& param) const;
457 
463  template <typename T>
464  void checkConfigParameter(std::string const& param, T const& value) const;
465 
467  template <typename Ch>
468  void checkConfigParameter(std::string const& param, Ch const* value) const;
469 
471 
475 
482  ConfigTree getConfigSubtree(std::string const& root) const;
483 
488  std::optional<ConfigTree> getConfigSubtreeOptional(
489  std::string const& root) const;
490 
498  Range<SubtreeIterator> getConfigSubtreeList(std::string const& root) const;
499 
501 
505 
512  void ignoreConfigParameter(std::string const& param) const;
513 
521  void ignoreConfigParameterAll(std::string const& param) const;
522 
529  void ignoreConfigAttribute(std::string const& attr) const;
530 
532 
536  ~ConfigTree();
537 
540  static void onerror(std::string const& filename, std::string const& path,
541  std::string const& message);
542 
545  static void onwarning(std::string const& filename, std::string const& path,
546  std::string const& message);
547 
549  static void assertNoSwallowedErrors();
550 
551 private:
553  template <typename T>
554  std::optional<T> getConfigParameterOptionalImpl(std::string const& param,
555  T* /*unused*/) const;
556 
558  template <typename T>
559  std::optional<std::vector<T>> getConfigParameterOptionalImpl(
560  std::string const& param, std::vector<T>* /*unused*/) const;
561 
562  struct CountType
563  {
564  int count;
565  std::type_index type;
566  };
567 
569  enum class Attr : bool
570  {
571  TAG = false,
572  ATTR = true
573  };
574 
576  explicit ConfigTree(PTree const& tree, ConfigTree const& parent,
577  std::string const& root);
578 
583  [[noreturn]] void error(std::string const& message) const;
584 
587  void warning(std::string const& message) const;
588 
590  void checkKeyname(std::string const& key) const;
591 
593  std::string joinPaths(std::string const& p1, std::string const& p2) const;
594 
596  void checkUnique(std::string const& key) const;
597 
599  void checkUniqueAttr(std::string const& attr) const;
600 
608  template <typename T>
609  CountType& markVisited(std::string const& key, Attr const is_attr,
610  bool peek_only) const;
611 
619  CountType& markVisited(std::string const& key, Attr const is_attr,
620  bool const peek_only) const;
621 
624  void markVisitedDecrement(Attr const is_attr, std::string const& key) const;
625 
627  bool hasChildren() const;
628 
635  void checkAndInvalidate();
636 
638  static std::string shortString(std::string const& s);
639 
641  boost::property_tree::ptree const* tree_;
642 
644  std::string path_;
645 
647  std::string filename_;
648 
650  using KeyType = std::pair<Attr, std::string>;
651 
659  mutable std::map<KeyType, CountType> visited_params_;
660 
663  mutable bool have_read_data_ = false;
664 
667 
669  static const char pathseparator;
670 
672  static const std::string key_chars_start;
673 
675  static const std::string key_chars;
676 
677  friend void checkAndInvalidate(ConfigTree* const conf);
678  friend void checkAndInvalidate(ConfigTree& conf);
679  friend void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
680 };
681 
682 } // namespace BaseLib
683 
684 #include "ConfigTree-impl.h"
bool operator!=(SubtreeIterator const &other) const
Definition: ConfigTree.h:146
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:114
SubtreeIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:116
bool operator==(SubtreeIterator const &other) const
Definition: ConfigTree.h:141
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:195
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:223
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:203
ValueIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:197
bool operator!=(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:228
T peekConfigParameter(std::string const &param) const
void markVisitedDecrement(Attr const is_attr, std::string const &key) const
Definition: ConfigTree.cpp:360
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:181
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:225
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Definition: ConfigTree.cpp:239
Callback onwarning_
Custom warning callback.
Definition: ConfigTree.h:666
void checkConfigParameter(std::string const &param, T const &value) const
static const char pathseparator
Character separating two path components.
Definition: ConfigTree.h:669
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:319
std::map< KeyType, CountType > visited_params_
Definition: ConfigTree.h:659
static std::string shortString(std::string const &s)
returns a short string at suitable for error/warning messages
Definition: ConfigTree.cpp:257
ConfigTree(PTree const &tree, std::string filename, Callback error_cb, Callback warning_cb)
Definition: ConfigTree.cpp:34
void error(std::string const &message) const
Definition: ConfigTree.cpp:212
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:155
ConfigTree(PTree &&, std::string const &, Callback const &, Callback const &)=delete
std::optional< T > getConfigParameterOptional(std::string const &param) const
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:189
void checkUnique(std::string const &key) const
Asserts that the key has not been read yet.
Definition: ConfigTree.cpp:309
T getConfigParameter(std::string const &param) const
T getConfigAttribute(std::string const &attr) const
Attr
Used to indicate if dealing with XML tags or XML attributes.
Definition: ConfigTree.h:570
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:169
static const std::string key_chars_start
Set of allowed characters as the first letter of a key name.
Definition: ConfigTree.h:672
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:252
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:146
std::pair< Attr, std::string > KeyType
A pair (is attribute, tag/attribute name).
Definition: ConfigTree.h:650
std::string path_
A path printed in error/warning messages.
Definition: ConfigTree.h:644
CountType & markVisited(std::string const &key, Attr const is_attr, bool peek_only) const
void ignoreConfigParameterAll(std::string const &param) const
Definition: ConfigTree.cpp:200
boost::property_tree::ptree const * tree_
The wrapped tree.
Definition: ConfigTree.h:641
Callback onerror_
Custom error callback.
Definition: ConfigTree.h:665
std::string const & getProjectFileName() const
Used to get the project file name.
Definition: ConfigTree.h:297
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:293
std::optional< T > getConfigParameterOptionalImpl(std::string const &param, T *) const
Default implementation of reading a value of type T.
ConfigTree(ConfigTree const &)=delete
copying is not compatible with the semantics of this class
Range< ValueIterator< T > > getConfigParameterList(std::string const &param) const
ConfigTree & operator=(ConfigTree const &)=delete
copying is not compatible with the semantics of this class
std::optional< T > getConfigAttributeOptional(std::string const &attr) const
void warning(std::string const &message) const
Definition: ConfigTree.cpp:220
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:375
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:241
std::string filename_
The path of the file from which this tree has been read.
Definition: ConfigTree.h:647
void checkKeyname(std::string const &key) const
Checks if key complies with the rules [a-z0-9_].
Definition: ConfigTree.cpp:269
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:232
static const std::string key_chars
Set of allowed characters in a key name.
Definition: ConfigTree.h:675
Wraps a pair of iterators for use as a range in range-based for-loops.
void checkAndInvalidate(ConfigTree &conf)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ConfigTree.cpp:470