<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0038)http://glynos.github.com/uri_proposal/ -->
<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="http://glynos.github.com/uri_proposal/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="http://glynos.github.com/uri_proposal/#a-uri-library-for-c" title="Permalink to this headline">¶</a></h1>
<div class="line-block">
<div class="line"><strong>Document Number</strong>: N3420=12-0110</div>
<div class="line"><strong>Date</strong>: 2012-09-21</div>
<div class="line"><strong>Authors</strong>: Glyn Matthews &lt;<a class="reference external" href="mailto:glynos%40acm.org">glynos<span>@</span>acm<span>.</span>org</a>&gt;, Dean Michael Berris &lt;<a class="reference external" href="mailto:dberris%40google.com">dberris<span>@</span>google<span>.</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="http://glynos.github.com/uri_proposal/#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.github.com/">http://cpp-netlib.github.com/</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.</p>
<p>The scope of this proposal will include a single <cite>uri</cite> 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>
<p>This is a preliminary proposal. There are still many omissions and the
most important open issues are listed in the final section.</p>
<div class="section" id="example-usage">
<h3>Example Usage<a class="headerlink" href="http://glynos.github.com/uri_proposal/#example-usage" 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">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">"http://www.example.com/glynos/?key=value#frag"</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_valid</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="n">uri</span><span class="p">.</span><span class="n">scheme</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"http"</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">host</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"www.example.com"</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">path</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"/glynos/"</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">query</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"?key=value"</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">fragment</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"frag"</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> 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="n">std</span><span class="o">::</span><span class="n">network</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">"xmpp:example-node@example.com?message;subject=Hello%20World"</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_valid</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="n">uri</span><span class="p">.</span><span class="n">scheme</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"xmpp"</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">path</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"example-node@example.com"</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">query</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"?message;subject=Hello%20World"</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</span></tt> objects in UTF-8 encoding.</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="http://glynos.github.com/uri_proposal/#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">"//"</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">"@"</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">":"</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 starting with a question mark
<tt class="docutils literal"><span class="pre">"?"</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">"#"</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="http://glynos.github.com/uri_proposal/#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">@</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">"</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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#removing-dot-segments-from-the-path" title="Permalink to this headline">¶</a></h3>
<p>The segments <cite>”..”</cite> and <cite>”.”</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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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-network-uri-synopsis">
<span id="header-synopsis"></span><h2>Header <tt class="docutils literal"><span class="pre">&lt;network/uri&gt;</span></tt> Synopsis<a class="headerlink" href="http://glynos.github.com/uri_proposal/#header-network-uri-synopsis" title="Permalink to this headline">¶</a></h2>
<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">network</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="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">// hash functions</span>
<span class="n">std</span><span class="o">::</span><span class="n">size_t</span> <span class="n">hash_value</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="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">// percent encoding and decoding</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</span>
<span class="n">String</span> <span class="n">pct_encode</span><span class="p">(</span><span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</span>
<span class="n">String</span> <span class="n">pct_decode</span><span class="p">(</span><span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">);</span>

<span class="c1">// stream operators</span>
<span class="n">std</span><span class="o">::</span><span class="n">ostream</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">ostream</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="n">std</span><span class="o">::</span><span class="n">wostream</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">wostream</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="n">std</span><span class="o">::</span><span class="n">istream</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">istream</span> <span class="o">&amp;</span><span class="n">os</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="n">std</span><span class="o">::</span><span class="n">wistream</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">wistream</span> <span class="o">&amp;</span><span class="n">os</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="c1">// transformers</span>
<span class="n">uri</span> <span class="n">normalize</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="n">uri</span> <span class="n">relativize</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u2</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">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u2</span><span class="p">);</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</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">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">u2</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</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="http://glynos.github.com/uri_proposal/#declarations" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">&lt;network/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::network</span></tt> namespace.</p>
<p>At this stage, the sub-namespace <tt class="docutils literal"><span class="pre">network</span></tt> namespace should be
regarded as a placeholder for a namespace specified for network
components during the standardization process (should such as
sub-namespace be specified).</p>
</div>
<div class="section" id="equality-and-comparison-operators">
<h3>Equality and Comparison Operators<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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">network</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 network</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="percent-encoding-and-decoding">
<h3>Percent Encoding and Decoding<a class="headerlink" href="http://glynos.github.com/uri_proposal/#percent-encoding-and-decoding" 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">network</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</span>
<span class="n">String</span> <span class="n">pct_encode</span><span class="p">(</span><span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Encodes special characters in the source string and
returns the encoded 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>: A percent encoded string.</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">s</span> <span class="o">=</span> <span class="s">"string with spaces"</span><span class="p">;</span>
<span class="n">assert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">pct_encode</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">==</span> <span class="s">"string%20with%20spaces"</span><span class="p">);</span>
</pre></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">namespace</span> <span class="n">network</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</span>
<span class="n">String</span> <span class="n">pct_decode</span><span class="p">(</span><span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">source</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</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>: A percent decoded string.</div>
</div>
</div>
<div class="section" id="stream-operators">
<h3>Stream Operators<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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">network</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">ostream</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">ostream</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="n">std</span><span class="o">::</span><span class="n">wostream</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">wostream</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>This proposal specifies output stream operators for character and wide
character streams.</p>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u.is_valid()</span></tt></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">namespace</span> <span class="n">network</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">istream</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">istream</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="n">std</span><span class="o">::</span><span class="n">wistream</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">wistream</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>This proposal specifies input stream operators for character and wide
character streams.</p>
</div>
<div class="section" id="transformers">
<h3>Transformers<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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">relativize</span></tt> and <tt class="docutils literal"><span class="pre">resolve</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">network</span> <span class="p">{</span>
<span class="n">uri</span> <span class="n">normalize</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u.is_valid()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">std::network::normalize(u).is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">std::network::normalize(u)</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 valid, normalized <tt class="docutils literal"><span class="pre">uri</span></tt> object.</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">namespace</span> <span class="n">network</span> <span class="p">{</span>
<span class="n">uri</span> <span class="n">relativize</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u2</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u1.is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">u2.is_valid()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">relativize(u1,</span> <span class="pre">u2).is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">!relativize(u1,</span> <span class="pre">u2).is_absolute()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Returns a relative URI.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">base_uri</span><span class="p">(</span><span class="s">"http://www.example.com/"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">"http://www.example.com/glynos/?key=value#fragment"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">network</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">relativize</span><span class="p">(</span><span class="n">uri</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">"?key=value#fragment"</span><span class="p">);</span>
</pre></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">namespace</span> <span class="n">network</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">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">u2</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u1.is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">u2.is_valid()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">resolve(u1,</span> <span class="pre">u2).is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">resolve(u1,</span> <span class="pre">u2).is_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="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">network</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">String</span><span class="o">&gt;</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">u1</span><span class="p">,</span> <span class="k">const</span> <span class="n">String</span> <span class="o">&amp;</span><span class="n">u2</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u1.is_valid()</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Postconditions</cite>: <tt class="docutils literal"><span class="pre">resolve(u1,</span> <span class="pre">u2).is_valid()</span> <span class="pre">&amp;&amp;</span> <span class="pre">resolve(u1,</span> <span class="pre">u2).is_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> parses <tt class="docutils literal"><span class="pre">u2</span></tt> and resolves it against
the first, and returns a new <tt class="docutils literal"><span class="pre">uri</span></tt>.</div>
</div>
</div>
</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="http://glynos.github.com/uri_proposal/#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">network</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="k">class</span> <span class="nc">builder</span><span class="p">;</span>

    <span class="c1">// typedefs</span>
    <span class="k">typedef</span> <span class="p">...</span> <span class="n">value_type</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">basic_string</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;</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="c1">// range types</span>
    <span class="k">class</span> <span class="nc">part_range</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">InputIterator</span><span class="o">&gt;</span>
    <span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">last</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="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">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="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIterator</span><span class="o">&gt;</span>
    <span class="kt">void</span> <span class="n">assign</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">last</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="kt">void</span> <span class="n">assign</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="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">part_range</span> <span class="n">scheme</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">user_info</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">host</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">port</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">path</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">authority</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</span> <span class="n">query</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="n">part_range</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_valid</span><span class="p">()</span> <span class="k">const</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="p">;</span>
    <span class="kt">bool</span> <span class="n">is_opaque</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

    <span class="c1">// string accessors</span>
    <span class="n">string_type</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</span>
    <span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span><span class="n">c_str</span><span class="p">()</span> <span class="k">const</span> <span class="n">noexcept</span><span class="p">;</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">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</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">u32string</span> <span class="n">u32string</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>The uri class itself is a little more than a light-weight wrapper
around a string, a parser and the uri’s component parts. Parsing is
performed upon construction and, if successfully parsed, the component
parts are stored as iterator ranges 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     e         fg       h</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">"http"</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">user_info</span></tt></td>
<td>[c, c)</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">host</span></tt></td>
<td>[c, d)</td>
<td><tt class="docutils literal"><span class="pre">"www.example.com"</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">port</span></tt></td>
<td>[d, d)</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">path</span></tt></td>
<td>[d, e)</td>
<td><tt class="docutils literal"><span class="pre">"/path/"</span></tt></td>
</tr>
<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">query</span></tt></td>
<td>[e, f)</td>
<td><tt class="docutils literal"><span class="pre">"?key=value"</span></tt></td>
</tr>
<tr class="row-even"><td><tt class="docutils literal"><span class="pre">fragment</span></tt></td>
<td>[g, h)</td>
<td><tt class="docutils literal"><span class="pre">"fragment"</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="http://glynos.github.com/uri_proposal/#uri-requirements" title="Permalink to this headline">¶</a></h3>
<p>Template parameters named <tt class="docutils literal"><span class="pre">InputIterator</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’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="http://glynos.github.com/uri_proposal/#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">value_type</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">basic_string</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;</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>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">value_type</span></tt> is left unspecified in this proposal and is
intended to <strong>implementation defined</strong>. This may be either <tt class="docutils literal"><span class="pre">char</span></tt>
for POSIX systems and <tt class="docutils literal"><span class="pre">wchar_t</span></tt> for Windows. This is influenced by
the standard filesystem <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3365.html">proposal</a>.</p>
</div>
<div class="section" id="constructors-and-destructors">
<h3>Constructors and Destructors<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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> and <tt class="docutils literal"><span class="pre">valid()</span> <span class="pre">==</span> <span class="pre">false</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">InputIterator</span><span class="o">&gt;</span>
<span class="n">uri</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">last</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></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="o">&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>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>:</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="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="assignment">
<h3>Assignment<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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>
<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="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">InputIterator</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">assign</span><span class="p">(</span><span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">first</span><span class="p">,</span> <span class="k">const</span> <span class="n">InputIterator</span> <span class="o">&amp;</span><span class="n">last</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="kt">void</span> <span class="n">assign</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>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: The source is assigned to 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></div>
</div>
</div>
<div class="section" id="swap">
<h3>Swap<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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="http://glynos.github.com/uri_proposal/#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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></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="http://glynos.github.com/uri_proposal/#accessors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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">part_range</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">part_range</span></tt> object which spans the range of
the path in the underlying URI.</div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">part_range</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">part_range</span></tt> object which spans the range of
the authority in the underlying URI.</div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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">part_range</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: Returns a <tt class="docutils literal"><span class="pre">part_range</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="http://glynos.github.com/uri_proposal/#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_valid</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>: <tt class="docutils literal"><span class="pre">true</span></tt> if the string object has been parsed and is a
valid URI and <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="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></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 valid and if the scheme is not
empty. 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="p">;</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></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-specific
part does not start with a double-slash <tt class="docutils literal"><span class="pre">//</span></tt>.</div>
</div>
</div>
<div class="section" id="string-accessors">
<h3>String Accessors<a class="headerlink" href="http://glynos.github.com/uri_proposal/#string-accessors" title="Permalink to this headline">¶</a></h3>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">string_type</span> <span class="n">native</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: The native string.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span><span class="n">c_str</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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: A raw pointer to the underlying character array.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Preconditions</cite>: <tt class="docutils literal"><span class="pre">is_valid()</span> <span class="pre">==</span> <span class="pre">true</span></tt></div>
</div>
</div>
</div>
<span id="document-part_range"></span><div class="section" id="part-range">
<span id="id1"></span><h2><tt class="docutils literal"><span class="pre">part_range</span></tt><a class="headerlink" href="http://glynos.github.com/uri_proposal/#part-range" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="docutils literal"><span class="pre">part_range</span></tt> is designed to give a reference to different URI
parts in the original URI string. It is no more than a pair of
iterators defining an immutable range, plus some accessors that copy
the characters in the range to different string types:</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">network</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">uri</span><span class="o">::</span><span class="n">part_range</span> <span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
    <span class="k">typedef</span> <span class="n">uri</span><span class="o">::</span><span class="n">iterator</span> <span class="n">iterator</span><span class="p">;</span>
    <span class="k">typedef</span> <span class="n">uri</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">const_iterator</span><span class="p">;</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">// string accessors</span>
    <span class="n">uri</span><span class="o">::</span><span class="n">string_type</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span><span class="p">;</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">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</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">u32string</span> <span class="n">u32string</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<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 representing the URI
part in the parsed URI string.</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 sequence of characters of
the URI part in the parsed URI string.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">uri</span><span class="o">::</span><span class="n">string_type</span> <span class="n">native</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>: A copy of the URI part in the native string format.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Returns</cite>: A copy of the URI part as a <tt class="docutils literal"><span class="pre">std::string</span></tt>. Any
unicode conversions are performed using UTF-8, where appropriate.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Returns</cite>: A copy of the URI part as a <tt class="docutils literal"><span class="pre">std::wstring</span></tt>.</div>
</div>
<div class="line-block">
<div class="line"><cite>Returns</cite>: A copy of the URI part as a <tt class="docutils literal"><span class="pre">std::wstring</span></tt>. Any
unicode conversions are performed using UTF-16, where appropriate.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Returns</cite>: A copy of the URI part as a <tt class="docutils literal"><span class="pre">std::u16string</span></tt>. Any
unicode conversions are performed using UTF-16.</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><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>Returns</cite>: A copy of the URI part as a <tt class="docutils literal"><span class="pre">std::u32string</span></tt>. Any
unicode conversions are performed using UTF-32.</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="http://glynos.github.com/uri_proposal/#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">network</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">uri</span><span class="o">::</span><span class="n">builder</span> <span class="p">{</span>

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

    <span class="n">builder</span><span class="p">(</span><span class="n">uri</span> <span class="o">&amp;</span><span class="n">uri</span><span class="p">);</span>
    <span class="n">builder</span><span class="p">(</span><span class="k">const</span> <span class="n">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">builder</span> <span class="o">&amp;</span><span class="k">operator</span> <span class="o">=</span> <span class="n">builder</span><span class="p">(</span><span class="k">const</span> <span class="n">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="o">~</span><span class="n">builder</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">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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">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">class</span> <span class="nc">Source</span><span class="o">&gt;</span>
    <span class="n">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="p">};</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>The builder methods 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 encoding transformations or percent encoding on input
strings where appropriate, and could allow, for example, the port to
be provided as an integral type. More detailed examples are provided
with the API description of each method below.</p>
<div class="line-block">
<div class="line"><cite>Example</cite>:</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span><span class="o">::</span><span class="n">builder</span> <span class="n">builder</span><span class="p">(</span><span class="n">uri</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">"http"</span><span class="p">)</span>
       <span class="p">.</span><span class="n">host</span><span class="p">(</span><span class="s">"example.com"</span><span class="p">)</span>
       <span class="p">.</span><span class="n">path</span><span class="p">(</span><span class="s">"/glynos/"</span><span class="p">)</span>
       <span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="s">"key"</span><span class="p">,</span> <span class="s">"value"</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">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"http://example.com/glynos/?key=value"</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="constructor">
<h3>Constructor<a class="headerlink" href="http://glynos.github.com/uri_proposal/#constructor" 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">network</span> <span class="p">{</span>
<span class="n">uri</span><span class="o">::</span><span class="n">builder</span><span class="o">::</span><span class="n">builder</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Preconditions</cite>: <tt class="docutils literal"><span class="pre">u.is_valid()</span></tt></div>
</div>
</div>
<div class="section" id="builder-functions">
<h3>Builder functions<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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">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 network</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">namespace</span> <span class="n">network</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">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 network</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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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’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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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">namespace</span> <span class="n">network</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</span><span class="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<div class="line-block">
<div class="line"><cite>Effects</cite>: Adds a key / value pair to the <tt class="docutils literal"><span class="pre">uri</span></tt> object’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">namespace</span> <span class="n">network</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="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">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 network</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>
</div>
<span id="document-issues"></span><div class="section" id="issues">
<span id="id1"></span><h2>Issues<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issues" title="Permalink to this headline">¶</a></h2>
<p>The following is a list of issues that have not yet been addressed as
part of this proposal.</p>
<div class="section" id="issue-1-text-encoding-and-interoperability">
<h3>Issue 1 - Text Encoding and Interoperability<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-1-text-encoding-and-interoperability" title="Permalink to this headline">¶</a></h3>
<p>The most important open issue for this proposal is how to deal with
text encoding in a portable way. The main difficulty is that different
platforms, libraries and applications use different encodings, Unicode
or otherwise. Interoperability is therefore extremely hard.</p>
<p>With the advent of <tt class="docutils literal"><span class="pre">char16_t</span></tt> and <tt class="docutils literal"><span class="pre">char32_t</span></tt>, and of
<tt class="docutils literal"><span class="pre">std::u16string</span></tt> and <tt class="docutils literal"><span class="pre">std::u32string</span></tt>, this problem has been
acknowledged and encoding can done more explicitly, but issues with
interoperability have not been addressed.</p>
<p>This proposal currently partially resolves interoperability issues by
using a template for functions and member functions when string
arguments are used. e.g. The <tt class="docutils literal"><span class="pre">uri</span></tt> constructor:</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">network</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="o">::</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="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
<p>Internally, the <tt class="docutils literal"><span class="pre">uri</span></tt> constructor can handle strings in different
encodings by using template specialization to perform the correct
transformation depending on the source type.</p>
<p>This can help simplify the library interface but is not completely
satisfactory. For example, template specialization is limited to only
those types known to the standard - <tt class="docutils literal"><span class="pre">std::basic_string</span></tt> and its
variants, plus character arrays. A proposal exists to add a
<tt class="docutils literal"><span class="pre">string_ref</span></tt> type to the standard (<a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html">N3334</a>), which could provide
better flexibility and performance. This would replace <tt class="docutils literal"><span class="pre">part_range</span></tt>
in the current proposal.</p>
<p>This approach is limited when returning strings from functions. e.g.:</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">network</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Result</span><span class="o">&gt;</span>
<span class="n">Result</span> <span class="n">scheme</span><span class="p">(</span><span class="k">const</span> <span class="n">uri</span> <span class="o">&amp;</span><span class="n">uri_</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>

<span class="p">...</span>

<span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">"http://example.com/"</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">scheme</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">scheme</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">u32string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">uri</span><span class="p">);</span>
</pre></div>
</div>
<p>The above excerpt cannot work with character array, character pointers
or <tt class="docutils literal"><span class="pre">string_ref</span></tt> since memory allocation is required.</p>
<p>Secondly, <a class="reference external" href="http://tools.ietf.org/html/rfc3987">RFC 3987</a> is not well supported and often unicode text is
converted using percent encoding:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span>
    <span class="s">"http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8"</span><span class="p">);</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">pct_encode</span></tt> and <tt class="docutils literal"><span class="pre">pct_decode</span></tt> functions should take this into
account.</p>
<p>Thirdly, the iterators returned by <tt class="docutils literal"><span class="pre">begin</span></tt> and <tt class="docutils literal"><span class="pre">end</span></tt> are not
portable with the proposal in its current form. This proposal allows
different internal character types, but the iterator types are
completely unaware of the encoding. So the following examples are not
portable:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span>
    <span class="s">"http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">u32string</span> <span class="n">u32</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</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">end</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">back_inserter</span><span class="p">(</span><span class="n">u32</span><span class="p">));</span>
</pre></div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span>
    <span class="s">"http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8"</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">path_range</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="n">std</span><span class="o">::</span><span class="n">u32string</span> <span class="n">path</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">path_range</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">path_range</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">path</span><span class="p">));</span>
</pre></div>
</div>
<p>This proposal as it stands needs better library or language support in
order offer better portability. One promising solution is given in
another standard proposal, <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3336.html">N3336</a>.</p>
</div>
<div class="section" id="issue-2-the-parser-implementation">
<h3>Issue 2 - The Parser Implementation<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-2-the-parser-implementation" title="Permalink to this headline">¶</a></h3>
<p>At this stage it is important to note that there are many
compatibility issues with URIs. If this proposal were to specify full
standard compliance, it may not work in practice. For example, the
<tt class="docutils literal"><span class="pre">uri</span></tt> parser implementation must correctly deal with escape control
characters. Furthermore, no RFC fully specifies how to parse Windows
file-system paths (e.g. <tt class="docutils literal"><span class="pre">file:///C:\path\to\a\file.txt</span></tt>). Finally,
it is the belief of the author of this proposal that its success
depends strongly on the correct portable behavior of the parser
implementation. Without wishing to run the risk of over-specifying the
parser, leaving it as “implementation defined” will not be
sufficient. There will be more issues that may need to specified in
further detail in future revisions of this proposal.</p>
<p>This proposal includes internationalized URIs (<a class="reference external" href="http://tools.ietf.org/html/rfc2732">RFC 2732</a>). Since
this RFC is not widely supported, and as many applications deal with
unicode characters through percent encoding, the parser implementation
could be simplified if appropriate by removing <a class="reference external" href="http://tools.ietf.org/html/rfc2732">RFC 2732</a> from this
proposal.</p>
</div>
<div class="section" id="issue-3-error-and-exception-handling">
<h3>Issue 3 - Error and Exception Handling<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-3-error-and-exception-handling" title="Permalink to this headline">¶</a></h3>
<p>The proposal in its current form does not propose a detailed error
handling mechanism, beyond providing a <tt class="docutils literal"><span class="pre">uri::is_valid()</span></tt> accessor to
determine if the URI is valid according to the parser.</p>
<p>There several potential sources for errors:</p>
<div class="line-block">
<div class="line"><strong>Parse errors</strong>: This will happen during object construction. If
parsing fails, the <tt class="docutils literal"><span class="pre">uri::is_valid()</span></tt> will always return
<tt class="docutils literal"><span class="pre">false</span></tt>, and the <tt class="docutils literal"><span class="pre">uri</span></tt> accessors are invalid.</div>
</div>
<div class="line-block">
<div class="line"><strong>Memory allocation failures</strong>: The underlying string can throw
<tt class="docutils literal"><span class="pre">std::bad_alloc</span></tt> from its constructor. This can therefore be
thrown from the <tt class="docutils literal"><span class="pre">uri</span></tt> constructors and assignment functions, as
well as other functions, such as <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>).</div>
</div>
<div class="line-block">
<div class="line"><strong>Builder errors</strong>: These come in two forms: firstly, the design of
<tt class="docutils literal"><span class="pre">uri::builder</span></tt> makes it possible fo the URI to be in an
intermediate state. <tt class="docutils literal"><span class="pre">uri.is_valid()</span></tt> will return <tt class="docutils literal"><span class="pre">false</span></tt> for
<tt class="docutils literal"><span class="pre">uri</span></tt> objects in such a state:</div>
</div>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span><span class="o">::</span><span class="n">builder</span> <span class="n">builder</span><span class="p">(</span><span class="n">uri</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">"http"</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_valid</span><span class="p">());</span>
<span class="n">builder</span><span class="p">.</span><span class="n">authority</span><span class="p">(</span><span class="s">"example.com"</span><span class="p">)</span>
       <span class="p">.</span><span class="n">path</span><span class="p">(</span><span class="s">"/glynos/"</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_valid</span><span class="p">());</span>
</pre></div>
</div>
<p>Secondly, passing illegal arguments to the <tt class="docutils literal"><span class="pre">builder</span></tt> has the same
effect: the resultant <tt class="docutils literal"><span class="pre">uri</span></tt> object is simply invalid again. This
proposal leaves a lot of scope for improvement in better error
reporting when building <tt class="docutils literal"><span class="pre">uri</span></tt> objects.</p>
<p>It may be appropriate to develop a <tt class="docutils literal"><span class="pre">uri_parse_error</span></tt> exception type
that can be thrown when a parse error occurs.</p>
</div>
<div class="section" id="issue-4-equivalence">
<h3>Issue 4 - Equivalence<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-4-equivalence" title="Permalink to this headline">¶</a></h3>
<p>As explained in the previous section on normalization, there is more
than one way to test if two URIs are equivalent depending on different
accuracy, performance and complexity trade-offs.</p>
<p>Providing a single <tt class="docutils literal"><span class="pre">operator</span> <span class="pre">==</span></tt> is sufficient to allow developers
to choose different ways of testing URI equivalence, although choosing
a good default comparison will be sufficient for the vast majority of
cases. Future revisions of this proposal could provide functionality
to allow a library to use different parts of the <cite>Comparison Ladder</cite>.</p>
</div>
<div class="section" id="issue-5-extending-the-uri">
<h3>Issue 5 - Extending the URI<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-5-extending-the-uri" title="Permalink to this headline">¶</a></h3>
<p>The interface can be extended to allow more flexibility for accessing
parts of the URI. For example, an accessor could be provided which
converts all query elements into a map:</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">network</span> <span class="p">{</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">QueryMap</span><span class="o">&gt;</span>
<span class="n">QueryMap</span> <span class="n">query</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 network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>

<span class="p">...</span>

<span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">QueryMap</span><span class="p">;</span>
<span class="n">QueryMap</span> <span class="n">query</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">query</span><span class="o">&lt;</span><span class="n">QueryMap</span><span class="o">&gt;</span><span class="p">(</span><span class="n">uri</span><span class="p">);</span>
</pre></div>
</div>
<p>Additionally, his proposal can be extended to include factory
functions for common operations, such as constructing a URI from a
filesystem path:</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">network</span> <span class="p">{</span>
<span class="n">uri</span> <span class="n">uri</span><span class="o">::</span><span class="n">from_path</span><span class="p">(</span><span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&amp;</span><span class="n">path</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>

<span class="p">...</span>

<span class="n">std</span><span class="o">::</span><span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">path</span><span class="p">(</span><span class="s">"/usr/bin/c++"</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">uri_path</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span><span class="o">::</span><span class="n">from_path</span><span class="p">(</span><span class="n">path</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">uri_path</span><span class="p">.</span><span class="n">string</span><span class="p">()</span> <span class="o">==</span> <span class="s">"file:///usr/bin/c++"</span><span class="p">);</span>
</pre></div>
</div>
<p>Furthermore, there may be new proposals for types that represent IP
addresses. If such types can be accepted into the standard, it would
be possible to accommodate them in future revisions of this proposal:</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">network</span> <span class="p">{</span>
<span class="n">uri</span><span class="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">builder</span><span class="o">::</span><span class="n">host</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">address_ipv4</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">);</span>
<span class="n">uri</span><span class="o">::</span><span class="n">builder</span> <span class="o">&amp;</span><span class="n">uri</span><span class="o">::</span><span class="n">builder</span><span class="o">::</span><span class="n">host</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">address_ipv6</span> <span class="o">&amp;</span><span class="n">host</span><span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace network</span>
<span class="p">}</span> <span class="c1">// namespace std</span>
</pre></div>
</div>
</div>
<div class="section" id="issue-6-allocator-support">
<h3>Issue 6 - Allocator Support<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-6-allocator-support" title="Permalink to this headline">¶</a></h3>
<p>This proposal does not specify any kind of allocator support.</p>
</div>
<div class="section" id="issue-7-percent-encoding-and-iterators">
<h3>Issue 7 - Percent Encoding and Iterators<a class="headerlink" href="http://glynos.github.com/uri_proposal/#issue-7-percent-encoding-and-iterators" title="Permalink to this headline">¶</a></h3>
<p>It may be possible to gain extra flexibility and performance with
iterators that are aware of percent encoding and decoding. The
following untested examples give an illustration:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// assume we're on Windows, using wchar_t</span>
<span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">L"http://example.com/path%20with%20spaces/"</span><span class="p">);</span>
<span class="c1">// the iterators in the type returned by pct_decoded_path still refer to the native type</span>
<span class="k">auto</span> <span class="n">pct_decoded_path_range</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">pct_decoded_path</span><span class="p">(</span><span class="n">uri</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">equal</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">pct_decoded_path_range</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">pct_decoded_path_range</span><span class="p">),</span>
                  <span class="s">L"/path with spaces/"</span><span class="p">));</span>
</pre></div>
</div>
<p>This may even be improved by providing an overload for
<tt class="docutils literal"><span class="pre">std::network::pct_decode</span></tt>:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">L"http://example.com/path%20with%20spaces/"</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">pct_decoded_path_range</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">pct_decode</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="n">path</span><span class="p">());</span>
<span class="n">assert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">equal</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">pct_decoded_path_range</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">pct_decoded_path_range</span><span class="p">),</span>
                  <span class="s">L"/path with spaces/"</span><span class="p">));</span>
</pre></div>
</div>
<p>For better expressiveness this can be improved further by replacing
<tt class="docutils literal"><span class="pre">std::equal</span></tt> with a <a class="reference external" href="http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/algorithms/non_mutating/equal.html">range-based equivalent</a> available in <a class="reference external" href="http://www.boost.org/">Boost</a>:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">uri</span> <span class="n">uri</span><span class="p">(</span><span class="s">L"http://example.com/path%20with%20spaces/"</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">equal</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">pct_decode</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="n">path</span><span class="p">()),</span> <span class="s">L"/path with spaces/"</span><span class="p">));</span>
</pre></div>
</div>
</div>
</div>
<span id="document-acknowledgements"></span><div class="section" id="acknowledgements">
<span id="id1"></span><h2>Acknowledgements<a class="headerlink" href="http://glynos.github.com/uri_proposal/#acknowledgements" title="Permalink to this headline">¶</a></h2>
<div class="line-block">
<div class="line">C++ Network Library users and mailing list</div>
<div class="line">Kyle Kloepper</div>
<div class="line">Niklas Gustafsson</div>
<div class="line">Beman Dawes and Filesystem proposal / Text encoding</div>
<div class="line">Wikipedia</div>
</div>
</div>
<span id="document-references"></span><div class="section" id="references">
<span id="id1"></span><h2>References<a class="headerlink" href="http://glynos.github.com/uri_proposal/#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 (Feb 2012)</strong>: <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3365.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3365.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>