Github   Telegram
Loading...
Searching...
No Matches
iterator.hpp
1#pragma once
2
3#include <iterator>
4
5#include <userver/formats/yaml/value.hpp>
6
7USERVER_NAMESPACE_BEGIN
8
9namespace yaml_config {
10
11template <typename iter_traits>
12class Iterator final {
13 public:
14 using YamlIterator = formats::yaml::Value::const_iterator;
15 using iterator_category = std::forward_iterator_tag;
16 using difference_type = std::ptrdiff_t;
17 using value_type = typename iter_traits::value_type;
18 using reference = typename iter_traits::reference;
19 using pointer = typename iter_traits::pointer;
20
21 Iterator(const value_type& container, YamlIterator it)
22 : container_(&container), it_(std::move(it)) {}
23
24 Iterator(const Iterator& other);
25 Iterator(Iterator&& other) noexcept;
26 Iterator& operator=(const Iterator&);
27 Iterator& operator=(Iterator&&) noexcept;
28
29 Iterator operator++(int) {
30 current_.reset();
31 return Iterator{*container_, it_++};
32 }
33 Iterator& operator++() {
34 ++it_;
35 current_.reset();
36 return *this;
37 }
38 reference operator*() const {
39 UpdateValue();
40 return *current_;
41 }
42 pointer operator->() const {
43 UpdateValue();
44 return &(*current_);
45 }
46
47 /// Return whether this is iterator over object or over array
48 /// @returns formats::common::kArray or formats::common::kObject
49 formats::common::Type GetIteratorType() const {
50 return it_.GetIteratorType();
51 }
52
53 // Get member name - only if iterator is over object
54 auto GetName() const { return it_.GetName(); }
55
56 bool operator==(const Iterator& other) const { return it_ == other.it_; }
57 bool operator!=(const Iterator& other) const { return it_ != other.it_; }
58
59 private:
60 void UpdateValue() const;
61
62 // Pointer to the 'container' yaml - because substitution parsing
63 // only works with container[index/key] statements
64 const value_type* container_{nullptr};
65 // Iterator over container. We actually only use its GetIndex/GetName
66 // members
67 YamlIterator it_;
68 mutable std::optional<value_type> current_;
69};
70
71} // namespace yaml_config
72
73USERVER_NAMESPACE_END