119 for (
size_t i = 0; i < params.size(); i++) {
120 auto key = ada::unicode::percent_encode(params[i].first, character_set);
121 auto value = ada::unicode::percent_encode(params[i].second, character_set);
124 std::ranges::replace(key,
' ',
'+');
125 std::ranges::replace(value,
' ',
'+');
138 const std::string_view value) {
139 const auto find = [&key](
const auto ¶m) {
return param.first == key; };
141 auto it = std::ranges::find_if(params, find);
143 if (it == params.end()) {
144 params.emplace_back(key, value);
147 params.erase(std::remove_if(std::next(it), params.end(), find),
167 std::ranges::stable_sort(params, [](
const key_value_pair &lhs,
168 const key_value_pair &rhs) {
170 uint32_t low_surrogate1 = 0, low_surrogate2 = 0;
171 while ((i < lhs.first.size() || low_surrogate1 != 0) &&
172 (j < rhs.first.size() || low_surrogate2 != 0)) {
173 uint32_t codePoint1 = 0, codePoint2 = 0;
175 if (low_surrogate1 != 0) {
176 codePoint1 = low_surrogate1;
179 uint8_t c1 = uint8_t(lhs.first[i]);
180 if (c1 > 0x7F && c1 <= 0xDF && i + 1 < lhs.first.size()) {
181 codePoint1 = ((c1 & 0x1F) << 6) | (uint8_t(lhs.first[i + 1]) & 0x3F);
183 }
else if (c1 > 0xDF && c1 <= 0xEF && i + 2 < lhs.first.size()) {
184 codePoint1 = ((c1 & 0x0F) << 12) |
185 ((uint8_t(lhs.first[i + 1]) & 0x3F) << 6) |
186 (uint8_t(lhs.first[i + 2]) & 0x3F);
188 }
else if (c1 > 0xEF && c1 <= 0xF7 && i + 3 < lhs.first.size()) {
189 codePoint1 = ((c1 & 0x07) << 18) |
190 ((uint8_t(lhs.first[i + 1]) & 0x3F) << 12) |
191 ((uint8_t(lhs.first[i + 2]) & 0x3F) << 6) |
192 (uint8_t(lhs.first[i + 3]) & 0x3F);
195 codePoint1 -= 0x10000;
196 uint16_t high_surrogate = uint16_t(0xD800 + (codePoint1 >> 10));
197 low_surrogate1 = uint16_t(0xDC00 + (codePoint1 & 0x3FF));
198 codePoint1 = high_surrogate;
206 if (low_surrogate2 != 0) {
207 codePoint2 = low_surrogate2;
210 uint8_t c2 = uint8_t(rhs.first[j]);
211 if (c2 > 0x7F && c2 <= 0xDF && j + 1 < rhs.first.size()) {
212 codePoint2 = ((c2 & 0x1F) << 6) | (uint8_t(rhs.first[j + 1]) & 0x3F);
214 }
else if (c2 > 0xDF && c2 <= 0xEF && j + 2 < rhs.first.size()) {
215 codePoint2 = ((c2 & 0x0F) << 12) |
216 ((uint8_t(rhs.first[j + 1]) & 0x3F) << 6) |
217 (uint8_t(rhs.first[j + 2]) & 0x3F);
219 }
else if (c2 > 0xEF && c2 <= 0xF7 && j + 3 < rhs.first.size()) {
220 codePoint2 = ((c2 & 0x07) << 18) |
221 ((uint8_t(rhs.first[j + 1]) & 0x3F) << 12) |
222 ((uint8_t(rhs.first[j + 2]) & 0x3F) << 6) |
223 (uint8_t(rhs.first[j + 3]) & 0x3F);
225 codePoint2 -= 0x10000;
226 uint16_t high_surrogate = uint16_t(0xD800 + (codePoint2 >> 10));
227 low_surrogate2 = uint16_t(0xDC00 + (codePoint2 & 0x3FF));
228 codePoint2 = high_surrogate;
236 if (codePoint1 != codePoint2) {
237 return (codePoint1 < codePoint2);
240 return (j < rhs.first.size() || low_surrogate2 != 0);