userver: userver/storages/postgres/detail/const_data_iterator.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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