LCOV - code coverage report
Current view: top level - boost/url/grammar/string_token.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.7 % 43 42
Test Date: 2024-07-10 02:48:26 Functions: 94.1 % 17 16

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 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_STRING_TOKEN_HPP
      11              : #define BOOST_URL_GRAMMAR_STRING_TOKEN_HPP
      12              : 
      13              : #include <boost/url/detail/config.hpp>
      14              : #include <boost/core/detail/string_view.hpp>
      15              : #include <boost/url/detail/except.hpp>
      16              : #include <memory>
      17              : #include <string>
      18              : 
      19              : namespace boost {
      20              : namespace urls {
      21              : namespace string_token {
      22              : 
      23              : /** Base class for string tokens, and algorithm parameters
      24              : 
      25              :     This abstract interface provides a means
      26              :     for an algorithm to generically obtain a
      27              :     modifiable, contiguous character buffer
      28              :     of prescribed size. As the author of an
      29              :     algorithm simply declare an rvalue
      30              :     reference as a parameter type.
      31              : 
      32              :     <br>
      33              : 
      34              :     Instances of this type are intended only
      35              :     to be used once and then destroyed.
      36              : 
      37              :     @par Example
      38              :     The declared function accepts any
      39              :     temporary instance of `arg` to be
      40              :     used for writing:
      41              :     @code
      42              :     void algorithm( string_token::arg&& dest );
      43              :     @endcode
      44              : 
      45              :     To implement the interface for your type
      46              :     or use-case, derive from the class and
      47              :     implement the prepare function.
      48              : */
      49              : struct arg
      50              : {
      51              :     /** Return a modifiable character buffer
      52              : 
      53              :         This function attempts to obtain a
      54              :         character buffer with space for at
      55              :         least `n` characters. Upon success,
      56              :         a pointer to the beginning of the
      57              :         buffer is returned. Ownership is not
      58              :         transferred; the caller should not
      59              :         attempt to free the storage. The
      60              :         buffer shall remain valid until
      61              :         `this` is destroyed.
      62              : 
      63              :         @note
      64              :         This function may only be called once.
      65              :         After invoking the function, the only
      66              :         valid operation is destruction.
      67              :     */
      68              :     virtual char* prepare(std::size_t n) = 0;
      69              : 
      70              :     // prevent misuse
      71         3372 :     virtual ~arg() = default;
      72         3372 :     arg() = default;
      73              :     arg(arg&&) = default;
      74              :     arg(arg const&) = delete;
      75              :     arg& operator=(arg&&) = delete;
      76              :     arg& operator=(arg const&) = delete;
      77              : };
      78              : 
      79              : //------------------------------------------------
      80              : 
      81              : /** Metafunction returning true if T is a StringToken
      82              : */
      83              : #ifdef BOOST_URL_DOCS
      84              : template<class T>
      85              : using is_token = __see_below__;
      86              : #else
      87              : template<class T, class = void>
      88              : struct is_token : std::false_type {};
      89              : 
      90              : template<class T>
      91              : struct is_token<T, void_t<
      92              :     decltype(std::declval<T&>().prepare(
      93              :         std::declval<std::size_t>())),
      94              :     decltype(std::declval<T&>().result())
      95              :     > > : std::integral_constant<bool,
      96              :         std::is_convertible<decltype(
      97              :             std::declval<T&>().result()),
      98              :             typename T::result_type>::value &&
      99              :         std::is_same<decltype(
     100              :             std::declval<T&>().prepare(0)),
     101              :             char*>::value &&
     102              :         std::is_base_of<arg, T>::value &&
     103              :         std::is_convertible<T const volatile*,
     104              :             arg const volatile*>::value
     105              :     >
     106              : {
     107              : };
     108              : #endif
     109              : 
     110              : //------------------------------------------------
     111              : 
     112              : /** A token for returning a plain string
     113              : */
     114              : #ifdef BOOST_URL_DOCS
     115              : using return_string = __implementation_defined__;
     116              : #else
     117              : struct return_string
     118              :     : arg
     119              : {
     120              :     using result_type = std::string;
     121              : 
     122              :     char*
     123         3028 :     prepare(std::size_t n) override
     124              :     {
     125         3028 :         s_.resize(n);
     126         3028 :         return &s_[0];
     127              :     }
     128              : 
     129              :     result_type
     130         3028 :     result() noexcept
     131              :     {
     132         3028 :         return std::move(s_);
     133              :     }
     134              : 
     135              : private:
     136              :     result_type s_;
     137              : };
     138              : #endif
     139              : 
     140              : //------------------------------------------------
     141              : 
     142              : /** A token for appending to a plain string
     143              : */
     144              : #ifdef BOOST_URL_DOCS
     145              : template<
     146              :     class Allocator =
     147              :         std::allocator<char>>
     148              : __implementation_defined__
     149              : append_to(
     150              :     std::basic_string<
     151              :         char,
     152              :         std::char_traits<char>,
     153              :         Allocator>& s);
     154              : #else
     155              : template<class Alloc>
     156              : struct append_to_t
     157              :     : arg
     158              : {
     159              :     using string_type = std::basic_string<
     160              :         char, std::char_traits<char>,
     161              :             Alloc>;
     162              : 
     163              :     using result_type = string_type&;
     164              : 
     165              :     explicit
     166            3 :     append_to_t(
     167              :         string_type& s) noexcept
     168            3 :         : s_(s)
     169              :     {
     170            3 :     }
     171              : 
     172              :     char*
     173            3 :     prepare(std::size_t n) override
     174              :     {
     175            3 :         std::size_t n0 = s_.size();
     176            3 :         if(n > s_.max_size() - n0)
     177            0 :             urls::detail::throw_length_error();
     178            3 :         s_.resize(n0 + n);
     179            3 :         return &s_[n0];
     180              :     }
     181              : 
     182              :     result_type
     183            3 :     result() noexcept
     184              :     {
     185            3 :         return s_;
     186              :     }
     187              : 
     188              : private:
     189              :     string_type& s_;
     190              : };
     191              : 
     192              : template<
     193              :     class Alloc =
     194              :         std::allocator<char>>
     195              : append_to_t<Alloc>
     196            3 : append_to(
     197              :     std::basic_string<
     198              :         char,
     199              :         std::char_traits<char>,
     200              :         Alloc>& s)
     201              : {
     202            3 :     return append_to_t<Alloc>(s);
     203              : }
     204              : #endif
     205              : 
     206              : //------------------------------------------------
     207              : 
     208              : /** A token for assigning to a plain string
     209              : */
     210              : #ifdef BOOST_URL_DOCS
     211              : template<
     212              :     class Allocator =
     213              :         std::allocator<char>>
     214              : __implementation_defined__
     215              : assign_to(
     216              :     std::basic_string<
     217              :         char,
     218              :         std::char_traits<char>,
     219              :         Allocator>& s);
     220              : #else
     221              : template<class Alloc>
     222              : struct assign_to_t
     223              :     : arg
     224              : {
     225              :     using string_type = std::basic_string<
     226              :         char, std::char_traits<char>,
     227              :             Alloc>;
     228              : 
     229              :     using result_type = string_type&;
     230              : 
     231              :     explicit
     232          337 :     assign_to_t(
     233              :         string_type& s) noexcept
     234          337 :         : s_(s)
     235              :     {
     236          337 :     }
     237              : 
     238              :     char*
     239          337 :     prepare(std::size_t n) override
     240              :     {
     241          337 :         s_.resize(n);
     242          337 :         return &s_[0];
     243              :     }
     244              : 
     245              :     result_type
     246          337 :     result() noexcept
     247              :     {
     248          337 :         return s_;
     249              :     }
     250              : 
     251              : private:
     252              :     string_type& s_;
     253              : };
     254              : 
     255              : template<
     256              :     class Alloc =
     257              :         std::allocator<char>>
     258              : assign_to_t<Alloc>
     259          337 : assign_to(
     260              :     std::basic_string<
     261              :         char,
     262              :         std::char_traits<char>,
     263              :         Alloc>& s)
     264              : {
     265          337 :     return assign_to_t<Alloc>(s);
     266              : }
     267              : #endif
     268              : 
     269              : //------------------------------------------------
     270              : 
     271              : /** A token for producing a durable core::string_view from a temporary string
     272              : */
     273              : #ifdef BOOST_URL_DOCS
     274              : template<
     275              :     class Allocator =
     276              :         std::allocator<char>>
     277              : __implementation_defined__
     278              : preserve_size(
     279              :     std::basic_string<
     280              :         char,
     281              :         std::char_traits<char>,
     282              :         Allocator>& s);
     283              : #else
     284              : template<class Alloc>
     285              : struct preserve_size_t
     286              :     : arg
     287              : {
     288              :     using result_type = core::string_view;
     289              : 
     290              :     using string_type = std::basic_string<
     291              :         char, std::char_traits<char>,
     292              :             Alloc>;
     293              : 
     294              :     explicit
     295            4 :     preserve_size_t(
     296              :         string_type& s) noexcept
     297            4 :         : s_(s)
     298              :     {
     299            4 :     }
     300              : 
     301              :     char*
     302            4 :     prepare(std::size_t n) override
     303              :     {
     304            4 :         n_ = n;
     305              :         // preserve size() to
     306              :         // avoid value-init
     307            4 :         if(s_.size() < n)
     308            2 :             s_.resize(n);
     309            4 :         return &s_[0];
     310              :     }
     311              : 
     312              :     result_type
     313            4 :     result() noexcept
     314              :     {
     315            4 :         return core::string_view(
     316            8 :             s_.data(), n_);
     317              :     }
     318              : 
     319              : private:
     320              :     string_type& s_;
     321              :     std::size_t n_ = 0;
     322              : };
     323              : 
     324              : template<
     325              :     class Alloc =
     326              :         std::allocator<char>>
     327              : preserve_size_t<Alloc>
     328            4 : preserve_size(
     329              :     std::basic_string<
     330              :         char,
     331              :         std::char_traits<char>,
     332              :         Alloc>& s)
     333              : {
     334            4 :     return preserve_size_t<Alloc>(s);
     335              : }
     336              : #endif
     337              : 
     338              : } // string_token
     339              : 
     340              : namespace grammar {
     341              : namespace string_token = ::boost::urls::string_token;
     342              : } // grammar
     343              : 
     344              : } // urls
     345              : } // boost
     346              : 
     347              : #endif
        

Generated by: LCOV version 2.1