segments_encoded_ref.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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_REF_HPP
  11. #define BOOST_URL_SEGMENTS_ENCODED_REF_HPP
  12. #include <boost/url/detail/config.hpp>
  13. #include <boost/url/segments_encoded_base.hpp>
  14. #include <initializer_list>
  15. #include <iterator>
  16. namespace boost {
  17. namespace urls {
  18. #ifndef BOOST_URL_DOCS
  19. class url_base;
  20. class segments_encoded_view;
  21. #endif
  22. /** A view representing path segments in a URL
  23. Objects of this type are used to interpret
  24. the path as a bidirectional view of segments,
  25. where each segment is a string which may
  26. contain percent-escapes.
  27. The view does not retain ownership of the
  28. elements and instead references the original
  29. character buffer. The caller is responsible
  30. for ensuring that the lifetime of the buffer
  31. extends until it is no longer referenced.
  32. The view is modifiable; calling non-const
  33. members causes changes to the referenced
  34. url.
  35. @par Example
  36. @code
  37. url u( "/path/to/file.txt" );
  38. segments_encoded_ref ps = u.encoded_segments();
  39. @endcode
  40. The strings returned when iterators are
  41. dereferenced have type @ref pct_string_view
  42. and may contain percent-escapes.
  43. Reserved characters in inputs are
  44. automatically escaped.
  45. Escapes in inputs are preserved.
  46. Exceptions are thrown on invalid inputs.
  47. @par Iterator Invalidation
  48. Changes to the underlying character buffer
  49. can invalidate iterators which reference it.
  50. Modifications made through the container
  51. invalidate some or all iterators:
  52. <br>
  53. @li @ref push_back : Only `end()`.
  54. @li @ref assign, @ref clear,
  55. @ref operator= : All elements.
  56. @li @ref erase : Erased elements and all
  57. elements after (including `end()`).
  58. @li @ref insert : All elements at or after
  59. the insertion point (including `end()`).
  60. @li @ref replace : Modified
  61. elements and all elements
  62. after (including `end()`).
  63. @see
  64. @ref segments_encoded_view,
  65. @ref segments_view,
  66. @ref segments_ref.
  67. */
  68. class segments_encoded_ref
  69. : public segments_encoded_base
  70. {
  71. friend class url_base;
  72. url_base* u_ = nullptr;
  73. segments_encoded_ref(
  74. url_base& u) noexcept;
  75. public:
  76. //--------------------------------------------
  77. //
  78. // Special Members
  79. //
  80. //--------------------------------------------
  81. /** Constructor
  82. After construction, both views
  83. reference the same url. Ownership is not
  84. transferred; the caller is responsible
  85. for ensuring the lifetime of the url
  86. extends until it is no longer
  87. referenced.
  88. @par Postconditions
  89. @code
  90. &this->url() == &other.url();
  91. @endcode
  92. @par Complexity
  93. Constant.
  94. @par Exception Safety
  95. Throws nothing.
  96. @param other The other view.
  97. */
  98. segments_encoded_ref(
  99. segments_encoded_ref const& other) = default;
  100. /** Assignment
  101. The existing contents are replaced
  102. by a copy of the other segments.
  103. <br>
  104. All iterators are invalidated.
  105. @note
  106. None of the character buffers referenced
  107. by `other` may overlap the buffer of the
  108. underlying url, or else the behavior
  109. is undefined.
  110. @par Effects
  111. @code
  112. this->assign( other.begin(), other.end() );
  113. @endcode
  114. @par Complexity
  115. Linear in `other.buffer().size()`.
  116. @par Exception Safety
  117. Strong guarantee.
  118. Calls to allocate may throw.
  119. @param other The segments to assign.
  120. */
  121. /** @{ */
  122. BOOST_URL_DECL
  123. segments_encoded_ref&
  124. operator=(segments_encoded_ref const& other);
  125. BOOST_URL_DECL
  126. segments_encoded_ref&
  127. operator=(segments_encoded_view const& other);
  128. /** @} */
  129. /** Assignment
  130. The existing contents are replaced
  131. by a copy of the contents of the
  132. initializer list.
  133. Reserved characters in the list are
  134. automatically escaped.
  135. Escapes in the list are preserved.
  136. <br>
  137. All iterators are invalidated.
  138. @par Example
  139. @code
  140. url u;
  141. u.encoded_segments() = {"path", "to", "file.txt"};
  142. @endcode
  143. @par Preconditions
  144. None of the character buffers referenced
  145. by the list may overlap the character buffer
  146. of the underlying url, or else the behavior
  147. is undefined.
  148. @par Effects
  149. @code
  150. this->assign( init.begin(), init.end() );
  151. @endcode
  152. @par Complexity
  153. Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
  154. @par Exception Safety
  155. Strong guarantee.
  156. Calls to allocate may throw.
  157. Exceptions thrown on invalid input.
  158. @throw system_error
  159. The list contains an invalid percent-encoding.
  160. @param init The list of segments to assign.
  161. */
  162. BOOST_URL_DECL
  163. segments_encoded_ref&
  164. operator=(std::initializer_list<
  165. pct_string_view> init);
  166. /** Conversion
  167. @see
  168. @ref segments_encoded_view.
  169. */
  170. BOOST_URL_DECL
  171. operator
  172. segments_encoded_view() const noexcept;
  173. //--------------------------------------------
  174. //
  175. // Observers
  176. //
  177. //--------------------------------------------
  178. /** Return the referenced url
  179. This function returns the url referenced
  180. by the view.
  181. @par Example
  182. @code
  183. url u( "/path/to/file.txt" );
  184. assert( &u.encoded_segments().url() == &u );
  185. @endcode
  186. @par Exception Safety
  187. Throws nothing.
  188. */
  189. url_base&
  190. url() const noexcept
  191. {
  192. return *u_;
  193. }
  194. //--------------------------------------------
  195. //
  196. // Modifiers
  197. //
  198. //--------------------------------------------
  199. /** Clear the contents of the container
  200. <br>
  201. All iterators are invalidated.
  202. @par Effects
  203. @code
  204. this->url().set_encoded_path( "" );
  205. @endcode
  206. @par Postconditions
  207. @code
  208. this->empty() == true
  209. @endcode
  210. @par Complexity
  211. Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
  212. @par Exception Safety
  213. Throws nothing.
  214. */
  215. void
  216. clear() noexcept;
  217. /** Assign segments
  218. The existing contents are replaced
  219. by a copy of the contents of the
  220. initializer list.
  221. Reserved characters in the list are
  222. automatically escaped.
  223. Escapes in the list are preserved.
  224. <br>
  225. All iterators are invalidated.
  226. @note
  227. None of the character buffers referenced
  228. by the list may overlap the character
  229. buffer of the underlying url, or else
  230. the behavior is undefined.
  231. @par Example
  232. @code
  233. url u;
  234. u.segments().assign( {"path", "to", "file.txt"} );
  235. @endcode
  236. @par Complexity
  237. Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
  238. @par Exception Safety
  239. Strong guarantee.
  240. Calls to allocate may throw.
  241. Exceptions thrown on invalid input.
  242. @throw system_error
  243. The list contains an invalid percent-encoding.
  244. @param init The list of segments to assign.
  245. */
  246. BOOST_URL_DECL
  247. void
  248. assign(std::initializer_list<
  249. pct_string_view> init);
  250. /** Assign segments
  251. The existing contents are replaced
  252. by a copy of the contents of the range.
  253. Reserved characters in the range are
  254. automatically escaped.
  255. Escapes in the range are preserved.
  256. <br>
  257. All iterators are invalidated.
  258. @note
  259. None of the character buffers referenced
  260. by the range may overlap the character
  261. buffer of the underlying url, or else
  262. the behavior is undefined.
  263. @par Mandates
  264. @code
  265. std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
  266. @endcode
  267. @par Complexity
  268. Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
  269. @par Exception Safety
  270. Strong guarantee.
  271. Calls to allocate may throw.
  272. Exceptions thrown on invalid input.
  273. @throw system_error
  274. The range contains an invalid percent-encoding.
  275. @param first, last The range of segments
  276. to assign.
  277. */
  278. template<class FwdIt>
  279. void
  280. assign(FwdIt first, FwdIt last);
  281. //--------------------------------------------
  282. /** Insert segments
  283. This function inserts a segment
  284. before the specified position.
  285. Reserved characters in the segment are
  286. automatically escaped.
  287. Escapes in the segment are preserved.
  288. <br>
  289. All iterators that are equal to
  290. `before` or come after are invalidated.
  291. @par Complexity
  292. Linear in `s.size() + this->url().encoded_resource().size()`.
  293. @par Exception Safety
  294. Strong guarantee.
  295. Calls to allocate may throw.
  296. Exceptions thrown on invalid input.
  297. @throw system_error
  298. The segment contains an invalid percent-encoding.
  299. @return An iterator to the inserted
  300. segment.
  301. @param before An iterator before which
  302. the segment is inserted. This may
  303. be equal to `end()`.
  304. @param s The segment to insert.
  305. */
  306. BOOST_URL_DECL
  307. iterator
  308. insert(
  309. iterator before,
  310. pct_string_view s);
  311. /** Insert segments
  312. This function inserts the segments
  313. in an initializer list before the
  314. specified position.
  315. Reserved characters in the list are
  316. automatically escaped.
  317. Escapes in the list are preserved.
  318. <br>
  319. All iterators that are equal to
  320. `before` or come after are invalidated.
  321. @note
  322. None of the character buffers referenced
  323. by the list may overlap the character
  324. buffer of the underlying url, or else
  325. the behavior is undefined.
  326. @par Example
  327. @code
  328. url u( "/file.txt" );
  329. u.encoded_segments().insert( u.encoded_segments().begin(), { "path", "to" } );
  330. @endcode
  331. @par Complexity
  332. Linear in `init.size() + this->url().encoded_resource().size()`.
  333. @par Exception Safety
  334. Strong guarantee.
  335. Calls to allocate may throw.
  336. Exceptions thrown on invalid input.
  337. @throw system_error
  338. The list contains an invalid percent-encoding.
  339. @return An iterator to the first
  340. element inserted, or `before` if
  341. `init.size() == 0`.
  342. @param before An iterator before which
  343. the list is inserted. This may
  344. be equal to `end()`.
  345. @param init The list of segments to insert.
  346. */
  347. BOOST_URL_DECL
  348. iterator
  349. insert(
  350. iterator before,
  351. std::initializer_list<
  352. pct_string_view> init);
  353. /** Insert segments
  354. This function inserts the segments in
  355. a range before the specified position.
  356. Reserved characters in the range are
  357. automatically escaped.
  358. Escapes in the range are preserved.
  359. <br>
  360. All iterators that are equal to
  361. `before` or come after are invalidated.
  362. @note
  363. None of the character buffers referenced
  364. by the range may overlap the character
  365. buffer of the underlying url, or else
  366. the behavior is undefined.
  367. @par Mandates
  368. @code
  369. std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
  370. @endcode
  371. @par Complexity
  372. Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
  373. @par Exception Safety
  374. Strong guarantee.
  375. Calls to allocate may throw.
  376. Exceptions thrown on invalid input.
  377. @throw system_error
  378. The range contains an invalid percent-encoding.
  379. @return An iterator to the first
  380. segment inserted, or `before` if
  381. `init.empty()`.
  382. @param before An iterator before which
  383. the range is inserted. This may
  384. be equal to `end()`.
  385. @param first, last The range of segments
  386. to insert.
  387. */
  388. template<class FwdIt>
  389. iterator
  390. insert(
  391. iterator before,
  392. FwdIt first,
  393. FwdIt last);
  394. //--------------------------------------------
  395. /** Erase segments
  396. This function removes a segment.
  397. <br>
  398. All iterators that are equal to
  399. `pos` or come after are invalidated.
  400. @par Complexity
  401. Linear in `this->url().encoded_resource().size()`.
  402. @par Exception Safety
  403. Throws nothing.
  404. @return An iterator to one past
  405. the removed segment.
  406. @param pos An iterator to the element.
  407. */
  408. iterator
  409. erase(
  410. iterator pos) noexcept;
  411. /** Erase segments
  412. This function removes a range of segments
  413. from the container.
  414. <br>
  415. All iterators that are equal to
  416. `first` or come after are invalidated.
  417. @par Complexity
  418. Linear in `this->url().encoded_resource().size()`.
  419. @par Exception Safety
  420. Throws nothing.
  421. @return An iterator to one past
  422. the removed range.
  423. @param first, last The range of
  424. segments to erase.
  425. */
  426. BOOST_URL_DECL
  427. iterator
  428. erase(
  429. iterator first,
  430. iterator last) noexcept;
  431. //--------------------------------------------
  432. /** Replace segments
  433. This function replaces the segment at
  434. the specified position.
  435. Reserved characters in the string are
  436. automatically escaped.
  437. Escapes in the string are preserved.
  438. <br>
  439. All iterators that are equal to
  440. `pos` or come after are invalidated.
  441. @par Complexity
  442. Linear in `s.size() + this->url().encoded_resouce().size()`.
  443. @par Exception Safety
  444. Strong guarantee.
  445. Calls to allocate may throw.
  446. @return An iterator to the replaced segment.
  447. @param pos An iterator to the segment.
  448. @param s The string to assign.
  449. */
  450. BOOST_URL_DECL
  451. iterator
  452. replace(
  453. iterator pos,
  454. pct_string_view s);
  455. /** Replace segments
  456. This function replaces a range of
  457. segments with one segment.
  458. Reserved characters in the string are
  459. automatically escaped.
  460. Escapes in the string are preserved.
  461. <br>
  462. All iterators that are equal to
  463. `from` or come after are invalidated.
  464. @par Complexity
  465. Linear in `s.size() + this->url().encoded_resouce().size()`.
  466. @par Exception Safety
  467. Strong guarantee.
  468. Calls to allocate may throw.
  469. Exceptions thrown on invalid input.
  470. @throw system_error
  471. The string contains an invalid percent-encoding.
  472. @return An iterator to the new segment.
  473. @param from, to The range of segments to replace.
  474. @param s The string to assign.
  475. */
  476. BOOST_URL_DECL
  477. iterator
  478. replace(
  479. iterator from,
  480. iterator to,
  481. pct_string_view s);
  482. /** Replace segments
  483. This function replaces a range of
  484. segments with a list of segments in
  485. an initializer list.
  486. Reserved characters in the list are
  487. automatically escaped.
  488. Escapes in the list are preserved.
  489. <br>
  490. All iterators that are equal to
  491. `from` or come after are invalidated.
  492. @par Preconditions
  493. None of the character buffers referenced
  494. by the list may overlap the character
  495. buffer of the underlying url, or else
  496. the behavior is undefined.
  497. @par Complexity
  498. Linear in `init.size() + this->url().encoded_resouce().size()`.
  499. @par Exception Safety
  500. Strong guarantee.
  501. Calls to allocate may throw.
  502. Exceptions thrown on invalid input.
  503. @throw system_error
  504. The list contains an invalid percent-encoding.
  505. @return An iterator to the first
  506. segment inserted, or one past `to` if
  507. `init.size() == 0`.
  508. @param from, to The range of segments to replace.
  509. @param init The list of segments to assign.
  510. */
  511. BOOST_URL_DECL
  512. iterator
  513. replace(
  514. iterator from,
  515. iterator to,
  516. std::initializer_list<
  517. pct_string_view> init);
  518. /** Replace segments
  519. This function replaces a range of
  520. segments with annother range of segments.
  521. Reserved characters in the new range are
  522. automatically escaped.
  523. Escapes in the new range are preserved.
  524. <br>
  525. All iterators that are equal to
  526. `from` or come after are invalidated.
  527. @par Preconditions
  528. None of the character buffers referenced
  529. by the new range may overlap the character
  530. buffer of the underlying url, or else
  531. the behavior is undefined.
  532. @par Complexity
  533. Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
  534. @par Exception Safety
  535. Strong guarantee.
  536. Calls to allocate may throw.
  537. Exceptions thrown on invalid input.
  538. @throw system_error
  539. The range contains an invalid percent-encoding.
  540. @return An iterator to the first
  541. segment inserted, or one past `to` if
  542. `init.size() == 0`.
  543. @param from, to The range of segments to replace.
  544. @param first, last The range of segments to assign.
  545. */
  546. template<class FwdIt>
  547. iterator
  548. replace(
  549. iterator from,
  550. iterator to,
  551. FwdIt first,
  552. FwdIt last);
  553. //--------------------------------------------
  554. /** Append a segment
  555. This function appends a segment to
  556. the end of the path.
  557. Reserved characters in the string are
  558. automatically escaped.
  559. Escapes in the string are preserved.
  560. <br>
  561. All end iterators are invalidated.
  562. @par Postconditions
  563. @code
  564. this->back() == s
  565. @endcode
  566. @par Exception Safety
  567. Strong guarantee.
  568. Calls to allocate may throw.
  569. Exceptions thrown on invalid input.
  570. @throw system_error
  571. The string contains an invalid percent-encoding.
  572. @param s The segment to append.
  573. */
  574. void
  575. push_back(
  576. pct_string_view s);
  577. /** Remove the last segment
  578. This function removes the last segment
  579. from the container.
  580. <br>
  581. Iterators to the last segment as well
  582. as all end iterators are invalidated.
  583. @par Preconditions
  584. @code
  585. not this->empty()
  586. @endcode
  587. @par Exception Safety
  588. Throws nothing.
  589. */
  590. void
  591. pop_back() noexcept;
  592. private:
  593. template<class FwdIt>
  594. iterator
  595. insert(
  596. iterator before,
  597. FwdIt first,
  598. FwdIt last,
  599. std::input_iterator_tag) = delete;
  600. template<class FwdIt>
  601. iterator
  602. insert(
  603. iterator before,
  604. FwdIt first,
  605. FwdIt last,
  606. std::forward_iterator_tag);
  607. };
  608. } // urls
  609. } // boost
  610. // This is in <boost/url/url_base.hpp>
  611. //
  612. // #include <boost/url/impl/segments_encoded_ref.hpp>
  613. #endif