segments_encoded_base.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  3. // Copyright (c) 2022 Alan de Freitas ([email protected])
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/url
  9. //
  10. #ifndef BOOST_URL_SEGMENTS_ENCODED_BASE_HPP
  11. #define BOOST_URL_SEGMENTS_ENCODED_BASE_HPP
  12. #include <boost/url/detail/config.hpp>
  13. #include <boost/url/ignore_case.hpp>
  14. #include <boost/url/pct_string_view.hpp>
  15. #include <boost/url/detail/url_impl.hpp>
  16. #include <iosfwd>
  17. namespace boost {
  18. namespace urls {
  19. /** Common functionality for containers
  20. This base class is used by the library
  21. to provide common member functions for
  22. containers. This cannot be instantiated
  23. directly; Instead, use one of the
  24. containers or functions:
  25. @par Containers
  26. @li @ref segments_ref
  27. @li @ref segments_view
  28. @li @ref segments_encoded_ref
  29. @li @ref segments_encoded_view
  30. */
  31. class segments_encoded_base
  32. {
  33. detail::path_ref ref_;
  34. friend class url_view_base;
  35. friend class segments_encoded_ref;
  36. friend class segments_encoded_view;
  37. segments_encoded_base(
  38. detail::path_ref const& ref) noexcept;
  39. segments_encoded_base() = default;
  40. segments_encoded_base(
  41. segments_encoded_base const&) = default;
  42. segments_encoded_base& operator=(
  43. segments_encoded_base const&) = default;
  44. public:
  45. /** A Bidirectional iterator to a path segment
  46. Objects of this type allow iteration
  47. through the segments in the path.
  48. Strings returned by iterators may
  49. contain percent escapes.
  50. The values returned are read-only;
  51. changes to segments must be made
  52. through the container instead, if the
  53. container supports modification.
  54. <br>
  55. The strings produced when iterators
  56. are dereferenced refer to the underlying
  57. character buffer.
  58. Ownership is not transferred; the caller
  59. is responsible for ensuring that the
  60. lifetime of the buffer extends until
  61. it is no longer referenced by any
  62. container or iterator.
  63. */
  64. #ifdef BOOST_URL_DOCS
  65. using iterator = __see_below__;
  66. #else
  67. class iterator;
  68. #endif
  69. /// @copydoc iterator
  70. using const_iterator = iterator;
  71. /** The value type
  72. Values of this type represent a segment
  73. where unique ownership is retained by
  74. making a copy.
  75. @par Example
  76. @code
  77. segments_encoded_base::value_type ps( url_view( "/path/to/file.txt" ).encoded_segments().back() );
  78. @endcode
  79. */
  80. using value_type = std::string;
  81. /** The reference type
  82. This is the type of value returned when
  83. iterators of the view are dereferenced.
  84. */
  85. using reference = pct_string_view;
  86. /// @copydoc reference
  87. using const_reference = pct_string_view;
  88. /** An unsigned integer type used to represent size.
  89. */
  90. using size_type = std::size_t;
  91. /** A signed integer type used to represent differences.
  92. */
  93. using difference_type = std::ptrdiff_t;
  94. //--------------------------------------------
  95. //
  96. // Observers
  97. //
  98. //--------------------------------------------
  99. /** Return the maximum number of characters possible
  100. This represents the largest number of
  101. characters that are possible in a path,
  102. not including any null terminator.
  103. @par Exception Safety
  104. Throws nothing.
  105. */
  106. static
  107. constexpr
  108. std::size_t
  109. max_size() noexcept
  110. {
  111. return BOOST_URL_MAX_SIZE;
  112. }
  113. /** Return the referenced character buffer.
  114. This function returns the character
  115. buffer referenced by the view.
  116. The returned string may contain
  117. percent escapes.
  118. @par Example
  119. @code
  120. assert( url_view( "/path/to/file.txt" ).encoded_segments().buffer() == "/path/to/file.txt" );
  121. @endcode
  122. @par Complexity
  123. Constant.
  124. @par Exception Safety
  125. Throws nothing.
  126. */
  127. BOOST_URL_DECL
  128. pct_string_view
  129. buffer() const noexcept;
  130. /** Returns true if this references an absolute path.
  131. Absolute paths always start with a
  132. forward slash ('/').
  133. @par Example
  134. @code
  135. assert( url_view( "/path/to/file.txt" ).encoded_segments().is_absolute() == true );
  136. @endcode
  137. @par Complexity
  138. Constant.
  139. @par Exception Safety
  140. Throws nothing.
  141. */
  142. BOOST_URL_DECL
  143. bool
  144. is_absolute() const noexcept;
  145. /** Return true if there are no segments
  146. @par Example
  147. @code
  148. assert( ! url_view( "/index.htm" ).encoded_segments().empty() );
  149. @endcode
  150. @par Complexity
  151. Constant.
  152. @par Exception Safety
  153. Throws nothing.
  154. */
  155. BOOST_URL_DECL
  156. bool
  157. empty() const noexcept;
  158. /** Return the number of segments
  159. @par Example
  160. @code
  161. assert( url_view( "/path/to/file.txt" ).encoded_segments().size() == 3 );
  162. @endcode
  163. @par Complexity
  164. Constant.
  165. @par Exception Safety
  166. Throws nothing.
  167. */
  168. BOOST_URL_DECL
  169. std::size_t
  170. size() const noexcept;
  171. /** Return the first segment
  172. This function returns a string with the
  173. first segment of the path without any
  174. leading or trailing '/' separators.
  175. The returned string may contain
  176. percent escapes.
  177. @par Preconditions
  178. @code
  179. this->empty() == false
  180. @endcode
  181. @par Effects
  182. @code
  183. return *begin();
  184. @endcode
  185. @par Example
  186. @code
  187. assert( url_view( "/path/to/file.txt" ).encoded_segments().front() == "path" );
  188. @endcode
  189. @par Complexity
  190. Constant.
  191. @par Exception Safety
  192. Throws nothing.
  193. */
  194. pct_string_view
  195. front() const noexcept;
  196. /** Return the last segment
  197. This function returns a string with the
  198. last segment of the path without any
  199. leading or trailing '/' separators.
  200. The returned string may contain
  201. percent escapes.
  202. @par Preconditions
  203. @code
  204. this->empty() == false
  205. @endcode
  206. @par Example
  207. @code
  208. assert( url_view( "/path/to/file.txt" ).encoded_segments().back() == "file.txt" );
  209. @endcode
  210. @par Preconditions
  211. @code
  212. this->empty() == false
  213. @endcode
  214. @par Effects
  215. @code
  216. return *--end();
  217. @endcode
  218. @par Complexity
  219. Constant.
  220. @par Exception Safety
  221. Throws nothing.
  222. */
  223. pct_string_view
  224. back() const noexcept;
  225. /** Return an iterator to the beginning
  226. @par Complexity
  227. Linear in `this->front().size()` or
  228. constant if `this->empty()`.
  229. @par Exception Safety
  230. Throws nothing.
  231. */
  232. BOOST_URL_DECL
  233. iterator
  234. begin() const noexcept;
  235. /** Return an iterator to the end
  236. @par Complexity
  237. Constant.
  238. @par Exception Safety
  239. Throws nothing.
  240. */
  241. BOOST_URL_DECL
  242. iterator
  243. end() const noexcept;
  244. };
  245. //------------------------------------------------
  246. /** Format to an output stream
  247. Any percent-escapes are emitted as-is;
  248. no decoding is performed.
  249. @par Complexity
  250. Linear in `ps.buffer().size()`.
  251. @par Effects
  252. @code
  253. return os << ps.buffer();
  254. @endcode
  255. */
  256. BOOST_URL_DECL
  257. std::ostream&
  258. operator<<(
  259. std::ostream& os,
  260. segments_encoded_base const& ps);
  261. } // urls
  262. } // boost
  263. #include <boost/url/impl/segments_encoded_base.hpp>
  264. #endif