LCOV - code coverage report
Current view: top level - url/detail - format_args.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 88 88
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 103 103

           TLA  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 HIT         740 :     format_parse_context(
      37                 :         char const* first,
      38                 :         char const* last,
      39                 :         std::size_t arg_id = 0)
      40             740 :         : begin_( first )
      41             740 :         , end_( last )
      42             740 :         , arg_id_( arg_id )
      43             740 :     {}
      44                 : 
      45                 :     constexpr
      46             589 :     format_parse_context(
      47                 :         core::string_view fmt,
      48                 :         std::size_t arg_id = 0)
      49             589 :         : format_parse_context(
      50                 :             fmt.data(),
      51             589 :             fmt.data() + fmt.size(),
      52             589 :             arg_id )
      53             589 :     {}
      54                 : 
      55                 :     constexpr
      56                 :     char const*
      57            1723 :     begin() const noexcept
      58                 :     {
      59            1723 :         return begin_;
      60                 :     }
      61                 : 
      62                 :     constexpr
      63                 :     char const*
      64            1157 :     end() const noexcept
      65                 :     {
      66            1157 :         return end_;
      67                 :     }
      68                 : 
      69                 :     BOOST_CXX14_CONSTEXPR
      70                 :     void
      71            1134 :     advance_to( char const* it )
      72                 :     {
      73            1134 :         begin_ = it;
      74            1134 :     }
      75                 : 
      76                 :     std::size_t
      77            1011 :     next_arg_id()
      78                 :     {
      79            1011 :         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              21 :     named_arg(core::string_view n, T const& v)
      95              21 :         : name(n)
      96              21 :         , value(v)
      97              21 :     {}
      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             286 :     measure(
     158                 :         format_parse_context& pctx,
     159                 :         measure_context& mctx,
     160                 :         grammar::lut_chars const& cs)
     161                 :     {
     162             286 :         measure_( pctx, mctx, cs, arg_ );
     163             284 :     }
     164                 : 
     165                 :     void
     166             282 :     format(
     167                 :         format_parse_context& pctx,
     168                 :         format_context& fctx,
     169                 :         grammar::lut_chars const& cs )
     170                 :     {
     171             282 :         fmt_( pctx, fctx, cs, arg_ );
     172             282 :     }
     173                 : 
     174                 :     core::string_view
     175             224 :     name() const
     176                 :     {
     177             224 :         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             155 : make_format_args( Args&&... args )
     191                 : {
     192             155 :     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               6 :     format_args(
     203                 :         detail::format_arg const* first,
     204                 :         detail::format_arg const* last ) noexcept
     205               6 :         : p_(first)
     206               6 :         , n_(static_cast<std::size_t>(last - first))
     207               6 :     {}
     208                 : 
     209                 :     template < std::size_t N >
     210             155 :     format_args( std::array<format_arg, N> const& store ) noexcept
     211             155 :         : p_(store.data())
     212             155 :         , n_(store.size())
     213             155 :     {}
     214                 : 
     215                 :     format_arg
     216             500 :     get( std::size_t i ) const noexcept
     217                 :     {
     218             500 :         if (i < n_)
     219             496 :             return p_[i];
     220               4 :         return {};
     221                 :     }
     222                 : 
     223                 :     format_arg
     224              96 :     get( core::string_view name ) const noexcept
     225                 :     {
     226             226 :         for (std::size_t i = 0; i < n_; ++i)
     227                 :         {
     228             224 :             if (p_[i].name() == name)
     229              94 :                 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             151 :     format_context(
     243                 :         char* out,
     244                 :         format_args args )
     245             151 :         : args_( args )
     246             151 :         , out_( out )
     247             151 :     {}
     248                 : 
     249                 :     format_args
     250              14 :     args() const noexcept
     251                 :     {
     252              14 :         return args_;
     253                 :     }
     254                 : 
     255                 :     format_arg
     256             239 :     arg( std::size_t id ) const noexcept
     257                 :     {
     258             239 :         return args_.get( id );
     259                 :     }
     260                 : 
     261                 :     format_arg
     262              43 :     arg( core::string_view name ) const noexcept
     263                 :     {
     264              43 :         return args_.get( name );
     265                 :     }
     266                 : 
     267                 :     char*
     268            1119 :     out()
     269                 :     {
     270            1119 :         return out_;
     271                 :     }
     272                 : 
     273                 :     void
     274            1119 :     advance_to( char* it )
     275                 :     {
     276            1119 :         out_ = it;
     277            1119 :     }
     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             154 :     measure_context(
     288                 :         format_args args )
     289             154 :         : measure_context(0, args)
     290             154 :     {}
     291                 : 
     292             154 :     measure_context(
     293                 :         std::size_t out,
     294                 :         format_args args )
     295             154 :         : args_( args )
     296             154 :         , out_( out )
     297             154 :     {}
     298                 : 
     299                 :     format_args
     300              14 :     args() const noexcept
     301                 :     {
     302              14 :         return args_;
     303                 :     }
     304                 : 
     305                 :     format_arg
     306             243 :     arg( std::size_t id ) const noexcept
     307                 :     {
     308             243 :         return args_.get( id );
     309                 :     }
     310                 : 
     311                 :     format_arg
     312              43 :     arg( core::string_view name ) const noexcept
     313                 :     {
     314              43 :         return args_.get( name );
     315                 :     }
     316                 : 
     317                 :     std::size_t
     318            1133 :     out()
     319                 :     {
     320            1133 :         return out_;
     321                 :     }
     322                 : 
     323                 :     void
     324            1133 :     advance_to( std::size_t n )
     325                 :     {
     326            1133 :         out_ = n;
     327            1133 :     }
     328                 : };
     329                 : 
     330                 : // fwd declare the formatter
     331                 : template <class T, class = void>
     332                 : struct formatter;
     333                 : 
     334                 : } // detail
     335                 : } // url
     336                 : } // boost
     337                 : 
     338                 : #include <boost/url/detail/impl/format_args.hpp>
     339                 : 
     340                 : #endif
        

Generated by: LCOV version 2.3