LCOV - code coverage report
Current view: top level - url/detail - any_segments_iter.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 98.5 % 67 66 1
Test Date: 2026-02-25 21:00:01 Functions: 89.2 % 37 33 4

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/boostorg/url
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
      11                 : #define BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
      12                 : 
      13                 : #include <boost/url/pct_string_view.hpp>
      14                 : #include <boost/core/detail/static_assert.hpp>
      15                 : #include <cstddef>
      16                 : #include <iterator>
      17                 : #include <type_traits>
      18                 : 
      19                 : namespace boost {
      20                 : namespace urls {
      21                 : namespace detail {
      22                 : 
      23                 : struct BOOST_SYMBOL_VISIBLE
      24                 :     any_segments_iter
      25                 : {
      26                 : protected:
      27                 :     explicit
      28 HIT         611 :     any_segments_iter(
      29                 :         core::string_view s_ = {}) noexcept
      30             611 :         : s(s_)
      31                 :     {
      32             611 :     }
      33                 : 
      34             611 :     virtual ~any_segments_iter() = default;
      35                 : 
      36                 : public:
      37                 :     // this is adjusted
      38                 :     // when self-intersecting
      39                 :     core::string_view s;
      40                 : 
      41                 :     // the first segment,
      42                 :     // to handle special cases
      43                 :     core::string_view front;
      44                 : 
      45                 :     // quick number of segments
      46                 :     // 0 = zero
      47                 :     // 1 = one
      48                 :     // 2 = two, or more
      49                 :     int fast_nseg = 0;
      50                 : 
      51                 :     // whether the segments should encode colons
      52                 :     // when we measure and copy. the calling
      53                 :     // function uses this for the first
      54                 :     // segment in some cases, such as:
      55                 :     // "x:y:z" -> remove_scheme -> "y%3Az"
      56                 :     // as "y:z" would no longer represent a path
      57                 :     bool encode_colons = false;
      58                 : 
      59                 :     // Rewind the iterator to the beginning
      60                 :     virtual void rewind() noexcept = 0;
      61                 : 
      62                 :     // Measure and increment the current
      63                 :     // element. n is increased by the
      64                 :     // encoded size. Returns false on
      65                 :     // end of range. 
      66                 :     virtual bool measure(std::size_t& n) = 0;
      67                 : 
      68                 :     // Copy and increment the current
      69                 :     // element, encoding as needed.
      70                 :     virtual void copy(char*& dest,
      71                 :         char const* end) noexcept = 0;
      72                 : };
      73                 : 
      74                 : //------------------------------------------------
      75                 : //
      76                 : // segment_iter
      77                 : //
      78                 : //------------------------------------------------
      79                 : 
      80                 : // A 1-segment range
      81                 : // allowing self-intersection
      82                 : struct BOOST_SYMBOL_VISIBLE
      83                 :     segment_iter
      84                 :     : any_segments_iter
      85                 : {
      86              75 :     virtual ~segment_iter() = default;
      87                 : 
      88                 :     explicit
      89                 :     segment_iter(
      90                 :         core::string_view s) noexcept;
      91                 : 
      92                 : private:
      93                 :     bool at_end_ = false;
      94                 :     void rewind() noexcept override;
      95                 :     bool measure(std::size_t&) noexcept override;
      96                 :     void copy(char*&, char const*) noexcept override;
      97                 : };
      98                 : 
      99                 : //------------------------------------------------
     100                 : //
     101                 : // segments_iter
     102                 : //
     103                 : //------------------------------------------------
     104                 : 
     105                 : struct segments_iter_base
     106                 : {
     107                 : protected:
     108                 :     static void
     109                 :     measure_impl(std::size_t&,
     110                 :         core::string_view, bool) noexcept;
     111                 :     static void
     112                 :     copy_impl(char*&, char const*,
     113                 :         core::string_view, bool) noexcept;
     114                 : };
     115                 : 
     116                 : // iterates segments in a
     117                 : // plain segment range
     118                 : template<class FwdIt>
     119                 : struct segments_iter
     120                 :     : any_segments_iter
     121                 :     , segments_iter_base
     122                 : {
     123                 :     BOOST_CORE_STATIC_ASSERT(
     124                 :         std::is_convertible<
     125                 :             typename std::iterator_traits<
     126                 :                 FwdIt>::reference,
     127                 :             core::string_view>::value);
     128                 : 
     129              79 :     segments_iter(
     130                 :         FwdIt first,
     131                 :         FwdIt last) noexcept
     132              79 :         : it_(first)
     133              79 :         , it0_(first)
     134              79 :         , end_(last)
     135                 :     {
     136              79 :         if(first != last)
     137                 :         {
     138              79 :             front = *first;
     139              79 :             auto it = first;
     140              79 :             if(++it == last)
     141               8 :                 fast_nseg = 1;
     142                 :             else
     143              71 :                 fast_nseg = 2;
     144                 :         }
     145                 :         else
     146                 :         {
     147 MIS           0 :             fast_nseg = 0;
     148                 :         }
     149 HIT          79 :     }
     150                 : 
     151                 : private:
     152                 :     FwdIt it_;
     153                 :     FwdIt it0_;
     154                 :     FwdIt end_;
     155                 : 
     156                 :     void
     157              79 :     rewind() noexcept override
     158                 :     {
     159              79 :         it_ = it0_;
     160              79 :     }
     161                 : 
     162                 :     bool
     163             267 :     measure(
     164                 :         std::size_t& n) noexcept override
     165                 :     {
     166             267 :         if(it_ == end_)
     167              79 :             return false;
     168             188 :         measure_impl(n,
     169             182 :             detail::to_sv(*it_),
     170             188 :             encode_colons);
     171             188 :         ++it_;
     172             188 :         return true;
     173                 :     }
     174                 : 
     175                 :     void
     176             188 :     copy(
     177                 :         char*& dest,
     178                 :         char const* end) noexcept override
     179                 :     {
     180             188 :         copy_impl(dest, end,
     181             194 :             detail::to_sv(*it_++),
     182             188 :             encode_colons);
     183             188 :     }
     184                 : };
     185                 : 
     186                 : //------------------------------------------------
     187                 : //
     188                 : // segment_encoded_iter
     189                 : //
     190                 : //------------------------------------------------
     191                 : 
     192                 : // A 1-segment range
     193                 : // allowing self-intersection
     194                 : struct BOOST_SYMBOL_VISIBLE
     195                 :     segment_encoded_iter
     196                 :     : any_segments_iter
     197                 : {
     198              72 :     virtual ~segment_encoded_iter() = default;
     199                 : 
     200                 :     explicit
     201                 :     segment_encoded_iter(
     202                 :         pct_string_view const& s) noexcept;
     203                 : 
     204                 : private:
     205                 :     bool at_end_ = false;
     206                 :     void rewind() noexcept override;
     207                 :     bool measure(std::size_t&) noexcept override;
     208                 :     void copy(char*&, char const*) noexcept override;
     209                 : };
     210                 : 
     211                 : //------------------------------------------------
     212                 : //
     213                 : // segments_encoded_iter
     214                 : //
     215                 : //------------------------------------------------
     216                 : 
     217                 : // Validating and copying from
     218                 : // a string of encoded segments
     219                 : struct segments_encoded_iter_base
     220                 : {
     221                 : protected:
     222                 :     static void
     223                 :     measure_impl(std::size_t&,
     224                 :         core::string_view, bool) noexcept;
     225                 :     static void
     226                 :     copy_impl(char*&, char const*,
     227                 :         core::string_view, bool) noexcept;
     228                 : };
     229                 : 
     230                 : // iterates segments in an
     231                 : // encoded segment range
     232                 : template<class FwdIt>
     233                 : struct segments_encoded_iter
     234                 :     : public any_segments_iter
     235                 :     , public segments_encoded_iter_base
     236                 : {
     237                 :     BOOST_CORE_STATIC_ASSERT(
     238                 :         std::is_convertible<
     239                 :             typename std::iterator_traits<
     240                 :                 FwdIt>::reference,
     241                 :             core::string_view>::value);
     242                 : 
     243             385 :     segments_encoded_iter(
     244                 :         FwdIt first,
     245                 :         FwdIt last)
     246             385 :         : it_(first)
     247             385 :         , it0_(first)
     248             385 :         , end_(last)
     249                 :     {
     250             385 :         if(it_ != end_)
     251                 :         {
     252                 :             // throw on invalid input
     253             196 :             front = pct_string_view(
     254             125 :                 detail::to_sv(*first));
     255             183 :             auto it = first;
     256             183 :             if(++it == last)
     257              65 :                 fast_nseg = 1;
     258                 :             else
     259             118 :                 fast_nseg = 2;
     260                 :         }
     261                 :         else
     262                 :         {
     263             189 :             fast_nseg = 0;
     264                 :         }
     265             385 :     }
     266                 : 
     267                 : private:
     268                 :     FwdIt it_;
     269                 :     FwdIt it0_;
     270                 :     FwdIt end_;
     271                 : 
     272                 :     void
     273             370 :     rewind() noexcept override
     274                 :     {
     275             370 :         it_ = it0_;
     276             370 :     }
     277                 : 
     278                 :     bool
     279             771 :     measure(
     280                 :         std::size_t& n) override
     281                 :     {
     282             771 :         if(it_ == end_)
     283             370 :             return false;
     284                 :         // throw on invalid input
     285             399 :         measure_impl(n,
     286             401 :             pct_string_view(
     287             401 :                 detail::to_sv(*it_++)),
     288             401 :             encode_colons);
     289             399 :         return true;
     290                 :     }
     291                 : 
     292                 :     void
     293             397 :     copy(
     294                 :         char*& dest,
     295                 :         char const* end) noexcept override
     296                 :     {
     297             397 :         copy_impl(dest, end,
     298             397 :             detail::to_sv(*it_++),
     299             397 :             encode_colons);
     300             397 :     }
     301                 : };
     302                 : 
     303                 : //------------------------------------------------
     304                 : 
     305                 : template<class FwdIt>
     306                 : segments_iter<FwdIt>
     307              79 : make_segments_iter(
     308                 :     FwdIt first, FwdIt last)
     309                 : {
     310                 :     return segments_iter<
     311              79 :         FwdIt>(first, last);
     312                 : }
     313                 : 
     314                 : template<class FwdIt>
     315                 : segments_encoded_iter<FwdIt>
     316             385 : make_segments_encoded_iter(
     317                 :     FwdIt first, FwdIt last)
     318                 : {
     319                 :     return segments_encoded_iter<
     320             385 :         FwdIt>(first, last);
     321                 : }
     322                 : 
     323                 : } // detail
     324                 : } // urls
     325                 : } // boost
     326                 : 
     327                 : #include <boost/url/detail/impl/any_segments_iter.hpp>
     328                 : 
     329                 : #endif
        

Generated by: LCOV version 2.3