row_view.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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_ROW_VIEW_HPP
  8. #define BOOST_MYSQL_ROW_VIEW_HPP
  9. #include <boost/mysql/field.hpp>
  10. #include <boost/mysql/field_view.hpp>
  11. #include <boost/mysql/detail/auxiliar/access_fwd.hpp>
  12. #include <cstddef>
  13. #include <iosfwd>
  14. #include <iterator>
  15. #include <vector>
  16. namespace boost {
  17. namespace mysql {
  18. /**
  19. * \brief A non-owning read-only reference to a sequence of fields.
  20. * \details
  21. * A `row_view` points to memory owned by an external entity (like `string_view` does). The validity
  22. * of a `row_view` depends on how it was obtained:
  23. * \n
  24. * \li If it was constructed from a \ref row object (by calling \ref row::operator row_view()), the
  25. * view acts as a reference to the row's allocated memory, and is valid as long as references
  26. * to that row elements are valid.
  27. * \li If it was obtained by indexing a \ref rows object, the same applies.
  28. * \li If it was obtained by indexing a \ref rows_view object, it's valid as long as the
  29. * `rows_view` is valid.
  30. * \n
  31. * Calling any member function on an invalid view results in undefined behavior.
  32. * \n
  33. * When indexed (by using iterators, \ref row_view::at or \ref row_view::operator[]), it returns
  34. * \ref field_view elements that are valid as long as the underlying storage that `*this` points
  35. * to is valid. Destroying a `row_view` doesn't invalidate `field_view`s obtained from
  36. * it.
  37. * \n Instances of this class are usually created by the library, not by the user.
  38. */
  39. class row_view
  40. {
  41. public:
  42. /**
  43. * \brief Constructs an empty (but valid) view.
  44. * \par Exception safety
  45. * No-throw guarantee.
  46. */
  47. row_view() = default;
  48. #ifdef BOOST_MYSQL_DOXYGEN
  49. /**
  50. * \brief A random access iterator to an element.
  51. * \details The exact type of the iterator is unspecified.
  52. */
  53. using iterator = __see_below__;
  54. #else
  55. using iterator = const field_view*;
  56. #endif
  57. /// \copydoc iterator
  58. using const_iterator = iterator;
  59. /// A type that can hold elements in this collection with value semantics.
  60. using value_type = field;
  61. /// The reference type.
  62. using reference = field_view;
  63. /// \copydoc reference
  64. using const_reference = field_view;
  65. /// An unsigned integer type to represent sizes.
  66. using size_type = std::size_t;
  67. /// A signed integer type used to represent differences.
  68. using difference_type = std::ptrdiff_t;
  69. /**
  70. * \brief Returns an iterator to the first field in the row.
  71. * \par Exception safety
  72. * No-throw guarantee.
  73. *
  74. * \par Complexity
  75. * Constant.
  76. */
  77. iterator begin() const noexcept { return fields_; }
  78. /**
  79. * \brief Returns an iterator to one-past-the-last field in the row.
  80. * \par Exception safety
  81. * No-throw guarantee.
  82. *
  83. * \par Complexity
  84. * Constant.
  85. */
  86. iterator end() const noexcept { return fields_ + size_; }
  87. /**
  88. * \brief Returns the i-th element in the row or throws an exception.
  89. * \par Exception safety
  90. * Strong guranatee. Throws on invalid input.
  91. * \throws std::out_of_range `i >= this->size()`
  92. *
  93. * \par Complexity
  94. * Constant.
  95. */
  96. inline field_view at(std::size_t i) const;
  97. /**
  98. * \brief Returns the i-th element in the row (unchecked access).
  99. * \par Preconditions
  100. * `i < this->size()`
  101. *
  102. * \par Exception safety
  103. * No-throw guarantee.
  104. *
  105. * \par Complexity
  106. * Constant.
  107. */
  108. field_view operator[](std::size_t i) const noexcept { return fields_[i]; }
  109. /**
  110. * \brief Returns the first element in the row.
  111. * \par Preconditions
  112. * `this->size() > 0`
  113. *
  114. * \par Exception safety
  115. * No-throw guarantee.
  116. *
  117. * \par Complexity
  118. * Constant.
  119. */
  120. field_view front() const noexcept { return *fields_; }
  121. /**
  122. * \brief Returns the last element in the row.
  123. * \par Preconditions
  124. * `this->size() > 0`
  125. *
  126. * \par Exception safety
  127. * No-throw guarantee.
  128. *
  129. * \par Complexity
  130. * Constant.
  131. */
  132. field_view back() const noexcept { return fields_[size_ - 1]; }
  133. /**
  134. * \brief Returns true if there are no fields in the row (i.e. `this->size() == 0`).
  135. * \par Exception safety
  136. * No-throw guarantee.
  137. *
  138. * \par Complexity
  139. * Constant.
  140. */
  141. bool empty() const noexcept { return size_ == 0; }
  142. /**
  143. * \brief Returns the number of fields in the row.
  144. * \par Exception safety
  145. * No-throw guarantee.
  146. *
  147. * \par Complexity
  148. * Constant.
  149. */
  150. std::size_t size() const noexcept { return size_; }
  151. /**
  152. * \brief Converts the row into a `std::vector` of \ref field's.
  153. * \details As \ref row objects are read-only, you can use this function if you need to mutate
  154. * fields in a row.
  155. *
  156. * \par Exception safety
  157. * Basic guarantee. Allocations may throw.
  158. *
  159. * \par Complexity
  160. * Linear in `this->size()`.
  161. */
  162. template <class Allocator>
  163. void as_vector(std::vector<field, Allocator>& out) const
  164. {
  165. out.assign(begin(), end());
  166. }
  167. /// \copydoc as_vector
  168. std::vector<field> as_vector() const { return std::vector<field>(begin(), end()); }
  169. #ifndef BOOST_MYSQL_DOXYGEN
  170. // Required by iterators
  171. const row_view* operator->() const noexcept { return this; }
  172. #endif
  173. private:
  174. row_view(const field_view* f, std::size_t size) noexcept : fields_(f), size_(size) {}
  175. const field_view* fields_{};
  176. std::size_t size_{};
  177. #ifndef BOOST_MYSQL_DOXYGEN
  178. friend struct detail::row_view_access;
  179. friend class row;
  180. #endif
  181. };
  182. /**
  183. * \relates row_view
  184. * \brief Equality operator.
  185. * \details The containers are considered equal if they have the same number of elements and they
  186. * all compare equal, as defined by \ref field_view::operator==.
  187. *
  188. * \par Exception safety
  189. * No-throw guarantee.
  190. *
  191. * \par Complexity
  192. * Linear in `lhs.size()` and `rhs.size()`.
  193. */
  194. inline bool operator==(const row_view& lhs, const row_view& rhs) noexcept;
  195. /**
  196. * \relates row_view
  197. * \brief Inequality operator.
  198. *
  199. * \par Exception safety
  200. * No-throw guarantee.
  201. *
  202. * \par Complexity
  203. * Linear in `lhs.size()` and `rhs.size()`.
  204. */
  205. inline bool operator!=(const row_view& lhs, const row_view& rhs) noexcept { return !(lhs == rhs); }
  206. } // namespace mysql
  207. } // namespace boost
  208. #include <boost/mysql/impl/row_view.hpp>
  209. #endif