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 <iosfwd>
16#include <iterator>
17#include <map>
18#include <memory>
19#include <optional>
20#include <typeindex>
21#include <utility>
22#include <vector>
23
24extern template class boost::property_tree::basic_ptree<
25 std::string, std::string, std::less<>>;
26
27namespace BaseLib
28{
29class ConfigTree;
30
37void checkAndInvalidate(ConfigTree* const conf);
38
40void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
41
43void checkAndInvalidate(ConfigTree& conf);
44
45template <typename Iterator>
46class Range;
47
104class ConfigTree final
105{
106public:
113 {
114 public:
115 using iterator_category = std::input_iterator_tag;
117 using difference_type = std::ptrdiff_t;
120
121 using Iterator = boost::property_tree::ptree::const_assoc_iterator;
122
123 explicit SubtreeIterator(Iterator const& it, std::string const& root,
124 ConfigTree const& parent)
125 : it_(it), tagname_(root), parent_(parent)
126 {
127 }
128
130 {
131 ++it_;
132 has_incremented_ = true;
133 return *this;
134 }
135
137 {
138 // if this iterator has been incremented since the last dereference,
139 // tell the parent_ instance that a subtree now has been parsed.
141 {
142 has_incremented_ = false;
144 }
145 return ConfigTree(it_->second, parent_, tagname_);
146 }
147
148 bool operator==(SubtreeIterator const& other) const
149 {
150 return it_ == other.it_;
151 }
152
153 bool operator!=(SubtreeIterator const& other) const
154 {
155 return it_ != other.it_;
156 }
157
158 private:
159 bool has_incremented_ = true;
161
162 protected:
163 std::string const tagname_;
165 };
166
174 {
175 public:
178
180 {
181 auto st = SubtreeIterator::operator*();
182 if (st.hasChildren())
183 {
184 parent_.error("The requested parameter <" + tagname_ +
185 "> has child elements.");
186 }
187 return st;
188 }
189 };
190
197 template <typename ValueType>
199 {
200 public:
201 using iterator_category = std::input_iterator_tag;
203 using difference_type = std::ptrdiff_t;
206
207 using Iterator = boost::property_tree::ptree::const_assoc_iterator;
208
209 explicit ValueIterator(Iterator const& it, std::string const& root,
210 ConfigTree const& parent)
211 : it_(it), tagname_(root), parent_(parent)
212 {
213 }
214
216 {
217 ++it_;
218 has_incremented_ = true;
219 return *this;
220 }
221
222 ValueType operator*()
223 {
224 // if this iterator has been incremented since the last dereference,
225 // tell the parent_ instance that a setting now has been parsed.
227 {
228 has_incremented_ = false;
229 parent_.markVisited<ValueType>(tagname_, Attr::TAG, false);
230 }
231 return ConfigTree(it_->second, parent_, tagname_)
232 .getValue<ValueType>();
233 }
234
235 bool operator==(ValueIterator<ValueType> const& other) const
236 {
237 return it_ == other.it_;
238 }
239
240 bool operator!=(ValueIterator<ValueType> const& other) const
241 {
242 return it_ != other.it_;
243 }
244
245 private:
246 bool has_incremented_ = true;
248 std::string const tagname_;
250 };
251
253 using PTree = boost::property_tree::ptree;
254
262 using Callback = std::function<void(const std::string& filename,
263 const std::string& path,
264 const std::string& message)>;
265
281 explicit ConfigTree(PTree&& top_level_tree,
282 std::string filename,
283 Callback error_cb,
284 Callback warning_cb);
285
287 ConfigTree(ConfigTree const&) = delete;
288
291 ConfigTree(ConfigTree&& other);
292
294 ConfigTree& operator=(ConfigTree const&) = delete;
295
299
301 std::string const& getProjectFileName() const { return filename_; }
302
307
314 template <typename T>
315 T getConfigParameter(std::string const& param) const;
316
326 template <typename T>
327 T getConfigParameter(std::string const& param,
328 T const& default_value) const;
329
339 template <typename T>
340 std::optional<T> getConfigParameterOptional(std::string const& param) const;
341
349 template <typename T>
351 std::string const& param) const;
352
354
367
374 ConfigTree getConfigParameter(std::string const& root) const;
375
382 std::optional<ConfigTree> getConfigParameterOptional(
383 std::string const& root) const;
384
393 std::string const& param) const;
394
401 template <typename T>
402 T getValue() const;
403
410 template <typename T>
411 T getConfigAttribute(std::string const& attr) const;
412
424 template <typename T>
425 T getConfigAttribute(std::string const& attr, T const& default_value) const;
426
434 template <typename T>
435 std::optional<T> getConfigAttributeOptional(std::string const& attr) const;
436
438
446
459 template <typename T>
460 T peekConfigParameter(std::string const& param) const;
461
467 template <typename T>
468 void checkConfigParameter(std::string const& param, T const& value) const;
469
471 template <typename Ch>
472 void checkConfigParameter(std::string const& param, Ch const* value) const;
473
475
479
486 ConfigTree getConfigSubtree(std::string const& root) const;
487
492 std::optional<ConfigTree> getConfigSubtreeOptional(
493 std::string const& root) const;
494
502 Range<SubtreeIterator> getConfigSubtreeList(std::string const& root) const;
503
505
509
516 void ignoreConfigParameter(std::string const& param) const;
517
525 void ignoreConfigParameterAll(std::string const& param) const;
526
533 void ignoreConfigAttribute(std::string const& attr) const;
534
536
540 ~ConfigTree();
541
544 static void onerror(std::string const& filename, std::string const& path,
545 std::string const& message);
546
549 static void onwarning(std::string const& filename, std::string const& path,
550 std::string const& message);
551
553 static void assertNoSwallowedErrors();
554
555private:
557 template <typename T>
558 std::optional<T> getConfigParameterOptionalImpl(std::string const& param,
559 T* /*unused*/) const;
560
562 template <typename T>
563 std::optional<std::vector<T>> getConfigParameterOptionalImpl(
564 std::string const& param, std::vector<T>* /*unused*/) const;
565
567 {
568 int count;
569 std::type_index type;
570 };
571
573 enum class Attr : bool
574 {
575 TAG = false,
576 ATTR = true
577 };
578
580 explicit ConfigTree(PTree const& tree, ConfigTree const& parent,
581 std::string const& root);
582
587 [[noreturn]] void error(std::string const& message) const;
588
591 void warning(std::string const& message) const;
592
594 void checkKeyname(std::string const& key) const;
595
597 std::string joinPaths(std::string const& p1, std::string const& p2) const;
598
600 void checkUnique(std::string const& key) const;
601
603 void checkUniqueAttr(std::string const& attr) const;
604
612 template <typename T>
613 CountType& markVisited(std::string const& key, Attr const is_attr,
614 bool peek_only) const;
615
623 CountType& markVisited(std::string const& key, Attr const is_attr,
624 bool const peek_only) const;
625
628 void markVisitedDecrement(Attr const is_attr, std::string const& key) const;
629
631 bool hasChildren() const;
632
639 void checkAndInvalidate();
640
642 static std::string shortString(std::string const& s);
643
647 std::shared_ptr<PTree const> top_level_tree_;
648
650 PTree const* tree_;
651
653 std::string path_;
654
656 std::string filename_;
657
659 using KeyType = std::pair<Attr, std::string>;
660
668 mutable std::map<KeyType, CountType> visited_params_;
669
672 mutable bool have_read_data_ = false;
673
676
678 static const char pathseparator;
679
681 static const std::string key_chars_start;
682
684 static const std::string key_chars;
685
686 friend void checkAndInvalidate(ConfigTree* const conf);
687 friend void checkAndInvalidate(ConfigTree& conf);
688 friend void checkAndInvalidate(std::unique_ptr<ConfigTree> const& conf);
689};
690
691} // namespace BaseLib
692
693#include "ConfigTree-impl.h" // IWYU pragma: keep
bool operator!=(SubtreeIterator const &other) const
Definition: ConfigTree.h:153
std::input_iterator_tag iterator_category
Definition: ConfigTree.h:115
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:121
SubtreeIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:123
bool operator==(SubtreeIterator const &other) const
Definition: ConfigTree.h:148
boost::property_tree::ptree::const_assoc_iterator Iterator
Definition: ConfigTree.h:207
std::input_iterator_tag iterator_category
Definition: ConfigTree.h:201
ValueIterator< ValueType > & operator++()
Definition: ConfigTree.h:215
bool operator==(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:235
ValueIterator(Iterator const &it, std::string const &root, ConfigTree const &parent)
Definition: ConfigTree.h:209
bool operator!=(ValueIterator< ValueType > const &other) const
Definition: ConfigTree.h:240
T peekConfigParameter(std::string const &param) const
void markVisitedDecrement(Attr const is_attr, std::string const &key) const
Definition: ConfigTree.cpp:365
void ignoreConfigParameter(std::string const &param) const
Definition: ConfigTree.cpp:186
static void onerror(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:230
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Definition: ConfigTree.cpp:244
Callback onwarning_
Custom warning callback.
Definition: ConfigTree.h:675
void checkConfigParameter(std::string const &param, T const &value) const
static const char pathseparator
Character separating two path components.
Definition: ConfigTree.h:678
void checkUniqueAttr(std::string const &attr) const
Asserts that the attribute attr has not been read yet.
Definition: ConfigTree.cpp:324
std::map< KeyType, CountType > visited_params_
Definition: ConfigTree.h:668
std::string const & getProjectFileName() const
Used to get the project file name.
Definition: ConfigTree.h:301
static std::string shortString(std::string const &s)
returns a short string at suitable for error/warning messages
Definition: ConfigTree.cpp:262
std::shared_ptr< PTree const > top_level_tree_
Definition: ConfigTree.h:647
void error(std::string const &message) const
Definition: ConfigTree.cpp:217
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:160
std::optional< T > getConfigParameterOptional(std::string const &param) const
void ignoreConfigAttribute(std::string const &attr) const
Definition: ConfigTree.cpp:194
void checkUnique(std::string const &key) const
Asserts that the key has not been read yet.
Definition: ConfigTree.cpp:314
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:574
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:174
static const std::string key_chars_start
Set of allowed characters as the first letter of a key name.
Definition: ConfigTree.h:681
std::function< void(const std::string &filename, const std::string &path, const std::string &message)> Callback
Definition: ConfigTree.h:264
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:151
std::pair< Attr, std::string > KeyType
A pair (is attribute, tag/attribute name).
Definition: ConfigTree.h:659
std::string path_
A path printed in error/warning messages.
Definition: ConfigTree.h:653
CountType & markVisited(std::string const &key, Attr const is_attr, bool peek_only) const
void ignoreConfigParameterAll(std::string const &param) const
Definition: ConfigTree.cpp:205
Callback onerror_
Custom error callback.
Definition: ConfigTree.h:674
std::string joinPaths(std::string const &p1, std::string const &p2) const
Used to generate the path of a subtree.
Definition: ConfigTree.cpp:298
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:225
bool hasChildren() const
Checks if this tree has any children.
Definition: ConfigTree.cpp:380
PTree const * tree_
The wrapped tree.
Definition: ConfigTree.h:650
boost::property_tree::ptree PTree
The tree being wrapped by this class.
Definition: ConfigTree.h:253
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:656
void checkKeyname(std::string const &key) const
Checks if key complies with the rules [a-z0-9_].
Definition: ConfigTree.cpp:274
static void onwarning(std::string const &filename, std::string const &path, std::string const &message)
Definition: ConfigTree.cpp:237
static const std::string key_chars
Set of allowed characters in a key name.
Definition: ConfigTree.h:684
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:475