LCOV - code coverage report
Current view: top level - boost/url/grammar - string_token.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 41 42 97.6 %
Date: 2024-04-08 19:38:36 Functions: 16 17 94.1 %

          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        3368 :     virtual ~arg() = default;
      72        3368 :     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        3027 :     prepare(std::size_t n) override
     124             :     {
     125        3027 :         s_.resize(n);
     126        3027 :         return &s_[0];
     127             :     }
     128             : 
     129             :     result_type
     130        3027 :     result() noexcept
     131             :     {
     132        3027 :         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           2 :     append_to_t(
     167             :         string_type& s) noexcept
     168           2 :         : s_(s)
     169             :     {
     170           2 :     }
     171             : 
     172             :     char*
     173           2 :     prepare(std::size_t n) override
     174             :     {
     175           2 :         std::size_t n0 = s_.size();
     176           2 :         if(n > s_.max_size() - n0)
     177           0 :             urls::detail::throw_length_error();
     178           2 :         s_.resize(n0 + n);
     179           2 :         return &s_[n0];
     180             :     }
     181             : 
     182             :     result_type
     183           2 :     result() noexcept
     184             :     {
     185           2 :         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           2 : append_to(
     197             :     std::basic_string<
     198             :         char,
     199             :         std::char_traits<char>,
     200             :         Alloc>& s)
     201             : {
     202           2 :     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         336 :     assign_to_t(
     233             :         string_type& s) noexcept
     234         336 :         : s_(s)
     235             :     {
     236         336 :     }
     237             : 
     238             :     char*
     239         336 :     prepare(std::size_t n) override
     240             :     {
     241         336 :         s_.resize(n);
     242         336 :         return &s_[0];
     243             :     }
     244             : 
     245             :     result_type
     246         336 :     result() noexcept
     247             :     {
     248         336 :         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         336 : assign_to(
     260             :     std::basic_string<
     261             :         char,
     262             :         std::char_traits<char>,
     263             :         Alloc>& s)
     264             : {
     265         336 :     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           3 :     preserve_size_t(
     296             :         string_type& s) noexcept
     297           3 :         : s_(s)
     298             :     {
     299           3 :     }
     300             : 
     301             :     char*
     302           3 :     prepare(std::size_t n) override
     303             :     {
     304           3 :         n_ = n;
     305             :         // preserve size() to
     306             :         // avoid value-init
     307           3 :         if(s_.size() < n)
     308           2 :             s_.resize(n);
     309           3 :         return &s_[0];
     310             :     }
     311             : 
     312             :     result_type
     313           3 :     result() noexcept
     314             :     {
     315             :         return core::string_view(
     316           3 :             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           3 : preserve_size(
     329             :     std::basic_string<
     330             :         char,
     331             :         std::char_traits<char>,
     332             :         Alloc>& s)
     333             : {
     334           3 :     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 1.15