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-08-19 20:08:54 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              :     /// Virtual destructor
      71         3372 :     virtual ~arg() = default;
      72              : 
      73              :     /// Default constructor
      74         3372 :     arg() = default;
      75              : 
      76              :     /// Default move constructor
      77              :     arg(arg&&) = default;
      78              : 
      79              :     /// Deleted copy constructor
      80              :     arg(arg const&) = delete;
      81              : 
      82              :     /// Deleted move assignment
      83              :     arg& operator=(arg&&) = delete;
      84              : 
      85              :     /// Deleted copy assignment
      86              :     arg& operator=(arg const&) = delete;
      87              : };
      88              : 
      89              : //------------------------------------------------
      90              : 
      91              : /** Metafunction returning true if T is a StringToken
      92              : */
      93              : #ifdef BOOST_URL_DOCS
      94              : template<class T>
      95              : using is_token = __see_below__;
      96              : #else
      97              : namespace see_below {
      98              : /** Metafunction returning true if T is a StringToken
      99              :  */
     100              : template<class T, class = void>
     101              : struct is_token : std::false_type {};
     102              : 
     103              : /** Metafunction returning true if T is a StringToken
     104              :  */
     105              : template<class T>
     106              : struct is_token<T, void_t<
     107              :     decltype(std::declval<T&>().prepare(
     108              :         std::declval<std::size_t>())),
     109              :     decltype(std::declval<T&>().result())
     110              :     > > : std::integral_constant<bool,
     111              :         std::is_convertible<decltype(
     112              :             std::declval<T&>().result()),
     113              :             typename T::result_type>::value &&
     114              :         std::is_same<decltype(
     115              :             std::declval<T&>().prepare(0)),
     116              :             char*>::value &&
     117              :         std::is_base_of<arg, T>::value &&
     118              :         std::is_convertible<T const volatile*,
     119              :             arg const volatile*>::value
     120              :     >
     121              : {
     122              : };
     123              : } // see_below
     124              : 
     125              : /** Metafunction returning true if T is a StringToken
     126              :  */
     127              : template<class T>
     128              : using is_token = see_below::is_token<T>;
     129              : #endif
     130              : 
     131              : //------------------------------------------------
     132              : 
     133              : /** A token for returning a plain string
     134              : */
     135              : #ifdef BOOST_URL_DOCS
     136              : using return_string = __implementation_defined__;
     137              : #else
     138              : namespace implementation_defined {
     139              : struct return_string
     140              :     : arg
     141              : {
     142              :     using result_type = std::string;
     143              : 
     144              :     char*
     145         3028 :     prepare(std::size_t n) override
     146              :     {
     147         3028 :         s_.resize(n);
     148         3028 :         return &s_[0];
     149              :     }
     150              : 
     151              :     result_type
     152         3028 :     result() noexcept
     153              :     {
     154         3028 :         return std::move(s_);
     155              :     }
     156              : 
     157              : private:
     158              :     result_type s_;
     159              : };
     160              : } // implementation_defined
     161              : 
     162              : /** A token for returning a plain string
     163              :  */
     164              : using return_string = implementation_defined::return_string;
     165              : #endif
     166              : 
     167              : //------------------------------------------------
     168              : 
     169              : /** A token for appending to a plain string
     170              : */
     171              : #ifdef BOOST_URL_DOCS
     172              : template<
     173              :     class Allocator =
     174              :         std::allocator<char>>
     175              : __implementation_defined__
     176              : append_to(
     177              :     std::basic_string<
     178              :         char,
     179              :         std::char_traits<char>,
     180              :         Allocator>& s);
     181              : #else
     182              : namespace implementation_defined {
     183              : template<class Alloc>
     184              : struct append_to_t
     185              :     : arg
     186              : {
     187              :     using string_type = std::basic_string<
     188              :         char, std::char_traits<char>,
     189              :             Alloc>;
     190              : 
     191              :     using result_type = string_type&;
     192              : 
     193              :     explicit
     194            3 :     append_to_t(
     195              :         string_type& s) noexcept
     196            3 :         : s_(s)
     197              :     {
     198            3 :     }
     199              : 
     200              :     char*
     201            3 :     prepare(std::size_t n) override
     202              :     {
     203            3 :         std::size_t n0 = s_.size();
     204            3 :         if(n > s_.max_size() - n0)
     205            0 :             urls::detail::throw_length_error();
     206            3 :         s_.resize(n0 + n);
     207            3 :         return &s_[n0];
     208              :     }
     209              : 
     210              :     result_type
     211            3 :     result() noexcept
     212              :     {
     213            3 :         return s_;
     214              :     }
     215              : 
     216              : private:
     217              :     string_type& s_;
     218              : };
     219              : } // implementation_defined
     220              : 
     221              : /** Create a token for appending to a plain string
     222              :  */
     223              : template<
     224              :     class Alloc =
     225              :         std::allocator<char>>
     226              : implementation_defined::append_to_t<Alloc>
     227            3 : append_to(
     228              :     std::basic_string<
     229              :         char,
     230              :         std::char_traits<char>,
     231              :         Alloc>& s)
     232              : {
     233            3 :     return implementation_defined::append_to_t<Alloc>(s);
     234              : }
     235              : #endif
     236              : 
     237              : //------------------------------------------------
     238              : 
     239              : /** A token for assigning to a plain string
     240              : */
     241              : #ifdef BOOST_URL_DOCS
     242              : template<
     243              :     class Allocator =
     244              :         std::allocator<char>>
     245              : __implementation_defined__
     246              : assign_to(
     247              :     std::basic_string<
     248              :         char,
     249              :         std::char_traits<char>,
     250              :         Allocator>& s);
     251              : #else
     252              : namespace implementation_defined {
     253              : template<class Alloc>
     254              : struct assign_to_t
     255              :     : arg
     256              : {
     257              :     using string_type = std::basic_string<
     258              :         char, std::char_traits<char>,
     259              :             Alloc>;
     260              : 
     261              :     using result_type = string_type&;
     262              : 
     263              :     explicit
     264          337 :     assign_to_t(
     265              :         string_type& s) noexcept
     266          337 :         : s_(s)
     267              :     {
     268          337 :     }
     269              : 
     270              :     char*
     271          337 :     prepare(std::size_t n) override
     272              :     {
     273          337 :         s_.resize(n);
     274          337 :         return &s_[0];
     275              :     }
     276              : 
     277              :     result_type
     278          337 :     result() noexcept
     279              :     {
     280          337 :         return s_;
     281              :     }
     282              : 
     283              : private:
     284              :     string_type& s_;
     285              : };
     286              : } // implementation_defined
     287              : 
     288              : /** A token for assigning to a plain string
     289              :  */
     290              : template<
     291              :     class Alloc =
     292              :         std::allocator<char>>
     293              : implementation_defined::assign_to_t<Alloc>
     294          337 : assign_to(
     295              :     std::basic_string<
     296              :         char,
     297              :         std::char_traits<char>,
     298              :         Alloc>& s)
     299              : {
     300          337 :     return implementation_defined::assign_to_t<Alloc>(s);
     301              : }
     302              : #endif
     303              : 
     304              : //------------------------------------------------
     305              : 
     306              : /** A token for producing a durable core::string_view from a temporary string
     307              : */
     308              : #ifdef BOOST_URL_DOCS
     309              : template<
     310              :     class Allocator =
     311              :         std::allocator<char>>
     312              : __implementation_defined__
     313              : preserve_size(
     314              :     std::basic_string<
     315              :         char,
     316              :         std::char_traits<char>,
     317              :         Allocator>& s);
     318              : #else
     319              : namespace implementation_defined {
     320              : template<class Alloc>
     321              : struct preserve_size_t
     322              :     : arg
     323              : {
     324              :     using result_type = core::string_view;
     325              : 
     326              :     using string_type = std::basic_string<
     327              :         char, std::char_traits<char>,
     328              :             Alloc>;
     329              : 
     330              :     explicit
     331            4 :     preserve_size_t(
     332              :         string_type& s) noexcept
     333            4 :         : s_(s)
     334              :     {
     335            4 :     }
     336              : 
     337              :     char*
     338            4 :     prepare(std::size_t n) override
     339              :     {
     340            4 :         n_ = n;
     341              :         // preserve size() to
     342              :         // avoid value-init
     343            4 :         if(s_.size() < n)
     344            2 :             s_.resize(n);
     345            4 :         return &s_[0];
     346              :     }
     347              : 
     348              :     result_type
     349            4 :     result() noexcept
     350              :     {
     351            4 :         return core::string_view(
     352            8 :             s_.data(), n_);
     353              :     }
     354              : 
     355              : private:
     356              :     string_type& s_;
     357              :     std::size_t n_ = 0;
     358              : };
     359              : } // implementation_defined
     360              : 
     361              : /** A token for producing a durable core::string_view from a temporary string
     362              :  */
     363              : template<
     364              :     class Alloc =
     365              :         std::allocator<char>>
     366              : implementation_defined::preserve_size_t<Alloc>
     367            4 : preserve_size(
     368              :     std::basic_string<
     369              :         char,
     370              :         std::char_traits<char>,
     371              :         Alloc>& s)
     372              : {
     373            4 :     return implementation_defined::preserve_size_t<Alloc>(s);
     374              : }
     375              : #endif
     376              : 
     377              : } // string_token
     378              : 
     379              : namespace grammar {
     380              : namespace string_token = ::boost::urls::string_token;
     381              : } // grammar
     382              : 
     383              : } // urls
     384              : } // boost
     385              : 
     386              : #endif
        

Generated by: LCOV version 2.1