userver: userver/storages/postgres/detail/typed_rows.hpp Source File
Loading...
Searching...
No Matches
typed_rows.hpp
1#pragma once
2
3#include <boost/pfr/core.hpp>
4
5#include <userver/storages/postgres/result_set.hpp>
6
7#include <userver/storages/postgres/detail/iterator_direction.hpp>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace storages::postgres::detail {
12
13template <typename T, typename ExtractionTag,
14 IteratorDirection direction = IteratorDirection::kForward>
15class ConstTypedRowIterator : private Row {
16 public:
17 //@{
18 /** @name Iterator concept */
19 using value_type = T;
20 using difference_type = std::ptrdiff_t;
21 using reference = value_type;
22 using pointer = const value_type*;
23 /// This iterator doesn't satisfy ForwardIterator concept as it returns
24 /// data by value. In all other respects it behaves as a random access
25 /// iterator.
26 using iterator_category = std::input_iterator_tag;
27 //@}
28 static constexpr ExtractionTag kExtractTag{};
29
30 //@{
31 /** @name Iterator dereferencing */
32 /// Read typed value from underlying postgres buffers and return it.
33 /// Please note there is no operator ->.
34 value_type operator*() const { return As<value_type>(kExtractTag); }
35 //@}
36 //@{
37 /** @name Iterator validity */
38 explicit operator bool() const { return this->IsValid(); }
39 bool operator!() const { return !this->IsValid(); }
40 //@}
41
42 //@{
43 /** @name Iterator movement */
44 ConstTypedRowIterator& operator++() { return DoAdvance(1); }
45 ConstTypedRowIterator operator++(int) {
46 ConstTypedRowIterator prev{*this};
47 DoAdvance(1);
48 return prev;
49 }
50
51 ConstTypedRowIterator& operator--() { return DoAdvance(-1); }
52 ConstTypedRowIterator operator--(int) {
53 ConstTypedRowIterator prev{*this};
54 DoAdvance(-1);
55 return prev;
56 }
57
58 ConstTypedRowIterator operator+(difference_type distance) const {
59 ConstTypedRowIterator res{*this};
60 res.DoAdvance(distance);
61 return res;
62 }
63 ConstTypedRowIterator operator-(difference_type distance) const {
64 ConstTypedRowIterator res{*this};
65 res.DoAdvance(-distance);
66 return res;
67 }
68
69 difference_type operator-(const ConstTypedRowIterator& rhs) const {
70 return this->Distance(rhs) * static_cast<int>(direction);
71 }
72
73 ConstTypedRowIterator operator[](difference_type index) const {
74 return *this + index * static_cast<int>(direction);
75 }
76
77 ConstTypedRowIterator& operator+=(difference_type distance) {
78 return DoAdvance(distance);
79 }
80 ConstTypedRowIterator& operator-=(difference_type distance) {
81 return DoAdvance(-distance);
82 }
83 //@}
84
85 //@{
86 /** @name Iterator comparison */
87 bool operator==(const ConstTypedRowIterator& rhs) const {
88 return this->Compare(rhs) == 0;
89 }
90
91 bool operator!=(const ConstTypedRowIterator& rhs) const {
92 return !(*this == rhs);
93 }
94
95 bool operator<(const ConstTypedRowIterator& rhs) const {
96 return this->Compare(rhs) < 0;
97 }
98 bool operator<=(const ConstTypedRowIterator& rhs) const {
99 return this->Compare(rhs) <= 0;
100 }
101 bool operator>(const ConstTypedRowIterator& rhs) const {
102 return this->Compare(rhs) > 0;
103 }
104 bool operator>=(const ConstTypedRowIterator& rhs) const {
105 return this->Compare(rhs) >= 0;
106 }
107 //@}
108 private:
109 friend class TypedResultSet<T, ExtractionTag>;
110
111 ConstTypedRowIterator(detail::ResultWrapperPtr res, size_type row)
112 : Row{std::move(res), row} {}
113 ConstTypedRowIterator& DoAdvance(difference_type distance) {
114 this->Advance(distance * static_cast<int>(direction));
115 return *this;
116 }
117};
118
119} // namespace storages::postgres::detail
120
121USERVER_NAMESPACE_END