userver: userver/storages/postgres/detail/const_data_iterator.hpp Source File
Loading...
Searching...
No Matches
const_data_iterator.hpp
1#pragma once
2
3#include <iterator>
4
5#include <userver/storages/postgres/detail/iterator_direction.hpp>
6
7USERVER_NAMESPACE_BEGIN
8
9namespace storages::postgres::detail {
10
11/// @brief Template for implementing ResultSet::ConstRowIterator and
12/// ResultSet::ConstFieldIterator.
13///
14/// FinalType must provide following public functions:
15/// Advance(int)
16/// Compare(...)
17/// Distance(...)
18/// Valid()
19template <typename FinalType, typename DataType,
20 IteratorDirection direction = IteratorDirection::kForward>
21class ConstDataIterator : protected DataType {
22 using Iter = ConstDataIterator;
23
24 public:
25 //@{
26 /** @name Iterator concept */
27 using value_type = DataType;
28 using difference_type = std::ptrdiff_t;
29 using reference = const value_type&;
30 using pointer = const value_type*;
31 using iterator_category = std::random_access_iterator_tag;
32 //@}
33
34 //@{
35 /** @name Iterator dereferencing */
36 reference operator*() const { return static_cast<reference>(*this); }
37 pointer operator->() const { return static_cast<pointer>(this); }
38 //@}
39
40 //@{
41 /** @name Iterator validity */
42 explicit operator bool() const { return this->IsValid(); }
43 bool operator!() const { return !this->IsValid(); }
44 //@}
45
46 //@{
47 /** @name Iterator movement */
48 FinalType& operator++() { return DoAdvance(1); }
49 FinalType operator++(int) {
50 FinalType prev{Rebind()};
51 DoAdvance(1);
52 return prev;
53 }
54
55 FinalType& operator--() { return DoAdvance(-1); }
56 FinalType operator--(int) {
57 FinalType prev{Rebind()};
58 DoAdvance(-1);
59 return prev;
60 }
61
62 FinalType operator+(difference_type distance) const {
63 FinalType res{Rebind()};
64 res.DoAdvance(distance);
65 return res;
66 }
67
68 FinalType operator-(difference_type distance) const {
69 FinalType res{Rebind()};
70 res.DoAdvance(-distance);
71 return res;
72 }
73
74 difference_type operator-(const FinalType& rhs) const {
75 return this->Distance(rhs) * static_cast<int>(direction);
76 }
77
78 FinalType operator[](difference_type index) const {
79 return *this + index * static_cast<int>(direction);
80 }
81
82 FinalType& operator+=(difference_type distance) {
83 return DoAdvance(distance);
84 }
85 FinalType& operator-=(difference_type distance) {
86 return DoAdvance(-distance);
87 }
88 //@}
89
90 //@{
91 /** @name Iterator comparison */
92 bool operator==(const Iter& rhs) const { return DoCompare(rhs) == 0; }
93 bool operator!=(const Iter& rhs) const { return !(*this == rhs); }
94
95 bool operator<(const Iter& rhs) const { return DoCompare(rhs) < 0; }
96 bool operator<=(const Iter& rhs) const { return DoCompare(rhs) <= 0; }
97 bool operator>(const Iter& rhs) const { return DoCompare(rhs) > 0; }
98 bool operator>=(const Iter& rhs) const { return DoCompare(rhs) >= 0; }
99 //@}
100 protected:
101 template <typename... T>
102 ConstDataIterator(T&&... args) : value_type(std::forward<T>(args)...) {}
103
104 private:
105 FinalType& Rebind() { return static_cast<FinalType&>(*this); }
106 const FinalType& Rebind() const {
107 return static_cast<const FinalType&>(*this);
108 }
109
110 FinalType& DoAdvance(difference_type distance) {
111 this->Advance(distance * static_cast<int>(direction));
112 return Rebind();
113 }
114 int DoCompare(const Iter& rhs) const { return this->Compare(rhs); }
115};
116
117} // namespace storages::postgres::detail
118
119USERVER_NAMESPACE_END