Percent-encode and parse URL query pairs

C++
#include <cctype>
#include <map>
#include <sstream>
#include <string>

std::string urlEncode(const std::string& s) {
    static const char* hex = "0123456789ABCDEF";
    std::string out;
    for (unsigned char c : s)
        out += std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'
                   ? std::string(1, char(c))
                   : std::string{'%', hex[c >> 4], hex[c & 15]};
    return out;
}

std::map<std::string, std::string> parseQuery(const std::string& query) {
    std::map<std::string, std::string> out;
    std::istringstream in(query);
    for (std::string pair; std::getline(in, pair, '&');) {
        auto eq = pair.find('=');
        if (eq != std::string::npos) out[pair.substr(0, eq)] = pair.substr(eq + 1);
    }
    return out;
}