userver: userver/yaml_config/iterator.hpp Source File
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 IterTraits>
12class Iterator final {
13public:
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 IterTraits::value_type;
18 using reference = typename IterTraits::reference;
19 using pointer = typename IterTraits::pointer;
20
21 Iterator(const value_type& container, YamlIterator it)
22 : container_(&container),
23 it_(std::move(it))
24 {}
25
26 Iterator(const Iterator& other);
27 Iterator(Iterator&& other) noexcept;
28 Iterator& operator=(const Iterator&);
29 Iterator& operator=(Iterator&&) noexcept;
30
31 Iterator operator++(int);
32 Iterator& operator++();
33
34 reference operator*() const {
35 UpdateValue();
36 return *current_;
37 }
38 pointer operator->() const {
39 UpdateValue();
40 return &(*current_);
41 }
42
43 /// Return whether this is iterator over object or over array
44 /// @returns formats::common::kArray or formats::common::kObject
46
47 // Get member name - only if iterator is over object
48 std::string GetName() const;
49
50 bool operator==(const Iterator& other) const { return it_ == other.it_; }
51 bool operator!=(const Iterator& other) const { return it_ != other.it_; }
52
53private:
54 void UpdateValue() const;
55 void IncrementInternalIterator();
56
57 // Pointer to the 'container' yaml - because substitution parsing
58 // only works with container[index/key] statements
59 const value_type* container_{nullptr};
60 // Iterator over container. We actually only use its GetIndex/GetName
61 // members
62 YamlIterator it_;
63 mutable std::optional<value_type> current_;
64};
65
66} // namespace yaml_config
67
68USERVER_NAMESPACE_END