5#ifndef ADA_URL_SEARCH_PARAMS_INL_H 
    6#define ADA_URL_SEARCH_PARAMS_INL_H 
   22template <
typename T, ada::url_search_params_iter_type Type>
 
   25inline void url_search_params::reset(std::string_view input) {
 
   30inline void url_search_params::initialize(std::string_view input) {
 
   31  if (!input.empty() && input.front() == 
'?') {
 
   32    input.remove_prefix(1);
 
   35  auto process_key_value = [&](
const std::string_view current) {
 
   36    auto equal = current.find(
'=');
 
   38    if (equal == std::string_view::npos) {
 
   39      std::string name(current);
 
   40      std::ranges::replace(name, 
'+', 
' ');
 
   41      params.emplace_back(unicode::percent_decode(name, name.find(
'%')), 
"");
 
   43      std::string name(current.substr(0, equal));
 
   44      std::string value(current.substr(equal + 1));
 
   46      std::ranges::replace(name, 
'+', 
' ');
 
   47      std::ranges::replace(value, 
'+', 
' ');
 
   49      params.emplace_back(unicode::percent_decode(name, name.find(
'%')),
 
   50                          unicode::percent_decode(value, value.find(
'%')));
 
   54  while (!input.empty()) {
 
   55    auto ampersand_index = input.find(
'&');
 
   57    if (ampersand_index == std::string_view::npos) {
 
   59        process_key_value(input);
 
   62    } 
else if (ampersand_index != 0) {
 
   63      process_key_value(input.substr(0, ampersand_index));
 
   66    input.remove_prefix(ampersand_index + 1);
 
   71                                      const std::string_view value) {
 
   72  params.emplace_back(key, value);
 
 
   78    const std::string_view key) {
 
   79  auto entry = std::ranges::find_if(
 
   80      params, [&key](
const auto ¶m) { 
return param.first == key; });
 
   82  if (entry == params.end()) {
 
 
   90    const std::string_view key) {
 
   91  std::vector<std::string> out{};
 
   93  for (
auto ¶m : params) {
 
   94    if (param.first == key) {
 
   95      out.emplace_back(param.second);
 
 
  103  auto entry = std::ranges::find_if(
 
  104      params, [&key](
const auto ¶m) { 
return param.first == key; });
 
  105  return entry != params.end();
 
 
  109                                   std::string_view value) 
noexcept {
 
  110  auto entry = std::ranges::find_if(params, [&key, &value](
const auto ¶m) {
 
  111    return param.first == key && param.second == value;
 
  113  return entry != params.end();
 
 
  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),
 
 
  153  std::erase_if(params,
 
  154                [&key](
const auto ¶m) { 
return param.first == key; });
 
 
  158                                      const std::string_view value) {
 
  159  std::erase_if(params, [&key, &value](
const auto ¶m) {
 
  160    return param.first == key && param.second == value;
 
 
  166  std::ranges::stable_sort(params, [](
const key_value_pair &lhs,
 
  167                                      const key_value_pair &rhs) {
 
  169    uint32_t low_surrogate1 = 0, low_surrogate2 = 0;
 
  170    while ((i < lhs.first.size() || low_surrogate1 != 0) &&
 
  171           (j < rhs.first.size() || low_surrogate2 != 0)) {
 
  172      uint32_t codePoint1 = 0, codePoint2 = 0;
 
  174      if (low_surrogate1 != 0) {
 
  175        codePoint1 = low_surrogate1;
 
  178        uint8_t c1 = uint8_t(lhs.first[i]);
 
  182        } 
else if (c1 <= 0xDF) {
 
  183          codePoint1 = ((c1 & 0x1F) << 6) | (uint8_t(lhs.first[i + 1]) & 0x3F);
 
  185        } 
else if (c1 <= 0xEF) {
 
  186          codePoint1 = ((c1 & 0x0F) << 12) |
 
  187                       ((uint8_t(lhs.first[i + 1]) & 0x3F) << 6) |
 
  188                       (uint8_t(lhs.first[i + 2]) & 0x3F);
 
  191          codePoint1 = ((c1 & 0x07) << 18) |
 
  192                       ((uint8_t(lhs.first[i + 1]) & 0x3F) << 12) |
 
  193                       ((uint8_t(lhs.first[i + 2]) & 0x3F) << 6) |
 
  194                       (uint8_t(lhs.first[i + 3]) & 0x3F);
 
  197          codePoint1 -= 0x10000;
 
  198          uint16_t high_surrogate = uint16_t(0xD800 + (codePoint1 >> 10));
 
  199          low_surrogate1 = uint16_t(0xDC00 + (codePoint1 & 0x3FF));
 
  200          codePoint1 = high_surrogate;
 
  204      if (low_surrogate2 != 0) {
 
  205        codePoint2 = low_surrogate2;
 
  208        uint8_t c2 = uint8_t(rhs.first[j]);
 
  212        } 
else if (c2 <= 0xDF) {
 
  213          codePoint2 = ((c2 & 0x1F) << 6) | (uint8_t(rhs.first[j + 1]) & 0x3F);
 
  215        } 
else if (c2 <= 0xEF) {
 
  216          codePoint2 = ((c2 & 0x0F) << 12) |
 
  217                       ((uint8_t(rhs.first[j + 1]) & 0x3F) << 6) |
 
  218                       (uint8_t(rhs.first[j + 2]) & 0x3F);
 
  221          codePoint2 = ((c2 & 0x07) << 18) |
 
  222                       ((uint8_t(rhs.first[j + 1]) & 0x3F) << 12) |
 
  223                       ((uint8_t(rhs.first[j + 2]) & 0x3F) << 6) |
 
  224                       (uint8_t(rhs.first[j + 3]) & 0x3F);
 
  226          codePoint2 -= 0x10000;
 
  227          uint16_t high_surrogate = uint16_t(0xD800 + (codePoint2 >> 10));
 
  228          low_surrogate2 = uint16_t(0xDC00 + (codePoint2 & 0x3FF));
 
  229          codePoint2 = high_surrogate;
 
  233      if (codePoint1 != codePoint2) {
 
  234        return (codePoint1 < codePoint2);
 
  237    return (j < rhs.first.size() || low_surrogate2 != 0);
 
  259template <
typename T, url_search_params_iter_type Type>
 
  261  return pos < params.params.size();
 
 
 
  269  return params.params[pos++].first;
 
 
  277  return params.params[pos++].second;
 
 
  281inline std::optional<key_value_view_pair>
 
  286  return params.params[pos++];
 
 
 
Definitions of the character sets used by unicode functions.
 
constexpr uint8_t WWW_FORM_URLENCODED_PERCENT_ENCODE[32]
 
url_search_params_iter< std::string_view, url_search_params_iter_type::VALUES > url_search_params_values_iter
 
url_search_params_iter< key_value_view_pair, url_search_params_iter_type::ENTRIES > url_search_params_entries_iter
 
url_search_params_iter< std::string_view, url_search_params_iter_type::KEYS > url_search_params_keys_iter
 
std::optional< std::string_view > next()
 
void set(std::string_view key, std::string_view value)
 
std::vector< std::string > get_all(std::string_view key)
 
void remove(std::string_view key)
 
url_search_params_entries_iter get_entries()
 
std::string to_string() const
 
url_search_params_keys_iter get_keys()
 
size_t size() const noexcept
 
void append(std::string_view key, std::string_view value)
 
url_search_params_values_iter get_values()
 
std::optional< std::string_view > get(std::string_view key)
 
bool has(std::string_view key) noexcept
 
Definitions for all unicode specific functions.
 
Declaration for the URL Search Params.