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