File indexing completed on 2025-10-31 08:57:57
0001 
0002 
0003 
0004 
0005 
0006 
0007 
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 
0024 
0025 
0026 
0027 
0028 
0029 
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
0044 
0045 
0046 
0047 
0048 
0049 
0050 
0051 struct arg
0052 {
0053     
0054 
0055 
0056 
0057 
0058 
0059 
0060 
0061 
0062 
0063 
0064 
0065 
0066 
0067 
0068 
0069 
0070 
0071 
0072 
0073     virtual char* prepare(std::size_t n) = 0;
0074 
0075     
0076     virtual ~arg() = default;
0077 
0078     
0079     arg() = default;
0080 
0081     
0082     arg(arg&&) = default;
0083 
0084     
0085     arg(arg const&) = delete;
0086 
0087     
0088     arg& operator=(arg&&) = delete;
0089 
0090     
0091     arg& operator=(arg const&) = delete;
0092 };
0093 
0094 
0095 
0096 namespace implementation_defined {
0097 template<class T, class = void>
0098 struct is_token : std::false_type {};
0099 
0100 template<class T>
0101 struct is_token<T, void_t<
0102     decltype(std::declval<T&>().prepare(
0103         std::declval<std::size_t>())),
0104     decltype(std::declval<T&>().result())
0105     > > : std::integral_constant<bool,
0106         std::is_convertible<decltype(
0107             std::declval<T&>().result()),
0108             typename T::result_type>::value &&
0109         std::is_same<decltype(
0110             std::declval<T&>().prepare(0)),
0111             char*>::value &&
0112         std::is_base_of<arg, T>::value &&
0113         std::is_convertible<T const volatile*,
0114             arg const volatile*>::value
0115     >
0116 {
0117 };
0118 } 
0119 
0120 
0121 
0122 
0123 
0124 
0125 
0126 
0127 
0128 
0129 
0130 template<class T>
0131 using is_token = implementation_defined::is_token<T>;
0132 
0133 #ifdef BOOST_URL_HAS_CONCEPTS
0134 
0135 
0136 
0137 
0138 
0139 
0140 
0141 
0142 
0143 
0144 
0145 
0146 
0147 
0148 
0149 
0150 
0151 
0152 
0153 
0154 
0155 
0156 
0157 
0158 
0159 
0160 
0161 
0162 
0163 
0164 
0165 
0166 
0167 
0168 
0169 
0170 
0171 
0172 
0173 
0174 
0175 
0176 
0177 
0178 
0179 
0180 
0181 
0182 
0183 
0184 
0185 
0186 
0187 
0188 
0189 
0190 
0191 
0192 
0193 
0194 
0195 
0196 
0197 
0198 
0199 
0200 
0201 
0202 
0203 
0204 
0205 
0206 
0207 
0208 
0209 
0210 
0211 
0212 
0213 
0214 
0215 
0216 
0217 
0218 
0219 
0220 
0221 
0222 
0223 
0224 
0225 
0226 
0227 
0228 
0229 
0230 
0231 template <class T>
0232 concept StringToken =
0233     std::derived_from<T, string_token::arg> &&
0234     requires (T t, std::size_t n)
0235 {
0236     typename T::result_type;
0237     { t.prepare(n) } -> std::same_as<char*>;
0238     { t.result() } -> std::convertible_to<typename T::result_type>;
0239 };
0240 #endif
0241 
0242 
0243 
0244 namespace implementation_defined {
0245 struct return_string
0246     : arg
0247 {
0248     using result_type = std::string;
0249 
0250     char*
0251     prepare(std::size_t n) override
0252     {
0253         s_.resize(n);
0254         return &s_[0];
0255     }
0256 
0257     result_type
0258     result() noexcept
0259     {
0260         return std::move(s_);
0261     }
0262 
0263 private:
0264     result_type s_;
0265 };
0266 } 
0267 
0268 
0269 
0270 
0271 
0272 
0273 
0274 
0275 
0276 
0277 using return_string = implementation_defined::return_string;
0278 
0279 
0280 
0281 namespace implementation_defined {
0282 template<class Alloc>
0283 struct append_to_t
0284     : arg
0285 {
0286     using string_type = std::basic_string<
0287         char, std::char_traits<char>,
0288             Alloc>;
0289 
0290     using result_type = string_type&;
0291 
0292     explicit
0293     append_to_t(
0294         string_type& s) noexcept
0295         : s_(s)
0296     {
0297     }
0298 
0299     char*
0300     prepare(std::size_t n) override
0301     {
0302         std::size_t n0 = s_.size();
0303         if(n > s_.max_size() - n0)
0304             urls::detail::throw_length_error();
0305         s_.resize(n0 + n);
0306         return &s_[n0];
0307     }
0308 
0309     result_type
0310     result() noexcept
0311     {
0312         return s_;
0313     }
0314 
0315 private:
0316     string_type& s_;
0317 };
0318 } 
0319 
0320 
0321 
0322 
0323 
0324 
0325 
0326 
0327 
0328 
0329 
0330 
0331 
0332 template<
0333     class Alloc =
0334         std::allocator<char>>
0335 implementation_defined::append_to_t<Alloc>
0336 append_to(
0337     std::basic_string<
0338         char,
0339         std::char_traits<char>,
0340         Alloc>& s)
0341 {
0342     return implementation_defined::append_to_t<Alloc>(s);
0343 }
0344 
0345 
0346 
0347 namespace implementation_defined {
0348 template<class Alloc>
0349 struct assign_to_t
0350     : arg
0351 {
0352     using string_type = std::basic_string<
0353         char, std::char_traits<char>,
0354             Alloc>;
0355 
0356     using result_type = string_type&;
0357 
0358     explicit
0359     assign_to_t(
0360         string_type& s) noexcept
0361         : s_(s)
0362     {
0363     }
0364 
0365     char*
0366     prepare(std::size_t n) override
0367     {
0368         s_.resize(n);
0369         return &s_[0];
0370     }
0371 
0372     result_type
0373     result() noexcept
0374     {
0375         return s_;
0376     }
0377 
0378 private:
0379     string_type& s_;
0380 };
0381 } 
0382 
0383 
0384 
0385 
0386 
0387 
0388 
0389 
0390 
0391 
0392 
0393 
0394 
0395 template<
0396     class Alloc =
0397         std::allocator<char>>
0398 implementation_defined::assign_to_t<Alloc>
0399 assign_to(
0400     std::basic_string<
0401         char,
0402         std::char_traits<char>,
0403         Alloc>& s)
0404 {
0405     return implementation_defined::assign_to_t<Alloc>(s);
0406 }
0407 
0408 
0409 
0410 namespace implementation_defined {
0411 template<class Alloc>
0412 struct preserve_size_t
0413     : arg
0414 {
0415     using result_type = core::string_view;
0416 
0417     using string_type = std::basic_string<
0418         char, std::char_traits<char>,
0419             Alloc>;
0420 
0421     explicit
0422     preserve_size_t(
0423         string_type& s) noexcept
0424         : s_(s)
0425     {
0426     }
0427 
0428     char*
0429     prepare(std::size_t n) override
0430     {
0431         n_ = n;
0432         
0433         
0434         if(s_.size() < n)
0435             s_.resize(n);
0436         return &s_[0];
0437     }
0438 
0439     result_type
0440     result() noexcept
0441     {
0442         return core::string_view(
0443             s_.data(), n_);
0444     }
0445 
0446 private:
0447     string_type& s_;
0448     std::size_t n_ = 0;
0449 };
0450 } 
0451 
0452 
0453 
0454 
0455 
0456 
0457 
0458 
0459 
0460 
0461 
0462 
0463 
0464 template<
0465     class Alloc =
0466         std::allocator<char>>
0467 implementation_defined::preserve_size_t<Alloc>
0468 preserve_size(
0469     std::basic_string<
0470         char,
0471         std::char_traits<char>,
0472         Alloc>& s)
0473 {
0474     return implementation_defined::preserve_size_t<Alloc>(s);
0475 }
0476 } 
0477 
0478 namespace grammar {
0479 namespace string_token = ::boost::urls::string_token;
0480 } 
0481 
0482 } 
0483 } 
0484 
0485 #endif