LCOV - code coverage report
Current view: top level - boost/url/grammar/impl - tuple_rule.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 56 56 100.0 %
Date: 2024-03-15 19:37:08 Functions: 287 292 98.3 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot 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_GRAMMAR_IMPL_TUPLE_RULE_HPP
      11             : #define BOOST_URL_GRAMMAR_IMPL_TUPLE_RULE_HPP
      12             : 
      13             : #include <boost/url/grammar/parse.hpp>
      14             : #include <boost/mp11/integral.hpp>
      15             : #include <boost/mp11/list.hpp>
      16             : #include <boost/mp11/tuple.hpp>
      17             : #include <type_traits>
      18             : 
      19             : namespace boost {
      20             : namespace urls {
      21             : namespace grammar {
      22             : 
      23             : namespace detail {
      24             : 
      25             : // returns a tuple
      26             : template<
      27             :     bool IsList,
      28             :     class R0, class... Rn>
      29             : struct parse_sequence
      30             : {
      31             :     using R = detail::tuple<R0, Rn...>;
      32             : 
      33             :     using L = mp11::mp_list<
      34             :         typename R0::value_type,
      35             :         typename Rn::value_type...>;
      36             : 
      37             :     using V = mp11::mp_remove<
      38             :         std::tuple<
      39             :             system::result<typename R0::value_type>,
      40             :             system::result<typename Rn::value_type>...>,
      41             :         system::result<void>>;
      42             : 
      43             :     template<std::size_t I>
      44             :     using is_void = std::is_same<
      45             :         mp11::mp_at_c<L, I>, void>;
      46             : 
      47             :     system::error_code ec;
      48             :     R const& rn;
      49             :     V vn;
      50             : 
      51             :     explicit
      52        3626 :     parse_sequence(
      53             :         R const& rn_) noexcept
      54             :         : rn(rn_)
      55             :         , vn(mp11::mp_fill<
      56        3626 :             V, system::error_code>{})
      57             :     {
      58        3626 :     }
      59             : 
      60             :     void
      61        1180 :     apply(
      62             :         char const*&,
      63             :         char const*,
      64             :         ...) const noexcept
      65             :     {
      66        1180 :     }
      67             : 
      68             :     // for system::result<void>
      69             :     template<
      70             :         std::size_t Ir,
      71             :         std::size_t Iv>
      72             :     void
      73        1485 :     apply(
      74             :         char const*& it,
      75             :         char const* end,
      76             :         mp11::mp_size_t<Ir> const&,
      77             :         mp11::mp_size_t<Iv> const&,
      78             :         mp11::mp_true const&)
      79             :     {
      80             :         system::result<void> rv =
      81        1485 :             grammar::parse(
      82        1485 :                 it, end, get<Ir>(rn));
      83        1485 :         if( !rv )
      84             :         {
      85         352 :             ec = rv.error();
      86         352 :             return;
      87             :         }
      88        1133 :         apply(it, end,
      89             :             mp11::mp_size_t<Ir+1>{},
      90             :             mp11::mp_size_t<Iv>{});
      91             :     }
      92             : 
      93             :     template<
      94             :         std::size_t Ir,
      95             :         std::size_t Iv>
      96             :     void
      97        4844 :     apply(
      98             :         char const*& it,
      99             :         char const* end,
     100             :         mp11::mp_size_t<Ir> const&,
     101             :         mp11::mp_size_t<Iv> const&,
     102             :         mp11::mp_false const&)
     103             :     {
     104        4844 :         auto& rv = get<Iv>(vn);
     105        4844 :         rv = grammar::parse(
     106        4844 :             it, end, get<Ir>(rn));
     107        4844 :         if( !rv )
     108             :         {
     109        2094 :             ec = rv.error();
     110        2094 :             return;
     111             :         }
     112        2750 :         apply(it, end,
     113             :             mp11::mp_size_t<Ir+1>{},
     114             :             mp11::mp_size_t<Iv+1>{});
     115             :     }
     116             : 
     117             :     template<
     118             :         std::size_t Ir = 0,
     119             :         std::size_t Iv = 0>
     120             :     typename std::enable_if<
     121             :         Ir < 1 + sizeof...(Rn)>::type
     122        6329 :     apply(
     123             :         char const*& it,
     124             :         char const* end,
     125             :         mp11::mp_size_t<Ir> const& ir = {},
     126             :         mp11::mp_size_t<Iv> const& iv = {}
     127             :             ) noexcept
     128             :     {
     129        6329 :         apply(it, end, ir, iv, is_void<Ir>{});
     130        6329 :     }
     131             : 
     132             :     struct deref
     133             :     {
     134             :         template<class R>
     135             :         auto
     136        2619 :         operator()(R const& r) const ->
     137             :             decltype(*r)
     138             :         {
     139        2619 :             return *r;
     140             :         }
     141             :     };
     142             : 
     143             :     auto
     144        3626 :     make_result() noexcept ->
     145             :         system::result<typename tuple_rule_t<
     146             :             R0, Rn...>::value_type>
     147             :     {
     148        3626 :         if(ec.failed())
     149        2446 :             return ec;
     150             :         return mp11::tuple_transform(
     151        1180 :             deref{}, vn);
     152             :     }
     153             : };
     154             : 
     155             : // returns a value_type
     156             : template<class R0, class... Rn>
     157             : struct parse_sequence<false, R0, Rn...>
     158             : {
     159             :     using R = detail::tuple<R0, Rn...>;
     160             : 
     161             :     using L = mp11::mp_list<
     162             :         typename R0::value_type,
     163             :         typename Rn::value_type...>;
     164             : 
     165             :     using V = mp11::mp_first<
     166             :         mp11::mp_remove<
     167             :             mp11::mp_list<
     168             :                 system::result<typename R0::value_type>,
     169             :                 system::result<typename Rn::value_type>...>,
     170             :             system::result<void>>>;
     171             : 
     172             :     template<std::size_t I>
     173             :     using is_void = std::is_same<
     174             :         mp11::mp_at_c<L, I>, void>;
     175             : 
     176             :     R const& rn;
     177             :     V v;
     178             : 
     179             :     explicit
     180        7544 :     parse_sequence(
     181             :         R const& rn_) noexcept
     182             :         : rn(rn_)
     183        7544 :         , v(system::error_code{})
     184             :     {
     185        7544 :     }
     186             : 
     187             :     void
     188        3536 :     apply(
     189             :         char const*&,
     190             :         char const*,
     191             :         ...) const noexcept
     192             :     {
     193        3536 :     }
     194             : 
     195             :     // for system::result<void>
     196             :     template<
     197             :         std::size_t Ir,
     198             :         std::size_t Iv>
     199             :     BOOST_URL_NO_INLINE
     200             :     void
     201        6566 :     apply(
     202             :         char const*& it,
     203             :         char const* end,
     204             :         mp11::mp_size_t<Ir> const&,
     205             :         mp11::mp_size_t<Iv> const&,
     206             :         mp11::mp_true const&)
     207             :     {
     208             :         system::result<void> rv =
     209        6566 :             grammar::parse(
     210        6566 :                 it, end, get<Ir>(rn));
     211        6566 :         if( !rv )
     212             :         {
     213        2973 :             v = rv.error();
     214        2973 :             return;
     215             :         }
     216        3593 :         apply(it, end,
     217             :             mp11::mp_size_t<Ir+1>{},
     218             :             mp11::mp_size_t<Iv>{});
     219             :     }
     220             : 
     221             :     template<
     222             :         std::size_t Ir,
     223             :         std::size_t Iv>
     224             :     void
     225        6309 :     apply(
     226             :         char const*& it,
     227             :         char const* end,
     228             :         mp11::mp_size_t<Ir> const&,
     229             :         mp11::mp_size_t<Iv> const&,
     230             :         mp11::mp_false const&)
     231             :     {
     232        6309 :         v = grammar::parse(
     233        6309 :             it, end, get<Ir>(rn));
     234        6309 :         if( !v )
     235        1035 :             return;
     236        5274 :         apply(it, end,
     237             :             mp11::mp_size_t<Ir+1>{},
     238             :             mp11::mp_size_t<Iv+1>{});
     239             :     }
     240             : 
     241             :     template<
     242             :         std::size_t Ir = 0,
     243             :         std::size_t Iv = 0>
     244             :     typename std::enable_if<
     245             :         Ir < 1 + sizeof...(Rn)>::type
     246       12875 :     apply(
     247             :         char const*& it,
     248             :         char const* end,
     249             :         mp11::mp_size_t<Ir> const& ir = {},
     250             :         mp11::mp_size_t<Iv> const& iv = {}
     251             :             ) noexcept
     252             :     {
     253       12875 :         apply(it, end, ir, iv, is_void<Ir>{});
     254       12875 :     }
     255             : 
     256             :     V
     257        7544 :     make_result() noexcept
     258             :     {
     259        7544 :         return v;
     260             :     }
     261             : };
     262             : 
     263             : } // detail
     264             : 
     265             : template<
     266             :     class R0,
     267             :     class... Rn>
     268             : auto
     269       11170 : tuple_rule_t<R0, Rn...>::
     270             : parse(
     271             :     char const*& it,
     272             :     char const* end) const ->
     273             :         system::result<value_type>
     274             : {
     275             :     detail::parse_sequence<
     276       14237 :         IsList, R0, Rn...> t(this->get());
     277       11170 :     t.apply(it, end);
     278       11170 :     return t.make_result();
     279             : }
     280             : 
     281             : } // grammar
     282             : } // urls
     283             : } // boost
     284             : 
     285             : #endif

Generated by: LCOV version 1.15