62 static constexpr std::array<std::uint8_t, 256> SPECIAL_BYTES{{
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
80 constexpr std::uint64_t LOW_BITS{0x0101010101010101ULL};
81 constexpr std::uint64_t HIGH_BITS{0x8080808080808080ULL};
83 const auto size{input.size()};
86 std::size_t run_start{0};
87 std::size_t position{0};
88 while (position < size) {
90 if (size - position >= 8) {
91 std::uint64_t word{0};
92 std::memcpy(&word, input.data() + position, 8);
99 const auto quotations{word ^ (LOW_BITS *
'"')};
100 const auto apostrophes{(word | LOW_BITS) ^ (LOW_BITS *
'\'')};
101 const auto angles{(word | (LOW_BITS * 2U)) ^ (LOW_BITS *
'>')};
102 const auto leads{word ^ (LOW_BITS * 0xC2)};
103 const auto matches{((quotations - LOW_BITS) & ~quotations) |
104 ((apostrophes - LOW_BITS) & ~apostrophes) |
105 ((angles - LOW_BITS) & ~angles) |
106 ((leads - LOW_BITS) & ~leads)};
107 if ((
matches & HIGH_BITS) == 0) {
115 while (position < end) {
116 if (SPECIAL_BYTES[
static_cast<unsigned char>(input[position])] == 0) {
121 std::string_view replacement;
122 std::size_t consumed{1};
123 switch (input[position]) {
125 replacement =
"&";
128 replacement =
"<";
131 replacement =
">";
134 replacement =
""";
137 replacement =
"'";
142 if (
static_cast<unsigned char>(input[position]) == 0xC2 &&
143 position + 1 < size &&
144 static_cast<unsigned char>(input[position + 1]) == 0xA0) {
145 replacement =
" ";
152 if (replacement.empty()) {
157 output.append(input.substr(run_start, position - run_start));
158 output.append(replacement);
159 position += consumed;
160 run_start = position;
164 output.append(input.substr(run_start));