Skip to content

Commit

Permalink
Initial implementation and docs for path::reverse_iterator.
Browse files Browse the repository at this point in the history
  • Loading branch information
Beman committed Sep 4, 2015
1 parent 2af843f commit 8cd5522
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
34 changes: 28 additions & 6 deletions doc/reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,13 @@ <h2 dir="ltr"><a name="class-path">Class <code>path</code> [class.path]</a></h2>
// <a href="#path-iterators">iterators</a>
class iterator;
typedef iterator const_iterator;
class reverse_iterator;
typedef reverse_iterator const_reverse_iterator;

iterator begin() const;
iterator end() const;
reverse_iterator rbegin() const;
reverse_iterator rend() const;

// <a href="#path-imbued-locale">imbued locale</a>
static std::locale <a href="#path-imbue">imbue</a>(const std::locale&amp; loc);
Expand Down Expand Up @@ -1671,10 +1675,19 @@ <h3 dir="ltr"> <a name="path-query"> <code><font size="4">path</font></code> que
</blockquote>
<h3 dir="ltr"> <a name="path-iterators"> <code>
<font size="4">path</font></code> iterators</a> [path.itr]</h3>
<p dir="ltr"> Path iterators iterate over the elements of the stored pathname.</p>
<p dir="ltr"> A <code>path::iterator</code> is a constant iterator satisfying all
<p dir="ltr"> Path iterators <code>iterator</code>, <code>const_iterator</code>,
<code>reverse_iterator</code>, and <code>const_reverse_iterator</code> iterate over the elements of the stored pathname.</p>
<p dir="ltr"> Path iterators are constant iterators satisfying
the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional
iterators [lib.bidirectional.iterators]). Its <code>value_type</code> is <code>path</code>.</p>
iterators [lib.bidirectional.iterators]). The <code>value_type</code>&nbsp; of
an iterator is <code>path</code>.</p>
<blockquote>
<p dir="ltr"> [<i>Note:</i> Path iterators store their value objects internally
and when dereferenced return references to those internal objects. They cannot
be used with iterator adaptors such as <code>std::reverse_iterator</code> that
assume references obtained by dereferencing an iterator point to objects that
out-live the iterator itself. <i>—end note</i>] </p>
</blockquote>
<p dir="ltr">Calling any non-const member function of a <code>path</code> object
invalidates all iterators referring to elements of that object.</p>
<p dir="ltr"> The forward traversal order is as follows:</p>
Expand All @@ -1697,10 +1710,19 @@ <h3 dir="ltr"> <a name="path-iterators"> <code>
<p>The backward traversal order is the reverse of forward traversal.</p>
<pre>iterator begin() const;</pre>
<blockquote>
<p><i>Returns:</i> An iterator for the first present element in the traversal
list above. If no elements are present, the end iterator.</p>
<p><i>Returns:</i> An iterator for the first element in forward traversal
order. If no elements are present, the end iterator.</p>
</blockquote>
<pre>iterator end() const;</pre>
<blockquote>
<p><i>Returns:</i> The end iterator.</p>
</blockquote>
<pre>reverse_iterator rbegin() const;</pre>
<blockquote>
<p><i>Returns:</i> An iterator for the first element in backward traversal
order. If no elements are present, the end iterator.</p>
</blockquote>
<pre>reverse_iterator rend() const;</pre>
<blockquote>
<p><i>Returns:</i> The end iterator.</p>
</blockquote>
Expand Down Expand Up @@ -3987,7 +4009,7 @@ <h2><a name="References">References</a></h2>
</font>
<a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p>
<p><font size="2">Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->03 September 2015<!--webbot bot="Timestamp" endspan i-checksum="39624" --></font></p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->04 September 2015<!--webbot bot="Timestamp" endspan i-checksum="39626" --></font></p>


</body></html>
52 changes: 52 additions & 0 deletions include/boost/filesystem/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,13 @@ namespace filesystem

class iterator;
typedef iterator const_iterator;
class reverse_iterator;
typedef reverse_iterator const_reverse_iterator;

iterator begin() const;
iterator end() const;
reverse_iterator rbegin() const;
reverse_iterator rend() const;

// ----- static member functions -----

Expand Down Expand Up @@ -624,6 +628,7 @@ namespace filesystem
private:
friend class boost::iterator_core_access;
friend class boost::filesystem::path;
friend class boost::filesystem::path::reverse_iterator;
friend void m_path_iterator_increment(path::iterator & it);
friend void m_path_iterator_decrement(path::iterator & it);

Expand All @@ -649,6 +654,53 @@ namespace filesystem
// m_pos == m_path_ptr->m_pathname.size()
}; // path::iterator

//------------------------------------------------------------------------------------//
// class path::reverse_iterator //
//------------------------------------------------------------------------------------//

class path::reverse_iterator
: public boost::iterator_facade<
path::reverse_iterator,
path const,
boost::bidirectional_traversal_tag >
{
public:

explicit reverse_iterator(iterator itr) : m_itr(itr)
{
if (itr != itr.m_path_ptr->begin())
m_element = *--itr;
}
private:
friend class boost::iterator_core_access;
friend class boost::filesystem::path;

const path& dereference() const { return m_element; }
bool equal(const reverse_iterator& rhs) const { return m_itr == rhs.m_itr; }
void increment()
{
--m_itr;
if (m_itr != m_itr.m_path_ptr->begin())
{
iterator tmp = m_itr;
m_element = *--tmp;
}
}
void decrement()
{
m_element = *m_itr;
++m_itr;
}

iterator m_itr;
path m_element;

}; // path::reverse_iterator

inline path::reverse_iterator path::rbegin() const { return reverse_iterator(end()); }
inline path::reverse_iterator path::rend() const { return reverse_iterator(begin()); }


//------------------------------------------------------------------------------------//
// //
// non-member functions //
Expand Down
2 changes: 1 addition & 1 deletion test/msvc/issue_test/issue_test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\issues\11166-remove-race.cpp" />
<ClCompile Include="..\..\issues\11061-imposible-to-traverse-path-reverse-iterator.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down

0 comments on commit 8cd5522

Please sign in to comment.