...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Algorithms to format URLs construct a mutable URL by parsing and applying
arguments to a URL template. The following example uses the format
function to construct an
absolute URL:
url u = format("{}://{}:{}/rfc/{}", "https", "www.ietf.org", 80, "rfc2396.txt"); assert(u.buffer() == "https://www.ietf.org:80/rfc/rfc2396.txt");
The rules for a format URL string are the same as for a std::format_string
,
where replacement fields are delimited by curly braces. The URL type is inferred
from the format string.
The URL components to which replacement fields belong are identified before replacement is applied and any invalid characters for that formatted argument are percent-escaped:
url u = format("https://{}/{}", "www.boost.org", "Hello world!"); assert(u.buffer() == "https://www.boost.org/Hello%20world!");
Delimiters in the URL template, such as ":"
,
"//"
, "?"
, and "#"
,
unambiguously associate each replacement field to a URL component. All other
characters are normalized to ensure the URL is valid:
url u = format("{}:{}", "mailto", "someone@example.com"); assert(u.buffer() == "mailto:someone@example.com"); assert(u.scheme() == "mailto"); assert(u.path() == "someone@example.com");
url u = format("{}{}", "mailto:", "someone@example.com"); assert(u.buffer() == "mailto%3Asomeone@example.com"); assert(!u.has_scheme()); assert(u.path() == "mailto:someone@example.com"); assert(u.encoded_path() == "mailto%3Asomeone@example.com");
The function format_to
can be used to format
URLs into any modifiable URL container.
static_url<50> u; format_to(u, "{}://{}:{}/rfc/{}", "https", "www.ietf.org", 80, "rfc2396.txt"); assert(u.buffer() == "https://www.ietf.org:80/rfc/rfc2396.txt");
As with std::format
,
positional and named arguments are supported.
url u = format("{0}://{2}:{1}/{3}{4}{3}", "https", 80, "www.ietf.org", "abra", "cad"); assert(u.buffer() == "https://www.ietf.org:80/abracadabra");
The arg
function can be used to associate names with arguments:
url u = format("https://example.com/~{username}", arg("username", "mark")); assert(u.buffer() == "https://example.com/~mark");
A second overload based on std::initializer_list
is provided for both format
and format_to
. These overloads can help
with lists of named arguments:
boost::core::string_view fmt = "{scheme}://{host}:{port}/{dir}/{file}"; url u = format(fmt, {{"scheme", "https"}, {"port", 80}, {"host", "example.com"}, {"dir", "path/to"}, {"file", "file.txt"}}); assert(u.buffer() == "https://example.com:80/path/to/file.txt");