segments_base.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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_BASE_HPP
  11. #define BOOST_URL_SEGMENTS_BASE_HPP
  12. #include <boost/url/detail/config.hpp>
  13. #include <boost/url/ignore_case.hpp>
  14. #include <boost/url/detail/url_impl.hpp>
  15. #include <iosfwd>
  16. #include <string>
  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_base
  32. {
  33. detail::path_ref ref_;
  34. friend class url_view_base;
  35. friend class segments_ref;
  36. friend class segments_view;
  37. segments_base(
  38. detail::path_ref const& ref) noexcept;
  39. segments_base() = default;
  40. segments_base(
  41. segments_base const&) = default;
  42. segments_base& operator=(
  43. segments_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. Any percent-escapes in returned strings
  49. are decoded first.
  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 are
  56. dereferenced belong to the iterator and
  57. become invalidated when that particular
  58. iterator is incremented, decremented,
  59. or destroyed.
  60. */
  61. class iterator;
  62. /// @copydoc iterator
  63. using const_iterator = iterator;
  64. /** The value type
  65. Values of this type represent a segment
  66. where unique ownership is retained by
  67. making a copy.
  68. @par Example
  69. @code
  70. segments_base::value_type ps( url_view( "/path/to/file.txt" ).segments().back() );
  71. @endcode
  72. */
  73. using value_type = std::string;
  74. /** The reference type
  75. This is the type of value returned when
  76. iterators of the view are dereferenced.
  77. */
  78. using reference = std::string;
  79. /// @copydoc reference
  80. using const_reference = std::string;
  81. /** An unsigned integer type used to represent size.
  82. */
  83. using size_type = std::size_t;
  84. /** A signed integer type used to represent differences.
  85. */
  86. using difference_type = std::ptrdiff_t;
  87. //--------------------------------------------
  88. //
  89. // Observers
  90. //
  91. //--------------------------------------------
  92. /** Return the maximum number of characters possible
  93. This represents the largest number of
  94. characters that are possible in a path,
  95. not including any null terminator.
  96. @par Exception Safety
  97. Throws nothing.
  98. @return The maximum number of characters possible.
  99. */
  100. static
  101. constexpr
  102. std::size_t
  103. max_size() noexcept
  104. {
  105. return BOOST_URL_MAX_SIZE;
  106. }
  107. /** Return the referenced character buffer.
  108. This function returns the character
  109. buffer referenced by the view.
  110. The returned string may contain
  111. percent escapes.
  112. @par Example
  113. @code
  114. assert( url_view( "/path/to/file.txt" ).segments().buffer() == "/path/to/file.txt" );
  115. @endcode
  116. @par Complexity
  117. Constant.
  118. @par Exception Safety
  119. Throws nothing.
  120. @return A string containing the path.
  121. */
  122. BOOST_URL_DECL
  123. pct_string_view
  124. buffer() const noexcept;
  125. /** Returns true if this references an absolute path.
  126. Absolute paths always start with a
  127. forward slash ('/').
  128. @par Example
  129. @code
  130. assert( url_view( "/path/to/file.txt" ).segments().is_absolute() == true );
  131. @endcode
  132. @par Complexity
  133. Constant.
  134. @par Exception Safety
  135. Throws nothing.
  136. @return `true` if the path is absolute, otherwise `false`.
  137. */
  138. BOOST_URL_DECL
  139. bool
  140. is_absolute() const noexcept;
  141. /** Return true if there are no segments
  142. @par Example
  143. @code
  144. assert( ! url_view( "/index.htm" ).segments().empty() );
  145. @endcode
  146. @par Complexity
  147. Constant.
  148. @par Exception Safety
  149. Throws nothing.
  150. @return `true` if there are no segments, otherwise `false`.
  151. */
  152. BOOST_URL_DECL
  153. bool
  154. empty() const noexcept;
  155. /** Return the number of segments
  156. @par Example
  157. @code
  158. assert( url_view( "/path/to/file.txt" ).segments().size() == 3 );
  159. @endcode
  160. @par Complexity
  161. Constant.
  162. @par Exception Safety
  163. Throws nothing.
  164. @return The number of segments.
  165. */
  166. BOOST_URL_DECL
  167. std::size_t
  168. size() const noexcept;
  169. /** Return the first segment
  170. This function returns a string with the
  171. first segment of the path without any
  172. leading or trailing '/' separators.
  173. Any percent-escapes in the string are
  174. decoded first.
  175. @par Preconditions
  176. @code
  177. this->empty() == false
  178. @endcode
  179. @par Effects
  180. @code
  181. return *begin();
  182. @endcode
  183. @par Example
  184. @code
  185. assert( url_view( "/path/to/file.txt" ).segments().front() == "path" );
  186. @endcode
  187. @par Complexity
  188. Linear in `this->front().size()`.
  189. @par Exception Safety
  190. Calls to allocate may throw.
  191. @return The first segment.
  192. */
  193. std::string
  194. front() const noexcept;
  195. /** Return the last segment
  196. @par Preconditions
  197. @code
  198. this->empty() == false
  199. @endcode
  200. @par Example
  201. @code
  202. assert( url_view( "/path/to/file.txt" ).segments().back() == "file.txt" );
  203. @endcode
  204. @par Preconditions
  205. @code
  206. this->empty() == false
  207. @endcode
  208. @par Effects
  209. @code
  210. return *--end();
  211. @endcode
  212. @par Complexity
  213. Linear in `this->back().size()`.
  214. @par Exception Safety
  215. Calls to allocate may throw.
  216. @return The last segment.
  217. */
  218. std::string
  219. back() const noexcept;
  220. /** Return an iterator to the beginning
  221. @par Complexity
  222. Linear in `this->front().size()` or
  223. constant if `this->empty()`.
  224. @par Exception Safety
  225. Throws nothing.
  226. @return An iterator to the first segment.
  227. */
  228. BOOST_URL_DECL
  229. iterator
  230. begin() const noexcept;
  231. /** Return an iterator to the end
  232. @par Complexity
  233. Constant.
  234. @par Exception Safety
  235. Throws nothing.
  236. @return An iterator to one past the last segment.
  237. */
  238. BOOST_URL_DECL
  239. iterator
  240. end() const noexcept;
  241. };
  242. //------------------------------------------------
  243. /** Format to an output stream
  244. Any percent-escapes are emitted as-is;
  245. no decoding is performed.
  246. @par Complexity
  247. Linear in `ps.buffer().size()`.
  248. @par Effects
  249. @code
  250. return os << ps.buffer();
  251. @endcode
  252. @param os The output stream to write to.
  253. @param ps The segments to write.
  254. @return A reference to the output stream.
  255. */
  256. BOOST_URL_DECL
  257. std::ostream&
  258. operator<<(
  259. std::ostream& os,
  260. segments_base const& ps);
  261. } // urls
  262. } // boost
  263. #include <boost/url/impl/segments_base.hpp>
  264. #endif