segments_base.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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_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. #ifdef BOOST_URL_DOCS
  62. using iterator = __see_below__;
  63. #else
  64. class iterator;
  65. #endif
  66. /// @copydoc iterator
  67. using const_iterator = iterator;
  68. /** The value type
  69. Values of this type represent a segment
  70. where unique ownership is retained by
  71. making a copy.
  72. @par Example
  73. @code
  74. segments_base::value_type ps( url_view( "/path/to/file.txt" ).segments().back() );
  75. @endcode
  76. */
  77. using value_type = std::string;
  78. /** The reference type
  79. This is the type of value returned when
  80. iterators of the view are dereferenced.
  81. */
  82. using reference = std::string;
  83. /// @copydoc reference
  84. using const_reference = std::string;
  85. /** An unsigned integer type used to represent size.
  86. */
  87. using size_type = std::size_t;
  88. /** A signed integer type used to represent differences.
  89. */
  90. using difference_type = std::ptrdiff_t;
  91. //--------------------------------------------
  92. //
  93. // Observers
  94. //
  95. //--------------------------------------------
  96. /** Return the maximum number of characters possible
  97. This represents the largest number of
  98. characters that are possible in a path,
  99. not including any null terminator.
  100. @par Exception Safety
  101. Throws nothing.
  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" ).segments().buffer() == "/path/to/file.txt" );
  118. @endcode
  119. @par Complexity
  120. Constant.
  121. @par Exception Safety
  122. Throws nothing.
  123. */
  124. BOOST_URL_DECL
  125. pct_string_view
  126. buffer() const noexcept;
  127. /** Returns true if this references an absolute path.
  128. Absolute paths always start with a
  129. forward slash ('/').
  130. @par Example
  131. @code
  132. assert( url_view( "/path/to/file.txt" ).segments().is_absolute() == true );
  133. @endcode
  134. @par Complexity
  135. Constant.
  136. @par Exception Safety
  137. Throws nothing.
  138. */
  139. BOOST_URL_DECL
  140. bool
  141. is_absolute() const noexcept;
  142. /** Return true if there are no segments
  143. @par Example
  144. @code
  145. assert( ! url_view( "/index.htm" ).segments().empty() );
  146. @endcode
  147. @par Complexity
  148. Constant.
  149. @par Exception Safety
  150. Throws nothing.
  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. */
  165. BOOST_URL_DECL
  166. std::size_t
  167. size() const noexcept;
  168. /** Return the first segment
  169. This function returns a string with the
  170. first segment of the path without any
  171. leading or trailing '/' separators.
  172. Any percent-escapes in the string are
  173. decoded first.
  174. @par Preconditions
  175. @code
  176. this->empty() == false
  177. @endcode
  178. @par Effects
  179. @code
  180. return *begin();
  181. @endcode
  182. @par Example
  183. @code
  184. assert( url_view( "/path/to/file.txt" ).segments().front() == "path" );
  185. @endcode
  186. @par Complexity
  187. Linear in `this->front().size()`.
  188. @par Exception Safety
  189. Calls to allocate may throw.
  190. */
  191. std::string
  192. front() const noexcept;
  193. /** Return the last segment
  194. @par Preconditions
  195. @code
  196. this->empty() == false
  197. @endcode
  198. @par Example
  199. @code
  200. assert( url_view( "/path/to/file.txt" ).segments().back() == "file.txt" );
  201. @endcode
  202. @par Preconditions
  203. @code
  204. this->empty() == false
  205. @endcode
  206. @par Effects
  207. @code
  208. return *--end();
  209. @endcode
  210. @par Complexity
  211. Linear in `this->back().size()`.
  212. @par Exception Safety
  213. Calls to allocate may throw.
  214. */
  215. std::string
  216. back() const noexcept;
  217. /** Return an iterator to the beginning
  218. @par Complexity
  219. Linear in `this->front().size()` or
  220. constant if `this->empty()`.
  221. @par Exception Safety
  222. Throws nothing.
  223. */
  224. BOOST_URL_DECL
  225. iterator
  226. begin() const noexcept;
  227. /** Return an iterator to the end
  228. @par Complexity
  229. Constant.
  230. @par Exception Safety
  231. Throws nothing.
  232. */
  233. BOOST_URL_DECL
  234. iterator
  235. end() const noexcept;
  236. };
  237. //------------------------------------------------
  238. /** Format to an output stream
  239. Any percent-escapes are emitted as-is;
  240. no decoding is performed.
  241. @par Complexity
  242. Linear in `ps.buffer().size()`.
  243. @par Effects
  244. @code
  245. return os << ps.buffer();
  246. @endcode
  247. */
  248. BOOST_URL_DECL
  249. std::ostream&
  250. operator<<(
  251. std::ostream& os,
  252. segments_base const& ps);
  253. } // urls
  254. } // boost
  255. #include <boost/url/impl/segments_base.hpp>
  256. #endif