simdutf 9.0.0
Unicode at GB/s.
Loading...
Searching...
No Matches
ascii.h
1#ifndef SIMDUTF_ASCII_H
2#define SIMDUTF_ASCII_H
3
4#include <cstring>
5
6namespace simdutf {
7namespace scalar {
8namespace {
9namespace ascii {
10
11template <class InputPtr>
12#if SIMDUTF_CPLUSPLUS20
13 requires simdutf::detail::indexes_into_byte_like<InputPtr>
14#endif
15simdutf_warn_unused simdutf_constexpr23 bool validate(InputPtr data,
16 size_t len) noexcept {
17 uint64_t pos = 0;
18
19#if SIMDUTF_CPLUSPLUS23
20 // avoid memcpy during constant evaluation
21 if !consteval
22#endif
23 // process in blocks of 16 bytes when possible
24 {
25 for (; pos + 16 <= len; pos += 16) {
26 uint64_t v1;
27 std::memcpy(&v1, data + pos, sizeof(uint64_t));
28 uint64_t v2;
29 std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
30 uint64_t v{v1 | v2};
31 if ((v & 0x8080808080808080) != 0) {
32 return false;
33 }
34 }
35 }
36
37 // process the tail byte-by-byte
38 for (; pos < len; pos++) {
39 if (static_cast<std::uint8_t>(data[pos]) >= 0b10000000) {
40 return false;
41 }
42 }
43 return true;
44}
45template <class InputPtr>
46#if SIMDUTF_CPLUSPLUS20
47 requires simdutf::detail::indexes_into_byte_like<InputPtr>
48#endif
49simdutf_warn_unused simdutf_constexpr23 result
50validate_with_errors(InputPtr data, size_t len) noexcept {
51 size_t pos = 0;
52#if SIMDUTF_CPLUSPLUS23
53 // avoid memcpy during constant evaluation
54 if !consteval
55#endif
56 {
57 // process in blocks of 16 bytes when possible
58 for (; pos + 16 <= len; pos += 16) {
59 uint64_t v1;
60 std::memcpy(&v1, data + pos, sizeof(uint64_t));
61 uint64_t v2;
62 std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
63 uint64_t v{v1 | v2};
64 if ((v & 0x8080808080808080) != 0) {
65 for (; pos < len; pos++) {
66 if (static_cast<std::uint8_t>(data[pos]) >= 0b10000000) {
67 return result(error_code::TOO_LARGE, pos);
68 }
69 }
70 }
71 }
72 }
73
74 // process the tail byte-by-byte
75 for (; pos < len; pos++) {
76 if (static_cast<std::uint8_t>(data[pos]) >= 0b10000000) {
77 return result(error_code::TOO_LARGE, pos);
78 }
79 }
80 return result(error_code::SUCCESS, pos);
81}
82
83} // namespace ascii
84} // unnamed namespace
85} // namespace scalar
86} // namespace simdutf
87
88#endif
helpers placed in namespace detail are not a part of the public API