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
22extern template class boost::property_tree::basic_ptree<
23 std::string, std::string, std::less<>>;
24
25namespace BaseLib
26{
27class ConfigTree;
28
35void checkAndInvalidate(ConfigTree* const conf);
36
38void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
39
41void checkAndInvalidate(ConfigTree& conf);
42
43template <typename Iterator>
44class Range;
45
102class ConfigTree final
103{
104public:
111 {
112 public:
113 using iterator_category = std::input_iterator_tag;
115 using difference_type = std::ptrdiff_t;
118
119 using Iterator = boost::property_tree::ptree::const_assoc_iterator;
120
121 explicit SubtreeIterator(Iterator const& it, std::string const& root,
122 ConfigTree const& parent)
123 : it_(it), tagname_(root), parent_(parent)
124 {
125 }
126
128 {
129 ++it_;
130 has_incremented_ = true;
131 return *this;
132 }
133
135 {
136 // if this iterator has been incremented since the last dereference,
137 // tell the parent_ instance that a subtree now has been parsed.
139 {
140 has_incremented_ = false;
142 }
143 return ConfigTree(it_->second, parent_, tagname_);
144 }
145
146 bool operator==(SubtreeIterator const& other) const
147 {
148 return it_ == other.it_;
149 }
150
151 bool operator!=(SubtreeIterator const& other) const
152 {
153 return it_ != other.it_;
154 }
155
156 private:
157 bool has_incremented_ = true;
159
160 protected:
161 std::string const tagname_;
163 };
164
172 {
173 public:
176
178 {
179 auto st = SubtreeIterator::operator*();
180 if (st.hasChildren())
181 {
182 parent_.error("The requested parameter <" + tagname_ +
183 "> has child elements.");
184 }
185 return st;
186 }
187 };
188
195 template <typename ValueType>
197 {
198 public:
199 using iterator_category = std::input_iterator_tag;
201 using difference_type = std::ptrdiff_t;
204
205 using Iterator = boost::property_tree::ptree::const_assoc_iterator;
206
207 explicit ValueIterator(Iterator const& it, std::string const& root,
208 ConfigTree const& parent)
209 : it_(it), tagname_(root), parent_(parent)
210 {
211 }
212
214 {
215 ++it_;
216 has_incremented_ = true;
217 return *this;
218 }
219
220 ValueType operator*()
221 {
222 // if this iterator has been incremented since the last dereference,
223 // tell the parent_ instance that a setting now has been parsed.
225 {
226 has_incremented_ = false;
227 parent_.markVisited<ValueType>(tagname_, Attr::TAG, false);
228 }
229 return ConfigTree(it_->second, parent_, tagname_)
230 .getValue<ValueType>();
231 }
232
233 bool operator==(ValueIterator<ValueType> const& other) const
234 {
235 return it_ == other.it_;
236 }
237
238 bool operator!=(ValueIterator<ValueType> const& other) const
239 {
240 return it_ != other.it_;
241 }
242
243 private:
244 bool has_incremented_ = true;
246 std::string const tagname_;
248 };
249
251 using PTree = boost::property_tree::ptree;
252
260 using Callback = std::function<void(const std::string& filename,
261 const std::string& path,
262 const std::string& message)>;
263
279 explicit ConfigTree(PTree&& top_level_tree,
280 std::string filename,
281 Callback error_cb,
282 Callback warning_cb);
283
285 ConfigTree(ConfigTree const&) = delete;
286
289 ConfigTree(ConfigTree&& other);
290
292 ConfigTree& operator=(ConfigTree const&) = delete;
293
297
299 std::string const& getProjectFileName() const { return filename_; }
300
305
312 template <typename T>
313 T getConfigParameter(std::string const& param) const;
314
324 template <typename T>
325 T getConfigParameter(std::string const& param,
326 T const& default_value) const;
327
337 template <typename T>
338 std::optional<T> getConfigParameterOptional(std::string const& param) const;
339
347 template <typename T>
349 std::string const& param) const;
350
352
365
372 ConfigTree getConfigParameter(std::string const& root) const;
373
380 std::optional<ConfigTree> getConfigParameterOptional(
381 std::string const& root) const;
382
391 std::string const& param) const;
392
399 template <typename T>
400 T getValue() const;
401
408 template <typename T>
409 T getConfigAttribute(std::string const& attr) const;
410
422 template <typename T>
423 T getConfigAttribute(std::string const& attr, T const& default_value) const;
424
432 template <typename T>
433 std::optional<T> getConfigAttributeOptional(std::string const& attr) const;
434
436
444
457 template <typename T>
458 T peekConfigParameter(std::string const& param) const;
459
465 template <typename T>
466 void checkConfigParameter(std::string const& param, T const& value) const;
467
469 template <typename Ch>
470 void checkConfigParameter(std::string const& param, Ch const* value) const;
471
473
477
484 ConfigTree getConfigSubtree(std::string const& root) const;
485
490 std::optional<ConfigTree> getConfigSubtreeOptional(
491 std::string const& root) const;
492
500 Range<SubtreeIterator> getConfigSubtreeList(std::string const& root) const;
501
503
507
514 void ignoreConfigParameter(std::string const& param) const;
515
523 void ignoreConfigParameterAll(std::string const& param) const;
524
531 void ignoreConfigAttribute(std::string const& attr) const;
532
534
538 ~ConfigTree();
539
542 static void onerror(std::string const& filename, std::string const& path,
543 std::string const& message);
544
547 static void onwarning(std::string const& filename, std::string const& path,
548 std::string const& message);
549
551 static void assertNoSwallowedErrors();
552
553private:
555 template <typename T>
556 std::optional<T> getConfigParameterOptionalImpl(std::string const& param,
557 T* /*unused*/) const;
558
560 template <typename T>
561 std::optional<std::vector<T>> getConfigParameterOptionalImpl(
562 std::string const& param, std::vector<T>* /*unused*/) const;
563
565 {
566 int count;
567 std::type_index type;
568 };
569
571 enum class Attr : bool
572 {
573 TAG = false,
574 ATTR = true
575 };
576
578 explicit ConfigTree(PTree const& tree, ConfigTree const& parent,
579 std::string const& root);
580
585 [[noreturn]] void error(std::string const& message) const;
586
589 void warning(std::string const& message) const;
590
592 void checkKeyname(std::string const& key) const;
593
595 std::string joinPaths(std::string const& p1, std::string const& p2) const;
596
598 void checkUnique(std::string const& key) const;
599
601 void checkUniqueAttr(std::string const& attr) const;
602
610 template <typename T>
611 CountType& markVisited(std::string const& key, Attr const is_attr,
612 bool peek_only) const;
613
621 CountType& markVisited(std::string const& key, Attr const is_attr,
622 bool const peek_only) const;
623
626 void markVisitedDecrement(Attr const is_attr, std::string const& key) const;
627
629 bool hasChildren() const;
630
637 void checkAndInvalidate();
638
640 static std::string shortString(std::string const& s);
641
645 std::shared_ptr<PTree const> top_level_tree_;
646
648 PTree const* tree_;
649
651 std::string path_;
652
654 std::string filename_;
655
657 using KeyType = std::pair<Attr, std::string>;
658
666 mutable std::map<KeyType, CountType> visited_params_;
667
670 mutable bool have_read_data_ = false;
671
674
676 static const char pathseparator;
677
679 static const std::string key_chars_start;
680
682 static const std::string key_chars;
683
684 friend void checkAndInvalidate(ConfigTree* const conf);
685 friend void checkAndInvalidate(ConfigTree& conf);
686 friend void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
687};
688
689} // namespace BaseLib
690
691#include "ConfigTree-impl.h"
bool operator!=(SubtreeIterator const &other) const
Definition: ConfigTree.h:151
std::input_iterator_tag iterator_category
Definition: ConfigTree.h:113
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:119
SubtreeIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:121
bool operator==(SubtreeIterator const &other) const
Definition: ConfigTree.h:146
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:205
std::input_iterator_tag iterator_category
Definition: ConfigTree.h:199
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:213
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:233
ValueIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:207
bool operator!=(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:238
T peekConfigParameter(std::string const &param) const
void markVisitedDecrement(Attr const is_attr, std::string const &key) const
Definition: ConfigTree.cpp:364
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:185
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:229
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Definition: ConfigTree.cpp:243
Callback onwarning_
Custom warning callback.
Definition: ConfigTree.h:673
void checkConfigParameter(std::string const &param, T const &value) const
static const char pathseparator
Character separating two path components.
Definition: ConfigTree.h:676
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:323
std::map< KeyType, CountType > visited_params_
Definition: ConfigTree.h:666
std::string const & getProjectFileName() const
Used to get the project file name.
Definition: ConfigTree.h:299
static std::string shortString(std::string const &s)
returns a short string at suitable for error/warning messages
Definition: ConfigTree.cpp:261
std::shared_ptr< PTree const > top_level_tree_
Definition: ConfigTree.h:645
void error(std::string const &message) const
Definition: ConfigTree.cpp:216
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:159
std::optional< T > getConfigParameterOptional(std::string const &param) const
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:193
void checkUnique(std::string const &key) const
Asserts that the key has not been read yet.
Definition: ConfigTree.cpp:313
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:572
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:173
static const std::string key_chars_start
Set of allowed characters as the first letter of a key name.
Definition: ConfigTree.h:679
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:262
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:150
std::pair< Attr, std::string > KeyType
A pair (is attribute, tag/attribute name).
Definition: ConfigTree.h:657
std::string path_
A path printed in error/warning messages.
Definition: ConfigTree.h:651
CountType & markVisited(std::string const &key, Attr const is_attr, bool peek_only) const
void ignoreConfigParameterAll(std::string const &param) const
Definition: ConfigTree.cpp:204
Callback onerror_
Custom error callback.
Definition: ConfigTree.h:672
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:297
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
std::optional< T > getConfigAttributeOptional(std::string const &attr) const
void warning(std::string const &message) const
Definition: ConfigTree.cpp:224
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:379
PTree const * tree_
The wrapped tree.
Definition: ConfigTree.h:648
ConfigTree(PTree &&top_level_tree, std::string filename, Callback error_cb, Callback warning_cb)
Definition: ConfigTree.cpp:34
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:251
ConfigTree & operator=(ConfigTree const &)=delete
copying is not compatible with the semantics of this class
std::string filename_
The path of the file from which this tree has been read.
Definition: ConfigTree.h:654
void checkKeyname(std::string const &key) const
Checks if key complies with the rules [a-z0-9_].
Definition: ConfigTree.cpp:273
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:236
static const std::string key_chars
Set of allowed characters in a key name.
Definition: ConfigTree.h:682
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:474
static const double s