result_iterator.hxx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /** Definitions for the pqxx::result class and support classes.
  2. *
  3. * pqxx::result represents the set of result rows from a database query.
  4. *
  5. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
  6. *
  7. * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
  8. *
  9. * See COPYING for copyright license. If you did not receive a file called
  10. * COPYING with this source code, please notify the distributor of this mistake,
  11. * or contact the author.
  12. */
  13. #ifndef PQXX_H_RESULT_ITERATOR
  14. #define PQXX_H_RESULT_ITERATOR
  15. #include "pqxx/compiler-public.hxx"
  16. #include "pqxx/compiler-internal-pre.hxx"
  17. #include "pqxx/row.hxx"
  18. /* Result iterator.
  19. *
  20. * Don't include this header from your own application; it is included for you
  21. * by other libpqxx headers.
  22. */
  23. namespace pqxx
  24. {
  25. /// Iterator for rows in a result. Use as result::const_iterator.
  26. /** A result, once obtained, cannot be modified. Therefore there is no
  27. * plain iterator type for result. However its const_iterator type can be
  28. * used to inspect its rows without changing them.
  29. */
  30. class PQXX_LIBEXPORT const_result_iterator : public row
  31. {
  32. public:
  33. using iterator_category = std::random_access_iterator_tag;
  34. using value_type = const row;
  35. using pointer = const row *;
  36. using reference = row;
  37. using size_type = result_size_type;
  38. using difference_type = result_difference_type;
  39. const_result_iterator() noexcept : row{result(), 0} {}
  40. const_result_iterator(const row &t) noexcept : row{t} {}
  41. /**
  42. * @name Dereferencing operators
  43. */
  44. //@{
  45. /** The iterator "points to" its own row, which is also itself. This
  46. * allows a result to be addressed as a two-dimensional container without
  47. * going through the intermediate step of dereferencing the iterator. I
  48. * hope this works out to be similar to C pointer/array semantics in useful
  49. * cases.
  50. *
  51. * IIRC Alex Stepanov, the inventor of the STL, once remarked that having
  52. * this as standard behaviour for pointers would be useful in some
  53. * algorithms. So even if this makes me look foolish, I would seem to be in
  54. * distinguished company.
  55. */
  56. pointer operator->() const { return this; } //[t12]
  57. reference operator*() const { return row{*this}; } //[t12]
  58. //@}
  59. /**
  60. * @name Manipulations
  61. */
  62. //@{
  63. const_result_iterator operator++(int); //[t12]
  64. const_result_iterator &operator++() { ++m_index; return *this; } //[t01]
  65. const_result_iterator operator--(int); //[t12]
  66. const_result_iterator &operator--() { --m_index; return *this; } //[t12]
  67. const_result_iterator &operator+=(difference_type i) //[t12]
  68. { m_index += i; return *this; }
  69. const_result_iterator &operator-=(difference_type i) //[t12]
  70. { m_index -= i; return *this; }
  71. //@}
  72. /**
  73. * @name Comparisons
  74. */
  75. //@{
  76. bool operator==(const const_result_iterator &i) const //[t12]
  77. {return m_index==i.m_index;}
  78. bool operator!=(const const_result_iterator &i) const //[t12]
  79. {return m_index!=i.m_index;}
  80. bool operator<(const const_result_iterator &i) const //[t12]
  81. {return m_index<i.m_index;}
  82. bool operator<=(const const_result_iterator &i) const //[t12]
  83. {return m_index<=i.m_index;}
  84. bool operator>(const const_result_iterator &i) const //[t12]
  85. {return m_index>i.m_index;}
  86. bool operator>=(const const_result_iterator &i) const //[t12]
  87. {return m_index>=i.m_index;}
  88. //@}
  89. /**
  90. * @name Arithmetic operators
  91. */
  92. //@{
  93. inline const_result_iterator operator+(difference_type) const; //[t12]
  94. friend const_result_iterator operator+( //[t12]
  95. difference_type,
  96. const_result_iterator);
  97. inline const_result_iterator operator-(difference_type) const; //[t12]
  98. inline difference_type operator-(const_result_iterator) const; //[t12]
  99. //@}
  100. private:
  101. friend class pqxx::result;
  102. const_result_iterator(const pqxx::result *r, result_size_type i) noexcept :
  103. row{*r, i} {}
  104. };
  105. /// Reverse iterator for result. Use as result::const_reverse_iterator.
  106. class PQXX_LIBEXPORT const_reverse_result_iterator :
  107. private const_result_iterator
  108. {
  109. public:
  110. using super = const_result_iterator;
  111. using iterator_type = const_result_iterator;
  112. using iterator_type::iterator_category;
  113. using iterator_type::difference_type;
  114. using iterator_type::pointer;
  115. using value_type = iterator_type::value_type;
  116. using reference = iterator_type::reference;
  117. const_reverse_result_iterator( //[t75]
  118. const const_reverse_result_iterator &rhs) :
  119. const_result_iterator{rhs} {}
  120. explicit const_reverse_result_iterator( //[t75]
  121. const const_result_iterator &rhs) :
  122. const_result_iterator{rhs} { super::operator--(); }
  123. PQXX_PURE const_result_iterator base() const noexcept; //[t75]
  124. /**
  125. * @name Dereferencing operators
  126. */
  127. //@{
  128. using const_result_iterator::operator->; //[t75]
  129. using const_result_iterator::operator*; //[t75]
  130. //@}
  131. /**
  132. * @name Manipulations
  133. */
  134. //@{
  135. const_reverse_result_iterator &operator=( //[t75]
  136. const const_reverse_result_iterator &r)
  137. { iterator_type::operator=(r); return *this; }
  138. const_reverse_result_iterator &operator++() //[t75]
  139. { iterator_type::operator--(); return *this; }
  140. const_reverse_result_iterator operator++(int); //[t75]
  141. const_reverse_result_iterator &operator--() //[t75]
  142. { iterator_type::operator++(); return *this; }
  143. const_reverse_result_iterator operator--(int); //[t75]
  144. const_reverse_result_iterator &operator+=(difference_type i) //[t75]
  145. { iterator_type::operator-=(i); return *this; }
  146. const_reverse_result_iterator &operator-=(difference_type i) //[t75]
  147. { iterator_type::operator+=(i); return *this; }
  148. //@}
  149. /**
  150. * @name Arithmetic operators
  151. */
  152. //@{
  153. const_reverse_result_iterator operator+(difference_type i) const //[t75]
  154. { return const_reverse_result_iterator(base() - i); }
  155. const_reverse_result_iterator operator-(difference_type i) //[t75]
  156. { return const_reverse_result_iterator(base() + i); }
  157. difference_type operator-( //[t75]
  158. const const_reverse_result_iterator &rhs) const
  159. { return rhs.const_result_iterator::operator-(*this); }
  160. //@}
  161. /**
  162. * @name Comparisons
  163. */
  164. //@{
  165. bool operator==( //[t75]
  166. const const_reverse_result_iterator &rhs) const noexcept
  167. { return iterator_type::operator==(rhs); }
  168. bool operator!=( //[t75]
  169. const const_reverse_result_iterator &rhs) const noexcept
  170. { return not operator==(rhs); }
  171. bool operator<(const const_reverse_result_iterator &rhs) const //[t75]
  172. { return iterator_type::operator>(rhs); }
  173. bool operator<=(const const_reverse_result_iterator &rhs) const //[t75]
  174. { return iterator_type::operator>=(rhs); }
  175. bool operator>(const const_reverse_result_iterator &rhs) const //[t75]
  176. { return iterator_type::operator<(rhs); }
  177. bool operator>=(const const_reverse_result_iterator &rhs) const //[t75]
  178. { return iterator_type::operator<=(rhs); }
  179. //@}
  180. };
  181. inline const_result_iterator
  182. const_result_iterator::operator+(result::difference_type o) const
  183. {
  184. return const_result_iterator{
  185. &m_result, size_type(result::difference_type(m_index) + o)};
  186. }
  187. inline const_result_iterator
  188. operator+(result::difference_type o, const_result_iterator i)
  189. { return i + o; }
  190. inline const_result_iterator
  191. const_result_iterator::operator-(result::difference_type o) const
  192. {
  193. return const_result_iterator{
  194. &m_result,
  195. result_size_type(result::difference_type(m_index) - o)};
  196. }
  197. inline result::difference_type
  198. const_result_iterator::operator-(const_result_iterator i) const
  199. { return result::difference_type(num() - i.num()); }
  200. inline const_result_iterator result::end() const noexcept
  201. { return const_result_iterator{this, size()}; }
  202. inline const_result_iterator result::cend() const noexcept
  203. { return end(); }
  204. inline const_reverse_result_iterator
  205. operator+(
  206. result::difference_type n,
  207. const const_reverse_result_iterator &i)
  208. { return const_reverse_result_iterator{i.base() - n}; }
  209. } // namespace pqxx
  210. #include "pqxx/compiler-internal-post.hxx"
  211. #endif