File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_GRAMMAR_RANGE_RULE_HPP
0011 #define BOOST_URL_GRAMMAR_RANGE_RULE_HPP
0012
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/url/error.hpp>
0015 #include <boost/core/detail/string_view.hpp>
0016 #include <boost/url/grammar/parse.hpp>
0017 #include <boost/url/grammar/type_traits.hpp>
0018 #include <boost/static_assert.hpp>
0019 #include <cstddef>
0020 #include <iterator>
0021 #include <type_traits>
0022
0023 #include <stddef.h> // ::max_align_t
0024
0025 namespace boost {
0026 namespace urls {
0027 namespace grammar {
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template<class T>
0060 class range
0061 {
0062
0063 static constexpr
0064 std::size_t BufferSize = 128;
0065
0066 struct small_buffer
0067 {
0068 alignas(alignof(::max_align_t))
0069 unsigned char buf[BufferSize];
0070
0071 void const* addr() const noexcept
0072 {
0073 return buf;
0074 }
0075
0076 void* addr() noexcept
0077 {
0078 return buf;
0079 }
0080 };
0081
0082 small_buffer sb_;
0083 core::string_view s_;
0084 std::size_t n_ = 0;
0085
0086
0087
0088 struct any_rule;
0089
0090 template<class R, bool>
0091 struct impl1;
0092
0093 template<
0094 class R0, class R1, bool>
0095 struct impl2;
0096
0097 template<
0098 class R0, class R1>
0099 friend struct range_rule_t;
0100
0101 any_rule&
0102 get() noexcept
0103 {
0104 return *reinterpret_cast<
0105 any_rule*>(sb_.addr());
0106 }
0107
0108 any_rule const&
0109 get() const noexcept
0110 {
0111 return *reinterpret_cast<
0112 any_rule const*>(
0113 sb_.addr());
0114 }
0115
0116 template<class R>
0117 range(
0118 core::string_view s,
0119 std::size_t n,
0120 R const& r);
0121
0122 template<
0123 class R0, class R1>
0124 range(
0125 core::string_view s,
0126 std::size_t n,
0127 R0 const& first,
0128 R1 const& next);
0129
0130 public:
0131
0132
0133 using value_type = T;
0134
0135
0136
0137 using reference = T const&;
0138
0139
0140
0141 using const_reference = T const&;
0142
0143
0144
0145 using pointer = void const*;
0146
0147
0148
0149 using size_type = std::size_t;
0150
0151
0152
0153 using difference_type = std::ptrdiff_t;
0154
0155
0156
0157 class iterator;
0158
0159
0160
0161 using const_iterator = iterator;
0162
0163
0164
0165 ~range();
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 range() noexcept;
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 range(range&&) noexcept;
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 range(range const&) noexcept;
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 range&
0222 operator=(range&&) noexcept;
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 range&
0238 operator=(range const&) noexcept;
0239
0240
0241
0242 iterator begin() const noexcept;
0243
0244
0245
0246 iterator end() const noexcept;
0247
0248
0249
0250 bool
0251 empty() const noexcept
0252 {
0253 return n_ == 0;
0254 }
0255
0256
0257
0258 std::size_t
0259 size() const noexcept
0260 {
0261 return n_;
0262 }
0263
0264
0265
0266 core::string_view
0267 string() const noexcept
0268 {
0269 return s_;
0270 }
0271 };
0272
0273
0274
0275 #ifndef BOOST_URL_DOCS
0276 template<
0277 class R0,
0278 class R1 = void>
0279 struct range_rule_t;
0280 #endif
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 #ifdef BOOST_URL_DOCS
0349 template<class Rule>
0350 constexpr
0351 __implementation_defined__
0352 range_rule(
0353 Rule next,
0354 std::size_t N = 0,
0355 std::size_t M =
0356 std::size_t(-1)) noexcept;
0357 #else
0358 template<class R>
0359 struct range_rule_t<R>
0360 {
0361 using value_type =
0362 range<typename R::value_type>;
0363
0364 system::result<value_type>
0365 parse(
0366 char const*& it,
0367 char const* end) const;
0368
0369 private:
0370 constexpr
0371 range_rule_t(
0372 R const& next,
0373 std::size_t N,
0374 std::size_t M) noexcept
0375 : next_(next)
0376 , N_(N)
0377 , M_(M)
0378 {
0379 }
0380
0381 template<class R_>
0382 friend
0383 constexpr
0384 range_rule_t<R_>
0385 range_rule(
0386 R_ const& next,
0387 std::size_t N,
0388 std::size_t M) noexcept;
0389
0390 R const next_;
0391 std::size_t N_;
0392 std::size_t M_;
0393 };
0394
0395 template<class Rule>
0396 constexpr
0397 range_rule_t<Rule>
0398 range_rule(
0399 Rule const& next,
0400 std::size_t N = 0,
0401 std::size_t M =
0402 std::size_t(-1)) noexcept
0403 {
0404
0405
0406
0407
0408 static_assert(
0409 is_rule<Rule>::value,
0410 "Rule requirements not met");
0411
0412 return range_rule_t<Rule>{
0413 next, N, M};
0414 }
0415 #endif
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 #ifdef BOOST_URL_DOCS
0492 template<
0493 class Rule1, class Rule2>
0494 constexpr
0495 __implementation_defined__
0496 range_rule(
0497 Rule1 first,
0498 Rule2 next,
0499 std::size_t N = 0,
0500 std::size_t M =
0501 std::size_t(-1)) noexcept;
0502 #else
0503 template<class R0, class R1>
0504 struct range_rule_t
0505 {
0506 using value_type =
0507 range<typename R0::value_type>;
0508
0509 system::result<value_type>
0510 parse(
0511 char const*& it,
0512 char const* end) const;
0513
0514 private:
0515 constexpr
0516 range_rule_t(
0517 R0 const& first,
0518 R1 const& next,
0519 std::size_t N,
0520 std::size_t M) noexcept
0521 : first_(first)
0522 , next_(next)
0523 , N_(N)
0524 , M_(M)
0525 {
0526 }
0527
0528 template<
0529 class R0_, class R1_>
0530 friend
0531 constexpr
0532 auto
0533 range_rule(
0534 R0_ const& first,
0535 R1_ const& next,
0536 std::size_t N,
0537 std::size_t M) noexcept ->
0538 #if 1
0539 typename std::enable_if<
0540 ! std::is_integral<R1_>::value,
0541 range_rule_t<R0_, R1_>>::type;
0542 #else
0543 range_rule_t<R0_, R1_>;
0544 #endif
0545
0546 R0 const first_;
0547 R1 const next_;
0548 std::size_t N_;
0549 std::size_t M_;
0550 };
0551
0552 template<
0553 class Rule1, class Rule2>
0554 constexpr
0555 auto
0556 range_rule(
0557 Rule1 const& first,
0558 Rule2 const& next,
0559 std::size_t N = 0,
0560 std::size_t M =
0561 std::size_t(-1)) noexcept ->
0562 #if 1
0563 typename std::enable_if<
0564 ! std::is_integral<Rule2>::value,
0565 range_rule_t<Rule1, Rule2>>::type
0566 #else
0567 range_rule_t<Rule1, Rule2>
0568 #endif
0569 {
0570
0571
0572
0573
0574 static_assert(
0575 is_rule<Rule1>::value,
0576 "Rule requirements not met");
0577 static_assert(
0578 is_rule<Rule2>::value,
0579 "Rule requirements not met");
0580
0581
0582
0583
0584
0585 static_assert(
0586 std::is_same<
0587 typename Rule1::value_type,
0588 typename Rule2::value_type>::value,
0589 "Rule requirements not met");
0590
0591 return range_rule_t<Rule1, Rule2>{
0592 first, next, N, M};
0593 }
0594 #endif
0595
0596 }
0597 }
0598 }
0599
0600 #include <boost/url/grammar/impl/range_rule.hpp>
0601
0602 #endif