| 313 | template <typename SequenceIterator, typename PatternIterator, |
| 314 | typename EqualTo = cx::equal_to<void>> |
| 315 | constexpr match_result<SequenceIterator, PatternIterator> match_set( |
| 316 | SequenceIterator s, SequenceIterator send, PatternIterator p, PatternIterator pend, |
| 317 | const cards<iterated_item_t<PatternIterator>>& c = cards<iterated_item_t<PatternIterator>>(), |
| 318 | const EqualTo& equal_to = EqualTo(), match_set_state state = match_set_state::open) |
| 319 | { |
| 320 | #if cfg_HAS_CONSTEXPR14 |
| 321 | |
| 322 | if (!c.set_enabled) |
| 323 | { |
| 324 | #if cfg_HAS_FULL_FEATURED_CONSTEXPR14 |
| 325 | throw std::invalid_argument("The use of sets is disabled"); |
| 326 | #else |
| 327 | return throw_invalid_argument(make_match_result(false, s, p), "The use of sets is disabled"); |
| 328 | #endif |
| 329 | } |
| 330 | |
| 331 | while (p != pend) |
| 332 | { |
| 333 | switch (state) |
| 334 | { |
| 335 | case match_set_state::open: |
| 336 | if (*p != c.set_open) |
| 337 | { |
| 338 | #if cfg_HAS_FULL_FEATURED_CONSTEXPR14 |
| 339 | throw std::invalid_argument("The given pattern is not a valid set"); |
| 340 | #else |
| 341 | return throw_invalid_argument(make_match_result(false, s, p), |
| 342 | "The given pattern is not a valid set"); |
| 343 | #endif |
| 344 | } |
| 345 | |
| 346 | state = match_set_state::not_or_first_in; |
| 347 | break; |
| 348 | |
| 349 | case match_set_state::not_or_first_in: |
| 350 | if (*p == c.set_not) |
| 351 | { |
| 352 | state = match_set_state::first_out; |
| 353 | } |
| 354 | else |
| 355 | { |
| 356 | if (s == send) |
| 357 | { |
| 358 | return make_match_result(false, s, p); |
| 359 | } |
| 360 | |
| 361 | if (equal_to(*s, *p)) |
| 362 | { |
| 363 | return make_match_result(true, s, p); |
| 364 | } |
| 365 | |
| 366 | state = match_set_state::next_in; |
| 367 | } |
| 368 | |
| 369 | break; |
| 370 | |
| 371 | case match_set_state::first_out: |
| 372 | if (s == send || equal_to(*s, *p)) |
no test coverage detected