Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:28

0001 //
0002 // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_GRAMMAR_STRING_TOKEN_HPP
0011 #define BOOST_URL_GRAMMAR_STRING_TOKEN_HPP
0012 
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/core/detail/string_view.hpp>
0015 #include <boost/url/detail/except.hpp>
0016 #include <memory>
0017 #include <string>
0018 
0019 namespace boost {
0020 namespace urls {
0021 namespace string_token {
0022 
0023 /** Base class for string tokens, and algorithm parameters
0024 
0025     This abstract interface provides a means
0026     for an algorithm to generically obtain a
0027     modifiable, contiguous character buffer
0028     of prescribed size. As the author of an
0029     algorithm simply declare an rvalue
0030     reference as a parameter type.
0031 
0032     <br>
0033 
0034     Instances of this type are intended only
0035     to be used once and then destroyed.
0036 
0037     @par Example
0038     The declared function accepts any
0039     temporary instance of `arg` to be
0040     used for writing:
0041     @code
0042     void algorithm( string_token::arg&& dest );
0043     @endcode
0044 
0045     To implement the interface for your type
0046     or use-case, derive from the class and
0047     implement the prepare function.
0048 */
0049 struct arg
0050 {
0051     /** Return a modifiable character buffer
0052 
0053         This function attempts to obtain a
0054         character buffer with space for at
0055         least `n` characters. Upon success,
0056         a pointer to the beginning of the
0057         buffer is returned. Ownership is not
0058         transferred; the caller should not
0059         attempt to free the storage. The
0060         buffer shall remain valid until
0061         `this` is destroyed.
0062 
0063         @note
0064         This function may only be called once.
0065         After invoking the function, the only
0066         valid operation is destruction.
0067     */
0068     virtual char* prepare(std::size_t n) = 0;
0069 
0070     // prevent misuse
0071     virtual ~arg() = default;
0072     arg() = default;
0073     arg(arg&&) = default;
0074     arg(arg const&) = delete;
0075     arg& operator=(arg&&) = delete;
0076     arg& operator=(arg const&) = delete;
0077 };
0078 
0079 //------------------------------------------------
0080 
0081 /** Metafunction returning true if T is a StringToken
0082 */
0083 #ifdef BOOST_URL_DOCS
0084 template<class T>
0085 using is_token = __see_below__;
0086 #else
0087 template<class T, class = void>
0088 struct is_token : std::false_type {};
0089 
0090 template<class T>
0091 struct is_token<T, void_t<
0092     decltype(std::declval<T&>().prepare(
0093         std::declval<std::size_t>())),
0094     decltype(std::declval<T&>().result())
0095     > > : std::integral_constant<bool,
0096         std::is_convertible<decltype(
0097             std::declval<T&>().result()),
0098             typename T::result_type>::value &&
0099         std::is_same<decltype(
0100             std::declval<T&>().prepare(0)),
0101             char*>::value &&
0102         std::is_base_of<arg, T>::value &&
0103         std::is_convertible<T const volatile*,
0104             arg const volatile*>::value
0105     >
0106 {
0107 };
0108 #endif
0109 
0110 //------------------------------------------------
0111 
0112 /** A token for returning a plain string
0113 */
0114 #ifdef BOOST_URL_DOCS
0115 using return_string = __implementation_defined__;
0116 #else
0117 struct return_string
0118     : arg
0119 {
0120     using result_type = std::string;
0121 
0122     char*
0123     prepare(std::size_t n) override
0124     {
0125         s_.resize(n);
0126         return &s_[0];
0127     }
0128 
0129     result_type
0130     result() noexcept
0131     {
0132         return std::move(s_);
0133     }
0134 
0135 private:
0136     result_type s_;
0137 };
0138 #endif
0139 
0140 //------------------------------------------------
0141 
0142 /** A token for appending to a plain string
0143 */
0144 #ifdef BOOST_URL_DOCS
0145 template<
0146     class Allocator =
0147         std::allocator<char>>
0148 __implementation_defined__
0149 append_to(
0150     std::basic_string<
0151         char,
0152         std::char_traits<char>,
0153         Allocator>& s);
0154 #else
0155 template<class Alloc>
0156 struct append_to_t
0157     : arg
0158 {
0159     using string_type = std::basic_string<
0160         char, std::char_traits<char>,
0161             Alloc>;
0162 
0163     using result_type = string_type&;
0164 
0165     explicit
0166     append_to_t(
0167         string_type& s) noexcept
0168         : s_(s)
0169     {
0170     }
0171 
0172     char*
0173     prepare(std::size_t n) override
0174     {
0175         std::size_t n0 = s_.size();
0176         if(n > s_.max_size() - n0)
0177             urls::detail::throw_length_error();
0178         s_.resize(n0 + n);
0179         return &s_[n0];
0180     }
0181 
0182     result_type
0183     result() noexcept
0184     {
0185         return s_;
0186     }
0187 
0188 private:
0189     string_type& s_;
0190 };
0191 
0192 template<
0193     class Alloc =
0194         std::allocator<char>>
0195 append_to_t<Alloc>
0196 append_to(
0197     std::basic_string<
0198         char,
0199         std::char_traits<char>,
0200         Alloc>& s)
0201 {
0202     return append_to_t<Alloc>(s);
0203 }
0204 #endif
0205 
0206 //------------------------------------------------
0207 
0208 /** A token for assigning to a plain string
0209 */
0210 #ifdef BOOST_URL_DOCS
0211 template<
0212     class Allocator =
0213         std::allocator<char>>
0214 __implementation_defined__
0215 assign_to(
0216     std::basic_string<
0217         char,
0218         std::char_traits<char>,
0219         Allocator>& s);
0220 #else
0221 template<class Alloc>
0222 struct assign_to_t
0223     : arg
0224 {
0225     using string_type = std::basic_string<
0226         char, std::char_traits<char>,
0227             Alloc>;
0228 
0229     using result_type = string_type&;
0230 
0231     explicit
0232     assign_to_t(
0233         string_type& s) noexcept
0234         : s_(s)
0235     {
0236     }
0237 
0238     char*
0239     prepare(std::size_t n) override
0240     {
0241         s_.resize(n);
0242         return &s_[0];
0243     }
0244 
0245     result_type
0246     result() noexcept
0247     {
0248         return s_;
0249     }
0250 
0251 private:
0252     string_type& s_;
0253 };
0254 
0255 template<
0256     class Alloc =
0257         std::allocator<char>>
0258 assign_to_t<Alloc>
0259 assign_to(
0260     std::basic_string<
0261         char,
0262         std::char_traits<char>,
0263         Alloc>& s)
0264 {
0265     return assign_to_t<Alloc>(s);
0266 }
0267 #endif
0268 
0269 //------------------------------------------------
0270 
0271 /** A token for producing a durable core::string_view from a temporary string
0272 */
0273 #ifdef BOOST_URL_DOCS
0274 template<
0275     class Allocator =
0276         std::allocator<char>>
0277 __implementation_defined__
0278 preserve_size(
0279     std::basic_string<
0280         char,
0281         std::char_traits<char>,
0282         Allocator>& s);
0283 #else
0284 template<class Alloc>
0285 struct preserve_size_t
0286     : arg
0287 {
0288     using result_type = core::string_view;
0289 
0290     using string_type = std::basic_string<
0291         char, std::char_traits<char>,
0292             Alloc>;
0293 
0294     explicit
0295     preserve_size_t(
0296         string_type& s) noexcept
0297         : s_(s)
0298     {
0299     }
0300 
0301     char*
0302     prepare(std::size_t n) override
0303     {
0304         n_ = n;
0305         // preserve size() to
0306         // avoid value-init
0307         if(s_.size() < n)
0308             s_.resize(n);
0309         return &s_[0];
0310     }
0311 
0312     result_type
0313     result() noexcept
0314     {
0315         return core::string_view(
0316             s_.data(), n_);
0317     }
0318 
0319 private:
0320     string_type& s_;
0321     std::size_t n_ = 0;
0322 };
0323 
0324 template<
0325     class Alloc =
0326         std::allocator<char>>
0327 preserve_size_t<Alloc>
0328 preserve_size(
0329     std::basic_string<
0330         char,
0331         std::char_traits<char>,
0332         Alloc>& s)
0333 {
0334     return preserve_size_t<Alloc>(s);
0335 }
0336 #endif
0337 
0338 } // string_token
0339 
0340 namespace grammar {
0341 namespace string_token = ::boost::urls::string_token;
0342 } // grammar
0343 
0344 } // urls
0345 } // boost
0346 
0347 #endif