
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>A URI Library for C++</title>
    
    <style type="text/css">
.highlight .hll { background-color: #ffffcc }
.highlight  { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #303030 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */

body {
   font-family: sans-serif;
   margin: 1em;
   max-width : 8.5in;
}

/* -- main layout ----------------------------------------------------------- */

div.clearer {
    clear: both;
}

img {
    border: 0;
}

/* -- search page ----------------------------------------------------------- */

ul.search {
    margin: 10px 0 0 20px;
    padding: 0;
}

ul.search li {
    padding: 5px 0 5px 20px;
    background-image: url(file.png);
    background-repeat: no-repeat;
    background-position: 0 7px;
}

ul.search li a {
    font-weight: bold;
}

ul.search li div.context {
    color: #888;
    margin: 2px 0 0 30px;
    text-align: left;
}

ul.keywordmatches li.goodmatch a {
    font-weight: bold;
}

/* -- index page ------------------------------------------------------------ */

table.contentstable {
    width: 90%;
}

table.contentstable p.biglink {
    line-height: 150%;
}

a.biglink {
    font-size: 1.3em;
}

span.linkdescr {
    font-style: italic;
    padding-top: 5px;
    font-size: 90%;
}

/* -- general index --------------------------------------------------------- */

table.indextable {
    width: 100%;
}

table.indextable td {
    text-align: left;
    vertical-align: top;
}

table.indextable dl, table.indextable dd {
    margin-top: 0;
    margin-bottom: 0;
}

table.indextable tr.pcap {
    height: 10px;
}

table.indextable tr.cap {
    margin-top: 10px;
    background-color: #f2f2f2;
}

img.toggler {
    margin-right: 3px;
    margin-top: 3px;
    cursor: pointer;
}

div.modindex-jumpbox {
    border-top: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    margin: 1em 0 1em 0;
    padding: 0.4em;
}

div.genindex-jumpbox {
    border-top: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    margin: 1em 0 1em 0;
    padding: 0.4em;
}

/* -- general body styles --------------------------------------------------- */

a.headerlink {
    visibility: hidden;
}

h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
    visibility: visible;
}

div.body p.caption {
    text-align: inherit;
}

div.body td {
    text-align: left;
}

.field-list ul {
    padding-left: 1em;
}

.first {
    margin-top: 0 !important;
}

p.rubric {
    margin-top: 30px;
    font-weight: bold;
}

img.align-left, .figure.align-left, object.align-left {
    clear: left;
    float: left;
    margin-right: 1em;
}

img.align-right, .figure.align-right, object.align-right {
    clear: right;
    float: right;
    margin-left: 1em;
}

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
    text-align: left;
}

.align-center {
    text-align: center;
}

.align-right {
    text-align: right;
}

/* -- topics ---------------------------------------------------------------- */

div.topic {
    border: 1px solid #ccc;
    padding: 7px 7px 0 7px;
    margin: 10px 0 10px 0;
}

p.topic-title {
    font-size: 1.1em;
    font-weight: bold;
    margin-top: 10px;
}

/* -- admonitions ----------------------------------------------------------- */

div.admonition {
    margin-top: 10px;
    margin-bottom: 10px;
    padding: 7px;
    background-color: yellow;
}

div.admonition dt {
    font-weight: bold;
}

div.admonition dl {
    margin-bottom: 0;
}

p.admonition-title {
    margin: 0px 10px 5px 0px;
    font-weight: bold;
}

div.body p.centered {
    text-align: center;
    margin-top: 25px;
}

/* -- tables ---------------------------------------------------------------- */

table.docutils {
    border: 0;
    border-collapse: collapse;
}

table.docutils td, table.docutils th {
    padding: 1px 8px 1px 5px;
    border-top: 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 1px solid #aaa;
}

table.field-list td, table.field-list th {
    border: 0 !important;
}

table.footnote td, table.footnote th {
    border: 0 !important;
}

th {
    text-align: left;
    padding-right: 5px;
}

table.citation {
    border-left: solid 1px gray;
    margin-left: 1px;
}

table.citation td {
    border-bottom: none;
}

/* -- other body styles ----------------------------------------------------- */

ol.arabic {
    list-style: decimal;
}

ol.loweralpha {
    list-style: lower-alpha;
}

ol.upperalpha {
    list-style: upper-alpha;
}

ol.lowerroman {
    list-style: lower-roman;
}

ol.upperroman {
    list-style: upper-roman;
}

dl {
    margin-bottom: 15px;
}

dd p {
    margin-top: 0px;
}

dd ul, dd table {
    margin-bottom: 10px;
}

dd {
    margin-top: 3px;
    margin-bottom: 10px;
    margin-left: 30px;
}

dt:target, .highlighted {
    background-color: #fbe54e;
}

dl.glossary dt {
    font-weight: bold;
    font-size: 1.1em;
}

.field-list ul {
    margin: 0;
    padding-left: 1em;
}

.field-list p {
    margin: 0;
}

.refcount {
    color: #060;
}

.optional {
    font-size: 1.3em;
}

.versionmodified {
    font-style: italic;
}

.system-message {
    background-color: #fda;
    padding: 5px;
    border: 3px solid red;
}

.footnote:target  {
    background-color: #ffa;
}

.line-block {
    display: block;
    margin-top: 1em;
    margin-bottom: 1em;
}

.line-block .line-block {
    margin-top: 0;
    margin-bottom: 0;
    margin-left: 1.5em;
}

.guilabel, .menuselection {
    font-family: sans-serif;
}

.accelerator {
    text-decoration: underline;
}

.classifier {
    font-style: oblique;
}

abbr, acronym {
    border-bottom: dotted 1px;
    cursor: help;
}

/* -- code displays --------------------------------------------------------- */

pre {
    overflow: auto;
    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
}

td.linenos pre {
    padding: 5px 0px;
    border: 0;
    background-color: transparent;
    color: #aaa;
}

table.highlighttable {
    margin-left: 0.5em;
}

table.highlighttable td {
    padding: 0 0.5em 0 0.5em;
}

tt.descname {
    background-color: transparent;
    font-weight: bold;
    font-size: 1.2em;
}

tt.descclassname {
    background-color: transparent;
}

tt.xref, a tt {
    background-color: transparent;
    font-weight: bold;
}

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
    background-color: transparent;
}

.viewcode-link {
    float: right;
}

.viewcode-back {
    float: right;
    font-family: sans-serif;
}

div.viewcode-block:target {
    margin: -1px -10px;
    padding: 0 10px;
}

/* -- math display ---------------------------------------------------------- */

img.math {
    vertical-align: middle;
}

div.body div.math p {
    text-align: center;
}

span.eqno {
    float: right;
}

/* -- printout stylesheet --------------------------------------------------- */

@media print {
    div.document,
    div.documentwrapper,
    div.bodywrapper {
        margin: 0 !important;
        width: 100%;
    }

    div.related,
    div.footer,
    #top-link {
        display: none;
    }
}
    </style>
    <link rel="top" title="None" href="index.html#document-index" /> 
  </head>
  <body>

    <div class="document">
      <div class="documentwrapper">
          <div class="body">
            
  <span class="target" id="index"></span><div class="section" id="a-uri-library-for-c">
<h1>A URI Library for C++<a class="headerlink" href="#a-uri-library-for-c" title="Permalink to this headline">¶</a></h1>
<div class="line-block">
<div class="line"><strong>Document Number</strong>: N3625</div>
<div class="line"><strong>Date</strong>: 2013-04-30</div>
<div class="line"><strong>Authors</strong>: Glyn Matthews &lt;<a class="reference external" href="mailto:glyn&#46;matthews&#37;&#52;&#48;gmail&#46;com">glyn<span>&#46;</span>matthews<span>&#64;</span>gmail<span>&#46;</span>com</a>&gt;, Dean Michael Berris &lt;<a class="reference external" href="mailto:dberris&#37;&#52;&#48;google&#46;com">dberris<span>&#64;</span>google<span>&#46;</span>com</a>&gt;</div>
</div>
<div class="toctree-wrapper compound">
<span id="document-motivation_and_scope"></span><div class="section" id="motivation-and-scope">
<span id="id1"></span><h2>Motivation and Scope<a class="headerlink" href="#motivation-and-scope" title="Permalink to this headline">¶</a></h2>
<p>Given the increased importance of being able to develop portable,
scalable network-aware applications, C++ developers are at a
disavantage in having no standard network implementation to use. One
of the fundamental components of any network library is a URI and this
proposal is motivated by the desire to introduce a portable, efficient
and internationalized implementation of a URI to C++ standard library
users.</p>
<p>This proposal is based on original development done in the
<tt class="xref py py-mod docutils literal"><span class="pre">cpp-netlib</span></tt> project <a class="reference external" href="http://cpp-netlib.org/">http://cpp-netlib.org/</a>. This
implementation is released using the <a class="reference external" href="http://www.boost.org/users/license.html">Boost software license</a> and
will track the proposed library as it evolves. A standalone project
can be found at <a class="reference external" href="https://github.com/cpp-netlib/uri/">https://github.com/cpp-netlib/uri/</a>.</p>
<p>The scope of this proposal will include a single <tt class="docutils literal"><span class="pre">uri</span></tt> type, some
specifications about how URIs are intended to be processed and
extended, including some additional helper types and functions. It
will include a type and functions to build a URI from its
components. Finally, it will include types and functions for percent
encoding, URI references and URI normalization.</p>
<div class="section" id="example-usage">
<h3>Example Usage<a class="headerlink" href="#example-usage" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include &lt;experimental/uri&gt;</span>
<span class="cp">#include &lt;cassert&gt;</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">&quot;http://www.example.com/glynos/?key=value#frag&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="n">is_absolute</span><span class="p">());</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">!</span><span class="n">uri</span><span class="p">.</span><span class="n">is_opaque</span><span class="p">());</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">scheme</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;http&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">host</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;www.example.com&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">path</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;/glynos/&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">query</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;key=value&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">fragment</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;frag&quot;</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The code excerpt above shows a simple of how the proposed <tt class="docutils literal"><span class="pre">uri</span></tt>
class will work. The URI string is parsed during object construction
and broken down into its component parts. HTTP URIs are absolute and
hierarchical (i.e. not opaque).</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include &lt;experimental/uri&gt;</span>
<span class="cp">#include &lt;cassert&gt;</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="n">U</span><span class="s">&quot;xmpp:example-node@example.com?message;subject=Hello%20World&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="n">is_absolute</span><span class="p">());</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="n">is_opaque</span><span class="p">());</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">scheme</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;xmpp&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">path</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;example-node@example.com&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="o">*</span><span class="n">uri</span><span class="p">.</span><span class="n">query</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;message;subject=Hello%20World&quot;</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">uri</span></tt> in this proposal supports encoded strings and supports
encoding conversion. The example above shows a <tt class="docutils literal"><span class="pre">uri</span></tt> object
constructed using a <tt class="docutils literal"><span class="pre">std::u32string</span></tt> and allow the parts to be
accessed as <tt class="docutils literal"><span class="pre">std::string_view</span></tt> objects.</p>
</div>
</div>
<span id="document-impact"></span><div class="section" id="impact-on-the-standard">
<span id="impact"></span><h2>Impact on the Standard<a class="headerlink" href="#impact-on-the-standard" title="Permalink to this headline">¶</a></h2>
<p>This proposal is a library extension that adds a header, two classes
and some functions. It depends on the acceptance of other proposals
(<a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3527.html"><tt class="docutils literal"><span class="pre">std::optional</span></tt></a>, <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3609.html"><tt class="docutils literal"><span class="pre">std::string_view</span></tt></a>) for the API.</p>
</div>
<span id="document-revision_history"></span><div class="section" id="revision-history">
<span id="id1"></span><h2>Revision History<a class="headerlink" href="#revision-history" title="Permalink to this headline">¶</a></h2>
<div class="section" id="changes-since-bristol">
<h3>Changes since Bristol<a class="headerlink" href="#changes-since-bristol" title="Permalink to this headline">¶</a></h3>
<div class="section" id="namespace">
<h4>Namespace<a class="headerlink" href="#namespace" title="Permalink to this headline">¶</a></h4>
<p>The <tt class="docutils literal"><span class="pre">uri</span></tt> and <tt class="docutils literal"><span class="pre">uri_builder</span></tt> and all related free functions and
operators now belong in the <tt class="docutils literal"><span class="pre">std::experimental</span></tt> namespace.</p>
</div>
<div class="section" id="input-output-stream-operators">
<h4>Input/Output Stream Operators<a class="headerlink" href="#input-output-stream-operators" title="Permalink to this headline">¶</a></h4>
<p>The input and output stream operators are now template operators and
use <tt class="docutils literal"><span class="pre">std::basic_istream</span></tt> and <tt class="docutils literal"><span class="pre">std::basic_ostream</span></tt>.</p>
</div>
<div class="section" id="assignment">
<h4>Assignment<a class="headerlink" href="#assignment" title="Permalink to this headline">¶</a></h4>
<p>The assignment operators no longer needs to parse the URI string.</p>
</div>
<div class="section" id="percent-encoding-and-decoding">
<h4>Percent Encoding and Decoding<a class="headerlink" href="#percent-encoding-and-decoding" title="Permalink to this headline">¶</a></h4>
<p>All functions associated with percent encoding and decoding are now
static members of the <tt class="docutils literal"><span class="pre">std::experimental::uri</span></tt> class instead of free
functions. They also throw exceptions on encoding failures.</p>
</div>
<div class="section" id="query-accessors">
<h4>Query Accessors<a class="headerlink" href="#query-accessors" title="Permalink to this headline">¶</a></h4>
<p><tt class="docutils literal"><span class="pre">absolute</span></tt> and <tt class="docutils literal"><span class="pre">opaque</span></tt> become <tt class="docutils literal"><span class="pre">is_absolute</span></tt> and
<tt class="docutils literal"><span class="pre">is_opaque</span></tt>. This is a reversal of a previous revision (see <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3484.html">N3484</a>)
and brings the <tt class="docutils literal"><span class="pre">uri</span></tt> proposal into line with the file system path
(<a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3505.html">N3505</a>).</p>
</div>
<div class="section" id="transformers">
<h4>Transformers<a class="headerlink" href="#transformers" title="Permalink to this headline">¶</a></h4>
<p>Added <tt class="docutils literal"><span class="pre">noexcept</span></tt> overloads that take an additional <tt class="docutils literal"><span class="pre">error_code</span> <span class="pre">&amp;</span></tt>
argument. This applies to <tt class="docutils literal"><span class="pre">normalize</span></tt>, <tt class="docutils literal"><span class="pre">make_reference</span></tt> and
<tt class="docutils literal"><span class="pre">resolve</span></tt>.</p>
</div>
<div class="section" id="allocators">
<h4>Allocators<a class="headerlink" href="#allocators" title="Permalink to this headline">¶</a></h4>
<p>Added overloads to the <tt class="docutils literal"><span class="pre">uri</span></tt> constructors and to
<tt class="docutils literal"><span class="pre">std::experimental::make_uri</span></tt> to better support allocators.</p>
</div>
</div>
<div class="section" id="changes-since-n3507">
<h3>Changes since <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3507.html">N3507</a><a class="headerlink" href="#changes-since-n3507" title="Permalink to this headline">¶</a></h3>
<div class="section" id="contact-details">
<h4>Contact details<a class="headerlink" href="#contact-details" title="Permalink to this headline">¶</a></h4>
<p>The authors&#8217; contact details have been updated.</p>
</div>
<div class="section" id="std-string-view-rename">
<h4><tt class="docutils literal"><span class="pre">std::string_view</span></tt> rename<a class="headerlink" href="#std-string-view-rename" title="Permalink to this headline">¶</a></h4>
<p>The API has been updated to use the name <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3609.html"><tt class="docutils literal"><span class="pre">std::string_view</span></tt></a> instead
of <tt class="docutils literal"><span class="pre">std::string_ref</span></tt>.</p>
</div>
<div class="section" id="id2">
<h4>Namespace<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h4>
<p>The proposed <tt class="docutils literal"><span class="pre">uri</span></tt> class is now in the <tt class="docutils literal"><span class="pre">std</span></tt> namespace, after
feedback from the BSI C++ Panel. As a consequence the names of the
<tt class="docutils literal"><span class="pre">encode_*</span></tt> and <tt class="docutils literal"><span class="pre">decode</span></tt> free functions have been updated to
<tt class="docutils literal"><span class="pre">encode_uri_*</span></tt> and <tt class="docutils literal"><span class="pre">decode_uri</span></tt>.</p>
</div>
<div class="section" id="relativize">
<h4><tt class="docutils literal"><span class="pre">relativize</span></tt><a class="headerlink" href="#relativize" title="Permalink to this headline">¶</a></h4>
<p><tt class="docutils literal"><span class="pre">uri::relativize</span></tt> has been renamed <tt class="docutils literal"><span class="pre">uri::make_reference</span></tt>.</p>
</div>
</div>
<div class="section" id="sections">
<h3>Sections<a class="headerlink" href="#sections" title="Permalink to this headline">¶</a></h3>
<p>A section describing the impact of the proposal on the standard has
been added and the issues section was removed.</p>
</div>
<div class="section" id="changes-since-n3484">
<h3>Changes since <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3484.html">N3484</a><a class="headerlink" href="#changes-since-n3484" title="Permalink to this headline">¶</a></h3>
<div class="section" id="query-accessor-error">
<h4>Query Accessor Error<a class="headerlink" href="#query-accessor-error" title="Permalink to this headline">¶</a></h4>
<p>The document has been fixed so that query part now starts <strong>after</strong>
the question-mark separator.</p>
</div>
<div class="section" id="return-value-of-parts-accessors">
<h4>Return value of parts accessors<a class="headerlink" href="#return-value-of-parts-accessors" title="Permalink to this headline">¶</a></h4>
<p>All parts accessors (<tt class="docutils literal"><span class="pre">scheme</span></tt>, <tt class="docutils literal"><span class="pre">user_info</span></tt>, <tt class="docutils literal"><span class="pre">host</span></tt>, <tt class="docutils literal"><span class="pre">port</span></tt>,
<tt class="docutils literal"><span class="pre">path</span></tt>, <tt class="docutils literal"><span class="pre">query</span></tt> and <tt class="docutils literal"><span class="pre">fragment</span></tt>) now all return
<tt class="docutils literal"><span class="pre">std::optional&lt;std::string_view&gt;</span></tt>.</p>
</div>
<div class="section" id="comparison-level">
<h4>Comparison Level<a class="headerlink" href="#comparison-level" title="Permalink to this headline">¶</a></h4>
<p><tt class="docutils literal"><span class="pre">normalize</span></tt>, <tt class="docutils literal"><span class="pre">relativize</span></tt> and <tt class="docutils literal"><span class="pre">resolve</span></tt> all accept as an
argument the <tt class="docutils literal"><span class="pre">uri_comparison_level</span></tt>.</p>
</div>
<div class="section" id="exception">
<h4>Exception<a class="headerlink" href="#exception" title="Permalink to this headline">¶</a></h4>
<p>The <tt class="docutils literal"><span class="pre">uri(InputIterator,</span> <span class="pre">InputIterator)</span></tt> and <tt class="docutils literal"><span class="pre">uri(Source)</span></tt>
constructors now can throw a <tt class="docutils literal"><span class="pre">std::system_error</span></tt> exception instead
of <tt class="docutils literal"><span class="pre">uri_syntax_error</span></tt>. This makes the constructor exception
consistent with the error code set by <tt class="docutils literal"><span class="pre">make_uri</span></tt>.</p>
</div>
<div class="section" id="comparison-and-equality-operator">
<h4>Comparison and Equality Operator<a class="headerlink" href="#comparison-and-equality-operator" title="Permalink to this headline">¶</a></h4>
<p><tt class="docutils literal"><span class="pre">compare</span></tt> now returns an <tt class="docutils literal"><span class="pre">int</span></tt> instead of a <tt class="docutils literal"><span class="pre">bool</span></tt>. The return
value of <tt class="docutils literal"><span class="pre">compare</span></tt> will be <tt class="docutils literal"><span class="pre">-1</span></tt> if this (normalized) uri is
lexographically less than that of the other, <tt class="docutils literal"><span class="pre">0</span></tt> if they are equal
and <tt class="docutils literal"><span class="pre">1</span></tt> if this is greater than the other (see comparison ladder).</p>
</div>
<div class="section" id="updated-appendix">
<h4>Updated Appendix<a class="headerlink" href="#updated-appendix" title="Permalink to this headline">¶</a></h4>
<p>The items in the appendix describing the revision history have changed
to this section. The appendix now contains a response to questions
about existing practice and to the WhatWG URL Standard.</p>
</div>
</div>
<div class="section" id="changes-since-n3420">
<h3>Changes since <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3420.html">N3420</a><a class="headerlink" href="#changes-since-n3420" title="Permalink to this headline">¶</a></h3>
<div class="section" id="underlying-string-type">
<h4>Underlying String Type<a class="headerlink" href="#underlying-string-type" title="Permalink to this headline">¶</a></h4>
<p>The updated <tt class="docutils literal"><span class="pre">uri</span></tt> class no longer specifies the underlying string
type directly; it need not even be a <tt class="docutils literal"><span class="pre">std::basic_string</span></tt>. The
<tt class="docutils literal"><span class="pre">std::uri::value_type</span></tt> is now defined as the value of the string
iterator. Consequently, the <tt class="docutils literal"><span class="pre">uri</span></tt> class will no longer assume that
the underlying string is in a contiguous block of memory, so the
<tt class="docutils literal"><span class="pre">c_str()</span></tt> has been removed.</p>
</div>
<div class="section" id="id3">
<h4>Exception<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h4>
<p>The <tt class="docutils literal"><span class="pre">uri(InputIterator,</span> <span class="pre">InputIterator)</span></tt> and <tt class="docutils literal"><span class="pre">uri(Source)</span></tt>
constructors now can throw a <tt class="docutils literal"><span class="pre">uri_syntax_error</span></tt> exception. The
<tt class="docutils literal"><span class="pre">is_valid</span></tt> member has been removed as it is now redundant.</p>
</div>
<div class="section" id="syntactic-and-semantic-validity">
<h4>Syntactic and Semantic Validity<a class="headerlink" href="#syntactic-and-semantic-validity" title="Permalink to this headline">¶</a></h4>
<p>This proposal in its current form only specifies tests for syntactic
validity. To make this more explicit, the test for validity (now an
exception) is named <tt class="docutils literal"><span class="pre">uri_syntax_error</span></tt>. This decision will influence
others, especially related to normalization and equivalence. Future
versions of this proposal may address the question of semantic
validity. It would boil down to how complex the implementation of a
generic URI class needs to be, and if it can be made extensible in the
right ways to test scheme-specific semantics.</p>
</div>
<div class="section" id="accessor-name-consistency">
<h4>Accessor Name Consistency<a class="headerlink" href="#accessor-name-consistency" title="Permalink to this headline">¶</a></h4>
<p>The accessors <tt class="docutils literal"><span class="pre">is_absolute</span></tt> and <tt class="docutils literal"><span class="pre">is_opaque</span></tt> have been renamed
<tt class="docutils literal"><span class="pre">absolute</span></tt> and <tt class="docutils literal"><span class="pre">opaque</span></tt> in order to be more consistent.</p>
</div>
<div class="section" id="normalize-as-a-free-function">
<h4><tt class="docutils literal"><span class="pre">normalize</span></tt> as a Free Function<a class="headerlink" href="#normalize-as-a-free-function" title="Permalink to this headline">¶</a></h4>
<p>The functions <tt class="docutils literal"><span class="pre">normalize</span></tt>, <tt class="docutils literal"><span class="pre">relativize</span></tt> and <tt class="docutils literal"><span class="pre">resolve</span></tt> have been
removed and replaced with member functions in the <tt class="docutils literal"><span class="pre">class</span></tt>.</p>
</div>
<div class="section" id="id4">
<h4>Comparison and Equality Operator<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h4>
<p>A function <tt class="docutils literal"><span class="pre">compare</span></tt> is provided which takes as a 3rd argument a
<tt class="docutils literal"><span class="pre">uri_comparison_level</span></tt> enum. This can be used to determine the level
of the comparison ladder to use when comparing URIs. A more complete
description of what comparison and equivalence means can be discussed
and elaborated in a future proposal.</p>
<p>The question of semantics of relational operators will also be
addressed.</p>
</div>
<div class="section" id="encode-and-decode">
<h4><tt class="docutils literal"><span class="pre">encode</span></tt> and <tt class="docutils literal"><span class="pre">decode</span></tt><a class="headerlink" href="#encode-and-decode" title="Permalink to this headline">¶</a></h4>
<p>The functions <tt class="docutils literal"><span class="pre">pct_encode</span></tt> and <tt class="docutils literal"><span class="pre">pct_decode</span></tt> have been renamed
<tt class="docutils literal"><span class="pre">encode</span></tt> and <tt class="docutils literal"><span class="pre">decode</span></tt>. A few more functions have been added to
take into account the different types of encoding for different URI
parts.</p>
</div>
<div class="section" id="uri-builder">
<h4><tt class="docutils literal"><span class="pre">uri_builder</span></tt><a class="headerlink" href="#uri-builder" title="Permalink to this headline">¶</a></h4>
<p>The changes requires to the <tt class="docutils literal"><span class="pre">uri::builder</span></tt> have been taken into
account, including renaming it <tt class="docutils literal"><span class="pre">uri_builder</span></tt> and providing a method
<tt class="docutils literal"><span class="pre">uri()</span></tt> that returns a new <tt class="docutils literal"><span class="pre">uri</span></tt> object.</p>
</div>
</div>
</div>
<span id="document-issues"></span><div class="section" id="issues">
<span id="id1"></span><h2>Issues<a class="headerlink" href="#issues" title="Permalink to this headline">¶</a></h2>
<div class="section" id="bikeshedding">
<h3>Bikeshedding<a class="headerlink" href="#bikeshedding" title="Permalink to this headline">¶</a></h3>
<p>As seems to be inevitable when developing a proposal for a standards
committee, there are some differences of opinion regarding the names
of certain functions. I will attempt to justify some of them now:</p>
<div class="section" id="std-experimental-uri-resolve">
<h4><tt class="docutils literal"><span class="pre">std::experimental::uri::resolve</span></tt><a class="headerlink" href="#std-experimental-uri-resolve" title="Permalink to this headline">¶</a></h4>
<p>There has been some concern about the ambiguity with this term and
with name resolution. Nevertheless, <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-5">RFC 3986, Section 5</a> calls this
process &#8216;Reference Resolution&#8217; and existing URI classes in other
languages and frameworks also use this term (e.g. <a class="reference external" href="http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URI.html#resolve(java.net.URI)">Java</a> and <a class="reference external" href="http://qt-project.org/doc/qt-4.8/qurl.html#resolved">Qt</a>).</p>
</div>
<div class="section" id="query-accessors">
<h4>Query accessors<a class="headerlink" href="#query-accessors" title="Permalink to this headline">¶</a></h4>
<p>The names of the query accessors have changed at least twice (once
removing the <tt class="docutils literal"><span class="pre">is_</span></tt> suffix and again to add them). The current
revision of the proposal is consistent at least with
<tt class="docutils literal"><span class="pre">std::filesystem::path</span></tt> interface.</p>
</div>
</div>
<div class="section" id="extension-points">
<h3>Extension points<a class="headerlink" href="#extension-points" title="Permalink to this headline">¶</a></h3>
<p>The current proposal does not provide any way to allow a library
implementation or user to extend the API. This would be important to
allow scheme or protocol specific implementations of <tt class="docutils literal"><span class="pre">normalize</span></tt>
and <tt class="docutils literal"><span class="pre">compare</span></tt>. A future revision should address this.</p>
</div>
<div class="section" id="allocator-support">
<h3>Allocator support<a class="headerlink" href="#allocator-support" title="Permalink to this headline">¶</a></h3>
<p>A future revision of this proposal should acknowledge polymorphics
allocators (<a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3525.pdf">N3525</a>).</p>
</div>
</div>
<span id="document-generic_syntax"></span><div class="section" id="generic-syntax">
<span id="id1"></span><h2>Generic Syntax<a class="headerlink" href="#generic-syntax" title="Permalink to this headline">¶</a></h2>
<p>The generic syntax of a URI is defined in <a class="reference external" href="http://tools.ietf.org/html/rfc3986">RFC 3986</a>.</p>
<p>All URIs are of the form:</p>
<div class="highlight-python"><pre>scheme ":" "hierarchical part" [ "?" query ] [ "#" fragment ]</pre>
</div>
<p>The <strong>scheme</strong> is used to identify the specification needed to parse
the rest of the URI. A generic syntax parser can parse any URI into
its main parts. The scheme can then be used to identify whether
further scheme-specific parsing can be performed.</p>
<p>The <strong>hierarchical part</strong> refers to the part of the URI that holds
identification information that is hierarchical in nature. This may
contain an <strong>authority</strong> (always prefixed with a double slash
<tt class="docutils literal"><span class="pre">&quot;//&quot;</span></tt>) and/or a <strong>path</strong>. The <strong>path</strong> part is required, thought it
may be empty. The <strong>authority</strong> part holds an optional <strong>user info</strong>
part, ending with an at sign <tt class="docutils literal"><span class="pre">&quot;&#64;&quot;</span></tt>; a <strong>host</strong> identifier and an
optional <strong>port</strong> number, preceded by a colon <tt class="docutils literal"><span class="pre">&quot;:&quot;</span></tt>. The <strong>host</strong>
may be an IP address or domain name. <a class="reference external" href="http://tools.ietf.org/html/rfc3986">RFC 3986</a> does not specify the
format for IPv6 addresses, though <a class="reference external" href="http://tools.ietf.org/html/rfc2732">RFC 2732</a> does.</p>
<p>The <strong>query</strong> is an optional part following a question mark <tt class="docutils literal"><span class="pre">&quot;?&quot;</span></tt>
that contains information that is not hierarchical.</p>
<p>Finally, the <strong>fragment</strong> is an optional part, prefixed by a hash
symbol <tt class="docutils literal"><span class="pre">&quot;#&quot;</span></tt> that is used to identify secondary sources.</p>
<p><a class="reference external" href="http://tools.ietf.org/html/rfc3987">RFC 3987</a> specifies a new protocol element, the Internationalized
Resource Identifier (IRI). The IRI complements a URI, and extends it
to allow unicode characters.</p>
<p>This proposal will define a <tt class="docutils literal"><span class="pre">uri</span></tt> type that will attempt to
encompass all three of these RFCs.</p>
<div class="section" id="percent-encoding">
<h3>Percent Encoding<a class="headerlink" href="#percent-encoding" title="Permalink to this headline">¶</a></h3>
<p>URI percent encoding is described in <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986, section 2.1</a> and <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.4">RFC
3986, section 2.4</a>.</p>
<p>Percent encoding is the mechanism used to encode reserved characters
in a URI. According to <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.2">RFC 3986, section 2.2</a>, the set of reserved
characters are:</p>
<table border="1" class="docutils">
<caption>Set of reserved characters and percent encoded strings</caption>
<colgroup>
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">!</span></tt></td>
<td><tt class="docutils literal"><span class="pre">#</span></tt></td>
<td><tt class="docutils literal"><span class="pre">$</span></tt></td>
<td><tt class="docutils literal"><span class="pre">&amp;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">'</span></tt></td>
<td><tt class="docutils literal"><span class="pre">(</span></tt></td>
<td><tt class="docutils literal"><span class="pre">)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">*</span></tt></td>
<td><tt class="docutils literal"><span class="pre">+</span></tt></td>
<td><tt class="docutils literal"><span class="pre">,</span></tt></td>
<td><tt class="docutils literal"><span class="pre">/</span></tt></td>
<td><tt class="docutils literal"><span class="pre">:</span></tt></td>
<td><tt class="docutils literal"><span class="pre">;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">=</span></tt></td>
<td><tt class="docutils literal"><span class="pre">?</span></tt></td>
<td><tt class="docutils literal"><span class="pre">&#64;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">[</span></tt></td>
<td><tt class="docutils literal"><span class="pre">]</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">%21</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%23</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%24</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%26</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%27</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%28</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%29</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2A</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2B</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2C</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2F</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3A</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3B</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3D</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3F</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%40</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%5B</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%5D</span></tt></td>
</tr>
</tbody>
</table>
<p>Percent encoding is not limited to reserved characters. Any character data may be percent encoded:</p>
<table border="1" class="docutils">
<caption>Common characters and percent encoded strings</caption>
<colgroup>
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
<col width="6%" />
</colgroup>
<tbody valign="top">
<tr class="row-odd"><td>newline</td>
<td>space</td>
<td><tt class="docutils literal"><span class="pre">&quot;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%</span></tt></td>
<td><tt class="docutils literal"><span class="pre">-</span></tt></td>
<td><tt class="docutils literal"><span class="pre">.</span></tt></td>
<td><tt class="docutils literal"><span class="pre">&lt;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">&gt;</span></tt></td>
<td><tt class="docutils literal"><span class="pre">\</span></tt></td>
<td><tt class="docutils literal"><span class="pre">^</span></tt></td>
<td><tt class="docutils literal"><span class="pre">_</span></tt></td>
<td><em>`</em></td>
<td><tt class="docutils literal"><span class="pre">{</span></tt></td>
<td><tt class="docutils literal"><span class="pre">|</span></tt></td>
<td><tt class="docutils literal"><span class="pre">}</span></tt></td>
<td><tt class="docutils literal"><span class="pre">~</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">%0A</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%20</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%22</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%25</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2D</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%2E</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3C</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%3E</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%5C</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%5E</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%5F</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%60</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%7B</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%7C</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%7D</span></tt></td>
<td><tt class="docutils literal"><span class="pre">%7E</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
<span id="document-uri_normalization"></span><div class="section" id="uri-normalization-and-comparison">
<span id="uri-normalization"></span><h2>URI Normalization and Comparison<a class="headerlink" href="#uri-normalization-and-comparison" title="Permalink to this headline">¶</a></h2>
<p>URI <strong>normalization</strong> is described in <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-6">RFC 3986, Section 6</a> and in
<a class="reference external" href="http://tools.ietf.org/html/rfc3987#section-5">RFC 3987, Section 5</a>. Normalization is the process by which a URI is
transformed in order to determine if two URIs are equivalent.</p>
<p>Different types of normalization may preserve semantics, and others
may not. Normalization may also depend on the scheme.</p>
<div class="section" id="converting-the-scheme-host-to-lower-case">
<h3>Converting the Scheme / Host to Lower Case<a class="headerlink" href="#converting-the-scheme-host-to-lower-case" title="Permalink to this headline">¶</a></h3>
<p>The <em>scheme</em> and <em>host</em> are case-insensitive. The proposed
normalization solution will convert these to lowercase.</p>
<div class="highlight-python"><pre>HTTP://Example.com/ --&gt; http://example.com/</pre>
</div>
<p>The <em>user info</em>, <em>path</em>, <em>query</em> and <em>fragment</em> are case-sensitive and
so must not be converted.</p>
</div>
<div class="section" id="capitalizing-characters-in-escape-sequences">
<h3>Capitalizing Characters in Escape Sequences<a class="headerlink" href="#capitalizing-characters-in-escape-sequences" title="Permalink to this headline">¶</a></h3>
<p>Characters in a percent-encoded triplet are case-insensitive. The
proposed normalization solution will convert these to lowercase.</p>
<div class="highlight-python"><pre>http://example.com/%5b%5d --&gt; http://example.com/%5B%5D</pre>
</div>
</div>
<div class="section" id="decoding-unreserved-characters">
<h3>Decoding Unreserved Characters<a class="headerlink" href="#decoding-unreserved-characters" title="Permalink to this headline">¶</a></h3>
<p>Unreserved characters that have been encoded will be decoded.</p>
<div class="highlight-python"><pre>http://example.com/%7Eglynos/ --&gt; http://example.com/~glynos/</pre>
</div>
</div>
<div class="section" id="adding-trailing">
<h3>Adding Trailing <tt class="docutils literal"><span class="pre">/</span></tt><a class="headerlink" href="#adding-trailing" title="Permalink to this headline">¶</a></h3>
<p>If a <em>path</em> refers to a directory, it should be indicated with a
trailing slash.</p>
<div class="highlight-python"><pre>http://example.com/glynos --&gt; http://example.com/glynos/</pre>
</div>
<p>But not if the <em>path</em> refers to a file.</p>
<div class="highlight-python"><pre>http://example.com/glynos/page.html --&gt; http://example.com/glynos/page.html</pre>
</div>
</div>
<div class="section" id="removing-dot-segments-from-the-path">
<h3>Removing dot-segments from the Path<a class="headerlink" href="#removing-dot-segments-from-the-path" title="Permalink to this headline">¶</a></h3>
<p>The segments <cite>&#8221;..&#8221;</cite> and <cite>&#8221;.&#8221;</cite> can be removed according to the
algorithm specified in <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-5.2.4">RFC 3986, Section 5.2.4</a>.</p>
<div class="highlight-python"><pre>http://example.com/glynos/./proposals/../ --&gt; http://example.com/glynos/</pre>
</div>
</div>
<div class="section" id="removing-the-default-port">
<h3>Removing the default port<a class="headerlink" href="#removing-the-default-port" title="Permalink to this headline">¶</a></h3>
<p>Some schemes may have a default port (for HTTP it is <cite>80</cite>). The
default port can be removed.</p>
<div class="highlight-python"><pre>http://example.com:80/ --&gt; http://example.com/
http://example.com:/ --&gt; http://example.com/</pre>
</div>
</div>
<div class="section" id="the-comparison-ladder">
<h3>The <em>Comparison Ladder</em><a class="headerlink" href="#the-comparison-ladder" title="Permalink to this headline">¶</a></h3>
<p>The <em>Comparison Ladder</em> is described in <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-6.2">RFC 3986, Section 6.2</a>. It
explains that comparing URIs using normalization can be implemented in
different ways according to the complexity of the method and the
number of false negatives which may arise.</p>
<div class="line-block">
<div class="line"><strong>String comparison</strong>: The simplest and fastest method is to simply
test the URI strings byte-for-byte.</div>
</div>
<div class="line-block">
<div class="line"><strong>Case normalization</strong>: The first step to reduce false negatives is to
normalize the parts that are case-insenstive - the <em>scheme</em> and
the <em>host</em> and any percent-encoded triplets.</div>
</div>
<div class="line-block">
<div class="line"><strong>Percent encoding normalization</strong>: Next, any percent-encoded
triplets that correspond to unreserved characters can be decoded.</div>
</div>
<div class="line-block">
<div class="line"><strong>Path segment normalization</strong>: Any dot-segments can be removed from
the path.</div>
</div>
<div class="line-block">
<div class="line"><strong>Scheme based normalization</strong>: Trailing slashes can be added and
default ports can be removed. Additionally for HTTP, key/value
pairs in the query can appear in any order.</div>
</div>
<div class="line-block">
<div class="line"><strong>Protocol based normalization</strong>: Finally, URI equivalence can be
tested by testing the resources directly, e.g. using HTTP to see
if one URI redirects to another.</div>
</div>
<p>The final two steps in the <em>Comparison Ladder</em> require more
information than can be provided within the limits of the proposal in
order to be implemented comprehensively, and will not form part of the
proposal at this stage.</p>
</div>
</div>
<span id="document-uri_references"></span><div class="section" id="uri-references">
<span id="id1"></span><h2>URI References<a class="headerlink" href="#uri-references" title="Permalink to this headline">¶</a></h2>
<p>URI <strong>references</strong> are described in <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-4">RFC 3986, section 4</a>, <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-5">RFC 3986,
section 5</a> and <a class="reference external" href="http://tools.ietf.org/html/rfc3987#section-6.5">RFC 3987, section 6.5</a>. URI references are
particularly useful when working on the server side when the base URI is
always the same, and also when using URIs within the same document.</p>
<p>Two operations related to references are of use: acquiring the
relative reference of a URI, and resolving a reference against a base
URI.</p>
</div>
<span id="document-header_synopsis"></span><div class="section" id="header-experimental-uri-synopsis">
<span id="header-synopsis"></span><h2>Header <tt class="docutils literal"><span class="pre">&lt;experimental/uri&gt;</span></tt> Synopsis<a class="headerlink" href="#header-experimental-uri-synopsis" title="Permalink to this headline">¶</a></h2>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include &lt;string&gt;        </span><span class="c1">// std::basic_string</span>
<span class="cp">#include &lt;system_error&gt;  </span><span class="c1">// std::error_code</span>
<span class="cp">#include &lt;iosfwd&gt;        </span><span class="c1">// std::basic_istream, std::basic_ostream</span>
<span class="cp">#include &lt;iterator&gt;      </span><span class="c1">// std::iterator_traits</span>
<span class="cp">#include &lt;memory&gt;        </span><span class="c1">// std::allocator</span>
<span class="cp">#include &lt;optional&gt;      </span><span class="c1">// std::optional</span>

<span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="c1">// class declarations</span>
<span class="k">class</span> <span class="nc">uri</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">uri_builder</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">uri_syntax_error</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">uri_builder_error</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">uri_encoding_error</span><span class="p">;</span>

<span class="k">enum</span> <span class="k">class</span> <span class="nc">uri_error</span> <span class="p">{</span>
 <span class="n">invalid_syntax</span><span class="p">,</span>
 <span class="n">invalid_uri</span><span class="p">,</span>
 <span class="n">invalid_scheme</span><span class="p">,</span>
 <span class="n">invalid_user_info</span><span class="p">,</span>
 <span class="n">invalid_host</span><span class="p">,</span>
 <span class="n">invalid_port</span><span class="p">,</span>
 <span class="n">invalid_path</span><span class="p">,</span>
 <span class="n">invalid_query</span><span class="p">,</span>
 <span class="n">invalid_fragment</span><span class="p">,</span>
<span class="p">};</span>

<span class="k">enum</span> <span class="k">class</span> <span class="nc">uri_comparison_level</span> <span class="p">{</span>
 <span class="n">string_comparison</span><span class="p">,</span>
 <span class="n">case_normalization</span><span class="p">,</span>
 <span class="n">percent_encoding_normalization</span><span class="p">,</span>
 <span class="n">path_segment_normalization</span><span class="p">,</span>
 <span class="n">scheme_based_normalization</span><span class="p">,</span>
 <span class="n">protocol_based_normalization</span><span class="p">,</span>
<span class="p">};</span>

<span class="c1">// factory functions</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIter</span><span class="o">&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">alloc</span><span class="o">&lt;</span><span class="n">uri</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIter</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">uri</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>

<span class="c1">// swap functions</span>
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>

<span class="c1">// equality and comparison operators</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span>  <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span>  <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>

<span class="c1">// stream operators</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span>
<span class="k">operator</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span>
<span class="k">operator</span> <span class="o">&gt;&gt;</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">is</span><span class="p">,</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="section" id="declarations">
<h3>Declarations<a class="headerlink" href="#declarations" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">&lt;experimental/uri&gt;</span></tt> header contains a declaration for a single
<tt class="docutils literal"><span class="pre">uri</span></tt> class in the <tt class="docutils literal"><span class="pre">std::experimental</span></tt> namespace.</p>
<p>Previous revisions of this proposal used the sub-namespace <tt class="docutils literal"><span class="pre">network</span></tt>
namespace, but given feedback this is no longer the case.</p>
</div>
<div class="section" id="factory-functions">
<h3>Factory functions<a class="headerlink" href="#factory-functions" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// factory functions</span>
<span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIter</span><span class="o">&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">alloc</span><span class="o">&lt;</span><span class="n">uri</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">InputIter</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">uri</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span> <span class="n">make_uri</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>These factory functions are provided in order to be able to construct
a <tt class="docutils literal"><span class="pre">uri</span></tt> object without throwing an exception. The error code is
stored in the <tt class="docutils literal"><span class="pre">std::error_code</span></tt> object, if the string <tt class="docutils literal"><span class="pre">source</span></tt> is
an invalid URI.</p>
</div>
<div class="section" id="equality-and-comparison-operators">
<h3>Equality and Comparison Operators<a class="headerlink" href="#equality-and-comparison-operators" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">enum</span> <span class="n">uri_comparison_level</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span>  <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span>  <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: This proposal specifies common overloads of the equality,
inequality and comparison. The equality and inequality operators
test two <tt class="docutils literal"><span class="pre">uri</span></tt> objects according to the notion of <em>equivalence</em>
(<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-6.1">RFC 3986, section 6.1</a> and <a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-6.2">RFC 3986, section 6.2</a>).</div>
</div>
</div>
<div class="section" id="stream-operators">
<h3>Stream Operators<a class="headerlink" href="#stream-operators" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span>
<span class="k">operator</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Output stream operator for <tt class="docutils literal"><span class="pre">std::experimental::uri</span></tt>.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span>
<span class="k">operator</span> <span class="o">&gt;&gt;</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">is</span><span class="p">,</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Input stream operator for <tt class="docutils literal"><span class="pre">std::experimental::uri</span></tt>.</p>
</div>
</div>
<span id="document-error_reporting"></span><div class="section" id="error-reporting">
<span id="id1"></span><h2>Error Reporting<a class="headerlink" href="#error-reporting" title="Permalink to this headline">¶</a></h2>
<p>The proposed <tt class="docutils literal"><span class="pre">std::experimental::uri</span></tt> class constructor throws a
<tt class="docutils literal"><span class="pre">std::experimental::uri_syntax_error</span></tt> exception if the URI string
passed as an argument is an invalid URI. A factory function,
<tt class="docutils literal"><span class="pre">std::experimental::make_uri</span></tt> is provided that sets an error code to
report an error.</p>
<p>The proposed <tt class="docutils literal"><span class="pre">std::experimental::uri::encode_*</span></tt> and
<tt class="docutils literal"><span class="pre">std::experimental::uri::decode</span></tt> throw a <tt class="docutils literal"><span class="pre">uri_encoding_error</span></tt>.</p>
<p>The <tt class="docutils literal"><span class="pre">uri</span></tt> member function of <tt class="docutils literal"><span class="pre">std::experimental::uri_builder</span></tt> can
also throw a <tt class="docutils literal"><span class="pre">std::experimental::uri_builder_error</span></tt> exception if it
is not possible to build a valid URI.</p>
<p><tt class="docutils literal"><span class="pre">std::experimental::uri_syntax_error</span></tt>, <tt class="docutils literal"><span class="pre">std::uri_encoding_error</span></tt>
and <tt class="docutils literal"><span class="pre">std::experimental::uri_builder_error</span></tt> are all subclasses of
<tt class="docutils literal"><span class="pre">std::system_error</span></tt>.</p>
<p>An <tt class="docutils literal"><span class="pre">enum</span></tt> <tt class="docutils literal"><span class="pre">class</span></tt>, <tt class="docutils literal"><span class="pre">std::experimental::uri_error</span></tt>, forms a part
of this proposal, and its values are used to indicate the type of URI
error in a <tt class="docutils literal"><span class="pre">std::error_code</span></tt> object.</p>
<p><tt class="docutils literal"><span class="pre">std::experimental::uri</span></tt> constructors can throw <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt>
on a failure to allocate storage.</p>
</div>
<span id="document-class_uri"></span><div class="section" id="class-uri">
<span id="id1"></span><h2>Class <tt class="docutils literal"><span class="pre">uri</span></tt><a class="headerlink" href="#class-uri" title="Permalink to this headline">¶</a></h2>
<p>Below is the proposed interface for the <tt class="docutils literal"><span class="pre">uri</span></tt> class:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">uri</span> <span class="p">{</span>

<span class="k">public</span><span class="o">:</span>

    <span class="c1">// typedefs</span>
    <span class="k">typedef</span> <span class="p">...</span> <span class="n">string_type</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">string_type</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">iterator</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">string_type</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">const_iterator</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;::</span><span class="n">value_type</span> <span class="n">value_type</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">basic_string_view</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;</span> <span class="n">string_view</span><span class="p">;</span>

    <span class="c1">// constructors and destructor</span>
    <span class="n">uri</span><span class="p">();</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
    <span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIter</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIter</span> <span class="o">&amp;</span><span class="n">last</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">());</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
    <span class="k">explicit</span> <span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">());</span>
    <span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">);</span>
    <span class="n">uri</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="o">~</span><span class="n">uri</span><span class="p">();</span>

    <span class="c1">// assignment</span>
    <span class="n">uri</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">);</span>
    <span class="n">uri</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">uri</span> <span class="o">&amp;&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>

    <span class="c1">// swap</span>
    <span class="kt">void</span> <span class="n">swap</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>

    <span class="c1">// iterators</span>
    <span class="n">const_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">const_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

    <span class="c1">// accessors</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">scheme</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">user_info</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">host</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">port</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">path</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">authority</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">query</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">fragment</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

    <span class="c1">// query</span>
    <span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">is_absolute</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">is_opaque</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>

    <span class="c1">// transformers</span>
    <span class="n">uri</span> <span class="n">normalize</span><span class="p">(</span><span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">uri</span> <span class="n">normalize</span><span class="p">(</span><span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">ec</span><span class="p">)</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="n">uri</span> <span class="n">make_reference</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">uri</span> <span class="n">make_reference</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">,</span>
                       <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">ec</span><span class="p">)</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="n">uri</span> <span class="n">resolve</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">uri</span> <span class="n">resolve</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">,</span>
                <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&amp;</span><span class="n">ec</span><span class="p">)</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>

    <span class="c1">// comparison</span>
    <span class="kt">int</span> <span class="n">compare</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>

    <span class="c1">// string accessors</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span>
              <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;</span><span class="p">,</span>
              <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="p">,</span> <span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">string</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">u16string</span> <span class="n">u16string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">u32string</span> <span class="n">u32string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

    <span class="c1">// percent encoding and decoding</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_user_info</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_host</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_port</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_path</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_query</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">encode_fragment</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
    <span class="k">static</span> <span class="n">OutputIter</span> <span class="n">decode</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>

<span class="p">};</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">uri</span></tt> class itself is a little more than a light-weight wrapper
around a string, a parser and the <tt class="docutils literal"><span class="pre">uri</span></tt>&#8216;s component parts. Parsing
is performed upon construction and, if successfully parsed, the
component parts are stored as <tt class="docutils literal"><span class="pre">string_view</span></tt>&#8216;s that reference the
original string. For example, consider the following URI:</p>
<div class="highlight-python"><pre>http://www.example.com/path/?key=value#fragment
^   ^  ^              ^     ^^        ^^       ^
a   b  c              d     ef        gh       i</pre>
</div>
<p>On parsing, the uri object will contain a set of range types
corresponding to the ranges for <strong>scheme</strong>, <strong>user info</strong>, <strong>host</strong>,
<strong>port</strong>, <strong>path</strong>, <strong>query</strong> and <strong>fragment</strong>. So the ranges
corresponding to the example above will be:</p>
<table border="1" class="docutils">
<colgroup>
<col width="32%" />
<col width="15%" />
<col width="54%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">URI part</th>
<th class="head">Range</th>
<th class="head">String</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">scheme</span></tt></td>
<td>[a, b)</td>
<td><tt class="docutils literal"><span class="pre">&quot;http&quot;</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">user_info</span></tt></td>
<td>&nbsp;</td>
<td><tt class="docutils literal"><span class="pre">nullopt</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">host</span></tt></td>
<td>[c, d)</td>
<td><tt class="docutils literal"><span class="pre">&quot;www.example.com&quot;</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">port</span></tt></td>
<td>&nbsp;</td>
<td><tt class="docutils literal"><span class="pre">nullopt</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">path</span></tt></td>
<td>[d, e)</td>
<td><tt class="docutils literal"><span class="pre">&quot;/path/&quot;</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">query</span></tt></td>
<td>[f, g)</td>
<td><tt class="docutils literal"><span class="pre">&quot;key=value&quot;</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">fragment</span></tt></td>
<td>[h, i)</td>
<td><tt class="docutils literal"><span class="pre">&quot;fragment&quot;</span></tt></td>
</tr>
</tbody>
</table>
<div class="section" id="uri-requirements">
<h3><tt class="docutils literal"><span class="pre">uri</span></tt> Requirements<a class="headerlink" href="#uri-requirements" title="Permalink to this headline">¶</a></h3>
<p>Template parameters named <tt class="docutils literal"><span class="pre">InputIter</span></tt> are required meet the
requirements for a C++ standard library <tt class="docutils literal"><span class="pre">RandomIterator</span></tt> compliant
iterator. The iterator&#8217;s value type is required to be <tt class="docutils literal"><span class="pre">char</span></tt>,
<tt class="docutils literal"><span class="pre">wchar_t</span></tt>, <tt class="docutils literal"><span class="pre">char16_t</span></tt>, or <tt class="docutils literal"><span class="pre">char32_t</span></tt>.</p>
<p>Template parameters named <tt class="docutils literal"><span class="pre">Source</span></tt> are required to be one of:</p>
<p>A container with a value type of <tt class="docutils literal"><span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">wchar_t</span></tt>, <tt class="docutils literal"><span class="pre">char16_t</span></tt>,
or <tt class="docutils literal"><span class="pre">char32_t</span></tt>.</p>
<p>An iterator for a null terminated byte-string. The value type is
required to be <tt class="docutils literal"><span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">wchar_t</span></tt>, <tt class="docutils literal"><span class="pre">char16_t</span></tt>, or <tt class="docutils literal"><span class="pre">char32_t</span></tt>.</p>
<p>A C-array. The value type is required to be <tt class="docutils literal"><span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">wchar_t</span></tt>,
<tt class="docutils literal"><span class="pre">char16_t</span></tt>, or <tt class="docutils literal"><span class="pre">char32_t</span></tt>.</p>
<p>This is identical wording to that found in the filesystem proposal
(<a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3365.html">N3365</a>).</p>
</div>
<div class="section" id="typedef-s">
<h3><tt class="docutils literal"><span class="pre">typedef</span></tt> s<a class="headerlink" href="#typedef-s" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">typedef</span> <span class="p">...</span> <span class="n">string_type</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">string_type</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">iterator</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">string_type</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">const_iterator</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;::</span><span class="n">value_type</span> <span class="n">value_type</span><span class="p">;</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">string_type</span></tt> is left unspecified in this proposal and is
intended to be <strong>implementation defined</strong>.</p>
</div>
<div class="section" id="constructors-and-destructors">
<h3>Constructors and Destructors<a class="headerlink" href="#constructors-and-destructors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span><span class="p">();</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">empty()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIter</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIter</span> <span class="o">&amp;</span><span class="n">last</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">());</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The range is copied into the <tt class="docutils literal"><span class="pre">uri</span></tt> object and
parsed. The encoding is assumed to depend on the
underlying character type and operating system.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt>, <tt class="docutils literal"><span class="pre">std::system_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Source</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;&gt;</span>
<span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">,</span> <span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">());</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The source is copied into the <tt class="docutils literal"><span class="pre">uri</span></tt> object and
parsed. The encoding is assumed to depend on the
underlying character type and operating system.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The source <tt class="docutils literal"><span class="pre">uri</span></tt> string is copied to the new <tt class="docutils literal"><span class="pre">uri</span></tt>
object.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The source <tt class="docutils literal"><span class="pre">uri</span></tt> string is moved to the new <tt class="docutils literal"><span class="pre">uri</span></tt>
object.</div>
</div>
</div>
<div class="section" id="assignment">
<h3>Assignment<a class="headerlink" href="#assignment" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The uri is copy assigned to the <tt class="docutils literal"><span class="pre">uri</span></tt> object.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">uri</span> <span class="o">&amp;&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The uri is move assigned to the <tt class="docutils literal"><span class="pre">uri</span></tt> object.</div>
</div>
</div>
<div class="section" id="swap">
<h3>Swap<a class="headerlink" href="#swap" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="n">swap</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">)</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Swaps the contents of <tt class="docutils literal"><span class="pre">this</span></tt> object with the other.</div>
</div>
</div>
<div class="section" id="iterators">
<h3>Iterators<a class="headerlink" href="#iterators" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">const_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the first element in the underlying string
container.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">const_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the end of the underlying string
container.</div>
</div>
</div>
<div class="section" id="accessors">
<h3>Accessors<a class="headerlink" href="#accessors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">scheme</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the scheme in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">user_info</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the user info in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">host</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the host in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">port</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the port in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">path</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the path in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">authority</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the authority in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">query</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the query in the underlying URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">string_view</span><span class="o">&gt;</span> <span class="n">fragment</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">std::optional&lt;string_view&gt;</span></tt> object which spans the range of
the fragment in the underlying URI.</div>
</div>
</div>
<div class="section" id="query">
<h3>Query<a class="headerlink" href="#query" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: <tt class="docutils literal"><span class="pre">true</span></tt> if the underlying string object is empty,
<tt class="docutils literal"><span class="pre">false</span></tt> otherwise.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">bool</span> <span class="n">is_absolute</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: <tt class="docutils literal"><span class="pre">true</span></tt> if the URI is absolute. Equivalent to
<tt class="docutils literal"><span class="pre">!scheme().empty()</span></tt>.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">bool</span> <span class="n">is_opaque</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: <tt class="docutils literal"><span class="pre">true</span></tt> if the URI is absolute and its scheme is not
hierarchical (i.e. scheme-specific does not start with a
double-slash <tt class="docutils literal"><span class="pre">//</span></tt> and its authority is empty).</div>
</div>
</div>
<div class="section" id="transformers">
<h3>Transformers<a class="headerlink" href="#transformers" title="Permalink to this headline">¶</a></h3>
<p>This proposal specifies three transformer functions: <tt class="docutils literal"><span class="pre">normalize</span></tt>,
<tt class="docutils literal"><span class="pre">make_reference</span></tt> and <tt class="docutils literal"><span class="pre">resolve</span></tt>.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span> <span class="n">normalize</span><span class="p">(</span><span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">u.normalize(level)</span> <span class="pre">==</span> <span class="pre">u</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: <tt class="docutils literal"><span class="pre">normalize</span></tt> takes as an argument a <tt class="docutils literal"><span class="pre">uri</span></tt> object and
returns a normalized <tt class="docutils literal"><span class="pre">uri</span></tt> object.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span> <span class="n">make_reference</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">!u1.make_reference(u2,</span> <span class="pre">level).absolute()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Returns a relative URI reference.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">base_uri</span><span class="p">(</span><span class="s">&quot;http://www.example.com/&quot;</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">&quot;http://www.example.com/glynos/?key=value#fragment&quot;</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">rel_uri</span><span class="p">(</span><span class="n">base_uri</span><span class="p">.</span><span class="n">make_reference</span><span class="p">(</span><span class="n">uri</span><span class="p">,</span>
                               <span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri_comparison_level</span><span class="o">::</span><span class="n">string_comparison</span><span class="p">));</span>
<span class="n">assert</span><span class="p">(</span><span class="n">rel_uri</span><span class="p">.</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;/glynos/?key=value#fragment&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span> <span class="n">resolve</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">u1.resolve(u2,</span> <span class="pre">level).absolute()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: <tt class="docutils literal"><span class="pre">resolve</span></tt> resolves the second <tt class="docutils literal"><span class="pre">uri</span></tt> object against
the first, and returns a new <tt class="docutils literal"><span class="pre">uri</span></tt>.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">int</span> <span class="n">compare</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">other</span><span class="p">,</span> <span class="n">uri_comparison_level</span> <span class="n">level</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>:</div>
</div>
<blockquote>
<div>Returns -1 if this is less than <tt class="docutils literal"><span class="pre">other</span></tt>, given the comparison
<tt class="docutils literal"><span class="pre">level</span></tt>; 0 if they are considered equal and 1 if this is greater.</div></blockquote>
</div>
<div class="section" id="string-accessors">
<h3>String Accessors<a class="headerlink" href="#string-accessors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">CharT</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">CharTraits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;</span><span class="p">,</span>
          <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o">&lt;</span><span class="n">CharT</span><span class="o">&gt;&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o">&lt;</span><span class="n">CharT</span><span class="p">,</span> <span class="n">CharTraits</span><span class="p">,</span> <span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">string</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span> <span class="o">&amp;</span><span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">u16string</span> <span class="n">u16string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">u32string</span> <span class="n">u32string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt></div>
</div>
</div>
<div class="section" id="percent-encoding-and-decoding">
<h3>Percent Encoding and Decoding<a class="headerlink" href="#percent-encoding-and-decoding" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_user_info</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the user_info part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC
3986, section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">user_info</span></tt> string
that has been encoded.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_host</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the host part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986,
section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">host</span></tt> string that
has been encoded.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_port</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the port part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986,
section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">port</span></tt> string that
has been encoded.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_path</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the path part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986,
section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">path</span></tt> string that
has been encoded.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_query</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the query part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986,
section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">query</span></tt> string that
has been encoded.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
<span class="n">encode_fragment</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters for the fragment part (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986,
section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::experimental::uri_encoding_error</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">fragment</span></tt> string that
has been encoded.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIter</span><span class="p">,</span> <span class="k">typename</span> <span class="n">OutputIter</span><span class="o">&gt;</span>
<span class="k">static</span> <span class="n">OutputIter</span>
 <span class="n">decode</span><span class="p">(</span><span class="n">InputIter</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIter</span> <span class="n">last</span><span class="p">,</span> <span class="n">OutputIter</span> <span class="n">out</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Decodes special characters in the source string and
returns the unencoded string (<a class="reference external" href="http://tools.ietf.org/html/rfc3986#section-2.1">RFC 3986, section 2.1</a>).</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: An iterator to the last element of a <tt class="docutils literal"><span class="pre">uri</span></tt> string that
has been decoded.</div>
</div>
</div>
</div>
<span id="document-class_uri_builder"></span><div class="section" id="class-uri-builder">
<span id="id1"></span><h2>Class <tt class="docutils literal"><span class="pre">uri_builder</span></tt><a class="headerlink" href="#class-uri-builder" title="Permalink to this headline">¶</a></h2>
<p>The proposed <tt class="docutils literal"><span class="pre">uri_builder</span></tt> class is provided in order to construct
<tt class="docutils literal"><span class="pre">uri</span></tt> objects more safely and more productively.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">uri_builder</span> <span class="p">{</span>

<span class="k">private</span><span class="o">:</span>

    <span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>

<span class="k">public</span><span class="o">:</span>

    <span class="n">uri_builder</span><span class="p">();</span>
    <span class="k">explicit</span> <span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">base</span><span class="p">);</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="k">explicit</span> <span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">base</span><span class="p">);</span>
    <span class="o">~</span><span class="n">uri_builder</span><span class="p">();</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">scheme</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">scheme</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">user_info</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">user_info</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">port</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">port</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">user_info</span><span class="p">,</span> <span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">,</span> <span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">port</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">append_path</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">query</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">query</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Key</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Param</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">query</span><span class="p">(</span><span class="k">const</span> <span class="n">Key</span> <span class="o">&amp;</span><span class="n">key</span><span class="p">,</span> <span class="k">const</span> <span class="n">Param</span> <span class="o">&amp;</span><span class="n">param</span><span class="p">);</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
    <span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">fragment</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">fragment</span><span class="p">);</span>

    <span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

<span class="p">};</span>
<span class="p">}</span> <span class="c1">// namespace experimental</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>The builder member functions are templates. This can allow the
implementation to provide specializations depending on the argument
type in order ensure that resultant URI remains valid and
consistent. This could mean performing normalization or percent
encoding on input strings where appropriate, and could allow other
types to be used.  For example, the port could be provided as an
integral type.</p>
<p>To build a <tt class="docutils literal"><span class="pre">uri</span></tt> object, invoke the <tt class="docutils literal"><span class="pre">uri_builder::uri()</span></tt>
member function. All encoding takes place here, and a
<tt class="docutils literal"><span class="pre">std::system_error</span></tt> is thrown in case the uri is invalid.</p>
<div class="line-block">
<div class="line"><cite>Example 1</cite>:</div>
</div>
<p>The first example shows that the <tt class="docutils literal"><span class="pre">uri_builder</span></tt> can build a <tt class="docutils literal"><span class="pre">uri</span></tt>
with a port number supplied as an integer. Also, since the
<tt class="docutils literal"><span class="pre">uri_builder</span></tt> also handles normalization, a trailing slash is added
where a path was not provided.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri_builder</span> <span class="n">builder</span><span class="p">;</span>
<span class="n">builder</span><span class="p">.</span><span class="n">scheme</span><span class="p">(</span><span class="s">&quot;http&quot;</span><span class="p">)</span>
       <span class="p">.</span><span class="n">host</span><span class="p">(</span><span class="s">&quot;example.com&quot;</span><span class="p">)</span>
       <span class="p">.</span><span class="n">port</span><span class="p">(</span><span class="mi">8080</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">builder</span><span class="p">.</span><span class="n">uri</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;http://example.com:8080/&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Example 2</cite>:</div>
</div>
<p>The builder should work with any scheme. The second example shows how
the <tt class="docutils literal"><span class="pre">uri_builder</span></tt> would be used to create an e-mail address using
the <tt class="docutils literal"><span class="pre">mailto</span></tt> scheme.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri_builder</span> <span class="n">builder</span><span class="p">;</span>
<span class="n">builder</span><span class="p">.</span><span class="n">scheme</span><span class="p">(</span><span class="s">&quot;mailto&quot;</span><span class="p">)</span>
       <span class="p">.</span><span class="n">path</span><span class="p">(</span><span class="s">&quot;glynos@example.com&quot;</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">builder</span><span class="p">.</span><span class="n">uri</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;mailto:glynos@example.com&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Example 3</cite>:</div>
</div>
<p>The third example shows how the builder should normalize all parts of
the URI.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">experimental</span><span class="o">::</span><span class="n">uri_builder</span> <span class="n">builder</span><span class="p">;</span>
<span class="n">builder</span><span class="p">.</span><span class="n">scheme</span><span class="p">(</span><span class="s">&quot;http&quot;</span><span class="p">)</span>
       <span class="p">.</span><span class="n">host</span><span class="p">(</span><span class="s">&quot;Example.com&quot;</span><span class="p">)</span>
       <span class="p">.</span><span class="n">path</span><span class="p">(</span><span class="s">&quot;%7Eglynos//My Path/&quot;</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">builder</span><span class="p">.</span><span class="n">uri</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;http://example.com/~glynos/My%20Path/&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="section" id="constructors">
<h3>Constructors<a class="headerlink" href="#constructors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="n">uri_builder</span><span class="o">::</span><span class="n">uri_builder</span><span class="p">();</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Constructs a <tt class="docutils literal"><span class="pre">uri_builder</span></tt> object.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="n">uri_builder</span><span class="o">::</span><span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">base</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Constructs a <tt class="docutils literal"><span class="pre">uri_builder</span></tt> object from a base URI.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span><span class="o">::</span><span class="n">uri_builder</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">base</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Constructs a <tt class="docutils literal"><span class="pre">uri_builder</span></tt> object from a base URI.</p>
</div>
<div class="section" id="builder-functions">
<h3>Builder functions<a class="headerlink" href="#builder-functions" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">scheme</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">scheme</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI scheme.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">user_info</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">user_info</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI user_info.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">host</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI host.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">port</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">port</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI port.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI authority.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">authority</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">user_info</span><span class="p">,</span> <span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">,</span> <span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">port</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI user info, host and port.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">path</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI path.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">append_path</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Appends an element to the <tt class="docutils literal"><span class="pre">uri</span></tt> object&#8217;s path.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">query</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">query</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI query.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Key</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Param</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">query</span><span class="p">(</span><span class="k">const</span> <span class="n">Key</span> <span class="o">&amp;</span><span class="n">key</span><span class="p">,</span> <span class="k">const</span> <span class="n">Param</span> <span class="o">&amp;</span><span class="n">param</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Appends a key-value pair to the <tt class="docutils literal"><span class="pre">uri</span></tt> object&#8217;s query.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri_builder</span> <span class="o">&amp;</span><span class="n">uri_builder</span><span class="o">::</span><span class="n">fragment</span><span class="p">(</span><span class="k">const</span> <span class="n">Source</span> <span class="o">&amp;</span><span class="n">fragment</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Sets the URI fragment.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Source</span><span class="o">&gt;</span>
<span class="n">uri</span> <span class="n">uri_builder</span><span class="o">::</span><span class="n">uri</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Builds a URI object from the provided parts.</div>
</div>
<div class="line-block">
<div class="line"><cite>Throws</cite>: <tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt>, <tt class="docutils literal"><span class="pre">std::system_error</span></tt></div>
</div>
</div>
</div>
<span id="document-appendix"></span><div class="section" id="appendix">
<span id="id1"></span><h2>Appendix<a class="headerlink" href="#appendix" title="Permalink to this headline">¶</a></h2>
<div class="section" id="existing-practice">
<h3>Existing Practice<a class="headerlink" href="#existing-practice" title="Permalink to this headline">¶</a></h3>
<p>There exist several implementations of C++, including (but not limited
to):</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/cpp-netlib/uri/">cpp-netlib</a></li>
<li><a class="reference external" href="http://qt-project.org/doc/qt-4.8/qurl.html">QUrl</a> (From Qt)</li>
<li><a class="reference external" href="http://code.google.com/p/google-url/">google-url</a></li>
<li><a class="reference external" href="http://casablanca.codeplex.com/wikipage?title=URI&amp;referringTitle=Documentation">Casablanca</a></li>
</ul>
<p>The <cite>cpp-netlib</cite> uri is the library that has motivated this
proposal. It implements a generic URI, support for percent encoding,
normalization and URI resolution. It also currently partially
implements a URI builder.</p>
<p><cite>QUrl</cite> supports much of the same functionality. It is fully
internationalized, supports URI resolution and implicitly
normalization. The part accessors differ from <cite>cpp-netlib</cite>, in that
they return copies of the underlying parts, not references.</p>
<p><cite>google-url</cite> is another existing library which is fast and robust. Its
parsing strategy is such that it never fails (there is no validation),
but always tries to find the best fit for the URL components. It
supports normalization (but has called it canonicalization).</p>
<p>All of the implementations listed above do effectively the same
thing - they parse a string and split it into components, either by
storing separate copies of each part or by storing references to
sub-strings in the original uri string.</p>
</div>
<div class="section" id="whatwg-url-standard">
<h3>WhatWG URL Standard<a class="headerlink" href="#whatwg-url-standard" title="Permalink to this headline">¶</a></h3>
<p>In addition to <a class="reference external" href="http://tools.ietf.org/html/rfc3986">RFC 3986</a> and <a class="reference external" href="http://tools.ietf.org/html/rfc3987">RFC 3987</a>, the <a class="reference external" href="http://url.spec.whatwg.org/">WhatWG URL Standard</a>
is proposal for a standard that sets out to make URLs more
interoperable.</p>
<p>The most important features of this proposed standard seem to be:</p>
<ul class="simple">
<li>The obsolescence of <a class="reference external" href="http://tools.ietf.org/html/rfc3986">RFC 3986</a> and <a class="reference external" href="http://tools.ietf.org/html/rfc3987">RFC 3987</a> and an alignment of
the URL with modern implementations</li>
<li>To standardize on the term <cite>URL</cite>, instead of <cite>URI</cite> or <cite>IRI</cite></li>
<li>A detailed definition of the URL JavaScript API</li>
</ul>
<p>It does not explicitly describe operations such as normalization,
comparison or resolution.</p>
<p>As this proposal allows the URI parsing to be implementation defined,
there is no reason why an implementor could not decide to use this
standard. Apart from a few naming differences, the proposed <tt class="docutils literal"><span class="pre">uri</span></tt>
interface maps closely to the WhatWG <cite>URL</cite> JavaScript <a class="reference external" href="http://url.spec.whatwg.org/#api">API</a>. If there
is a strong interest in doing so, a future revision of this proposal
could rename its class and member functions.</p>
</div>
</div>
<span id="document-acknowledgements"></span><div class="section" id="acknowledgements">
<span id="id1"></span><h2>Acknowledgements<a class="headerlink" href="#acknowledgements" title="Permalink to this headline">¶</a></h2>
<p>C++ Network Library users and mailing list</p>
<p>Kyle Kloepper and Niklas Gustafsson for providing valuable feedback
and encouragement, and for presenting different versions of this
proposal at committee meetings.</p>
<p>Beman Dawes and his Filesystem proposal from which I was influenced
strongly in the class design.</p>
<p>Wikipedia, for being there.</p>
</div>
<span id="document-references"></span><div class="section" id="references">
<span id="id1"></span><h2>References<a class="headerlink" href="#references" title="Permalink to this headline">¶</a></h2>
<div class="line-block">
<div class="line"><strong>RFC 3986</strong>: <a class="reference external" href="http://tools.ietf.org/html/rfc3986">http://tools.ietf.org/html/rfc3986</a></div>
<div class="line"><strong>RFC 3987</strong>: <a class="reference external" href="http://tools.ietf.org/html/rfc3987">http://tools.ietf.org/html/rfc3987</a></div>
<div class="line"><strong>RFC 2732</strong>: <a class="reference external" href="http://tools.ietf.org/html/rfc2732">http://tools.ietf.org/html/rfc2732</a></div>
<div class="line"><strong>Filesystem Library Proposal (Revision 4)</strong>: <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3505.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3505.html</a></div>
<div class="line"><strong>Uri Class (C#)</strong>: <a class="reference external" href="http://msdn.microsoft.com/en-us/library/system.uri.aspx">http://msdn.microsoft.com/en-us/library/system.uri.aspx</a></div>
<div class="line"><strong>Uri Class (Java)</strong>: <a class="reference external" href="http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URI.html">http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URI.html</a></div>
<div class="line"><strong>Uri Class (Android)</strong>: <a class="reference external" href="http://developer.android.com/reference/android/net/Uri.html">http://developer.android.com/reference/android/net/Uri.html</a></div>
<div class="line"><strong>URI (Casablanca)</strong>: <a class="reference external" href="http://msdn.microsoft.com/en-US/devlabs/hh977125.aspx">http://msdn.microsoft.com/en-US/devlabs/hh977125.aspx</a></div>
</div>
</div>
</div>
</div>


          </div>
      </div>

      <div class="clearer"></div>
    </div>
    <div class="footer">
    </div>
  </body>
</html>