rows_view.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. //
  2. // Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_ROWS_VIEW_HPP
  8. #define BOOST_MYSQL_ROWS_VIEW_HPP
  9. #include <boost/mysql/field_view.hpp>
  10. #include <boost/mysql/row.hpp>
  11. #include <boost/mysql/row_view.hpp>
  12. #include <boost/mysql/detail/auxiliar/rows_iterator.hpp>
  13. #include <cstddef>
  14. namespace boost {
  15. namespace mysql {
  16. /**
  17. * \brief A non-owning read-only reference to a sequence of rows.
  18. * \details
  19. * Models a non-owning matrix-like container. Indexing a `rows_view` object (by using iterators,
  20. * \ref rows_view::at or \ref rows_view::operator[]) returns a \ref row_view object, representing a
  21. * single row. All rows in the collection are the same size (as given by \ref num_columns).
  22. * \n
  23. * A `rows_view` object points to memory owned by an external entity (like `string_view` does). The
  24. * validity of a `rows_view` object depends on how it was obtained:
  25. * \n
  26. * \li If it was constructed from a \ref rows object (by calling \ref rows::operator rows_view()),
  27. * the view acts as a reference to the `rows`' allocated memory, and is valid as long as
  28. * references to that `rows` elements are valid.
  29. * \li If it was obtained by calling \ref connection::read_some_rows it's valid until the
  30. * `connection` performs the next network call or is destroyed.
  31. * \n
  32. * \ref row_view's and \ref field_view's obtained by using a `rows_view` object are valid as long as
  33. * the underlying storage that `*this` points to is valid. Destroying `*this` doesn't invalidate
  34. * such references.
  35. * \n
  36. * Calling any member function on an invalid view results in undefined behavior.
  37. * \n
  38. * Instances of this class are usually created by the library, not by the user.
  39. */
  40. class rows_view
  41. {
  42. public:
  43. #ifdef BOOST_MYSQL_DOXYGEN
  44. /**
  45. * \brief A random access iterator to an element.
  46. * \details The exact type of the iterator is unspecified.
  47. */
  48. using iterator = __see_below__;
  49. #else
  50. using iterator = detail::rows_iterator;
  51. #endif
  52. /// \copydoc iterator
  53. using const_iterator = iterator;
  54. /// A type that can hold elements in this collection with value semantics.
  55. using value_type = row;
  56. /// The reference type.
  57. using reference = row_view;
  58. /// \copydoc reference
  59. using const_reference = row_view;
  60. /// An unsigned integer type to represent sizes.
  61. using size_type = std::size_t;
  62. /// A signed integer type used to represent differences.
  63. using difference_type = std::ptrdiff_t;
  64. /**
  65. * \brief Construct an empty (but valid) view.
  66. * \par Exception safety
  67. * No-throw guarantee.
  68. */
  69. rows_view() = default;
  70. /**
  71. * \brief Returns an iterator to the first element in the collection.
  72. * \par Exception safety
  73. * No-throw guarantee.
  74. *
  75. * \par Complexity
  76. * Constant.
  77. */
  78. const_iterator begin() const noexcept { return iterator(fields_, num_columns_, 0); }
  79. /**
  80. * \brief Returns an iterator to one-past-the-last element in the collection.
  81. * \par Exception safety
  82. * No-throw guarantee.
  83. *
  84. * \par Complexity
  85. * Constant.
  86. */
  87. const_iterator end() const noexcept { return iterator(fields_, num_columns_, size()); }
  88. /**
  89. * \brief Returns the i-th row or throws an exception.
  90. * \par Exception safety
  91. * Strong guranatee. Throws on invalid input.
  92. * \throws std::out_of_range `i >= this->size()`
  93. *
  94. * \par Complexity
  95. * Constant.
  96. */
  97. inline row_view at(std::size_t i) const;
  98. /**
  99. * \brief Returns the i-th row (unchecked access).
  100. * \par Preconditions
  101. * `i < this->size()`
  102. *
  103. * \par Exception safety
  104. * No-throw guarantee.
  105. *
  106. * \par Complexity
  107. * Constant.
  108. */
  109. inline row_view operator[](std::size_t i) const noexcept;
  110. /**
  111. * \brief Returns the first row.
  112. * \par Preconditions
  113. * `this->size() > 0`
  114. *
  115. * \par Exception safety
  116. * No-throw guarantee.
  117. *
  118. * \par Complexity
  119. * Constant.
  120. */
  121. row_view front() const noexcept { return (*this)[0]; }
  122. /**
  123. * \brief Returns the last row.
  124. * \par Preconditions
  125. * `this->size() > 0`
  126. *
  127. * \par Exception safety
  128. * No-throw guarantee.
  129. *
  130. * \par Complexity
  131. * Constant.
  132. */
  133. row_view back() const noexcept { return (*this)[size() - 1]; }
  134. /**
  135. * \brief Returns true if there are no rows in the collection (i.e. `this->size() == 0`)
  136. * \par Exception safety
  137. * No-throw guarantee.
  138. *
  139. * \par Complexity
  140. * Constant.
  141. */
  142. bool empty() const noexcept { return num_fields_ == 0; }
  143. /**
  144. * \brief Returns the number of rows in the collection.
  145. * \par Exception safety
  146. * No-throw guarantee.
  147. *
  148. * \par Complexity
  149. * Constant.
  150. */
  151. std::size_t size() const noexcept { return (num_columns_ == 0) ? 0 : (num_fields_ / num_columns_); }
  152. /**
  153. * \brief Returns the number of elements each row in the collection has.
  154. * \details For every \ref row_view object r obtained from this collection,
  155. * `r.size() == this->num_columns()`.
  156. *
  157. * \par Exception safety
  158. * No-throw guarantee.
  159. *
  160. * \par Complexity
  161. * Constant.
  162. */
  163. std::size_t num_columns() const noexcept { return num_columns_; }
  164. /**
  165. * \brief Equality operator.
  166. * \details The containers are considered equal if they have the same number of rows and
  167. * they all compare equal, as defined by \ref row_view::operator==.
  168. *
  169. * \par Exception safety
  170. * No-throw guarantee.
  171. *
  172. * \par Complexity
  173. * Linear on `this->size() * this->num_columns()`.
  174. */
  175. inline bool operator==(const rows_view& rhs) const noexcept;
  176. /**
  177. * \brief Inequality operator.
  178. *
  179. * \par Exception safety
  180. * No-throw guarantee.
  181. *
  182. * \par Complexity
  183. * Linear on `this->size() * this->num_columns()`.
  184. */
  185. inline bool operator!=(const rows_view& rhs) const noexcept { return !(*this == rhs); }
  186. private:
  187. const field_view* fields_{};
  188. std::size_t num_fields_{};
  189. std::size_t num_columns_{};
  190. rows_view(const field_view* fields, std::size_t num_fields, std::size_t num_columns) noexcept
  191. : fields_(fields), num_fields_(num_fields), num_columns_(num_columns)
  192. {
  193. assert(fields != nullptr || num_fields == 0); // fields null => num_fields 0
  194. assert(num_fields == 0 || num_columns != 0); // num_fields != 0 => num_columns != 0
  195. assert(num_columns == 0 || (num_fields % num_columns == 0));
  196. }
  197. #ifndef BOOST_MYSQL_DOXYGEN
  198. friend struct detail::rows_view_access;
  199. friend class rows;
  200. #endif
  201. };
  202. } // namespace mysql
  203. } // namespace boost
  204. #include <boost/mysql/impl/rows_view.hpp>
  205. #endif