<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0555R0, ISO/IEC JTC1 SC22 WG21">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css"/>
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
code.sameSize {
  font-size: 0.85em;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: none;
    border-bottom: 1px solid /*#005100*/ #008c00;
    color: /*#005100*/ #008c00;
    line-height: 1.4em;
}
ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
span.section_name {
    float: right;
    font-weight: bold;
}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em;
  padding-right: 0.5em; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto;
  margin-top: 2em; margin-bottom: 2em;}

table.withBorder {
  border-top: none;
  border-left: none;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
}
.withBorder th {
  border-top: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
/*  border-top: 2px solid black;
  border-left: 2px solid black;
  border-bottom: 1px solid black;
  border-right: 1px solid black;*/
}
.withBorder td {
  border-top: 1px solid black;
  border-left: 1px solid black;
}

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }
</style>

<title>string_view for source_location</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td><b>P0555R0</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>LEWG</td></tr>
    <tr><td>Date:</td><td>2017-01-30</td></tr>
  <tr><td>Author:</td><td>Axel Naumann (axel@cern.ch)</td></tr>
</table>
<h1><code class="sameSize">string_view</code> for <code class="sameSize">source_location</code></h1>

    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#motivation">Motivation</a></li>
<li><a href="#proposed-wording">Proposed wording</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#history">Revision history</a></li>
<li><a href="#references">References</a></li>
</ul>
</nav>

    <h2>&nbsp;</h2>
<blockquote>
<p>I have a great respect for incremental improvement, ...<br />
 <em>[followed by words that we don't care about here.]</em><br />
 &nbsp;<br/>
 <em>- Steve Jobs; Interview with The Rolling Stone, 1994</em></p>
</blockquote>


<h2 id="introduction">Introduction</h2>
<p>Access to the <em>null-terminated byte string</em> (NTBS) as returned by some of the member functions of <code>source_location</code> is unwieldy in <code>constexpr</code> contexts. This paper tries to explain and fix the issue.</p>

<h2 id="motivation">Motivation</h2>
<p>What <code>constexpr</code> strings need is a pointer to the start of the NTBS and its length. It is expected that <code>constexpr</code> string classes &mdash; whatever their shape will be &mdash; can be constructed from those two ingredients. We have a wonderful example for such a <code>constexpr</code> string class in <a href="http://wg21.link/p0259">p0259</a>. An example for a <code>constexpr</code> context for <code>source_location</code> and strings is the <em>Static Reflection</em> paper (<a href="http://wg21.link/p0194">p0194</a>).</p>

<p><code>source_location</code> is a constexpr object: all its state is defined at translation time. All its members are <code>constexpr</code>. Yet, building a <code>constexpr</code> string object out of the values returned by <code>file_name()</code> and <code>function_name()</code> is non-trivial, as the NTBS length needs to be determined first. That is traditionally done by <code>strlen</code> [cstring.syn] which is not marked <code>constexpr</code>. Instead, a <code>constexpr</code> loop must be written to determine the position of the trailing \0 character.</p>
<p>To facilitate handling the NTBS returned by <code>source_location</code>, this paper proposes to instead return <code>string_view</code>, which gives access to the NTBS value for instance through <code>front()</code>, and to its length through <code>length()</code>, both of which are <code>constexpr</code>.</p>

<h2 id="proposed-wording">Proposed wording</h2>
<p>The wording is relative to <a href="http://wg21.link/n4529">n4529</a>. <ins>Insertions</ins> and <del>deletions</del> are marked the usual way. Grayish background indicates proposed wording.</p>

<p>In <b>14.1.1 Header &lt;experimental/source_location&gt; synopsis [reflection.src_loc.synop]</b> change:</p>
<blockquote class="std">
<pre><code>
// 14.1.3, source_location field access
constexpr uint_least32_t line() const noexcept;
constexpr uint_least32_t column() const noexcept;
constexpr <del>const char*</del><ins>string_view</ins> file_name() const noexcept;
constexpr <del>const char*</del><ins>string_view</ins> function_name() const noexcept;
</code></pre>
</blockquote>

<p>In <b>14.1.3 source_location field access [reflection.src_loc.fields]</b> change:</p>
<blockquote class="std">
<p class="function">
<code>
constexpr <del>const char*</del><ins>string_view</ins> file_name() const noexcept;
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
  <dd>
    <del>The</del><ins>A <code>string_view</code> on the</ins> presumed name of the current source file (C++14 §16.8) represented <del>by this object </del>as an NTBS.
</dd>
</dl>

<p class="function">
<code>
constexpr <del>const char*</del><ins>string_view</ins> function_name() const noexcept;
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
  <dd>
    If this object represents a position in the body of a function, returns <ins>a <code>string_view</code> on </ins>an implementation-defined NTBS that should correspond to the function name. Otherwise, returns an empty <del>string</del><ins><code>string_view</code></ins>.
</dd>
</dl>
</blockquote>
</body>
