LCOV - code coverage report
Current view: top level - boost/http_proto/rfc/impl/list_rule.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 98.2 % 57 56
Test Date: 2024-07-03 18:58:30 Functions: 100.0 % 16 16

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 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/cppalliance/http_proto
       8              : //
       9              : 
      10              : #ifndef BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
      11              : #define BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
      12              : 
      13              : #include <boost/url/grammar/parse.hpp>
      14              : #include <boost/url/grammar/range_rule.hpp>
      15              : #include <boost/core/empty_value.hpp>
      16              : #include <type_traits>
      17              : 
      18              : namespace boost {
      19              : namespace http_proto {
      20              : 
      21              : namespace detail {
      22              : 
      23              : /*  Peter:
      24              : 
      25              :     So, to put everything together, this is what I propose
      26              : 
      27              :     - make range2_rule that takes first and next with
      28              :       value types of optional<E> rather than E like the current rule
      29              :     - make variant_rule produce an optional<X> when otherwise
      30              :       the value type would have been variant<void, void, X, void>
      31              :     - add operators for combining the rules so that one can
      32              :       write *( OWS >> !literal(",") >> -( OWS >> element ) )
      33              :     - profit
      34              : */
      35              : 
      36              : // *( OWS "," )
      37              : struct ows_comma_t
      38              : {
      39              :     using value_type = void;
      40              : 
      41              :     auto
      42           99 :     parse(
      43              :         char const*& it,
      44              :         char const* end) const noexcept ->
      45              :             system::result<value_type>
      46              :     {
      47           99 :         auto it1 = it;
      48          247 :         while(it != end)
      49              :         {
      50              :             // SP / HT
      51          232 :             if( *it == ' ' ||
      52          176 :                 *it == '\t')
      53              :             {
      54           58 :                 ++it;
      55           58 :                 continue;
      56              :             }
      57          174 :             if(*it != ',')
      58           84 :                 break;
      59              :             // ","
      60           90 :             it1 = ++it;
      61              :         }
      62           99 :         it = it1;
      63           99 :         return {};
      64              :     }
      65              : };
      66              : 
      67              : constexpr ows_comma_t ows_comma{};
      68              : 
      69              : } // detail
      70              : 
      71              : /*
      72              :     #element    => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
      73              : 
      74              :     #element    => first *next
      75              :     first       => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
      76              :     next        => "" / ( 1*( OWS "," ) [ OWS element ] )
      77              : */
      78              : 
      79              : template<class Rule>
      80              : struct list_rule_t<Rule>::
      81              :     first_rule : empty_value<Rule>
      82              : {
      83              :     using value_type =
      84              :         typename Rule::value_type;
      85              : 
      86              :     constexpr
      87              :     explicit
      88          385 :     first_rule(
      89              :         Rule const& r) noexcept
      90              :         : empty_value<Rule>(
      91          385 :             empty_init, r)
      92              :     {
      93          385 :     }
      94              : 
      95              :     auto
      96          716 :     parse(
      97              :         char const*& it,
      98              :         char const* end) const ->
      99              :             system::result<value_type>
     100              :     {
     101              :     //  first       => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
     102              : 
     103          716 :         if(it == end)
     104            5 :             return grammar::error::end_of_range;
     105              :         {
     106              :             // element
     107          711 :             auto it0 = it;
     108          711 :             auto rv = this->get().parse(it, end);
     109          711 :             if(rv)
     110          684 :                 return std::move(*rv);
     111           27 :             it = it0;
     112          326 :         }
     113              :         // ","
     114           27 :         if(*it != ',')
     115           14 :             return grammar::error::end_of_range;
     116           13 :         ++it;
     117              :         // *( OWS "," )
     118           13 :         detail::ows_comma.parse(it, end);
     119           13 :         auto it1 = it;
     120              :         // OWS
     121           13 :         it = grammar::find_if_not(
     122              :             it, end, detail::ws);
     123              :         // element
     124           13 :         auto rv = this->get().parse(it, end);
     125           13 :         if(rv)
     126            6 :             return std::move(*rv);
     127            7 :         it = it1;
     128            7 :         return grammar::error::end_of_range;
     129            0 :     }
     130              : };
     131              : 
     132              : template<class Rule>
     133              : struct list_rule_t<Rule>::
     134              :     next_rule : empty_value<Rule>
     135              : {
     136              :     using value_type =
     137              :         typename Rule::value_type;
     138              : 
     139              :     constexpr
     140              :     explicit
     141          385 :     next_rule(
     142              :         Rule const& r) noexcept
     143              :         : empty_value<Rule>(
     144          385 :             empty_init, r)
     145              :     {
     146          385 :     }
     147              : 
     148              :     auto
     149          740 :     parse(
     150              :         char const*& it,
     151              :         char const* end) const ->
     152              :             system::result<value_type>
     153              :     {
     154              :     //  next        => "" / ( 1*( OWS "," ) [ OWS element ] )
     155              : 
     156              :         // ""
     157          740 :         if(it == end)
     158          654 :             return grammar::error::end_of_range;
     159              : 
     160              :         // 1*( OWS "," )
     161              :         {
     162           86 :             auto it0 = it;
     163           86 :             detail::ows_comma.parse(it, end);
     164           86 :             if(it == it0)
     165            7 :                 return grammar::error::end_of_range;
     166              :         }
     167           79 :         auto it1 = it;
     168              :         // OWS
     169           79 :         it = grammar::find_if_not(
     170              :             it, end, detail::ws);
     171           79 :         auto rv = this->get().parse(it, end);
     172           79 :         if(rv)
     173           70 :             return std::move(*rv);
     174            9 :         it = it1;
     175            9 :         return grammar::error::end_of_range;
     176           29 :     }
     177              : };
     178              : 
     179              : template<class Rule>
     180              : auto
     181          385 : list_rule_t<Rule>::
     182              : parse(
     183              :     char const*& it,
     184              :     char const* end) const ->
     185              :         system::result<value_type>
     186              : {
     187              :     return grammar::parse(it, end,
     188          770 :         grammar::range_rule(
     189              :             first_rule{this->get()},
     190              :             next_rule{this->get()},
     191         1155 :                 n_, m_));
     192              : }
     193              : 
     194              : } // http_proto
     195              : } // boost
     196              : 
     197              : #endif
        

Generated by: LCOV version 2.1