userver: userver/storages/postgres/detail/typed_rows.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
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