LCOV - code coverage report
Current view: top level - boost/url/detail/format_args.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 88 88
Test Date: 2024-08-19 20:08:54 Functions: 100.0 % 102 102

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2022 Alan de Freitas (alandefreitas@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_FORMAT_ARGS_HPP
      11              : #define BOOST_URL_DETAIL_FORMAT_ARGS_HPP
      12              : 
      13              : #include <boost/url/detail/encode.hpp>
      14              : #include <boost/url/grammar/lut_chars.hpp>
      15              : 
      16              : #include <boost/core/ignore_unused.hpp>
      17              : #include <array>
      18              : 
      19              : // This file implements functions and classes to
      20              : // type-erase format arguments.
      21              : 
      22              : namespace boost {
      23              : namespace urls {
      24              : namespace detail {
      25              : 
      26              : // state of the format string. It basically keeps
      27              : // track of where we are in the format string.
      28              : class format_parse_context
      29              : {
      30              :     char const* begin_;
      31              :     char const* end_;
      32              :     std::size_t arg_id_ = 0;
      33              : 
      34              : public:
      35              :     constexpr
      36          632 :     format_parse_context(
      37              :         char const* first,
      38              :         char const* last,
      39              :         std::size_t arg_id = 0)
      40          632 :         : begin_( first )
      41          632 :         , end_( last )
      42          632 :         , arg_id_( arg_id )
      43          632 :     {}
      44              : 
      45              :     constexpr
      46          495 :     format_parse_context(
      47              :         core::string_view fmt,
      48              :         std::size_t arg_id = 0)
      49          495 :         : format_parse_context(
      50              :             fmt.data(),
      51          495 :             fmt.data() + fmt.size(),
      52          495 :             arg_id )
      53          495 :     {}
      54              : 
      55              :     constexpr
      56              :     char const*
      57         1445 :     begin() const noexcept
      58              :     {
      59         1445 :         return begin_;
      60              :     }
      61              : 
      62              :     constexpr
      63              :     char const*
      64          971 :     end() const noexcept
      65              :     {
      66          971 :         return end_;
      67              :     }
      68              : 
      69              :     BOOST_CXX14_CONSTEXPR
      70              :     void
      71          950 :     advance_to( char const* it )
      72              :     {
      73          950 :         begin_ = it;
      74          950 :     }
      75              : 
      76              :     std::size_t
      77          871 :     next_arg_id()
      78              :     {
      79          871 :         return arg_id_++;
      80              :     }
      81              : };
      82              : 
      83              : // State of the destination string
      84              : class format_context;
      85              : class measure_context;
      86              : struct ignore_format {};
      87              : 
      88              : template <class T>
      89              : struct named_arg
      90              : {
      91              :     core::string_view name;
      92              :     T const& value;
      93              : 
      94           19 :     named_arg(core::string_view n, T const& v)
      95           19 :         : name(n)
      96           19 :         , value(v)
      97           19 :     {}
      98              : };
      99              : 
     100              : // A type erased format argument
     101              : class format_arg
     102              : {
     103              :     void const* arg_;
     104              :     void (*measure_)(
     105              :         format_parse_context&,
     106              :         measure_context&,
     107              :         grammar::lut_chars const&,
     108              :         void const* );
     109              :     void (*fmt_)(
     110              :         format_parse_context&,
     111              :         format_context&,
     112              :         grammar::lut_chars const&,
     113              :         void const* );
     114              :     core::string_view name_;
     115              :     std::size_t value_ = 0;
     116              :     bool ignore_ = false;
     117              : 
     118              :     template <class A>
     119              :     static
     120              :     void
     121              :     measure_impl(
     122              :         format_parse_context& pctx,
     123              :         measure_context& mctx,
     124              :         grammar::lut_chars const& cs,
     125              :         void const* a );
     126              : 
     127              :     template <class A>
     128              :     static
     129              :     void
     130              :     format_impl(
     131              :         format_parse_context& pctx,
     132              :         format_context& fctx,
     133              :         grammar::lut_chars const& cs,
     134              :         void const* a );
     135              : 
     136              : public:
     137              :     template<class A>
     138              :     format_arg( A&& a );
     139              : 
     140              :     template<class A>
     141              :     format_arg( named_arg<A>&& a );
     142              : 
     143              :     template<class A>
     144              :     format_arg( core::string_view name, A&& a );
     145              : 
     146           34 :     format_arg()
     147           34 :         : format_arg(ignore_format{})
     148           34 :     {}
     149              : 
     150              :     explicit
     151              :     operator bool() const noexcept
     152              :     {
     153              :         return !ignore_;
     154              :     }
     155              : 
     156              :     void
     157          240 :     measure(
     158              :         format_parse_context& pctx,
     159              :         measure_context& mctx,
     160              :         grammar::lut_chars const& cs)
     161              :     {
     162          240 :         measure_( pctx, mctx, cs, arg_ );
     163          238 :     }
     164              : 
     165              :     void
     166          236 :     format(
     167              :         format_parse_context& pctx,
     168              :         format_context& fctx,
     169              :         grammar::lut_chars const& cs )
     170              :     {
     171          236 :         fmt_( pctx, fctx, cs, arg_ );
     172          236 :     }
     173              : 
     174              :     core::string_view
     175          130 :     name() const
     176              :     {
     177          130 :         return name_;
     178              :     }
     179              : 
     180              :     std::size_t
     181           28 :     value() const
     182              :     {
     183           28 :         return value_;
     184              :     }
     185              : };
     186              : 
     187              : // create temp stack storage for type erased args
     188              : template< class... Args >
     189              : std::array<format_arg, sizeof...(Args)>
     190          144 : make_format_args( Args&&... args )
     191              : {
     192          144 :     return {{ std::forward<Args>(args)... }};
     193              : }
     194              : 
     195              : // reference to an array of format_args
     196              : class format_args
     197              : {
     198              :     format_arg const* p_{nullptr};
     199              :     std::size_t n_{0};
     200              : 
     201              : public:
     202            3 :     format_args(
     203              :         detail::format_arg const* first,
     204              :         detail::format_arg const* last ) noexcept
     205            3 :         : p_(first)
     206            3 :         , n_(static_cast<std::size_t>(last - first))
     207            3 :     {}
     208              : 
     209              :     template < std::size_t N >
     210          144 :     format_args( std::array<format_arg, N> const& store ) noexcept
     211          144 :         : p_(store.data())
     212          144 :         , n_(store.size())
     213          144 :     {}
     214              : 
     215              :     format_arg
     216          442 :     get( std::size_t i ) const noexcept
     217              :     {
     218          442 :         if (i < n_)
     219          438 :             return p_[i];
     220            4 :         return {};
     221              :     }
     222              : 
     223              :     format_arg
     224           62 :     get( core::string_view name ) const noexcept
     225              :     {
     226          132 :         for (std::size_t i = 0; i < n_; ++i)
     227              :         {
     228          130 :             if (p_[i].name() == name)
     229           60 :                 return p_[i];
     230              :         }
     231            2 :         return {};
     232              :     }
     233              : };
     234              : 
     235              : // define the format_context after format_args
     236              : class format_context
     237              : {
     238              :     format_args args_;
     239              :     char* out_;
     240              : 
     241              : public:
     242          137 :     format_context(
     243              :         char* out,
     244              :         format_args args )
     245          137 :         : args_( args )
     246          137 :         , out_( out )
     247          137 :     {}
     248              : 
     249              :     format_args
     250           14 :     args() const noexcept
     251              :     {
     252           14 :         return args_;
     253              :     }
     254              : 
     255              :     format_arg
     256          210 :     arg( std::size_t id ) const noexcept
     257              :     {
     258          210 :         return args_.get( id );
     259              :     }
     260              : 
     261              :     format_arg
     262           26 :     arg( core::string_view name ) const noexcept
     263              :     {
     264           26 :         return args_.get( name );
     265              :     }
     266              : 
     267              :     char*
     268          939 :     out()
     269              :     {
     270          939 :         return out_;
     271              :     }
     272              : 
     273              :     void
     274          939 :     advance_to( char* it )
     275              :     {
     276          939 :         out_ = it;
     277          939 :     }
     278              : };
     279              : 
     280              : // define the measure_context after format_args
     281              : class measure_context
     282              : {
     283              :     format_args args_;
     284              :     std::size_t out_;
     285              : 
     286              : public:
     287          140 :     measure_context(
     288              :         format_args args )
     289          140 :         : measure_context(0, args)
     290          140 :     {}
     291              : 
     292          140 :     measure_context(
     293              :         std::size_t out,
     294              :         format_args args )
     295          140 :         : args_( args )
     296          140 :         , out_( out )
     297          140 :     {}
     298              : 
     299              :     format_args
     300           14 :     args() const noexcept
     301              :     {
     302           14 :         return args_;
     303              :     }
     304              : 
     305              :     format_arg
     306          214 :     arg( std::size_t id ) const noexcept
     307              :     {
     308          214 :         return args_.get( id );
     309              :     }
     310              : 
     311              :     format_arg
     312           26 :     arg( core::string_view name ) const noexcept
     313              :     {
     314           26 :         return args_.get( name );
     315              :     }
     316              : 
     317              :     std::size_t
     318          953 :     out()
     319              :     {
     320          953 :         return out_;
     321              :     }
     322              : 
     323              :     void
     324          953 :     advance_to( std::size_t n )
     325              :     {
     326          953 :         out_ = n;
     327          953 :     }
     328              : };
     329              : 
     330              : // fwd declare the formatter
     331              : template <class T, class = void>
     332              : struct formatter;
     333              : 
     334              : } // detail
     335              : namespace see_below {
     336              : using format_arg = detail::format_arg;
     337              : }
     338              : namespace implementation_defined {
     339              : template <class T>
     340              : using named_arg = detail::named_arg<T>;
     341              : }
     342              : } // url
     343              : } // boost
     344              : 
     345              : 
     346              : #include <boost/url/detail/impl/format_args.hpp>
     347              : 
     348              : #endif
        

Generated by: LCOV version 2.1