<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2674: Bidirectional iterator requirement on path::iterator
is very expensive</title>
<meta property="og:title" content="Issue 2674: Bidirectional iterator requirement on path::iterator
is very expensive">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2674.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++17">C++17</a> status.</em></p>
<h3 id="2674"><a href="lwg-defects.html#2674">2674</a>. Bidirectional iterator requirement on <code>path::iterator</code>
is very expensive</h3>
<p><b>Section:</b> 31.12.6.6 <a href="https://wg21.link/fs.path.itr">[fs.path.itr]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2015-09-15 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#fs.path.itr">issues</a> in [fs.path.itr].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
31.12.6.6 <a href="https://wg21.link/fs.path.itr">[fs.path.itr]</a> requires <code>path::iterator</code> to be a BidirectionalIterator, which also implies
the ForwardIterator requirement in [forward.iterators] p6 for the following assertion
to pass:
</p>
<blockquote>
<pre>
path p("/");
auto it1 = p.begin();
auto it2 = p.begin();
assert( &amp;*it1 == &amp;*it2 );
</pre>
</blockquote>
<p>This prevents iterators containing a <code>path</code>, or constructing one on the fly when
dereferenced, the object they point to must exist outside the iterators and potentially
outlive them. The only practical way to meet the requirement is for <code>p</code> to hold
a container of child <code>path</code> objects so the iterators can refer to those
children. This makes a <code>path</code> object much larger than would naïvely be
expected.</p>
<p>The Boost and MSVC implementations of Filesystem fail to meet this requirement. The
GCC implementation meets it, but it makes <code>sizeof(path) == 64</code> (for 64-bit) or
<code>sizeof(path) == 40</code> for 32-bit, and makes many path operations
more expensive.</p>

<p><i>[21 Nov 2015 Beman comments:]</i></p>

<p>
The ForwardIterator requirement in
[forward.iterators] "If <code>a</code> and <code>b</code> are both dereferenceable, then <code>a == b</code> if and only if 
<code>*a</code> and <code>*b</code> are bound to the same object." will be removed by N4560, Working Draft, C++ Extensions for
Ranges. I see no point in requiring something for the File System TS that is expensive,
has never to my knowledge been requested by users, and is going to go away soon anyhow.
The wording I propose below removes the requirement.
</p>

<p><i>[<b>Apr 2016 Issue updated to address the C++ Working Paper. Previously addressed File System TS</b>]</i></p>
 



<p id="res-2674"><b>Proposed resolution:</b></p>
<p>
This wording is relative to N4582.
</p>

<ol>
<li>
<p>Change 31.12.6.6 <a href="https://wg21.link/fs.path.itr">[fs.path.itr]</a> paragraph 2:</p>
<blockquote>
<p>A <code>path::iterator</code> is a constant iterator satisfying all the requirements of a bidirectional iterator 
(C++14 §24.1.4 Bidirectional iterators) <ins>except that there is no requirement
that two equal iterators be bound to the same object</ins>. Its <code>value_type</code> is <code>path</code>.</p>
</blockquote>
</li>
</ol>





</body>
</html>
