segments_encoded_base.hpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
  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. class iterator;
  65. /// @copydoc iterator
  66. using const_iterator = iterator;
  67. /** The value type
  68. Values of this type represent a segment
  69. where unique ownership is retained by
  70. making a copy.
  71. @par Example
  72. @code
  73. segments_encoded_base::value_type ps( url_view( "/path/to/file.txt" ).encoded_segments().back() );
  74. @endcode
  75. */
  76. using value_type = std::string;
  77. /** The reference type
  78. This is the type of value returned when
  79. iterators of the view are dereferenced.
  80. */
  81. using reference = pct_string_view;
  82. /// @copydoc reference
  83. using const_reference = pct_string_view;
  84. /** An unsigned integer type used to represent size.
  85. */
  86. using size_type = std::size_t;
  87. /** A signed integer type used to represent differences.
  88. */
  89. using difference_type = std::ptrdiff_t;
  90. //--------------------------------------------
  91. //
  92. // Observers
  93. //
  94. //--------------------------------------------
  95. /** Return the maximum number of characters possible
  96. This represents the largest number of
  97. characters that are possible in a path,
  98. not including any null terminator.
  99. @par Exception Safety
  100. Throws nothing.
  101. @return The maximum number of characters possible.
  102. */
  103. static
  104. constexpr
  105. std::size_t
  106. max_size() noexcept
  107. {
  108. return BOOST_URL_MAX_SIZE;
  109. }
  110. /** Return the referenced character buffer.
  111. This function returns the character
  112. buffer referenced by the view.
  113. The returned string may contain
  114. percent escapes.
  115. @par Example
  116. @code
  117. assert( url_view( "/path/to/file.txt" ).encoded_segments().buffer() == "/path/to/file.txt" );
  118. @endcode
  119. @par Complexity
  120. Constant.
  121. @par Exception Safety
  122. Throws nothing.
  123. @return A string view of the buffer.
  124. */
  125. BOOST_URL_DECL
  126. pct_string_view
  127. buffer() const noexcept;
  128. /** Returns true if this references an absolute path.
  129. Absolute paths always start with a
  130. forward slash ('/').
  131. @par Example
  132. @code
  133. assert( url_view( "/path/to/file.txt" ).encoded_segments().is_absolute() == true );
  134. @endcode
  135. @par Complexity
  136. Constant.
  137. @par Exception Safety
  138. Throws nothing.
  139. @return `true` if the path is absolute, otherwise `false`.
  140. */
  141. BOOST_URL_DECL
  142. bool
  143. is_absolute() const noexcept;
  144. /** Return true if there are no segments
  145. @par Example
  146. @code
  147. assert( ! url_view( "/index.htm" ).encoded_segments().empty() );
  148. @endcode
  149. @par Complexity
  150. Constant.
  151. @par Exception Safety
  152. Throws nothing.
  153. @return `true` if there are no segments, otherwise `false`.
  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. @return The number of segments.
  168. */
  169. BOOST_URL_DECL
  170. std::size_t
  171. size() const noexcept;
  172. /** Return the first segment
  173. This function returns a string with the
  174. first segment of the path without any
  175. leading or trailing '/' separators.
  176. The returned string may contain
  177. percent escapes.
  178. @par Preconditions
  179. @code
  180. this->empty() == false
  181. @endcode
  182. @par Effects
  183. @code
  184. return *begin();
  185. @endcode
  186. @par Example
  187. @code
  188. assert( url_view( "/path/to/file.txt" ).encoded_segments().front() == "path" );
  189. @endcode
  190. @par Complexity
  191. Constant.
  192. @par Exception Safety
  193. Throws nothing.
  194. @return The first segment.
  195. */
  196. pct_string_view
  197. front() const noexcept;
  198. /** Return the last segment
  199. This function returns a string with the
  200. last segment of the path without any
  201. leading or trailing '/' separators.
  202. The returned string may contain
  203. percent escapes.
  204. @par Preconditions
  205. @code
  206. this->empty() == false
  207. @endcode
  208. @par Example
  209. @code
  210. assert( url_view( "/path/to/file.txt" ).encoded_segments().back() == "file.txt" );
  211. @endcode
  212. @par Preconditions
  213. @code
  214. this->empty() == false
  215. @endcode
  216. @par Effects
  217. @code
  218. return *--end();
  219. @endcode
  220. @par Complexity
  221. Constant.
  222. @par Exception Safety
  223. Throws nothing.
  224. @return The last segment.
  225. */
  226. pct_string_view
  227. back() const noexcept;
  228. /** Return an iterator to the beginning
  229. @par Complexity
  230. Linear in `this->front().size()` or
  231. constant if `this->empty()`.
  232. @par Exception Safety
  233. Throws nothing.
  234. @return An iterator to the first segment.
  235. */
  236. BOOST_URL_DECL
  237. iterator
  238. begin() const noexcept;
  239. /** Return an iterator to the end
  240. @par Complexity
  241. Constant.
  242. @par Exception Safety
  243. Throws nothing.
  244. @return An iterator to one past the last segment.
  245. */
  246. BOOST_URL_DECL
  247. iterator
  248. end() const noexcept;
  249. };
  250. //------------------------------------------------
  251. /** Format to an output stream
  252. Any percent-escapes are emitted as-is;
  253. no decoding is performed.
  254. @par Complexity
  255. Linear in `ps.buffer().size()`.
  256. @par Effects
  257. @code
  258. return os << ps.buffer();
  259. @endcode
  260. @param os The output stream to write to.
  261. @param ps The object to format.
  262. @return A reference to the output stream.
  263. */
  264. BOOST_URL_DECL
  265. std::ostream&
  266. operator<<(
  267. std::ostream& os,
  268. segments_encoded_base const& ps);
  269. } // urls
  270. } // boost
  271. #include <boost/url/impl/segments_encoded_base.hpp>
  272. #endif