| 10490 | } |
| 10491 | #if ADA_NEON |
| 10492 | ada_really_inline bool has_tabs_or_newline( |
| 10493 | std::string_view user_input) noexcept { |
| 10494 | // first check for short strings in which case we do it naively. |
| 10495 | if (user_input.size() < 16) { // slow path |
| 10496 | return std::ranges::any_of(user_input, is_tabs_or_newline); |
| 10497 | } |
| 10498 | // fast path for long strings (expected to be common) |
| 10499 | size_t i = 0; |
| 10500 | /** |
| 10501 | * The fastest way to check for `\t` (==9), '\n'(== 10) and `\r` (==13) relies |
| 10502 | * on table lookup instruction. We notice that these are all unique numbers |
| 10503 | * between 0..15. Let's prepare a special register, where we put '\t' in the |
| 10504 | * 9th position, '\n' - 10th and '\r' - 13th. Then we shuffle this register by |
| 10505 | * input register. If the input had `\t` in position X then this shuffled |
| 10506 | * register will also have '\t' in that position. Comparing input with this |
| 10507 | * shuffled register will mark us all interesting characters in the input. |
| 10508 | * |
| 10509 | * credit for algorithmic idea: @aqrit, credit for description: |
| 10510 | * @DenisYaroshevskiy |
| 10511 | */ |
| 10512 | static uint8_t rnt_array[16] = {1, 0, 0, 0, 0, 0, 0, 0, |
| 10513 | 0, 9, 10, 0, 0, 13, 0, 0}; |
| 10514 | const uint8x16_t rnt = vld1q_u8(rnt_array); |
| 10515 | // m['0xd', '0xa', '0x9'] |
| 10516 | uint8x16_t running{0}; |
| 10517 | for (; i + 15 < user_input.size(); i += 16) { |
| 10518 | uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i); |
| 10519 | |
| 10520 | running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word)); |
| 10521 | } |
| 10522 | if (i < user_input.size()) { |
| 10523 | uint8x16_t word = |
| 10524 | vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16); |
| 10525 | running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word)); |
| 10526 | } |
| 10527 | return vmaxvq_u32(vreinterpretq_u32_u8(running)) != 0; |
| 10528 | } |
| 10529 | #elif ADA_SSE2 |
| 10530 | ada_really_inline bool has_tabs_or_newline( |
| 10531 | std::string_view user_input) noexcept { |
no test coverage detected