File indexing completed on 2025-11-30 10:07:04
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