LCOV - code coverage report
Current view: top level - url - segments_ref.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 2 2
Test Date: 2026-02-13 15:53:22 Functions: 100.0 % 1 1

            Line data    Source code
       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              : 
      11              : #ifndef BOOST_URL_SEGMENTS_REF_HPP
      12              : #define BOOST_URL_SEGMENTS_REF_HPP
      13              : 
      14              : #include <boost/url/detail/config.hpp>
      15              : #include <boost/url/segments_base.hpp>
      16              : #include <initializer_list>
      17              : #include <iterator>
      18              : 
      19              : namespace boost {
      20              : namespace urls {
      21              : 
      22              : #ifndef BOOST_URL_DOCS
      23              : class url_base;
      24              : class segments_view;
      25              : #endif
      26              : 
      27              : /** Mutable decoded path segment proxy
      28              : 
      29              :     Presents the decoded path segments of a
      30              :     @ref url_base as a bidirectional range whose
      31              :     modifiers update the underlying URL. The proxy
      32              :     references the URL’s storage directly, so the
      33              :     owning URL must remain alive while the proxy
      34              :     is used.
      35              : 
      36              :     @par Example
      37              :     @code
      38              :     url u( "/path/to/file.txt" );
      39              : 
      40              :     segments_ref ps = u.segments();
      41              :     @endcode
      42              : 
      43              :     Percent escapes in strings returned when
      44              :     dereferencing iterators are automatically
      45              :     decoded.
      46              :     Reserved characters in strings supplied
      47              :     to modifier functions are automatically
      48              :     percent-escaped.
      49              : 
      50              :     @par Iterator Invalidation
      51              :     Changes to the underlying character buffer
      52              :     can invalidate iterators which reference it.
      53              :     Modifications made through the container
      54              :     invalidate some or all iterators:
      55              :     <br>
      56              : 
      57              :     @li @ref push_back : Only `end()`.
      58              : 
      59              :     @li @ref assign, @ref clear,
      60              :         @ref operator= : All elements.
      61              : 
      62              :     @li @ref erase : Erased elements and all
      63              :         elements after (including `end()`).
      64              : 
      65              :     @li @ref insert : All elements at or after
      66              :         the insertion point (including `end()`).
      67              : 
      68              :     @li @ref replace : Modified
      69              :         elements and all elements
      70              :         after (including `end()`).
      71              : 
      72              :     @see
      73              :         @ref segments_encoded_ref,
      74              :         @ref segments_encoded_view,
      75              :         @ref segments_view.
      76              : */
      77              : class BOOST_URL_DECL segments_ref
      78              :     : public segments_base
      79              : {
      80              :     url_base* u_ = nullptr;
      81              : 
      82              :     friend class url_base;
      83              :     friend class segments_encoded_ref;
      84              : 
      85              :     segments_ref(url_base& u) noexcept;
      86              : 
      87              : public:
      88              :     //--------------------------------------------
      89              :     //
      90              :     // Special Members
      91              :     //
      92              :     //--------------------------------------------
      93              : 
      94              :     /** Constructor
      95              : 
      96              :         After construction, both views
      97              :         reference the same url. Ownership is not
      98              :         transferred; the caller is responsible
      99              :         for ensuring the lifetime of the url
     100              :         extends until it is no longer
     101              :         referenced.
     102              : 
     103              :         @par Postconditions
     104              :         @code
     105              :         &this->url() == &other.url();
     106              :         @endcode
     107              : 
     108              :         @par Complexity
     109              :         Constant.
     110              : 
     111              :         @par Exception Safety
     112              :         Throws nothing.
     113              : 
     114              :         @param other The other view.
     115              :     */
     116              :     segments_ref(
     117              :         segments_ref const& other) = default;
     118              : 
     119              :     /** Assignment
     120              : 
     121              :         The existing contents are replaced
     122              :         by a copy of the other segments.
     123              : 
     124              :         <br>
     125              :         All iterators are invalidated.
     126              : 
     127              :         @note
     128              :         None of the character buffers referenced
     129              :         by `other` may overlap the buffer of the
     130              :         underlying url, or else the behavior
     131              :         is undefined.
     132              : 
     133              :         @par Effects
     134              :         @code
     135              :         this->assign( other.begin(), other.end() );
     136              :         @endcode
     137              : 
     138              :         @par Complexity
     139              :         Linear in `other.buffer().size()`.
     140              : 
     141              :         @par Exception Safety
     142              :         Strong guarantee.
     143              :         Calls to allocate may throw.
     144              : 
     145              :         @param other The segments to assign.
     146              :         @return A reference to this object.
     147              :     */
     148              :     segments_ref&
     149              :     operator=(segments_ref const& other);
     150              : 
     151              :     /// @copydoc segments_ref::operator=(segments_ref const&)
     152              :     segments_ref&
     153              :     operator=(segments_view const& other);
     154              : 
     155              :     /** Assignment
     156              : 
     157              :         The existing contents are replaced
     158              :         by a copy of the contents of the
     159              :         initializer list.
     160              :         Reserved characters in the list are
     161              :         automatically escaped.
     162              : 
     163              :         <br>
     164              :         All iterators are invalidated.
     165              : 
     166              :         @par Example
     167              :         @code
     168              :         url u;
     169              : 
     170              :         u.segments() = { "path", "to", "file.txt" };
     171              :         @endcode
     172              : 
     173              :         @par Preconditions
     174              :         None of the character buffers referenced
     175              :         by the list may overlap the character
     176              :         buffer of the underlying url, or else
     177              :         the behavior is undefined.
     178              : 
     179              :         @par Effects
     180              :         @code
     181              :         this->assign( init.begin(), init.end() );
     182              :         @endcode
     183              : 
     184              :         @par Complexity
     185              :         Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
     186              : 
     187              :         @par Exception Safety
     188              :         Strong guarantee.
     189              :         Calls to allocate may throw.
     190              : 
     191              :         @param init The list of segments to assign.
     192              :         @return A reference to this object.
     193              :     */
     194              :     segments_ref&
     195              :     operator=(std::initializer_list<
     196              :         core::string_view> init);
     197              : 
     198              :     /** Conversion
     199              : 
     200              :         @see
     201              :             @ref segments_view.
     202              : 
     203              :         @return A view of the segments.
     204              :     */
     205              :     operator
     206              :     segments_view() const noexcept;
     207              : 
     208              :     //--------------------------------------------
     209              :     //
     210              :     // Observers
     211              :     //
     212              :     //--------------------------------------------
     213              : 
     214              :     /** Return the referenced url
     215              : 
     216              :         This function returns the url referenced
     217              :         by the view.
     218              : 
     219              :         @par Example
     220              :         @code
     221              :         url u( "/path/to/file.txt" );
     222              : 
     223              :         assert( &u.segments().url() == &u );
     224              :         @endcode
     225              : 
     226              :         @par Exception Safety
     227              :         Throws nothing.
     228              : 
     229              :         @return A reference to the url.
     230              :     */
     231              :     url_base&
     232            9 :     url() const noexcept
     233              :     {
     234            9 :         return *u_;
     235              :     }
     236              : 
     237              :     //--------------------------------------------
     238              :     //
     239              :     // Modifiers
     240              :     //
     241              :     //--------------------------------------------
     242              : 
     243              :     /** Clear the contents of the container
     244              : 
     245              :         <br>
     246              :         All iterators are invalidated.
     247              : 
     248              :         @par Effects
     249              :         @code
     250              :         this->url().set_encoded_path( "" );
     251              :         @endcode
     252              : 
     253              :         @par Postconditions
     254              :         @code
     255              :         this->empty() == true
     256              :         @endcode
     257              : 
     258              :         @par Complexity
     259              :         Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
     260              : 
     261              :         @par Exception Safety
     262              :         Throws nothing.
     263              :     */
     264              :     void
     265              :     clear() noexcept;
     266              : 
     267              :     /** Assign segments
     268              : 
     269              :         The existing contents are replaced
     270              :         by a copy of the contents of the
     271              :         initializer list.
     272              :         Reserved characters in the list are
     273              :         automatically escaped.
     274              : 
     275              :         <br>
     276              :         All iterators are invalidated.
     277              : 
     278              :         @note
     279              :         None of the character buffers referenced
     280              :         by `init` may overlap the character buffer
     281              :         of the underlying url, or else the behavior
     282              :         is undefined.
     283              : 
     284              :         @par Example
     285              :         @code
     286              :         url u;
     287              : 
     288              :         u.segments().assign( { "path", "to", "file.txt" } );
     289              :         @endcode
     290              : 
     291              :         @par Complexity
     292              :         Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
     293              : 
     294              :         @par Exception Safety
     295              :         Strong guarantee.
     296              :         Calls to allocate may throw.
     297              : 
     298              :         @param init The list of segments to assign.
     299              :     */
     300              :     void
     301              :     assign(std::initializer_list<
     302              :         core::string_view> init);
     303              : 
     304              :     /** Assign segments
     305              : 
     306              :         The existing contents are replaced
     307              :         by a copy of the contents of the range.
     308              :         Reserved characters in the range are
     309              :         automatically escaped.
     310              : 
     311              :         <br>
     312              :         All iterators are invalidated.
     313              : 
     314              :         @note
     315              :         None of the character buffers referenced
     316              :         by the range may overlap the character
     317              :         buffer of the underlying url, or else
     318              :         the behavior is undefined.
     319              : 
     320              :         @par Mandates
     321              :         @code
     322              :         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
     323              :         @endcode
     324              : 
     325              :         @par Complexity
     326              :         Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
     327              : 
     328              :         @par Exception Safety
     329              :         Strong guarantee.
     330              :         Calls to allocate may throw.
     331              : 
     332              :         @param first The beginning of the range of segments to assign.
     333              :         @param last The end of the range of segments to assign.
     334              :     */
     335              :     template<class FwdIt>
     336              :     void
     337              :     assign(FwdIt first, FwdIt last);
     338              : 
     339              :     //--------------------------------------------
     340              : 
     341              :     /** Insert segments
     342              : 
     343              :         This function inserts a segment
     344              :         before the specified position.
     345              :         Reserved characters in the segment are
     346              :         automatically escaped.
     347              : 
     348              :         <br>
     349              :         All iterators that are equal to
     350              :         `before` or come after are invalidated.
     351              : 
     352              :         @par Complexity
     353              :         Linear in `s.size() + this->url().encoded_resource().size()`.
     354              : 
     355              :         @par Exception Safety
     356              :         Strong guarantee.
     357              :         Calls to allocate may throw.
     358              : 
     359              :         @return An iterator to the inserted
     360              :         segment.
     361              : 
     362              :         @param before An iterator before which
     363              :         the segment is inserted. This may
     364              :         be equal to `end()`.
     365              : 
     366              :         @param s The segment to insert.
     367              :     */
     368              :     iterator
     369              :     insert(
     370              :         iterator before,
     371              :         core::string_view s);
     372              : 
     373              :     /** Insert segments
     374              : 
     375              :         This function inserts the segments
     376              :         in an initializer list before the
     377              :         specified position.
     378              :         Reserved characters in the list are
     379              :         percent-escaped in the result.
     380              : 
     381              :         <br>
     382              :         All iterators that are equal to
     383              :         `before` or come after are invalidated.
     384              : 
     385              :         @note
     386              :         None of the character buffers referenced
     387              :         by the list may overlap the character
     388              :         buffer of the underlying url, or else
     389              :         the behavior is undefined.
     390              : 
     391              :         @par Example
     392              :         @code
     393              :         url u( "/file.txt" );
     394              : 
     395              :         u.segments().insert( u.segments().begin(), { "path", "to" } );
     396              :         @endcode
     397              : 
     398              :         @par Complexity
     399              :         Linear in `init.size() + this->url().encoded_resource().size()`.
     400              : 
     401              :         @par Exception Safety
     402              :         Strong guarantee.
     403              :         Calls to allocate may throw.
     404              : 
     405              :         @return An iterator to the first
     406              :         element inserted, or `before` if
     407              :         `init.size() == 0`.
     408              : 
     409              :         @param before An iterator before which
     410              :         the list is inserted. This may
     411              :         be equal to `end()`.
     412              : 
     413              :         @param init The list of segments to insert.
     414              :     */
     415              :     iterator
     416              :     insert(
     417              :         iterator before,
     418              :         std::initializer_list<core::string_view> init);
     419              : 
     420              :     /** Insert segments
     421              : 
     422              :         This function inserts the segments in
     423              :         a range before the specified position.
     424              :         Reserved characters in the list are
     425              :         automatically escaped.
     426              : 
     427              :         <br>
     428              :         All iterators that are equal to
     429              :         `before` or come after are invalidated.
     430              : 
     431              :         @note
     432              :         None of the character buffers referenced
     433              :         by the range may overlap the character
     434              :         buffer of the underlying url, or else
     435              :         the behavior is undefined.
     436              : 
     437              :         @par Mandates
     438              :         @code
     439              :         std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
     440              :         @endcode
     441              : 
     442              :         @par Complexity
     443              :         Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
     444              : 
     445              :         @par Exception Safety
     446              :         Strong guarantee.
     447              :         Calls to allocate may throw.
     448              : 
     449              :         @return An iterator to the first
     450              :         segment inserted, or `before` if
     451              :         `init.empty()`.
     452              : 
     453              :         @param before An iterator before which
     454              :         the range is inserted. This may
     455              :         be equal to `end()`.
     456              : 
     457              :         @param first The beginning of the range of segments to insert.
     458              :         @param last The end of the range of segments to insert.
     459              :     */
     460              :     template<class FwdIt>
     461              :     iterator
     462              :     insert(
     463              :         iterator before,
     464              :         FwdIt first,
     465              :         FwdIt last);
     466              : 
     467              :     //--------------------------------------------
     468              : 
     469              :     /** Erase segments
     470              : 
     471              :         This function removes a segment.
     472              : 
     473              :         <br>
     474              :         All iterators that are equal to
     475              :         `pos` or come after are invalidated.
     476              : 
     477              :         @par Complexity
     478              :         Linear in `this->url().encoded_resource().size()`.
     479              : 
     480              :         @par Exception Safety
     481              :         Throws nothing.
     482              : 
     483              :         @return An iterator to one past
     484              :         the removed segment.
     485              : 
     486              :         @param pos An iterator to the segment.
     487              :     */
     488              :     iterator
     489              :     erase(
     490              :         iterator pos) noexcept;
     491              : 
     492              :     /** Erase segments
     493              : 
     494              :         This function removes a range of segments.
     495              : 
     496              :         <br>
     497              :         All iterators that are equal to
     498              :         `first` or come after are invalidated.
     499              : 
     500              :         @par Complexity
     501              :         Linear in `this->url().encoded_resource().size()`.
     502              : 
     503              :         @par Exception Safety
     504              :         Throws nothing.
     505              : 
     506              :         @return An iterator to one past
     507              :         the removed range.
     508              : 
     509              :         @param first The beginning of the range to remove.
     510              :         @param last The end of the range to remove.
     511              :     */
     512              :     iterator
     513              :     erase(
     514              :         iterator first,
     515              :         iterator last) noexcept;
     516              : 
     517              :     //--------------------------------------------
     518              : 
     519              :     /** Replace segments
     520              : 
     521              :         This function replaces the segment at
     522              :         the specified position.
     523              :         Reserved characters in the string are
     524              :         automatically escaped.
     525              : 
     526              :         <br>
     527              :         All iterators that are equal to
     528              :         `pos` or come after are invalidated.
     529              : 
     530              :         @par Complexity
     531              :         Linear in `s.size() + this->url().encoded_resouce().size()`.
     532              : 
     533              :         @par Exception Safety
     534              :         Strong guarantee.
     535              :         Calls to allocate may throw.
     536              : 
     537              :         @return An iterator to the replaced segment.
     538              : 
     539              :         @param pos An iterator to the segment.
     540              : 
     541              :         @param s The string to assign.
     542              :     */
     543              :     iterator
     544              :     replace(
     545              :         iterator pos,
     546              :         core::string_view s);
     547              : 
     548              :     /** Replace segments
     549              : 
     550              :         This function replaces a range of
     551              :         segments with one segment.
     552              :         Reserved characters in the string are
     553              :         automatically escaped.
     554              : 
     555              :         <br>
     556              :         All iterators that are equal to
     557              :         `from` or come after are invalidated.
     558              : 
     559              :         @par Complexity
     560              :         Linear in `s.size() + this->url().encoded_resouce().size()`.
     561              : 
     562              :         @par Exception Safety
     563              :         Strong guarantee.
     564              :         Calls to allocate may throw.
     565              : 
     566              :         @return An iterator to the new segment.
     567              : 
     568              :         @param from The beginning of the range of segments to replace.
     569              :         @param to The end of the range of segments to replace.
     570              : 
     571              :         @param s The string to assign.
     572              :     */
     573              :     iterator
     574              :     replace(
     575              :         iterator from,
     576              :         iterator to,
     577              :         core::string_view s);
     578              : 
     579              :     /** Replace segments
     580              : 
     581              :         This function replaces a range of
     582              :         segments with a list of segments in
     583              :         an initializer list.
     584              :         Reserved characters in the list are
     585              :         automatically escaped.
     586              : 
     587              :         <br>
     588              :         All iterators that are equal to
     589              :         `from` or come after are invalidated.
     590              : 
     591              :         @par Preconditions
     592              :         None of the character buffers referenced
     593              :         by the list may overlap the character
     594              :         buffer of the underlying url, or else
     595              :         the behavior is undefined.
     596              : 
     597              :         @par Complexity
     598              :         Linear in `init.size() + this->url().encoded_resouce().size()`.
     599              : 
     600              :         @par Exception Safety
     601              :         Strong guarantee.
     602              :         Calls to allocate may throw.
     603              : 
     604              :         @return An iterator to the first
     605              :         segment inserted, or one past `to` if
     606              :         `init.size() == 0`.
     607              : 
     608              :         @param from The beginning of the range of segments to replace.
     609              :         @param to The end of the range of segments to replace.
     610              : 
     611              :         @param init The list of segments to assign.
     612              :     */
     613              :     iterator
     614              :     replace(
     615              :         iterator from,
     616              :         iterator to,
     617              :         std::initializer_list<
     618              :             core::string_view> init);
     619              : 
     620              :     /** Replace segments
     621              : 
     622              :         This function replaces a range of
     623              :         segments with annother range of segments.
     624              :         Reserved characters in the new range are
     625              :         automatically escaped.
     626              : 
     627              :         <br>
     628              :         All iterators that are equal to
     629              :         `from` or come after are invalidated.
     630              : 
     631              :         @par Preconditions
     632              :         None of the character buffers referenced
     633              :         by the new range may overlap the character
     634              :         buffer of the underlying url, or else
     635              :         the behavior is undefined.
     636              : 
     637              :         @par Complexity
     638              :         Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
     639              : 
     640              :         @par Exception Safety
     641              :         Strong guarantee.
     642              :         Calls to allocate may throw.
     643              : 
     644              :         @return An iterator to the first
     645              :         segment inserted, or one past `to` if
     646              :         `init.size() == 0`.
     647              : 
     648              :         @param from The beginning of the range of segments to replace.
     649              :         @param to The end of the range of segments to replace.
     650              :         @param first The beginning of the range of segments to assign.
     651              :         @param last The end of the range of segments to assign.
     652              :     */
     653              :     template<class FwdIt>
     654              :     iterator
     655              :     replace(
     656              :         iterator from,
     657              :         iterator to,
     658              :         FwdIt first,
     659              :         FwdIt last);
     660              : 
     661              :     /** Append a segment
     662              : 
     663              :         This function appends a segment to
     664              :         the end of the path.
     665              :         Reserved characters in the string are
     666              :         automatically escaped.
     667              : 
     668              :         <br>
     669              :         All end iterators are invalidated.
     670              : 
     671              :         @par Postconditions
     672              :         @code
     673              :         this->back() == s
     674              :         @endcode
     675              : 
     676              :         @par Exception Safety
     677              :         Strong guarantee.
     678              :         Calls to allocate may throw.
     679              : 
     680              :         @param s The segment to append.
     681              :     */
     682              :     void
     683              :     push_back(
     684              :         core::string_view s);
     685              : 
     686              :     /** Remove the last segment
     687              : 
     688              :         This function removes the last segment
     689              :         from the container.
     690              : 
     691              :         <br>
     692              :         Iterators to the last segment as well
     693              :         as all end iterators are invalidated.
     694              : 
     695              :         @par Preconditions
     696              :         @code
     697              :         not this->empty()
     698              :         @endcode
     699              : 
     700              :         @par Exception Safety
     701              :         Throws nothing.
     702              :     */
     703              :     void
     704              :     pop_back() noexcept;
     705              : 
     706              : private:
     707              :     template<class FwdIt>
     708              :     iterator
     709              :     insert(
     710              :         iterator before,
     711              :         FwdIt first,
     712              :         FwdIt last,
     713              :         std::input_iterator_tag) = delete;
     714              : 
     715              :     template<class FwdIt>
     716              :     iterator
     717              :     insert(
     718              :         iterator before,
     719              :         FwdIt first,
     720              :         FwdIt last,
     721              :         std::forward_iterator_tag);
     722              : };
     723              : 
     724              : } // urls
     725              : } // boost
     726              : 
     727              : // This include is at the bottom of
     728              : // url_base.hpp because of a circular dependency
     729              : //
     730              : // #include <boost/url/impl/segments_ref.hpp>
     731              : 
     732              : //------------------------------------------------
     733              : //
     734              : // std::ranges::enable_borrowed_range
     735              : //
     736              : //------------------------------------------------
     737              : 
     738              : #ifdef BOOST_URL_HAS_CONCEPTS
     739              : #include <ranges>
     740              : namespace std::ranges {
     741              :     template<>
     742              :     inline constexpr bool
     743              :         enable_borrowed_range<
     744              :             boost::urls::segments_ref> = true;
     745              : } // std::ranges
     746              : #endif
     747              : 
     748              : #endif
        

Generated by: LCOV version 2.3