<html>

<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
 ins  {background-color: #CCFFCC; text-decoration: none;}
 del  {background-color: #FFCACA; text-decoration: none;}
 a    {text-decoration: none;}
</style>
<title>Filesystem NB Comments C++17</title>
</head>

<body>
<table>
<tr>
  <td>Doc. no.:</td>
  <td>P0492R2</td>
</tr>
<tr>
  <td>Date:</td>
  <td>
  <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2017-03-03<!--webbot bot="Timestamp" endspan i-checksum="12212" --></td>
</tr>
<tr>
  <td>Reply to:</td>
  <td>Beman Dawes &lt;bdawes at acm dot org&gt;
</tr>
<tr>
  <td>&nbsp;</td>
  <td>S. Davis Herring &lt;herring at lanl dot gov&gt;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Nicolai Josuttis &lt;nico at josuttis dot de&gt;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Jason Liu &lt;jasonliu dot development at gmail dot com&gt;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Billy O&#39;Neal &lt;bion at microsoft dot com&gt;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>P.J. Plauger &lt;pjp at dinkumware dot com&gt;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Jonathan Wakely &lt;cxx at kayari dot org&gt;</td>
</tr>
<tr>
  <td>Audience:</td>
  <td>Library</td>
</tr>
</table>

<h1>Proposed Resolution of C++17  National Body Comments for Filesystems(R2)</h1>

<p>This document proposes resolutions of C++17 CD National Body Comments from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0488r0.pdf">
P0488R0</a> related to Filesystems (27.10 [filesystems]). Some &quot;Late&quot; Comments from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0489r0.pdf">
P0489R0</a> are also considered.</p>

<p>The proposed resolutions in this paper represent the consensus of the Library 
Working Group&#39;s Filesystem small group (SG) unless otherwise indicated.</p>

<p>Proposed wording  is 
relative to the C++ working paper,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf">
N4618</a>.</p>

<p>The effect of most of the proposed wording changes is to improve the 
specification of the library. Only a few of the changes modify the behavior of 
the library. Most if not all of the behavior changes have been implemented and 
tested.</p>

<h3>NB comment status</h3>

<p><a href="#US37">US-37</a> and <a href="#US63">US-63</a> need additional LWG 
review and votes.</p>

<h2>Index of comments</h2>

<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US25">US 25: has_filename() is equivalent to just !empty()</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US31">US 31: Everything is defined in terms of 
one implicit host system</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US32">US 32: Meaning of 27.10.2.1 unclear</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US33">US 33: Definition of <i>canonical path</i> problematic</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US34">US 34: Are there attributes of a file that are not an aspect of the file system?</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US35">US 35: What synchronization is required to avoid a file system race?</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US36">US 36: Symbolic links themselves are attached to a directory via (hard) links</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US37">US 37: The term “redundant current directory (dot) elements” is not defined</a><br> 
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US38">US 38: Duplicates §17.3.16</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US39">US 39: Remove note: Dot and dot-dot are not directories</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US40">US 40: Not all directories have a parent.</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US41">US 41: The term “parent directory” for a (non-directory) file is unusual</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US42">US 42: Pathname resolution does not always resolve a symlink</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US43">US 43: Concerns about <i>encoded character types</i></a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US44">US 44: Definition of path in terms of a string requires leaky abstraction</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US45">US 45: Generic format portability compromised by unspecified root-name</a><br> 
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US46">US 46: <i>filename</i> can be empty so productions for <i>relative-path</i> are redundant</a><br> 
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US47">US 47: “.” and “..” already match the name production</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US48">US 48: Multiple separators are often meaningful in a <i>root-name</i></a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US49">US 49: What does “method of conversion method” mean?</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US50">US 50: 27.10.8.1 ¶ 1.4 largely redundant with ¶ 1.3</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US51">US 51: Failing to add / when appending empty string prevents useful apps</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US52">US 52: <code>remove_filename()</code> postcondition is not by itself a definition</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US53">US 53: <code>remove_filename()</code>'s name does not correspond to its behavior</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US54">US 54: <code>remove_filename()</code> is broken</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US55">US 55: <code>replace_extension()</code>'s use of <code>path</code> as parameter is inappropriate</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US56">US 56: Remove <code>replace_extension()</code>&#39;s conditional addition of period</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US57">US 57: On Windows, absolute paths will sort in among relative paths</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US58">US 58: <code>parent_path()</code> behavior for root paths is useless</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US59">US 59: <code>filename()</code> returning <code>path</code> for single path components is bizarre</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US60">US 60: <code>path(&quot;/foo/&quot;).filename()==path(&quot;.&quot;)</code> is surprising</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US61">US 61: Leading dots in <code>filename()</code> should not begin an extension</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US62">US 62: It is important that <code>stem()+extension()==filename()</code></a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US63">US 63: <code>lexically_normal()</code> inconsistently treats trailing "/" but not &quot;/..&quot; as directory</a><br> 
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US73">US 73, CA 2: <i>root-name</i> is effectively implementation defined</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US74">US 74, CA 3: The term “pathname” is ambiguous in some contexts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US75">US 75, CA 4: Extra flag in path constructors is needed</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US76">US 76, CA 5: <i>root-name</i> definition is over-specified.</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US77">US 77, CA 6: <code>operator/</code> and other appends not useful if arg has <i>root-name</i></a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US78">US 78, CA 7: Member <code>absolute()</code> in 27.10.4.1 is overspecified for non-POSIX-like O/S</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US79">US 79, CA 8: Some  operation functions are overspecified for implementation-defined file types</a><br>
&nbsp;&nbsp;&nbsp; <a href="#US185">US 185: Fold <code>error_code</code> and non-<code>error_code</code> signatures into one signature</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#FI14">FI 14: <tt>directory_entry</tt> comparisons are members</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Late36">Late 36: <code>permissions()</code> <code>
error_code</code> overload should be <code>noexcept</code></a><br>
&nbsp;&nbsp;&nbsp; <a href="#Late37">Late 37: <code>permissions()</code> actions 
should be separate parameter</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Late42">Late 42: <code>resize_file()</code> <i>
Postcondition</i> missing argument</a><h2>Revision History</h2>

<h3>P0492R2 Post-Kona mailing</h3>

<ul>
  <li>Overall direction remains unchanged.</li>
  <li>Changes requested by the LWG 16-Dec-2016 Issues Telecon.</li>
  <li>Changes requested by the LWG line-by-line review in Kona, including 
  proposed wording for all NB comments missing wording.</li>
</ul>

<h3>P0492R1 Pre-Kona mailing</h3>

<ul>
  <li>Overall direction remains unchanged.</li>
  <li>Updated WP base document to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf">
N4618</a>.</li>
  <li>Modifications to reflect editorial changes to the standard WP. Most 
  importantly, the name of the class <code>path</code> exposition only data 
  member was changed from <code>pathname</code> to <code>pathstring</code>.</li>
  <li>Proposed wording supplied for numerous NB comments that had no proposed 
  wording.</li>
  <li>Numerous minor and editorial corrections.</li>
</ul>

<h3>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0492r0.html">
P0492R0</a> Post-Issaquah mailing</h3>

<blockquote>

<p>The initial version of this document.</p>

</blockquote>

<h2>Markup</h2>

<p><span style="font-style: italic; background-color: #FFFF99">Notes about work 
that remains to be done, who is planning to do that work, or wording that 
requires specially careful review by the LWG. Some of these notes may indicate 
that the proposed resolution is not yet ready to be voted into the 
C++17 working paper.</span>

<p><span style="font-style: italic; background-color: #E1E9FD">
SG informative notes that will remain in this proposal but do not become part of 
the WP.</span>

<p><i>Instructions to the project editor.</i><p><del>Text to be 
removed from the WP.</del>

<p><ins>Text 
to be added to the WP.</ins>

<p><b>&#10003;</b> after an NB comment's <b>Status</b> indicates indicates that 
the comment has been reviewed by the LWG, any changes they requested have been 
made, and the comment is ready for committee voting in Kona.

<h2><a name="nb-comments"></a>NB Technical and general comments</h2>

<h3>Comments related to <code>filename()</code></h3>

<p><span style="font-style: italic; background-color: #E1E9FD">These comments 
are tightly coupled and best resolved as a whole.</span></p>

<h4><a name="US25">US 25</a>; 27.10.8.4.10 [path.query]: <code>has_filename()</code> is equivalent to just 
<code>!empty()<br>
</code>Status: Reject ✓</h4>
<blockquote>
<p>Resolved by <a href="#US52">US-52</a>, <a href="#US53">US-53</a>, <a href="#US54">
US-54</a>, and <a href="#US60">US-60</a>.</p>

</blockquote>

<h4><a name="US37">US 37</a>; 27.10.4.12 [fs.def.normal.form]: The term “redundant current directory (dot) elements” is not defined<br>
Status: Accept with modifications</h4>




<blockquote>




<p><i>Change 27.10.4.12 [fs.def.normal.form]:</i></p>

<blockquote>
<p><b>normal form</b><br>
<del>A path with no redundant current directory (<i>dot</i>) elements, no redundant parent directory (<i>dot-dot</i>) 
elements, and no redundant <i>directory-separators</i>. The normal form for an 
empty path is an empty path. The normal form for a path ending in a
<i>directory-separator</i> that is not the root directory has a current directory (<i>dot</i>) 
element appended. A path in normal form is said to be <i>normalized</i>. The 
process of obtaining a normalized path from a path that is not in normal form is 
called <i>normalization</i>. [ <i>Note:</i> The rule that appends a current 
directory (<i>dot</i>) element supports operating systems like OpenVMS that use 
different syntax for directory names and regular file names. <i>—end note</i> ]</del></p>

<p><ins>A path in normal form is said to be <i>normalized</i>. The process of 
obtaining a normalized path from a path that is not in normal form is called <i>
normalization</i>.</ins></p>
<p><ins>Normalization of a generic format pathname means:</ins></p>
  <ol>
    <li><ins>If the path is empty, stop.</ins></li>
    <li><ins>Replace each slash character in the <i>root-name</i> with a <i>preferred-separator</i>.</ins></li>
    <li><ins>Replace each <i>directory-separator</i> with a <i>preferred-separator</i>. 
    [ <i>Note:</i> The generic pathname grammar ([path.generic]) defines <i>directory-separator</i> as one or 
    more slashes and <i>preferred-separator</i>s. &mdash;<i>end note</i> ]</ins></li>
    <li><ins>Remove each <i>dot</i> filename and any immediately following <i>directory-separator</i>.</ins></li>
    <li><ins>As long as any appear, remove a non-<i>dot-dot</i> filename immediately followed by a
    <i>directory-separator</i> and a <i>dot-dot</i> filename, along with any immediately following 
    <i>directory-separator</i>.</ins></li>
    <li><ins>If there is a <i>root-directory</i>, remove all <i>dot-dot</i> filenames and any 
    <i>directory-separator</i>s immediately following them. [
    <i>Note:</i> These <i>dot-dot</i> 
  filenames attempt to refer to nonexistent parent directories. <i>&mdash;end note</i> ]</ins></li>
    <li><ins>If the last filename is
    <i>dot-dot</i>, remove any trailing <i>directory-separator</i>.</ins></li>
    <li><ins>If the path is empty, add a <i>dot</i>.</ins></li>
</ol>
</blockquote>


</blockquote>

<h4><a name="US51">US 51</a>; 27.10.8.4.3 [path.append] ¶2.3: Failing to add / when appending empty string prevents useful apps<br>
Status: Accept with modifications ✓</h4>
<blockquote>

<p>Resolved by <a href="#US74">US-74/CA-3</a></p>
</blockquote>

<h4><a name="US52">US 52</a>; 27.10.8.4.5 [path.modifiers] ¶5: <code>remove_filename()</code> postcondition is not by itself a definition<br>
Status: Accept with modifications ✓</h4>
<blockquote>

<p>Resolves <a href="http://cplusplus.github.io/LWG/lwg-active.html#2665">LWG 2665</a>.</p>

<p>
<i>Change 27.10.8.4.5 [path.modifiers]:</i> </p>
<blockquote>
 <pre>path&amp; remove_filename();</pre>
 <blockquote>
   <p>
 <i>Postcondition:</i><code>!has_filename()</code>. </p>
 <p> <ins><i>Effects:</i> Remove the generic format pathname of <code>filename()</code> from the 
 generic format pathname.</ins></p>
 <p><i>Returns:</i> <code>*this</code>.</p>
 <p>[ <i>Example:</i></p>
   <blockquote>
<pre><del>std::cout &lt;&lt; path(&quot;/foo&quot;).remove_filename(); // outputs &quot;/&quot;
std::cout &lt;&lt; path(&quot;/&quot;).remove_filename();    // outputs &quot;&quot;</del>
<ins>path(&quot;foo/bar&quot;).remove_<wbr />filename(); // yields &quot;foo/&quot;
path(&quot;foo/&quot;).remove_filename()<wbr />;&nbsp; &nbsp; // yields &quot;foo/&quot;
path(&quot;/foo&quot;).remove_filename()<wbr />;&nbsp; &nbsp; // yields &quot;/&quot;
path(&quot;/&quot;).remove_filename();&nbsp; &nbsp; &nbsp; &nbsp;// yields &quot;/&quot;</ins></pre>
   </blockquote>
   <p>—<i>end example</i> ]</p>
 </blockquote>
</blockquote>
</blockquote>

<h4><a name="US53">US 53</a>; 27.10.8.4.5 [path.modifiers] ¶4 (was ¶7): <code>remove_filename()</code>'s name does not correspond to its behavior<code><br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p>As a consequence of the <a href="#US52">US-52</a> and <a href="#US60">US-60</a> fixes, the name now corresponds to 
the behavior.</p>

</blockquote>

<h4><a name="US54">US 54</a>; 27.10.8.4.5 [path.modifiers] ¶7 (was ¶10): <code>
replace_filename()</code> is broken<code><br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p>See <a href="#US52">US-52</a> and <a href="#US74">US-74</a> fixes.</p>

<p>
<i>Change 27.10.8.4.5 [path.modifiers]:</i></p>

  <blockquote>
    <pre>path&amp; replace_filename(const path&amp; replacement);</pre>
    <p><i>Effects:</i> Equivalent to:</p>
    <blockquote>
      <pre>  remove_filename();
  operator/=(replacement);</pre>
    </blockquote>
    <p><i>Returns:</i> <code>*this</code>.</p>

<p>[ <i>Example:</i></p>

    <blockquote>
      <pre><ins>path(&quot;/foo&quot;).replace_filename(&quot;bar&quot;);  // yields &quot;/bar&quot; on POSIX</ins>
<del>std::cout &lt;&lt; </del>path(&quot;/&quot;).replace_filename(&quot;bar&quot;);     // <del>outputs</del><ins>yields</ins> &quot;<ins>/</ins>bar&quot; <ins>on POSIX</ins></pre>
     </blockquote>

<p><i>—end example</i> ]</p>

  </blockquote>

<p><i>Change 27.10.12.2 [directory_entry.mods] <b>after 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0317r1.html">P0317</a>, 
Directory Entry Caching for Filesystem, has been applied</b>:</i></p>

  <blockquote>
    <pre>void replace_filename(const path&amp; p);
void replace_filename(const path&amp; p, error_code&amp; ec);</pre>
</blockquote>

</blockquote>

<blockquote>
  <blockquote>
    <blockquote>
      <p><i>Effects:</i> Equivalent to <code><del>pathobject = 
      pathobject.parent_path()/ p</del> <ins>pathobject.replace_filename(p)</ins></code>, then <code>refresh()</code>or <code>
      refresh(ec)</code>, respectively. If an error occurs&nbsp; the value of any 
      cached attributes is unspecified.</p>
      <p><i>Throws:</i> As specified in Error reporting ([fs.err.report]).</p>
    </blockquote>
  </blockquote>
</blockquote>

<h4><a name="US60">US 60</a>; 27.10.8.4.9 [path.decompose] ¶6: <code>path(&quot;/foo/&quot;).filename()==path(&quot;.&quot;)</code> is surprising<code><br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p><b>Discussion:</b></p>

<p>The <code>filename()</code> behavior at issue is specified in 27.10.8.4.9 [path.decompose] ¶6:</p>

<blockquote>

<p><i>Returns</i>: <code>empty() ? 
path() : *--end()</code>.</p>

</blockquote>

<p>So the underlying problem is in 27.10.8.5 path iterators [path.itr]
¶4:</p>

  <blockquote>

<font FACE="LMRoman7-Regular" SIZE="1">
<p>4 </font><font FACE="LMRoman10-Regular">For the 
elements of </font><font FACE="LMMono10-Regular">pathname </font>
<font FACE="LMRoman10-Regular">in the generic format, the forward 
traversal order is as follows:</p>
</font><font FACE="LMRoman7-Regular" SIZE="1">
<p>(4.1) </font><font FACE="LMRoman10-Regular">— The
</font><font FACE="LMRoman10-Italic"><i>root-name </i></font>
<font FACE="LMRoman10-Regular">element, if present.</p>
</font><font FACE="LMRoman7-Regular" SIZE="1">
<p>(4.2) </font><font FACE="LMRoman10-Regular">— The
</font><font FACE="LMRoman10-Italic"><i>root-directory </i></font>
<font FACE="LMRoman10-Regular">element, if present. [</font><font FACE="LMRoman10-Italic"><i>Note:
</i></font><font FACE="LMRoman10-Regular">the generic format is 
required to ensure lexicographical</p>
<p>comparison works correctly. </font>
<font FACE="LMRoman10-Italic"><i>—end note </i></font>
<font FACE="LMRoman10-Regular">]</p>
</font><font FACE="LMRoman7-Regular" SIZE="1">
<p>(4.3) </font><font FACE="LMRoman10-Regular">— Each 
successive </font><font FACE="LMRoman10-Italic"><i>filename </i></font>
<font FACE="LMRoman10-Regular">element, if present.</p>
</font><font FACE="LMRoman7-Regular" SIZE="1">
<p>(4.4) </font><font FACE="LMRoman10-Regular">— </font>
<font FACE="LMRoman10-Italic"><i>dot</i></font><font FACE="LMRoman10-Regular">, 
if one or more trailing non-root </font><font FACE="LMRoman10-Italic">
<i>slash </i></font><font FACE="LMRoman10-Regular">characters are 
present.</p>
</font>

  </blockquote>

<p>The ¶4.4 iterator behavior has always been surprising and controversial, so 
the LWG SG looked at the possible ways of dealing with trailing non-root slash 
characters:</p>

<p>The proposed resolution works, and was discussed at length by the SG. It appears to resolve a 
number of concerns raised by other NB comments and by the SG during discussion 
of those comments. The ripple effects of this 
change have been identified, and  wording changes proposed where needed or desirable.<font FACE="LMRoman10-Regular">&nbsp;</font></p>

<p><font face="LMRoman10-Regular">Because this is a design change, Nico 
presented it to LEWG in Issaquah as part of &quot;Clarify filename&quot;. It was accepted by a vote of 
13/3/0/0/0. </font> </p>

<p><b><font face="LMRoman10-Regular">Proposed resolution:</font></b></p>

<p><i><font face="LMRoman10-Regular">Change 27.10.8.5 [path.itr]:</font></i></p>

  <blockquote>

<p>

    <font FACE="LMRoman10-Regular">

<font FACE="LMRoman7-Regular" SIZE="1">
(4.4) </font>— <i><del>dot</del> </i><ins>an empty element</ins>, 
if one or more trailing non-root <font FACE="LMRoman10-Italic">
<i>slash </i></font>characters are 
present.</font></p>

  </blockquote>

</blockquote>

<h3>Other comments</h3>

<h4><a name="US31">US 31</a>; 27.10 [filesystems]: Everything is defined in terms of one implicit host system<code><br>
</code>Status: Reject ✓</h4>
<blockquote>
<p>That&#39;s by design, aimed at achieving portable syntax and portable behavior. 
And that objective has been largely achieved in practical real-world use for 
many years.&nbsp; There is no proposed wording, and without proposed wording 
there is no consensus for change.&nbsp; Will re-open if a paper or issue appears 
with proposed wording.</p>

</blockquote>

<h4><a name="US32">US 32</a>; 27.10.2.1 [fs.conform.9945] ¶3: Meaning of POSIX 
conformance unclear<code><br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p>The comment requests &quot;Clarify that ¶2 governs and an error must be 
reported in such cases&quot;.</p>

<p><i>Change 27.10.2.1 [fs.conform.9945]:</i></p>
  <blockquote>
    <p>Implementations are not required to provide behavior that is not 
    supported by a particular file system. [ <i>Example:</i> The FAT file system used 
    by some memory cards, camera memory, and floppy disks does not support hard 
    links, symlinks, and many other features of more capable file systems, so 
    implementations are not required to support those features on the FAT file 
    system <ins>but instead are required to report an error as described above</ins>. —<i>end example</i> ]</p>
  </blockquote>
</blockquote>
<h4 dir="ltr"><a name="US33">US 33</a>; 27.10.4.2 [fs.def.canonical.path]: Definition of <i>canonical path</i> problematic<br>
Status: Accept ✓</h4>
<blockquote>
<p>The comment appears to be correct in that the definition of canonical path is 
not used in the WP.</p>
<p><i>Remove 27.10.4.2 [fs.def.canonical.path]:</i></p>
<blockquote>
<p><del><b>canonical path</b><br>
An absolute path that has no elements that are symbolic links, and no dot or 
dot-dot elements (27.10.8.1).</del></p>
</blockquote>
</blockquote>
<h4><a name="US34">US 34</a>; 27.10.4.5 [fs.def.filesystem]: Are there attributes of a file that are not an aspect of the file system?<br>
Status: Accept with modifications ✓</h4>
<blockquote>
<p><i>Change 27.10.4.5 [fs.def.filesystem]:</i></p>
  <blockquote>
<p>A collection of files and <del>certain of</del> their attributes.</p>
  </blockquote>
</blockquote>
<h4><a name="US35">US 35</a>; 27.10.4.6 [fs.def.race]: What synchronization is required to avoid a file system race?<code><br>
</code>Status: Reject ✓</h4>
<blockquote>
<p>The LWG is rejecting US 35 for C++17 because there is currently no consensus 
for change. The LWG will address the problem later as an LWG issue when we know 
how to precisely say what we want. We are not happy with the current proposals 
for fixing the problen, so will defer it.</p>
</blockquote>
<h4><a name="US36">US 36</a>; 27.10.4.9 [fs.def.link]: Symbolic links themselves are attached to a directory via (hard) links<br>
Status: Accept with modifications ✓</h4>
<blockquote>
<p><i><span style="background-color: #E1E9FD">The filesystem small group 
provided wording, taken from POSIX definitions 3.130, Directory Entry 
(or Link).</span></i></p>
<p><i>Change 27.10.4.9 [fs.def.link]:</i></p>
  <blockquote>
<p><b>link</b><br>
<del>A directory entry that associates a filename with a file. A link is either 
a hard link (27.10.4.8) or a symbolic link (27.10.4.21).</del> <ins>An object 
that associates a filename with a file. Several links can associate names 
with the same file.</ins></p>
  </blockquote>
</blockquote>
<h4><a name="US40">US 40</a>; 27.10.4.15 [fs.def.parent]: Not all directories 
have a parent<br>
Status: Reject ✓</h4>

<blockquote>
<p>No proposed wording. The definition in question is taken directly from 
the POSIX
<font face="Times New Roman">§</font>3.268 <i>Parent Directory</i> definition. </p>

</blockquote>

<h4><a name="US43">US 43</a>; 27.10.5 [fs.req] ¶4: Concerns about <i>encoded character types</i><br>
Status: Accept with modifications ✓</h4>

<blockquote>

<p><i>Change 27.10.5 
Requirements [fs.req] ¶4:</i></p>

  <blockquote>

<p>[<i>Note:</i> Use of an encoded character type implies an associated <ins>character set and</ins> encoding.
Since <code>signed char</code> and <code>unsigned char</code> have 
no implied <ins>character set and</ins> encoding, they are not included as permitted types. 
<i>—end note</i> ]</p>

  </blockquote>

<p><i>Add a sentence to 27.10.8.2.2 path type and encoding conversions [path.type.cvt]:</i></p>

  <blockquote>

<p>If the encoding being converted to has no representation for source 
characters, the resulting converted characters, if any, are unspecified. 
<ins>Implementations are strongly encouraged  not to modify member function arguments 
if already of type <code>path::value_type</code>.</ins></p>

  </blockquote>

</blockquote>

<h4><a name="US44">US 44</a>; 27.10.8 [class.path]: Definition of path in terms of a string requires leaky abstraction<code><br>
</code>Status: Accept with modifications ✓</h4>
<blockquote>

<p>This is also <a href="https://cplusplus.github.io/LWG/lwg-active.html#2798">
LWG 2798</a>. In the 16-Dec-2016 Issues Telecon, LWG asked that the fix be 
included in this paper. Beman Dawes adapted Billy O&#39;Neal&#39;s proposed wording from 
LWG 2798 to N4618, the current C++ working paper.</p>

<p>The portion of this comment not resolved by the following proposed wording is resolved by
<a href="#US74">US-74/CA-3</a> </p>

<i>Change 27.10.8.4.4 [path.concat]: </i>

<blockquote>
      <pre>path&amp; operator+=(const path&amp; x);
path&amp; operator+=(const string_type&amp; x);
path&amp; operator+=(basic_string_view&lt;value_type&gt; x);
path&amp; operator+=(const value_type * x);
path&amp; operator+=(value_type x);
template &lt;class Source&gt;
    path&amp; operator+=(const Source&amp; x);
template &lt;class EcharT&gt;
    path&amp; operator+=(EcharT x);
template &lt;class Source&gt;
    path&amp; concat(const Source&amp; x);
<del>template &lt;class InputIterator&gt;
    path&amp; concat(InputIterator first, InputIterator last);</del>
</pre>
      <blockquote>
        <p> <del><em>Postcondition:</em> <tt>native() == prior_native + <em>
        effective-argument</em></tt>, where <tt>prior_native</tt> is <tt>
        native()</tt> prior to the call to <tt>operator+=</tt>, and <tt><em>
        effective-argument</em></tt> is:</del> </p>
        <ul>
          <li><del>if <tt>x</tt> is present and is <tt>const path&amp;</tt>, <tt>
          x.native()</tt>; otherwise,</del></li>
          <li><del>if <tt>source</tt> is present, the effective range of <tt>
          source</tt> path.req; otherwise,</del></li>
          <li><del>&gt;if <tt>first</tt> and <tt>last</tt> are present, the range
          <tt>[first, last)</tt>; otherwise,</del></li>
          <li><del><tt>x</tt>.</del></li>
        </ul>
        <p><del>If the value type of <tt><em>effective-argument</em></tt> would 
        not be <tt>path::value_type</tt>, the acctual argument or argument range 
        is first converted path.type.cvt so that <tt><em>effective-argument</em></tt> 
        has value type <tt>path::value_type</tt>.</del> </p>
        <p><ins><i>Effects:</i>Appends <code>path(x).native()</code> to the 
        pathname in the native format. [<em>Note:</em> 
        This directly manipulates the value of <tt>native()</tt> and may not be 
        portable between operating systems. — <em>end note</em>]</ins> </p>
        <p> <em>Returns:</em> <tt>*this</tt>. </p>
      </blockquote>
      <pre><ins>template &lt;class InputIterator&gt;
    path&amp; concat(InputIterator first, InputIterator last);</ins>
</pre>
      <blockquote>
        <p><ins> <em>Effects:</em> Equivalent to  <tt>return *this +=
        path(first, last)</tt>.</ins> </p>
      </blockquote>
    </blockquote>
</blockquote>

<h4><a name="US45">US 45</a>; 27.10.8.1 [path.generic]: Generic format portability compromised by unspecified 
<i>root-name</i><code><br>
</code>Status: Accept with modifications ✓</h4>
<blockquote>
<p>Resolved by <a href="#US73">US-73/CA-2</a></p>

</blockquote>

<h4><a name="US46">US 46</a>; 27.10.8.1 [path.generic]: <i>filename</i> can be empty so productions for <i>relative-path</i> are redundant<br>
Status: Accept with modifications ✓</h4>
<blockquote>
<p><i>Change [path.generic]:</i></p>

<blockquote>
<p><code>relative-path:<br>
&nbsp; filename<br>
&nbsp; relative-path directory-separator<br>
&nbsp; relative-path directory-separator filename<br></code>
&nbsp;
&nbsp; <ins>an empty path</ins>&nbsp;&nbsp;&nbsp; <i>
<span style="background-color: #C0C0C0">Note to editor: this line is 
deliberately not in code font</span></i></p>

<p>...</p>

<p><i>name:</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A <ins>non-empty</ins> sequence 
of characters other than directory-separator characters.</p>

</blockquote>

</blockquote>

<h4><a name="US48">US 48</a>; 27.10.8.1 [path.generic] ¶1: Multiple separators are often meaningful in a <i>root-name</i><br>
Status: Accept with modifications ✓</h4>
<blockquote>

<p><i>Change 27.10.8.1 [path.generic] ¶1:</i></p>

  <blockquote>
<p><ins>Except in <i>root-name</i>, m</ins><del>M</del>ultiple successive <i>
directory-separator</i> characters are considered to be the same as one <i>
directory-separator </i>character.</p>

  </blockquote>

</blockquote>

<h4><a name="US49">US 49</a>; 27.10.8.2.2 [path.type.cvt]: What does “method of conversion method” mean?<br>
Status: Editorial ✓</h4>
<blockquote>

<p>Fixed in the post-Issaquah working paper.</p>
</blockquote>

<font FACE="LMRoman10-Regular">

<h4><a name="US55">US 55</a>; 27.10.8.4.5 [path.modifiers] ¶11: <code>replace_extension()</code>'s use of <code>path</code> as parameter is inappropriate<br>
Status: Accept with modifications ✓</h4>

<blockquote>
<p>The SG believes <code>path</code> is the appropriate parameter type, but that 
the standard needs to clarify class <code>path</code> usage.</p>
<p><i>Change 27.10.8 [class.path] ¶1:</i></p>

<blockquote>
<p>An object of class path represents a path (27.10.4.17)
 and contains a pathname (27.10.4.18). Such an object
is concerned only with the lexical and syntactic aspects of a path. The path does not necessarily exist in
external storage, and the pathname is not necessarily valid for the current operating system or for a particular
file system.</p>

<p><ins>[<i>Note:</i> Class <code>path</code> is used to support the differences between the string types
 used by different operating systems to represent pathnames, and to perform 
conversions between encodings when necessary. &mdash; <i>end note</i>]</ins></p>

</blockquote>
 
</blockquote>
 
<h4><a name="US56">US 56</a>; 27.10.8.4.5 [path.modifiers] ¶11.2: Remove <code>
replace_extension()</code>&#39;s conditional addition of period<br>
Status: Reject ✓</h4>

<blockquote>
 
<p>Nico presented this to the Library Evolution Working group in 
Issaquah, including a number of examples (See Nico&#39;s <i>Filesystem: Filename 
Issues</i> slides on the Issaquah LEWG wiki.) There was no 
consensus for change; the vote was 3/3/3/7/2. See the Issaquah LEWG notes.</p>

</blockquote>

<h4><a name="US57">US 57</a>; 27.10.8.4.8 [path.compare] ¶2: On Windows, absolute paths will sort in among relative paths<br>
Status: Reject ✓</h4>

<blockquote>

<p>Insufficient motivation for change.</p>

</blockquote>

<h4><a name="US58">US 58</a>; 27.10.8.4.9 [path.decompose] ¶5: <code>parent_path()</code> behavior for root paths is useless<br>
Status: Accept with modifications </h4>

<blockquote>

<p>Resolved by <a href="#US77">US-77/CA-6</a></p>

</blockquote>

<h4><a name="US59">US 59</a>; 27.10.8.4.9 [path.decompose] ¶6: <code>filename()</code> returning <code>path</code> for single path components is bizarre<br>
Status: Reject ✓</h4>

<blockquote>

<p> <code>path</code> is filesystem's
vocabulary type for both full paths and for path components, in the same sense that
<code>std::string</code> might be used as the vocabulary type for both sentences and 
the words in the
sentences. See <a href="#US55">US 55</a> for further discussion.</p>

</blockquote>

<h4><a name="US61">US 61</a>; 27.10.8.4.9 [path.decompose] ¶8: Leading dots in <code>filename()</code> should not begin an extension<code><br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p>Nico Josuttis presented this to the Library Evolution Working group in 
Issaquah, including a number of examples (See Nico&#39;s <i>Filesystem: Filename 
Issues</i> slides on the Issaquah LEWG wiki.) Support was unanimous. See the 
Issaquah LEWG notes.</p>

<p>Resolved by <a href="#stem-fix">stem()</a> and <a href="#extension-fix">
extension()</a> changes in US-74/CA-3</p>

<p>Nico presented the following cases; the only change from the TS is for the
<code>&quot;.profile&quot;</code> case:</p>

<blockquote>

  <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
    <tr>
      <td><i><b><code>path p</code></b></i></td>
      <td><i><b><code>p.stem()</code></b></i></td>
      <td><i><b><code>p.extension()</code></b></i></td>
    </tr>
    <tr>
      <td><code>&quot;/foo/bar.txt&quot;</code></td>
      <td><code>&quot;bar&quot;</code></td>
      <td><code>&quot;.txt&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;.profile&quot;</code></td>
      <td><code><del>&quot;&quot;</del> <ins>&quot;.profile&quot;</ins></code></td>
      <td><code><del>&quot;.profile&quot;</del> <ins>&quot;&quot;</ins></code></td>
    </tr>
    <tr>
      <td><code>&quot;.profile.old&quot;</code></td>
      <td><code>&quot;.profile&quot;</code></td>
      <td><code>&quot;.old&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;..abc&quot;</code></td>
      <td><code>&quot;..abc&quot;</code></td>
      <td><code>&quot;&quot;</code></td>
    </tr>
    <tr>
      <td>&quot;<code>...abc</code>&quot;</td>
      <td><code>&quot;...abc&quot;</code></td>
      <td><code>&quot;&quot;</code></td>
    </tr>
    <tr>
      <td>&quot;<code>abc..def</code>&quot;</td>
      <td><code>&quot;abc.&quot;</code></td>
      <td><code>&quot;.def&quot;</code></td>
    </tr>
    <tr>
      <td>&quot;<code>abc...def</code>&quot;</td>
      <td><code>&quot;abc..&quot;</code></td>
      <td><code>&quot;.def&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;abc.&quot;</code></td>
      <td><code>&quot;abc&quot;</code></td>
      <td><code>&quot;.&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;abc..&quot;</code></td>
      <td><code>&quot;abc.&quot;</code></td>
      <td><code>&quot;.&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;abc.d.&quot;</code></td>
      <td><code>&quot;abc.d&quot;</code></td>
      <td><code>&quot;.&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;..&quot;</code></td>
      <td><code>&quot;..&quot;</code></td>
      <td><code>&quot;&quot;</code></td>
    </tr>
    <tr>
      <td><code>&quot;.&quot;</code></td>
      <td><code>&quot;.&quot;</code></td>
      <td><code>&quot;&quot;</code></td>
    </tr>
  </table>
</blockquote>

</blockquote>

<h4><a name="US62">US 62</a>; 27.10.8.4.9 [path.decompose] ¶11: It is important that <code>stem()+extension()==filename()<br>
</code>Status: Accept with modifications ✓</h4>

<blockquote>

<p>Resolved by change to <a href="#extension-fix"><code>extension()</code></a> 
in <a href="#US74">US-74/CA-3</a></p>

</blockquote>

<h4><a name="US63">US 63</a>; 27.10.8.4.11 [path.gen] ¶1: <code>lexically_normal()</code> inconsistently treats trailing "/" but not &quot;/..&quot; as directory<code><br>
</code>Status: Accept with modifications</h4>

<blockquote>

<p>Resolved by <a href="#US37">US-37</a> and the <a href="#path.gen">change to 
[path.gen]</a> in <a href="#US74">US-74/CA-3</a>.</p>

</blockquote>

<h4><b><a name="US185">US 185</a>; 27.10.7 [fs.err.report]: </b>Fold <code>error_code</code> and non-<code>error_code</code> signatures into one signature<br>
Status: Reject ✓</h4>

<blockquote>

<p> Does not handle one signature being <code>
noexcept(true)</code> and the other <code>noexcept(false)</code>, and many other 
problems. Even the submitter is no longer in favor. See LWG mailing list thread 
&quot;[filesystem] US-185 Eliminating dual signatures for operational functions&quot;, 
October 25, 2016.</p>

</blockquote>

<h4><a name="FI 14">FI 14</a>; 27.10.12.3 [directory_entry.obs]: <tt>directory_entry</tt> comparisons are members<br>
Status: Reject ✓</h4>



<blockquote>

<p>This is LWG issue
<a href="http://cplusplus.github.io/LWG/lwg-closed.html#2761">2761</a>, which 
has been closed as NAD. </p>

</blockquote>



<h4><a name="US73">US 73</a>, CA 2; 27.10.8.1 [path.generic]: <i>root-name</i> is effectively implementation defined<br>
Status: Accept with modifications ✓</h4>

<blockquote>



<p><i>Change [path.generic]:</i></p>

  <blockquote>
    <p><i>root-name:</i><br>
    An operating system dependent name that identifies the starting location for 
    absolute paths. <ins>If the operating system does not define at least one <i>
    root-name</i>, then the implementation defines a <i>root-name</i>. 
    Implementations are permitted to define additional <i>root-name</i>s.</ins> 
    [ <i>Note:</i> Many operating systems define a name beginning with two <i>
    directory-separator</i> characters as a <i>root-name</i> that identifies 
    network or other resource locations. Some operating systems define a single 
    letter followed by a colon as a drive specifier – a <i>root-name</i> 
    identifying a specific device such as a disk drive. —<i>end note</i> ]</p>
  </blockquote>
  <p><i>Add a new paragraph at the end of [path.generic]:</i></p>
  <blockquote>
    <p><ins>If <i>root-name</i> is otherwise ambiguous, the possibility with the 
    longest sequence of characters is chosen. [ <i>Note:</i> on a POSIX-like operating 
    system, it is impossible to have a <i>root-name</i> and a <i>relative-path</i> 
    without an intervening <i>root-directory</i> element. <i>-- end note</i> ]</ins></p>
  </blockquote>
</blockquote>

<h4><a name="US74">US 74</a>, CA 3; 27.10.8 [class.path]: The term “pathname” is ambiguous in some contexts<br>
Status: Accept with modifications &#10003;</h4>

<p><span style="background-color: #E1E9FD"><i>The proposed resolution of this 
National Body comment enables the resolution of many other filesystem NB 
comments.</i></span></p>

<p><b>Discussion: </b></p>
<p>Many operations on <code>filesystem::path</code> are defined in terms of its 
exposition-only <code>pathname</code> member, which is defined implicitly by
<code>path::native()</code> as the native format path. However, the native 
format need not be compatible with lexical operations like, for example, <code>
path::root_name()</code> and <code>path::extension()</code>. </p>
<p>This same concern was also raised by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0430r0.pdf">
P0430R0</a> Section 2.1, which provided additional rationale.</p>

<p><b>Proposed resolution:</b> </p>
<p><i>Remove In the [class.path] synopsis, remove the private (exposition-only) member from 
class path:</i></p>
<blockquote>
  <pre><del>private:
  string_type pathstring; // exposition only</del></pre>
</blockquote>
<p><i>Change [path.fmt.cvt]:</i></p>
<blockquote>
<p>[ <i>Note:</i> The format conversions described in this section are not applied on 
POSIX-<del> or Windows-</del>based operating systems because on these systems:</p>
<blockquote>
<p>— The generic format is acceptable as a native path.<br>
— There is no need to distinguish between native format and generic format in 
function arguments.<br>
— Paths for regular files and paths for directories share the same syntax.</p>
</blockquote>
<p>—end note ]</p>
<p><ins>Several functions are defined to accept <i>detected-format</i> arguments, 
which are character sequences. A detected-format argument represents a path using either 
a pathname in the generic 
  format&nbsp; ([path.generic]) or a pathname in the native format ([fs.def.native]). 
Such an argument is taken to be in the generic format if and only if it matches 
the generic format but is not acceptable to the operating system as a native 
path.
  </ins>
  </p>
  <p><del>Function arguments that take character sequences representing paths 
  may use the generic pathname format grammar (27.10.8.1) or the native pathname 
  format (27.10.4.11). If and only if such arguments are in the generic format 
  and the generic format is not acceptable to the operating system as a native 
  path, conversion to native format shall be performed during the processing of 
  the argument.</del></p>
<p>[ Note: Some operating systems may have no unambiguous way to 
distinguish between native format and generic format arguments. This is by 
design as it simplifies use for operating systems that do not require 
disambiguation. An implementation for an operating system where disambiguation 
is required is permitted to distinguish between the formats. —end note ]</p>
<p><ins>Pathnames are converted as needed between the generic and 
native formats in an operating-system-dependent manner. Let <i>G(n)</i> and <i>N(g)
</i>in a mathematical sense be the implementation&#39;s functions that convert 
native-to-generic and generic-to-native formats respectively. If <i>g=G(n)</i> for some
<i>n</i>, then <i>G(N(g))=g</i>; if <i>n=N(g)</i> for some <i>g</i>, then <i>N(G(n))=n</i>. [ <i>
Note:</i> Neither <i>G</i> nor <i>N</i> need be invertible. —<i>end 
note</i> ] </ins></p>
<p>If the native format requires paths for regular files to be formatted 
differently from paths for directories, the path shall be treated as a directory 
path if its last element is a directory-separator, otherwise it shall be treated 
as a path to a regular file.</p>
<p><ins>[ <i>Note:</i> A path stores a native format pathname ([path.native.obs]) 
and acts as if it also stores a generic format pathname, related as given 
below.&nbsp; The implementation may generate the generic format pathname based on the 
native format pathname (and possibly other information) when requested.&nbsp; <i>-- 
end note</i> ]</ins></p>
  <p><ins>When a path is constructed from or is assigned a single representation 
  separate from any path, the other representation is selected by the 
  appropriate conversion function (<i>G</i> or <i>N</i>). </ins> </p>
  <p><ins>When the (new) value <i>p</i> of one representation of a path is derived from the 
  representation of that or another path, a value <i>q</i> is chosen for the other 
  representation. The value <i>q</i> converts to <i>p</i> (by <i>G</i> or <i>N</i> as appropriate) if any 
  such value does so; <i>q</i> is otherwise unspecified. [ <i>Note:</i> If <i>q</i> is the result of 
  converting any path at all, it is the result of converting <i>p</i>.<i>—end note</i> ]
  </ins>
  </p>
<p><i><span style="background-color: #E1E9FD">[SG note: P0430R1 (for US 75/CA 4) 
adds support for explicitly specifying the format to use, at least in the 
constructor.]</span></i><span style="background-color: #E1E9FD"> </span></p>
</blockquote>
<p><i>Change [path.construct]: </i> </p>
<blockquote>
  <pre>path(const path&amp; p);
path(path&amp;&amp; p) noexcept;</pre>
  <blockquote>
  <p><i>Effects:</i> Constructs an object of class <code>path</code>
  <ins>having the same pathname in the native and generic formats, respectively, as 
  the original value of <code>p</code></ins> 
  <del>with <code>pathstring</code> having the original value of <code>p.pathstring</code></del>. In
  the second form, <code>p</code> is left in a valid but unspecified state.</p>
  </blockquote>
  <pre>path(string_type&amp;&amp; source);</pre>
  <blockquote>
    <p><i>Effects:</i> Constructs an object of class <code>path</code>
     <ins>for which the pathname in the detected-format&nbsp; of 
  <code>source</code> has</ins> <del>with
    <code>pathstring</code> having</del> the original value of <code>source</code>
     <ins>([path.fmt.cvt])</ins>.
    <code>source</code> is left in a valid but unspecified state.</p>
  </blockquote>
  <pre>template &lt;class Source&gt;
path(const Source&amp; source);
template &lt;class InputIterator&gt;
path(InputIterator first, InputIterator last);</pre>
  <blockquote>
    <p><i>Effects:</i> <ins>Let <code>s</code> be the effective range of <code>
    source</code> ([path.req]) or the range <code>[first, last)</code>, with the 
    encoding converted if required ([path.cvt]). Finds the detected-format of
    <code>s</code> ([path.fmt.cvt]) and constructs an object of class <code>path</code> 
    for which the pathname in that format is <code>s</code>.</ins>&nbsp; <del>Constructs an object of class <code>path</code>, storing 
    the effective range of source (27.10.8.3) or the range <code>[first, last)</code> 
    in <code>pathstring</code>, converting format and encoding if required 
    (27.10.8.2).</del></p>
  </blockquote>
  <pre>template &lt;class Source&gt;
path(const Source&amp; source, const locale&amp; loc);
template &lt;class InputIterator&gt;
path(InputIterator first, InputIterator last, const locale&amp; loc);</pre>
  <blockquote>
    <p><i>Requires:</i> The value type of <code>Source</code> and <code>
    InputIterator</code> is <code>char</code>. </p>
    <p>&nbsp;<i>Effects:&nbsp; </i> <del>Constructs an object of class <code>path</code>, 
    storing the effective range of source or the range <code>[first, last)</code> 
    in <code>pathstring</code>, after converting format if required and</del> <ins>
    Let <code>s</code> be the effective range of <code>source</code> or the 
    range <code>[first, last)</code>,</ins><i> </i>after 
    converting the encoding as follows:</p>
    <blockquote>
    <p>— If <code>value_type</code> is <code>wchar_t</code>, converts to the 
    native wide encoding (27.10.4.10) using the <code>codecvt&lt;wchar_t, char, 
    mbstate_t&gt;</code> facet of <code>loc</code>.</p>
    <p>&nbsp;— Otherwise a conversion is performed using the <code>
    codecvt&lt;wchar_t, char, mbstate_t&gt;</code> facet of <code>loc</code>, and then 
    a second conversion to the current narrow encoding.</p>
    </blockquote>
    <p><ins>Finds&nbsp;the detected-format of <code>s</code> ([path.fmt.cvt]) and constructs an object of class 
    <code>path</code> for which the pathname in that format is <code>s</code>.</ins></p>
  </blockquote>
</blockquote>
<p><i>In the example after [path.fmt.cvt] ¶ 7.2, change:</i></p>
<blockquote>
<p>For POSIX-based operating systems, the path is constructed by first 
using <code>latin1_facet</code> to convert ISO/IEC 8859-1 encoded <code>
latin1_string</code> to a wide character string in the native wide encoding 
(27.10.4.10). The resulting wide string is then converted to a narrow character
<code><del>pathstring</del></code> <ins>pathname</ins> string in the current 
native narrow encoding. If the native wide encoding is UTF-16 or UTF-32, and the 
current native narrow encoding is UTF-8, all of the characters in the ISO/IEC 
8859-1 character set will be converted to their Unicode representation, but for 
other native narrow encodings some characters may have no representation.</p>
<p>For Windows-based operating systems, the path is constructed by 
using <code>latin1_facet</code> to convert ISO/IEC 8859-1 encoded <code>
latin1_string</code> to a UTF-16 encoded wide character <code><del>pathstring</del></code>
<ins>pathname</ins> string. All of the characters in the ISO/IEC 8859-1 
character set will be converted to their Unicode representation.</p>
</blockquote>
<p><i>Change [path.assign]: </i> </p>
<blockquote>
  <pre>path&amp; operator=(const path&amp; p);</pre>
  <blockquote>
<p><i>Effects:</i> If <code>*this</code> and <code>p</code> are the same object, 
has no effect. Otherwise, <ins>sets both respective pathnames of <code>*this</code> 
to the respective pathnames of <code>p</code></ins> <del>modifies <code>pathstring</code> to have the original 
value of <code>p.pathstring</code></del>.</p>
<p><i>Returns:</i> <code>*this</code>.</p>
  </blockquote>
  <pre>path&amp; operator=(path&amp;&amp; p) noexcept;</pre>
  <blockquote>
<p><i>Effects:</i> If <code>*this</code> and <code>p</code> are the same object, 
has no effect. Otherwise, <ins>sets both respective pathnames of <code>*this</code> 
to the respective pathnames of <code>p</code></ins> <del>modifies <code>pathstring</code> to have the original 
value of <code>p.pathstring</code></del>. <code>p</code> is left in a valid but 
unspecified state. [ <i>Note:</i> A valid implementation is <code>swap(p)</code>. 
<i>—end 
note</i> ]</p>
<p><i>Returns:</i> <code>*this</code>.</p>
  </blockquote>
  <pre>path&amp; operator=(string_type&amp;&amp; source);
path&amp; assign(string_type&amp;&amp; source);</pre>
  <blockquote>
    <p><i>Effects:</i> <ins>Sets the pathname in the detected-format of <code>source</code>&nbsp; to 
    the original value of <code>source</code></ins> <del>Modifies <code>pathstring</code> to have the original value 
    of <code>source</code></del>. <code>source</code> is left in a valid but 
    unspecified state.</p>
    <p><i>Returns:</i> <code>*this</code>.</p>
  </blockquote>
  <pre>template &lt;class Source&gt;
path&amp; operator=(const Source&amp; source);
template &lt;class Source&gt;
path&amp; assign(const Source&amp; source);
template &lt;class InputIterator&gt;
path&amp; assign(InputIterator first, InputIterator last);</pre>
  <blockquote>
    <p><i>Effects: </i><ins>Let <code>s</code> be the effective range of <code>source</code> ([path.req]) or the 
    range <code>[first, last)</code>, with the encoding converted if required ([path.cvt]). 
    Finds the detected-format of <code>s</code> and sets the pathname in that format 
    to <code>s</code> ([path.fmt.cvt]).</ins> <del>Stores the effective range of <code>source</code> 
    (27.10.8.3) or the range <code>[first, last)</code> in <code>pathstring</code>, 
    converting format and encoding if required (27.10.8.2).</del></p>
    <p><i>Returns:</i> <code>*this</code>.</p>
  </blockquote>
</blockquote>
<p><i>Change [path.modifiers]:</i></p>
<blockquote>
  <pre>path&amp; make_preferred();</pre>
  <blockquote>
  <p><i>Effects:</i> Each <i>directory-separator </i><ins> of the 
  pathname in the generic format</ins> is converted to
  <i>preferred-separator</i>. </p>
  </blockquote>
</blockquote>
<p><i>Change [path.modifiers]:</i></p>
<blockquote>
  <pre>path&amp; replace_extension(const path&amp; replacement = path());</pre>
  <blockquote>
  <p><i>Effects:</i> <del><code>pathstring</code> (the stored path) is modified as follows:</del></p>
  <blockquote>
<p>— Any existing <code>extension()</code>(27.10.8.4.9) is removed from the <ins>
pathname in the generic format</ins>
<del>stored path</del>, then</p>
<p>— If <code>replacement</code> is not empty and does not begin with a <i>dot</i> character, a 
<i>dot</i> 
character is appended to the <ins>pathname in the generic format</ins> <del>stored path</del>, then</p>
<p>— <ins><code>operator+=(replacement);</code></ins> <code><del>replacement</del></code><del> is concatenated to the stored path</del>.</p>
  </blockquote>
<p><i>Returns</i> <code>*this</code>.</p>
  </blockquote>
</blockquote>
<p><i>Change [path.modifiers]:</i></p>
<blockquote>
  <pre>void swap(path&amp; rhs) noexcept;</pre>
  <blockquote>
  <p><i>Effects:</i> Swaps the contents <ins>(in all formats)</ins> of the two paths
  <code><del>pathstring</del></code><del> and </del><code><del>rhs.pathstring</del></code>. </p>
  </blockquote>
</blockquote>
<p><i>Change [path.native.obs]:</i></p>
<blockquote>
  <pre>const string_type&amp; native() const noexcept;</pre>
  <blockquote>
    <p><i>Returns: </i><ins>The pathname in the native format</ins> <code><del>
    pathstring</del></code>.</p>
  </blockquote>
  <pre>const value_type* c_str() const noexcept;</pre>
  <blockquote>
    <p><i>Returns: </i><ins>Equivalent to <code>native().c_str()</code></ins>
    <code><del>pathstring.c_str()</del></code>.</p>
  </blockquote>
  <pre>operator string_type() const;</pre>
  <blockquote>
    <p><i>Returns:</i> <ins><code>native()</code></ins> <code><del>pathstring</del></code>.</p>
<p>[ <i>Note:</i> Conversion to string_type is provided so that an object of 
class path can be given as an argument to existing standard library file stream 
constructors and open functions. —<i>end note</i> ]</p>
  </blockquote>
  <pre>template &lt;class EcharT, class traits = char_traits&lt;EcharT&gt;,
          class Allocator = allocator&lt;EcharT&gt;&gt;
  basic_string&lt;EcharT, traits, Allocator&gt;
    string(const Allocator&amp; a = Allocator()) const;</pre>
  <blockquote>
    <p><i>Returns:</i> <ins><code>native()</code></ins> <code><del>pathstring</del></code>.</p>
<p><i>Remarks:</i> All memory allocation, including for the return value, shall 
be performed by a. Conversion, if any, is specified by 27.10.8.2.</p>
  </blockquote>
</blockquote>
<p><i>Change [path.generic.obs]:</i></p>
<blockquote>
  <pre>template &lt;class EcharT, class traits = char_traits&lt;EcharT&gt;,
          class Allocator = allocator&lt;EcharT&gt;&gt;
  basic_string&lt;EcharT, traits, Allocator&gt;
    generic_string(const Allocator&amp; a = Allocator()) const;</pre>
  <blockquote>
<p><i>Returns: </i><ins>The pathname in the generic format</ins> <del><code>pathstring</code>, 
reformatted according to the generic pathname format (27.10.8.1)</del>.</p>
<p><i>Remarks:</i> All memory allocation, including for the return value, shall 
be performed by a. Conversion, if any, is specified by 27.10.8.2.</p>
  </blockquote>
  <pre>std::string generic_string() const;
std::wstring generic_wstring() const;
std::string generic_u8string() const;
std::u16string generic_u16string() const;
std::u32string generic_u32string() const;</pre>
  <blockquote>
<p><i>Returns:</i> <ins>The pathname in the generic format</ins> <del><code>pathstring</code>, 
reformatted according to the generic pathname format (27.10.8.1)</del>.</p>
<p><i>Remarks:</i> Conversion, if any, is specified by 27.10.8.2. The encoding 
of the string returned by <code>generic_u8string()</code> is always UTF-8.</p>
  </blockquote>
</blockquote>
<p><i>Change [path.decompose]:</i></p>
<blockquote>
  <pre>path root_name() const;</pre>
  <blockquote>
    <p><i>Returns:</i> <i>root-name</i>, if <ins>the pathname in the generic 
    format</ins> <del><code>pathstring</code></del> includes <i>root-name</i>, 
    otherwise <code>path()</code>. </p>
  </blockquote>
  <pre>path root_directory() const;</pre>
  <blockquote>
    <p><i>Returns:</i> <i>root-directory</i>, if <ins>the pathname in the 
    generic format</ins> <del><code>pathstring</code></del> includes <i>root-directory</i>, 
    otherwise <code>path()</code>.</p>
  </blockquote>
  <p>...</p>
  <pre>path relative_path() const;</pre>
  <blockquote>
    <p><i>Returns:</i> A path composed from <ins>the pathname in the generic 
    format</ins>
    <del><code>pathstring</code></del>, if <code>!empty()</code>, beginning with 
    the first <i>filename</i> after <i>root-path</i>. Otherwise, <code>path()</code>.</p>
  </blockquote>
  <p>...</p>
  <pre>path <a name="filename-fix">filename(</a>) const;</pre>
  <blockquote>
    <p><i>Returns:</i> <ins><code>relative_path().</ins>empty() ? path() : *--end()</code>.</p>
    <p>[ <i>Example:</i></p>
    <blockquote>
      <pre><del>std::cout &lt;&lt; </del>path(&quot;/foo/bar.txt&quot;).filename(); // <del>outputs</del> <ins>yields</ins> &quot;bar.txt&quot;
<ins>path(&quot;/foo/bar&quot;).filename();     // yields &quot;bar&quot;</ins>
<ins>path(&quot;/foo/bar/&quot;).filename();    // yields &quot;&quot;</ins>
<del>std::cout &lt;&lt; </del>path(&quot;/&quot;).filename();            // <del>outputs</del> <ins>yields</ins> &quot;<del>/</del>&quot;
<ins>path(&quot;//host&quot;).filename();       // yields &quot;&quot;</ins>
<del>std::cout &lt;&lt; </del>path(&quot;.&quot;).filename();            // <del>outputs</del> <ins>yields</ins> &quot;.&quot;
<del>std::cout &lt;&lt; </del>path(&quot;..&quot;).filename();           // <del>outputs</del> <ins>yields</ins> &quot;..&quot;</pre>
    </blockquote>
    <p>—<i>end example</i> ]</p>
  </blockquote>
  <pre>path <a name="stem-fix">stem()</a> const;</pre>
  <blockquote>
    <p><span style="background-color: #E1E9FD"><i>Note: This change also 
    resolves <a href="#US61">US 61</a>, </i>Leading dots in filename() should 
    not begin an extension<i>, as approved by LEWG in Issaquah, and affirmed by 
    LWG telecon, and reviewed in Kona.</i></span></p>
    <p><del><i>Returns:</i> if <code>filename()</code> contains a period but does not consist 
    solely of one or two periods, returns the substring of <code>filename()</code> starting 
    at its beginning and ending with the character before the last period. 
    Otherwise, returns <code>filename()</code>.</del></p>
  <p><ins><i>Returns:</i> Let <code>f</code> be the generic format 
  pathname of 
  <code>filename()</code>. Returns a 
  path whose the pathname in the generic format is </ins></p>
  <blockquote>
  <p><ins>- <code>f</code>, if it contains no periods other than a leading 
  period or consists solely of one or two periods;</ins>
  </p>
  <p><ins>- otherwise, the prefix of <code>f</code> ending before its last period.</ins> </p>
  </blockquote>
  <p><i><span style="background-color: #E1E9FD">&quot;other than a leading period&quot; 
  was inserted to reflect LEWG guidance from Issaquah that a filename like &quot;.profile&quot; 
  is not to be treated as an extension.</span></i></p>
<p>[ Example:</p>
    <blockquote>
      <pre>std::cout &lt;&lt; path(&quot;/foo/bar.txt&quot;).stem(); // outputs &quot;bar&quot;
path p = &quot;foo.bar.baz.tar&quot;;
for (; !p.extension().empty(); p = p.stem())
std::cout &lt;&lt; p.extension() &lt;&lt; ’\n’;
// outputs: .tar
// .baz
// .bar</pre>
    </blockquote>
    <p>—end example ]</p>
  </blockquote>
  <pre>path <a name="extension-fix">extension</a>() const;</pre>
  <blockquote>
    <p><span style="background-color: #E1E9FD"><i>Note: This change also 
    resolves <a href="#US61">US 61</a>, </i>Leading dots in filename() should 
    not begin an extension<i>, as approved by LEWG in Issaquah, and affirmed by 
    LWG telecon.</i></span></p>
    <p><i>Returns: </i><ins>a path whose pathname in the generic format is the suffix 
    of <code>filename()</code> not included in 
    <code>stem()</code>.</ins> 
    <del>if <code>filename()</code> contains a period but does not consist solely of 
    one or two periods, returns the substring of <code>filename()</code> 
    starting at the rightmost period and for the remainder of the path. 
    Otherwise, returns an empty path object.</del></p>
    <p><del><i>Remarks:</i> Implementations are permitted to define additional 
    behavior for file systems which append additional elements to extensions, 
    such as alternate data streams or partitioned dataset names. </del> </p>
    <p>[ <i>Example:</i></p>
    <blockquote>
    <pre><del>std::cout &lt;&lt; path(&quot;/foo/bar.txt&quot;).extension(); // outputs &quot;.txt&quot;</del>
<ins>path(&quot;/foo/bar.txt&quot;).extension(); // yields &quot;.txt&quot; and stem() is &quot;bar&quot;</ins>
<ins>path(&quot;/foo/bar&quot;).extension();     // yields &quot;&quot; and stem() is &quot;bar&quot;</ins>
<ins>path(&quot;/foo/.profile&quot;).extension(); // yields &quot;&quot; and stem() is &quot;.profile&quot;</ins>
<ins>path(&quot;.bar&quot;).extension();         // yields &quot;&quot; and stem() is &quot;.bar&quot;</ins>
<ins>path(&quot;..bar&quot;).extension();        // yields &quot;.bar&quot; and stem()is &quot;.&quot;</ins></pre>
    
    </blockquote>
    
    <p><i>—end example</i> ]</p>
    <p>[ <i>Note:</i> The period is included in the return value so that it is 
    possible to distinguish between no extension and an empty extension. <del>Also 
    note that for a path <code>p</code>, <code>p.stem()+p.extension() == 
    p.filename()</code>.<i></del> —end note </i>]</p>
    <p><ins>[ <i>Note:</i> On non-POSIX operating systems, for a path <code>p</code>, it may not be the 
    case that <code>p.stem()+p.extension()==p.filename()</code>, even though the 
    generic format pathnames are the same.&nbsp; <i>-- end note</i> ]</ins></p>
 
  </blockquote>
</blockquote>
<p><i>Change [path.query]:</i></p>
<blockquote>
  <pre>bool empty() const noexcept;</pre>
  <blockquote>
<p><i>Returns: </i><ins><code>true</code> if the pathname in the generic format is 
empty, else <code>false</code></ins><i> </i><del><code>pathstring.empty()</code></del>.</p>
  </blockquote>
<p>...</p>
  <pre>bool is_absolute() const;</pre>
  <blockquote>
<p><i>Returns:</i> <code>true</code> if <ins>the pathname in the native format</ins>
<code><del>pathstring</del></code> contains an absolute path (27.10.4.1), else 
false.</p>
<p>[ Example: <code>path(&quot;/&quot;).is_absolute()</code> is true for POSIX-based 
operating systems, and false for Windows-based operating systems. —end example ]</p>
  </blockquote>
</blockquote>
<p><i>Change [path.itr]:</i></p>
<blockquote>
<p>Path iterators iterate over the elements of <ins>the pathname in the generic 
format</ins>
<del><code>pathstring</code> in the generic format</del> (27.10.8.1).</p>
<p>A <code>path::iterator</code> is a constant iterator satisfying all the 
requirements of a bidirectional iterator (24.2.6) except that, for 
dereferenceable iterators <code>a</code> and <code>b</code> of type <code>
path::iterator</code> with <code>a == b</code>, there is no requirement that
<code>*a</code> and <code>*b</code> are bound to the same object. Its <code>
value_type</code> is <code>path</code>.</p>
<p>Calling any non-const member function of a path object invalidates all 
iterators referring to elements of that object.</p>
<p>For the elements of <ins>the pathname in the generic format</ins> <del><code>
pathstring</code> in the generic format</del>, the forward traversal order is as 
follows:</p>
<p>...</p>
</blockquote>
<p><i>Change [fs.op.canonical]:</i></p>
<blockquote>
  <pre>path canonical(const path&amp; p, error_code&amp; ec);
path canonical(const path&amp; p, const path&amp; base, error_code&amp; ec);</pre>
  <blockquote>
    <p><i>Effects:</i> Converts <code>p</code>, which must exist, to an absolute 
    path that has no symbolic link, <ins><i>dot</i>, or <i>dot-dot</i> elements 
    in its pathname in the generic format</ins> <del>&quot;.&quot;, or &quot;..&quot; elements</del>.</p>
    <p>...</p>
  </blockquote>
</blockquote>
<p><i>Change [fs.op.current_path]:</i></p>
<blockquote>
  <pre>path current_path();
path current_path(error_code&amp; ec);</pre>
  <blockquote>
<p><i>Returns:</i> The absolute path of the current working directory, <ins>
whose pathname in the native format is</ins> obtained&nbsp; as if by POSIX <code>getcwd()</code>. The 
signature with argument <code>ec</code> returns <code>path()</code> if an error 
occurs.</p>
<p>...</p>
  </blockquote>
<p><span style="font-style: italic; background-color: #E1E9FD">Rationale: </span>
</p>
<p><span style="font-style: italic; background-color: #E1E9FD">The lexical 
operation specifications leave some room for variation among implementations, 
but not as much as may be required for native formats; further relaxation would 
compromise the utility of the operations for portable, predictable path 
manipulation. Instead, we specify a usable but flexible mapping between the two 
formats and define each operation in terms of one (or, occasionally, both).
</span></p>
<p><span style="font-style: italic; background-color: #E1E9FD">The second bullet 
item in the first note in [path.fmt.cvt], which says for POSIX- or Windows-based 
operating systems &quot;There is no need to distinguish between native format and 
generic format in function arguments.&quot;, may not be true on Windows even if the 
other two bullet items are true.</span></p>

</blockquote>

<h4><a name="US75">US 75</a>, CA 4; 27.10.8.4.1 [path.construct]: Extra flag in path constructors is needed<br>
Status: Accept with modifications ✓</h4>

<blockquote>

<p>Resolved by P0430R2 Section US-75/CA-4.</p>

</blockquote>

<h4><a name="US76">US 76</a>, CA 5; 27.10.8.1 [path.generic]: <i>root-name</i> 
definition is over-specified<br>
Status: Accept with modifications ✓</h4>

<blockquote>

<p>Resolved by P0430R2 Section US-76/CA-5.</p>

</blockquote>

<h4><a name="US77">US 77</a>, CA 6; 27.10.8.4.3 [path.append]: <code>operator/</code> and other appends not useful if arg has <i>root-name</i><br>
Status: Accept with modifications</h4>

<blockquote>

<p><b>Discussion:</b></p>

<p>Passing a path that includes a root path (name or directory) to <code>
path.operator/=()</code> simply incorporates the root path into the middle of 
the result, changing its meaning drastically. LWG 2664 proposes disallowing a 
path with a root name (but leaves the root directory possibility untouched); US 
77/CA 6 (via P0430R0) objects and suggests instead making the same case 
implementation-defined. (P0430R1 drops the matter in favor of this issue.)</p>

<p>We can carefully define operator/=() to be broadly applicable instead of 
restricting it. (<code>path::parent_path()</code> and <code>
path::lexically_relative()</code> are casualties that must be rewritten; they 
need fixing anyway for US 58 and Late 16--18 respectively.)</p>

<p>With the better <code>operator/=()</code>, <code>absolute(p,base)</code> is 
of very little value: the user can easily write <code>absolute(base)/p</code> 
(or simply <code>base/p</code> if preferable). Since Table 126 produces nonsense 
in some cases (see Late 24), it is good to remove this complexity. <code>
canonical()</code> loses its <code>base</code> argument since it simply forwards 
it to <code>absolute()</code>.</p>

<p>Finally, <code>absolute(p)</code>, which would simply be <code>current_path()/p</code>, 
is of very limited utility on platforms like Windows with complicated notions of 
current directory. As such, its semantics may be replaced entirely by those of
<code>system_complete()</code> (as amended by Billy&#39;s email of 8 Feb 2017 
04:33:59), which can then be removed (resolving Late 44 and 45). On POSIX, it 
would remain a simple convenience for <code>current_path()/p</code> with 
superior portability.</p>

<p><b>Proposed wording:</b></p>

<p dir="ltr"><i>Change [path.append]:</i></p>
<blockquote dir="ltr">
  <div dir="ltr">
  <pre>path&amp; operator/=(const path&amp; p);</pre>
  </div>
  <blockquote dir="ltr">
<p dir="ltr"><del><i>Requires:</i> <code>!p.has_root_name()</code>.</del></p>
<p dir="ltr"><i>Effects:</i></p>
<blockquote dir="ltr">
<p dir="ltr">&nbsp;<del>Appends <code>path::preferred_separator</code> to <code>pathstring</code> 
unless:</del></p>
    <blockquote dir="ltr">
<p dir="ltr"><del>— an added <i>directory-separator</i> would be redundant, or</del></p>
<p dir="ltr"><del>— an added <i>directory-separator</i> would change a relative path into an 
absolute path [<i>Note:</i> An empty path is relative.<i>—end note</i> ] , or</del></p>
<p dir="ltr"><del>— <code>p.empty()</code> is <code>true</code>, or</del></p>
<p dir="ltr"><del>— <code>*p.native().cbegin()</code> is a directory-separator.</del></p>
    </blockquote>
<p dir="ltr"><del>Then appends <code>p.native()</code> to&nbsp; <code>
pathstring.</code></del></p>
<p dir="ltr"><ins>If <code>p.is_absolute() || (p.has_root_name() &amp;&amp; p.root_name()!= root_name())</code>, 
then <code>operator=(p)</code>.</ins></p>
<p dir="ltr"><ins>Otherwise, modifies <code>*this</code> as if by these steps:</ins></p>
<blockquote dir="ltr">
<p dir="ltr"><ins>If <code>p.has_root_directory()</code>, then removes any root directory and 
relative path from the generic format pathname. Otherwise, if <code>has_filename() 
|| (!has_root_directory() &amp;&amp; is_absolute())</code>, then appends <code>
path::preferred_separator</code> to the generic format pathname.</ins></p>
<p dir="ltr"><ins>Then appends the native format pathname of <code>p</code>, omitting any 
<i>root-name</i> from its generic format pathname, to the native format pathname.</ins></p>
</blockquote>
<p dir="ltr"><ins>[ <i>Example</i>:</ins></p>
<blockquote dir="ltr">
<p dir="ltr"><ins>Even if <code>//host</code> is interpreted as a root-name,
<code>path(&quot;//host&quot;)/&quot;foo&quot;</code> and <code>path(&quot;//host/&quot;)/&quot;foo&quot;</code> both 
equal <code>&quot;//host/foo&quot;</code>.</ins></p>
<p dir="ltr"><ins>Expression examples</ins></p>
  <blockquote dir="ltr">
    <div dir="ltr">
    <pre><ins>// On POSIX,
path(&quot;foo&quot;) / &quot;&quot;;     // yields &quot;foo/&quot;
path(&quot;foo&quot;) / &quot;/bar&quot;; // yields &quot;/bar&quot;
// On Windows, backslashes replace slashes in the above yields

// On Windows,
path(&quot;foo&quot;) / &quot;c:/bar&quot;;  // yields &quot;c:/bar&quot;
path(&quot;foo&quot;) / &quot;c:&quot;;      // yields &quot;c:&quot;
path(&quot;c:&quot;) / &quot;&quot;;         // yields &quot;c:&quot;
path(&quot;c:foo&quot;) / &quot;/bar&quot;;  // yields &quot;c:/bar&quot;
path(&quot;c:foo&quot;) / &quot;c:bar&quot;; // yields &quot;c:foo/bar&quot;</pre>
    </div>
    </ins>
  </blockquote>
</blockquote>
<p dir="ltr"><ins>&nbsp;<i>&mdash; end example</i> ]</ins></p>
</blockquote>
<p dir="ltr"><i>Returns:</i> <code>*this</code>.</p>
  </blockquote>
</blockquote>

<p><i>Change [path.decompose]:</i></p>

  <blockquote>
    <p><tt>path parent_path() const;</tt> </p>
  </blockquote>
  <blockquote>
    <p> <em>Returns:</em> <del><tt>(empty() || begin() == --end()) ? path() :
    </tt><em>pp</em>, where <em>pp</em> is constructed as if by starting with an empty <tt>path</tt> and successively 
    applying <tt>operator/=</tt> for each element in the range <tt>[begin(),
    --end())</tt>.</del> <ins><code>*this</code> if <code>!has_relative_path()</code>, otherwise a 
    path whose generic format pathname is the longest prefix of the generic 
    format pathname of <code>*this</code> that produces one fewer element in its iteration.</ins></p>
  </blockquote>

<p><i>Change [<a name="path.gen">path.gen</a>]:</i></p>
<blockquote>
  <pre>path lexically_normal() const;</pre>
  <blockquote>
<p><i>Returns: </i><ins>a path whose pathname in the generic format is the normal form 
([fs.def.normal.form]) of the pathname in generic format of <code>*this</code></ins><i>
</i><del><code>*this</code> in normal form ([fs.def.normal.form])</del>.</p>

<p>[ <i>Example:</i><br>
<code>&nbsp;&nbsp;&nbsp; assert(path(&quot;foo/./bar/..&quot;).lexically_normal() == &quot;foo<ins>/</ins>&quot;);<br>
&nbsp;&nbsp;&nbsp; assert(path(&quot;foo/.///bar/../&quot;).lexically_normal() == &quot;foo/<del>.</del>&quot;);<br>
</code><br>
The above assertions will succeed. <del>The second example ends with a current 
directory (dot) element appended to support operating systems that use different 
syntax for directory names and regular file names.</del></p>

<p>On Windows, the returned path’s directory-separator characters will be 
backslashes rather than slashes, but that does not affect path equality. —<i>end 
example</i> ]</p>

  </blockquote>

  <pre>path lexically_relative(const path&amp; base) const;</pre>
  <blockquote>
    <p><i>Returns:</i> <code>*this</code> made relative to <code>base</code>. Does not resolve (27.10.4.18) symlinks. 
Does not first
normalize (27.10.4.12) <code>*this</code> or <code>base</code>.</p>
    <p><i>Effects:</i> <ins>If <code>root_name()!=base.root_name() || is_absolute()!=base.is_<wbr />absolute() 
    || (!has_root_directory() &amp;&amp; base.has_root_directory())</code>, returns 
    <code>path()</code>.</ins> Determines the first mismatched element of <code>*this</code> and 
    <code>base</code> as if by:</p>
    <blockquote>
      <p><code>auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());</code></p>
    </blockquote>
    <p>Then,</p>
    <p><del>— if <code>a == begin()</code> and <code>b == base.begin()</code>, returns 
    <code>path()</code>; otherwise</del></p>
    <p>— if <code>a == end()</code> and <code>b == base.end()</code>, returns 
    <code>path(&quot;.&quot;)</code>; otherwise</p>
    <p><ins>—&nbsp; Let <code>n</code> be the number of <i>filename</i> elements in 
    <code>[b, base.end())</code> that 
    are not <i>dot</i> or <i>dot-dot</i> minus the number that are <i>dot-dot</i>. If 
    <code>n&lt;0</code>, returns 
    <code>path()</code>; otherwise</ins></p>
    <p>— returns an object of class <code>path</code> that is default-constructed, followed by</p>
    <blockquote>
      <p>— application of <code>operator/=(path(&quot;..&quot;))</code> for <del>each element in 
      <code>[b, base.end())</code></del> <ins><code>n</code> times</ins>, 
and then<br>
      — application of <code>operator/=</code> for each element in <code>[a, end())</code>.</p>
    </blockquote>

<p>[ <i>Example</i>:</p>

    <blockquote>

<pre>assert(path(&quot;/a/d&quot;).lexically_relative(&quot;/a/b/c&quot;) == &quot;../../d&quot;);
assert(path(&quot;/a/b/c&quot;).lexically_relative(&quot;/a/d&quot;) == &quot;../b/c&quot;);
assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a&quot;) == &quot;b/c&quot;);
assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a/b/c/x/y&quot;) == &quot;../..&quot;);
assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a/b/c&quot;) == &quot;.&quot;);
assert(path(&quot;a/b&quot;).lexically_relative(&quot;c/d&quot;) == &quot;<ins>../../a/b</ins>&quot;);</pre>

<p>The above assertions will succeed. On Windows, the returned path’s 
directory-separator characters will be backslashes rather than forward slashes, 
but that does not affect path equality.</p>

    </blockquote>

<p>&nbsp;—<i>end example</i> ]</p>

<p>[ <i>Note:</i> If symlink following semantics are desired, use the operational 
function <code>relative()</code>. —<i>end note</i> ]</p>

<p>[ <i>Note:</i> If normalization (27.10.4.12) is needed to ensure consistent matching 
of elements, apply <code>lexically_normal()</code> to <code>*this</code>, <code>base</code>, or both. —<i>end note
</i>]</p>

  </blockquote>

</blockquote>

</blockquote>

<h4><a name="US78">US 78</a>, CA 7; 27.10.15.1 [fs.op.absolute]: Member <code>absolute()</code> in 27.10.4.1 is overspecified for non-POSIX-like O/S<br>
Status: Accept with modifications </h4>

<blockquote>

<p><i>Change [fs.op.absolute] and update the synopsis in [fs.filesystem.syn] 
accordingly:</i></p>

  <blockquote>
    <pre><del>path absolute(const path&amp; p, const path&amp; base = current_path());</del>
<ins>path absolute(const path&amp; p);
path absolute(const path&amp; p, error_code&amp; ec);</ins></pre>
    <blockquote>

<p><del><i>Returns</i>: An absolute path (27.10.4.1) 
composed according to Table 126.</del></p>

      <blockquote>

<p><del>Table 126 — absolute(const path&amp;, const 
path&amp;) return value<br>
...</del></p>

      </blockquote>

<p><ins>&nbsp;<i>Effects:</i> Composes an absolute path referencing the same 
file system location as <code>p</code> according to the operating system ([fs.conform.os])</ins></p>

<p><ins><i>Returns:</i> The composed path. The signature with argument <code>ec</code> 
returns <code>path()</code> if an error occurs. </ins></p>

<blockquote>

<p>[ <i>Note:</i> For the returned path, <code>
rp</code>, <code>rp.is_absolute()</code> is <code>true</code> <ins>unless an error occurs</ins>. —<i>end note</i> 
]</p>

</blockquote>

<p><i>Throws:</i> As specified in 27.10.7.</p>

<p><ins>[ <i>Note:</i> To resolve symlinks, or perform other sanitization which might 
require queries to secondary storage, such as hard disks, consider <code>canonical</code> ([fs.po.canonical]). 
— <i>end note</i> ]</ins></p>

<p><ins>[ <i>Note:</i> Implementations are strongly encouraged to not query secondary 
storage, and not consider <code>!exists(p)</code> an error. — <i>end note</i> ]</ins></p>

<p><ins>[ <i>Example:</i></ins></p>

    <blockquote>

<p><ins>For POSIX-based operating systems, <code>absolute(p)</code> is simply
<code>current_path()/p</code>.</ins></p>

<p><ins>For Windows-based operating systems, <code>absolute</code> might have the same semantics 
as <code>GetFullPathNameW</code>.</ins></p>

    </blockquote>

<p><ins>— <i>end example</i> ]</ins></p>

    </blockquote>
  </blockquote>

<p><i>Remove [fs.op.system_complete] and remove system_complete() from the 
synopsis in [fs.filesystem.syn].</i></p>

<blockquote>

<p><b>Rationale:</b></p>

<p>The simple lexical definition produces identical results for <code>path(&quot;/foo&quot;)/&quot;bar&quot;</code> 
and <code>path(&quot;/foo&quot;)/&quot;/bar&quot;</code> and is likely to produce confusion; making it UB does 
not help that. The &quot;alternative interpretation&quot; from LWG 2664 is the natural 
extension of the obvious lexical meaning to cases involving a root path on the 
right (and breaks the symmetry when both paths are absolute), but there was 
never any proposed replacement more specific than &quot;implementation-defined&quot;. This 
resolution provides the natural meaning and supports non-POSIX root-names as 
well.</p>

</blockquote>

</blockquote>

<h4><a name="US79">US 79</a>, CA 8; Several: Some  operation functions are overspecified for implementation-defined file types<br>
Status: Accept with modifications ✓</h4>

<blockquote>

<p>Resolved by P0430R2 Section US-79/CA-8.</p>

</blockquote>



<h2><a name="editorial"></a>NB  comments submitted as editorial</h2>





<p>There was concern that some of these might involve substantive changes, so 
the SG processed them as ordinary technical comments.</p>





<h4><a name="US38">US 38</a>; 27.10.4.13 [fs.def.symlink]:&nbsp; Duplicates 
§17.3.16<br>
Status: Accept ✓</h4>



<blockquote>

<p> WP has been changed.</p>

</blockquote>



<h4><a name="US39">US 39</a>; 27.10.4.15 [fs.def.parent]: Remove note: Dot and 
dot-dot are not directories<br>
Status: Accept ✓</h4>



<blockquote>

<p> WP has been changed.</p>

</blockquote>



<h4><a name="US41">US 41</a>; 27.10.4.16 [fs.def.parent.other]: The term “parent 
directory” for a (non-directory) file is unusual<br>
Status: Reject ✓</h4>


<blockquote>
<p>Insufficient motivation for change. &quot;parent directory&quot; is the term we use to 
describe the containing directory; we&#39;re (already) following POSIX there, even 
though the POSIX definition is a bit weird.</p>
</blockquote>

<h4><a name="US42">US 42</a>; 27.10.4.21 [fs.def.symlink]: Pathname resolution 
does not always resolve a symlink<br>
Status: Reject ✓</h4>



<blockquote>

<p>There is an apparent corner case contradiction between the POSIX definition and other 
places in the POSIX standard. The [fs.def.symlink] definition is identical to 
the POSIX 3.381 Symbolic Link definition () and the SG prefers to keep it that 
way.</p>

</blockquote>



<h4><a name="US47">US 47</a>; 27.10.8.1 [path.generic]: “.” and “..” already 
match the name production<br>
Status: Accept with modifications ✓</h4>



<blockquote>



<p>&nbsp;<span style="background-color: #E1E9FD"><i>The filesystem small group 
believes this is not editorial.</i></span></p>



<p><b>Discussion</b>: <i>dot</i> and <i>dot-dot</i> are unneeded as grammar 
productions, since &#39;name&#39; already matches them.&nbsp;They also cause 
ambiguity in the <i>filename</i> grammar. They do, however, need to be 
defined terms in [fs.def.filename]</p>



<p><i>Change [fs.def.filename]:</i></p>



  <blockquote>



<p><b>filename</b><br>
The name of a file. Filenames <i>dot</i> and <i>dot-dot</i><ins>, consisting solely 
of one and two period characters respectively,</ins> have special meaning. The 
following characteristics of filenames are operating system dependent:<br>
— The permitted characters. [ <i>Example:</i> Some operating systems prohibit 
the ASCII control characters (0x00 – 0x1F) in filenames. <i>—end example</i> ]<br>
— The maximum permitted length.<br>
— Filenames that are not permitted.<br>
— Filenames that have special meaning.<br>
— Case awareness and sensitivity during path resolution.<br>
— Special rules that may apply to file types other than regular files, such as 
directories.</p>



  </blockquote>



<p><i>Change [path.generic]:</i></p>



  <blockquote>



<p><i><del>filename:</del></i></p>



    <blockquote>



<p><i><del>name</del><br>
<del>dot</del><br>
<del>dot-dot</del></i></p>



    </blockquote>



<p><i><ins>file</ins>name:</i></p>



    <blockquote>



<p>A sequence of characters other than directory-separator characters. [ <i>
Note:</i> Operating systems often place restrictions on the characters that may 
be used in a filename. For wide portability, users may wish to limit filename 
characters to the POSIX Portable Filename Character Set: <code>A B C D E F G H I 
J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w 
x y z 0 1 2 3 4 5 6 7 8 9 . _ -</code> <i>—end note</i> ]</p>



    </blockquote>



<p><i><del>dot:</del></i></p>



    <blockquote>



<p><i><del>The filename consisting solely of a single period character (.).</del></i></p>



    </blockquote>



<p><i><del>dot-dot:</del></i></p>



    <blockquote>



<p><i><del>The filename consisting solely of two period characters (..).</del></i></p>



    </blockquote>
</blockquote>



<p>...</p>



<p>The filename <i>dot</i> <ins>([fs.def.filename])</ins> is treated as a reference to the 
current directory. The filename <i>dot-dot</i> <ins>([fs.def.filename])</ins> is treated as a reference to the 
parent directory. What the filename <i>dot-dot</i> refers to relative to <i>
root-directory</i> is implementation-defined. Specific filenames may have 
special meanings for a particular operating system.</p>


</blockquote>



<h4><a name="US50">US 50</a>;&nbsp; 27.10.8.3 [path.req]: <code>path</code> 
requirements ¶ 1.4 largely redundant with ¶ 1.3<br>
Status: Reject ✓</h4>


<blockquote>

<p><i><span style="background-color: #FFFF99">Beman Dawes to open an issue to expose this concern to additional experts. 
This is not a priority issue for shipping C++17.</span></i></p>

</blockquote>



<h2><a name="late-comments"></a>Late comments from P0489R0</h2>



<p>Quoting P0489R0, &quot;These comments were not submitted in time to 
be registered as National Body Comments, but should be considered as possible 
issues against SC 22, N3151, ISO/IEC CD 14882.&quot; </p>




</ins>




</font>




<p><span style="background-color: #E1E9FD; font-style:italic">Late comments 15-47 apply to 27.10 [filesystems]. 
Except for as noted below, the submitter of these late comments has agreed to 
open LWG issues for any late comments that are still a concern.</span></p>

<font FACE="LMRoman10-Regular">

<h4><a name="Late15">Late 15</a>; 27.10.8.4.11 ¶3.1: A “mismatched element” cannot be equal to an iterator</h4>

<h4><a name="Late16">Late 16</a>; 27.10.8.4.11 ¶3.3.1: <code>lexically_relative("..\\foo")</code> produces nonsense.</h4>

<h4><a name="Late17">Late 17</a>; 27.10.8.4.11 ¶3.3.2: Behavior not always 
appropriate</h4>

<h4><a name="Late18">Late 18</a>; 27.10.8.4.11 ¶4: Behavior wrong in case corresponding to  comment Late17</h4>

<h4><a name="Late19">Late 19</a>; 27.10.8.5 ¶2: It is surprising that a path is a container of paths</h4>

<blockquote>

<p>Recommend NAD. See <a href="#US55">US 55</a>, <a href="#US59">US 59</a>.</p>

</blockquote>

<h4><a name="Late20">Late 20</a>; 27.10.11 ¶1: Anemic status structure</h4>

<h4><a name="Late21">Late 21</a>; 27.10.12: <code>directory_entry</code> is just a trivial wrapper for <code>path</code></h4>

<blockquote>

<p>Subsumed by LWG <a href="http://cplusplus.github.io/LWG/lwg-active.html#2663">
2663</a> and <a href="http://cplusplus.github.io/LWG/lwg-active.html#2677">2677</a></p>

</blockquote>

<h4><a name="Late22">Late 22</a>; 27.10.13 ¶6: <code>directory_iterator</code> cumbersome to assemble full path with iterator’s directory</h4>

<h4><a name="Late23">Late 23</a>; 27.10.14.1 ¶28: <code>disable_recursion_pending()</code> name is ugly implementation detail</h4>

<h4><a name="Late24">Late 24</a>; 27.10.15.1 ¶1: <code>absolute()</code> can produce nonsense result</h4>

<h4><a name="Late25">Late 25</a>; 27.10.15.4 ¶4.2: What attributes does <code>copy_file()</code> copy?</h4>

<h4><a name="Late26">Late 26</a>; 27.10.15.6 ¶5: <code>create_directories()</code> complexity assumes syscalls take constant time</h4>

<h4><a name="Late27">Late 27</a>; 27.10.15.7 ¶5: <code>create_directory()</code> specification prevents sensible security measures</code></h4>

<h4><a name="Late28">Late 28</a>; 27.10.15.10: <code>create_symlink()</code> might misbehave if <code>to</code> is a directory</h4>

<h4><a name="Late29">Late 29</a>; 27.10.15.13: Access to file ID is superior to <code>equivalent()</code></h4>

<blockquote>

<p>Suggest proposing a new function, post-C++17, along the lines of <code>
file_identity identity(const path&amp;,bool resolve=true);</code></p>

</blockquote>

<h4><a name="Late30">Late 30</a>; 27.10.15.13 ¶3: <code>equivalent()</code>'s <code>s1==s2</code> check is ill-formed and could race</h4>

<h4><a name="Late31">Late 31</a>; 27.10.15.13 ¶5: Surprising that <code>equivalent()</code>'s error_code overload 
can throw</h4>

<h4><a name="Late32">Late 32</a>; 27.10.15.13 ¶5 : <code>equivalent()</code> should not reject special files outright</h4>

<h4><a name="Late33">Late 33</a>; 27.10.15.21: <code>is_other()</code> result surprising</h4>

<h4><a name="Late34">Late 34</a>; 27.10.15.25 ¶5: Could <code>last_write_time()</code> guarantee the error direction</code></h4>

<blockquote>

<p>Recommend submitting a paper that researches whether this is in fact 
possible. If it is possible, providing proposed wording would be helpful.</p>

</blockquote>

<h4><a name="Late35">Late 35</a>; 27.10.15.26: Why is there no way to read permissions?</h4>

<blockquote>

<p>Recommend NAD. They are available in <code>file_status</code>. If anyone 
thinks a separate function would be useful, they should submit an issue or a 
paper.</p>

</blockquote>

<h4><a name="Late36">Late 36</a>; 27.10.15.26: The <code>permissions() error_code</code> overload should be <code>noexcept</code><br>
Status: Accept ✓</h4>

<blockquote>

<p>The proposed resolution has been integrated into <a href="#Late37">Late-37</a> 
below because it is much easier to understand when full context is provided and 
having two separate resolutions revising the same wording would be a recipe for 
disaster.</p>

</blockquote>

<h4><a name="Late37">Late 37</a>; 27.10.15.26 ¶2:<code>permissions()</code> actions should be separate parameter<br>
Status: Accept with modifications ✓</h4>


<blockquote>

<p><span style="font-style: italic; background-color: #E1E9FD">This problem, 
with the same suggested fix, was also reported for the Filesystem TS. It was not 
resolved in the TS due to an administrative snafu.</span></p>  
<p><i>Change [fs.filesystem.syn]:</i></p>
<blockquote>
  <pre>// 27.10.10, enumerations
enum class file_type;
enum class perms;
<ins>enum class perm_options;</ins>
enum class copy_options;
enum class directory_options;</pre>
<p>...</p>
  <pre>void permissions(const path&amp; p, perms prms<ins>, perm_options opts=perm_options::replace</ins>);
void permissions(const path&amp; p, perms prms, error_code&amp; ec) <ins>noexcept</ins>;
<ins>void permissions(const path&amp; p, perms prms, perm_options opts, error_code&amp; ec);</ins></pre>
</blockquote>

  <p><i>Strike the following rows in [fs.enum] Table nnn — Enum class
  <code>perms</code>:</i></p>
<ul>
  <li><del><i><code>add_perms</code></i></del></li>
  <li><del><i><code>remove_perms</code></i></del></li>
  <li><del><i><code>symlink_nofollow</code></i></del></li>
</ul>

  <p><i>Insert a new sub-section after [enum.perms]:</i></p>
<blockquote>

  <p><b><i><ins>27.10.n.n </i>Enum class <code>perm_options </code>[enum.perm_options]</b></ins></p>

  <p><ins>The <code>enum class</code> type <code>perm_options</code> is 
  a bitmask type ([bitmask.types]) that specifies bitmask constants used to 
  control the semantics of permissions operations, with the meanings listed in 
  Table <i>nnn</i>. The bitmask constants are bitmask elements. In Table <i>nnn</i>
  <code>perm</code> denotes a value of type <code>perms</code> passed to <code>
  permissions</code>.</ins></p>

  <p align="center"><ins>Table <i>nnn</i> &mdash; Enum class <code>perm_options</code></ins></p>
  <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
    <tr>
      <td bgcolor="#CCFFCC"><b>Name</b></td>
      <td bgcolor="#CCFFCC"><b>Meaning</b></td>
    </tr>
    <tr>
      <td bgcolor="#CCFFCC"><code>replace</code></td>
      <td bgcolor="#CCFFCC"> <code>permissions</code> shall replace the file's  permission bits with <code>
      perm</code>.</td>
    </tr>
    <tr>
      <td bgcolor="#CCFFCC"><code>add</code></td>
      <td bgcolor="#CCFFCC">
      <p><code>permissions</code> shall 

<font FACE="LMRoman10-Regular">

      replace the file&#39;s permission bits with the </font>bitwise OR of <code>
      perm</code> and the file’s current permission 
      bits.</td>
    </tr>
    <tr>
      <td bgcolor="#CCFFCC"><code>remove</code></td>
      <td bgcolor="#CCFFCC">
      <p><code>permissions</code> shall

<font FACE="LMRoman10-Regular">

      replace the file&#39;s permission bits with the bitwise</font> AND of the 
      complement of <code>perm</code>

<font FACE="LMRoman10-Regular">

      and the file’s current permission bits.</td>
    </tr>
    <tr>
      <td bgcolor="#CCFFCC"><code>nofollow</code></td>
      <td bgcolor="#CCFFCC"><code>permissions</code> shall change the permissions of a symbolic 
      link itself rather than the permissions of the file the link resolves to.</td>
    </tr>
  </table>
</blockquote>

<p><i>Change [fs.op.permissions]:</i></p>
<blockquote>
<pre>void permissions(const path&amp; p, perms prms<ins>, perm_options opts=perm_options::replace</ins>);
void permissions(const path&amp; p, perms prms, error_code&amp; ec) <ins>noexcept</ins>;
<ins>void permissions(const path&amp; p, perms prms, perm_options opts, error_code&amp; ec);</ins></pre>
<blockquote>
  <p><i>Requires:</i> <del><code>!((prms &amp; perms::add_perms) != perms::none &amp;&amp; (prms 
  &amp; perms::remove_perms) != perms::none)</code>.</del> <ins>One and 
  only one of the <code>perm_options</code> constants <code>replace</code>,
  <code>add</code>, or <code>remove</code> is present in <code>opts</code>.</ins></p>
  <p><ins><i>Remarks:</i> The second signature behaves as if it had an additional 
  argument&nbsp; <code>perm_options opts</code> with a value of <code>
  perm_options::replace</code>.</ins></p>
  <p><del><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> 
  to the file <code>p</code> resolves to, or if that file is a symbolic link and
  <code>symlink_nofollow</code> is not set in <code>prms</code>, the file that 
  it points to, as if by POSIX <code>fchmodat()</code>. The effective permission 
  bits are determined as specified in Table 127, where <code>s</code> is the 
  result of <code>(prms &amp; perms::symlink_nofollow) != perms::none ? 
  symlink_status(p) : status(p)</code>.</del></p>
  <p><ins><i>Effects:</i> Applies the action specified by <code>opts</code> 
  to the file <code>p</code> resolves to, or to file <code>p</code> itself if <code>p</code> is a symbolic link and
  <code>perm_options::nofollow</code> is set in <code>opts</code>. The action is 
  applied as if by POSIX <code>fchmodat()</code>.</ins></p>
  <p>[ <i>Note:</i> Conceptually permissions are viewed as bits, but the actual 
  implementation may use some other mechanism. <i>—end note</i> ]</p>
  <p><i>Throws:</i> As specified in 27.10.7.</p>
</blockquote>

  </blockquote>

</blockquote>

<h4><a name="Late38">Late 38</a>; 27.10.15.26 ¶2: Unimplementable implication that <code>permissions()</code> is atomic</h4>

<h4><a name="Late39">Late 39</a>; 27.10.15.29 ¶3: Suprising <code>relative()</code> behavior for symlinks</h4>

<h4><a name="Late40">Late 40</a>; 27.10.15.31 ¶1: <code>remove_all()</code> unclear for <code>symlink/</code></h4>

<h4><a name="Late41">Late 41</a>; 27.10.15.31 ¶3: Would be useful for <code>remove_all()</code> to report successful removal count on error</h4>

<h4><a name="Late42">Late 42</a>; 27.10.15.33 ¶1: <code>resize_file()</code> <i>Postcondition</i> missing argument<br>
Status: Editorial ✓</h4>

<blockquote>

<p>Fixed in the post-Issaquah working 
paper</p>

</blockquote>

<h4><a name="Late43">Late 43</a>; 27.10.15.33 ¶3: Add POSIX <code>ftruncate()</code> equivalent function</h4>

<blockquote>

<p>Recommend opening issue. Such a feature might be useful in 27.9 [file.streams] for C++2n.</p> 

</blockquote>

<h4><a name="Late44">Late 44</a>; 27.10.15.38: <code>system_complete()</code> name inconsistent with similar functions in subclause</h4>

<h4><a name="Late45">Late 45</a>; 27.10.15.38 ¶6: Remove <code>system_complete()</code> unless it can be made reliable</h4>

<h4><a name="Late46">Late 46</a>; 27.10.15.40 ¶2: Question about <code>weakly_canonical()</code> <i>Effects</i></code></h4>

<h4><a name="Late47">Late 47</a>; 27.10.15.40 ¶4: <code>weakly_canonical()</code> suggested caching is incorrect</h4>


<hr>

</body>

</html>