Add BOOST_FOREACH support. Correct C++11 range-based for statement enabler signatures. Improve test coverage. Clears feature requests #5896 and #6521.

[SVN r79451]
This commit is contained in:
Beman Dawes 2012-07-12 13:53:17 +00:00
parent af67382a81
commit bb0fe7585c
8 changed files with 167 additions and 47 deletions

View File

@ -134,7 +134,12 @@ del { background-color:#FFA0A0 }
<a href="#Class-directory_iterator">Class <code>directory_iterator</code></a><br>
&nbsp;&nbsp;&nbsp; <a href="#directory_iterator-members"><code>directory_iterator</code>
members</a><br>
&nbsp; <code>&nbsp;<a href="#directory_iterator-non-member-functions">directory_iterator</a></code><a href="#directory_iterator-members">
non-member functions</a><br>
<a href="#Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a><br>
<code>&nbsp; <a href="#recursive_directory_iterator-non-member-functions">
recursive_directory_iterator</a></code><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#recursive_directory_iterator-non-member-functions">&nbsp;non-member functions</a><br>
<a href="#Operational-functions">
Operational functions</a><br>
<code>&nbsp;&nbsp;&nbsp;&nbsp <a href="#absolute">absolute</a><br>
@ -152,11 +157,11 @@ del { background-color:#FFA0A0 }
&nbsp;&nbsp;&nbsp;&nbsp <a href="#equivalent">equivalent</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#file_size">file_size</a><br>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#hard_link_count">hard_link_count</a><br>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#initial_path">initial_path</a><br>
&nbsp;&nbsp;&nbsp;&nbsp i<a href="#is_directory">s_directory</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_empty">is_empty</a></code></td>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#initial_path">initial_path</a></code></td>
<td width="34%" valign="top">
<code>&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_other">is_other</a><br>
<code>&nbsp;&nbsp;&nbsp;&nbsp; i<a href="#is_directory">s_directory</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_empty">is_empty</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_other">is_other</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_regular_file">is_regular_file</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_symlink">is_symlink</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#last_write_time">last_write_time</a><br>
@ -402,14 +407,26 @@ void swap(path&amp; lhs, path&amp; rhs);
class <a href="#Class-directory_iterator">directory_iterator</a>;
inline directory_iterator&amp; begin(directory_iterator&amp; iter);
inline directory_iterator end(const directory_iterator&amp;);
// enable c++11 range-based for statements
const directory_iterator&amp; <a href="#directory_iterator-non-member-functions">begin</a>(const directory_iterator&amp; iter);
directory_iterator <a href="#directory_iterator-non-member-functions">end</a>(const directory_iterator&amp;);
// enable BOOST_FOREACH
directory_iterator&amp; range_begin(directory_iterator&amp; iter);
directory_iterator range_begin(const directory_iterator&amp; iter);
directory_iterator range_end(const directory_iterator&amp;);
class <a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a>;
inline recursive_directory_iterator&amp; begin(recursive_directory_iterator&amp; iter);
inline recursive_directory_iterator end(const recursive_directory_iterator&amp;);
// enable c++11 range-based for statements
const recursive_directory_iterator&amp; <a href="#recursive_directory_iterator-non-member-functions">begin</a>(const recursive_directory_iterator&amp; iter);
recursive_directory_iterator <a href="#recursive_directory_iterator-non-member-functions">end</a>(const recursive_directory_iterator&amp;);
&nbsp;&nbsp;&nbsp; // enable BOOST_FOREACH
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator&amp; range_begin(recursive_directory_iterator&amp; iter);
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator range_begin(const recursive_directory_iterator&amp; iter);
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator range_end(const recursive_directory_iterator&amp;);
&nbsp;
enum <a name="file_type" href="#Enum-file_type">file_type</a>
{
status_error, file_not_found, regular_file, directory_file,
@ -2045,12 +2062,12 @@ directory_iterator&amp; increment(system::error_code&amp; ec);</pre>
<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p>
</blockquote>
<h3><code>directory_iterator</code> non-member functions</h3>
<pre>inline directory_iterator&amp; begin(directory_iterator&amp; iter);</pre>
<h3><a name="directory_iterator-non-member-functions"><code>directory_iterator</code> non-member functions</a></h3>
<pre>const directory_iterator&amp; begin(const directory_iterator&amp; iter);</pre>
<blockquote>
<p><i>Returns: </i><code>iter</code>.</p>
</blockquote>
<pre>inline directory_iterator end(const directory_iterator&amp;);</pre>
<pre>directory_iterator end(const directory_iterator&amp;);</pre>
<blockquote>
<p><i>Returns: </i><code>directory_iterator()</code>.</p>
</blockquote>
@ -2191,14 +2208,14 @@ is decremented and iteration of the parent directory resumes.</li>
<p>[<i>Note:</i> <code>no_push()</code> is used to prevent
unwanted recursion into a directory. <i>--end note</i>]</p>
</blockquote>
<h3><code>recursive_directory_iterator</code> non-member functions</h3>
<pre>inline recursive_directory_iterator&amp; begin(recursive_directory_iterator&amp; iter);</pre>
<h3><a name="recursive_directory_iterator-non-member-functions"><code>recursive_directory_iterator</code> non-member functions</a></h3>
<pre>const recursive_directory_iterator&amp; begin(const recursive_directory_iterator&amp; iter);</pre>
<blockquote>
<p><i>Returns: </i><code>iter</code>.</p>
</blockquote>
<pre>inline recursive_directory_iterator end(const recursive_directory_iterator&amp;);</pre>
<pre>recursive_directory_iterator end(const recursive_directory_iterator&amp;);</pre>
<blockquote>
<p><i>Returns: </i>recursive_<code>directory_iterator()</code>.</p>
<p><i>Returns: </i><code>recursive_directory_iterator()</code>.</p>
</blockquote>
<h3><a name="Operational-functions">Operational functions</a></h3>
<p>Operational functions query or modify files, including directories, in external

View File

@ -39,8 +39,14 @@
<h2>1.51.0</h2>
<ul>
<li>Add begin() and end() non-member functions for directory_iterator and
recursive_directory_iterator so that C++11 range-based for statements now
work.</li>
recursive_directory_iterator so that C++11 range-based for statements work.
Suggested by feature requests
<a href="https://svn.boost.org/trac/boost/ticket/5896">#5896</a> and
<a href="https://svn.boost.org/trac/boost/ticket/6521">#6521</a>, using the
<a href="https://svn.boost.org/trac/boost/ticket/5896">#5896</a> approach.</li>
<li>Add range_begin() and range_end() non-member functions for directory_iterator and
recursive_directory_iterator so that
<a href="http://www.boost.org/libs/foreach/">BOOST_FOREACH</a> works.</li>
</ul>
<h2>1.50.0</h2>
@ -170,7 +176,7 @@
</ul>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->10 July, 2012<!--webbot bot="Timestamp" endspan i-checksum="21085" --></p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->12 July, 2012<!--webbot bot="Timestamp" endspan i-checksum="21089" --></p>
<p>© Copyright Beman Dawes, 2011</p>
<p> Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@ -1,5 +1,8 @@
@echo off
rem Copyright Beman Dawes 2012
rem Distributed under the Boost Software License, Version 1.0.
del tr2.html 2>nul
mmp TARGET=TR2 source.html tr2.html
del reference.html 2>nul
mmp TARGET=BOOST source.html reference.html
echo run "hoist" to hoist reference.html to doc directory

5
doc/src/hoist.bat Normal file
View File

@ -0,0 +1,5 @@
@echo off
rem Copyright Beman Dawes 2012
rem Distributed under the Boost Software License, Version 1.0.
copy /y reference.html ..
echo reference.html copied to ..

View File

@ -103,7 +103,12 @@ $endif
<a href="#Class-directory_iterator">Class <code>directory_iterator</code></a><br>
&nbsp;&nbsp;&nbsp; <a href="#directory_iterator-members"><code>directory_iterator</code>
members</a><br>
&nbsp; <code>&nbsp;<a href="#directory_iterator-non-member-functions">directory_iterator</a></code><a href="#directory_iterator-members">
non-member functions</a><br>
<a href="#Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a><br>
<code>&nbsp; <a href="#recursive_directory_iterator-non-member-functions">
recursive_directory_iterator</a></code><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#recursive_directory_iterator-non-member-functions">&nbsp;non-member functions</a><br>
<a href="#Operational-functions">
Operational functions</a><br>
<code>&nbsp;&nbsp;&nbsp;&nbsp <a href="#absolute">absolute</a><br>
@ -121,11 +126,11 @@ $endif
&nbsp;&nbsp;&nbsp;&nbsp <a href="#equivalent">equivalent</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#file_size">file_size</a><br>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#hard_link_count">hard_link_count</a><br>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#initial_path">initial_path</a><br>
&nbsp;&nbsp;&nbsp;&nbsp i<a href="#is_directory">s_directory</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_empty">is_empty</a></code></td>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#initial_path">initial_path</a></code></td>
<td width="34%" valign="top">
<code>&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_other">is_other</a><br>
<code>&nbsp;&nbsp;&nbsp;&nbsp; i<a href="#is_directory">s_directory</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_empty">is_empty</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_other">is_other</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_regular_file">is_regular_file</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#is_symlink">is_symlink</a><br>
&nbsp;&nbsp;&nbsp;&nbsp <a href="#last_write_time">last_write_time</a><br>
@ -364,14 +369,26 @@ $endif
class <a href="#Class-directory_iterator">directory_iterator</a>;
inline directory_iterator&amp; begin(directory_iterator&amp; iter);
inline directory_iterator end(const directory_iterator&amp;);
// enable c++11 range-based for statements
const directory_iterator&amp; <a href="#directory_iterator-non-member-functions">begin</a>(const directory_iterator&amp; iter);
directory_iterator <a href="#directory_iterator-non-member-functions">end</a>(const directory_iterator&amp;);
// enable BOOST_FOREACH
directory_iterator&amp; range_begin(directory_iterator&amp; iter);
directory_iterator range_begin(const directory_iterator&amp; iter);
directory_iterator range_end(const directory_iterator&amp;);
class <a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a>;
inline recursive_directory_iterator&amp; begin(recursive_directory_iterator&amp; iter);
inline recursive_directory_iterator end(const recursive_directory_iterator&amp;);
// enable c++11 range-based for statements
const recursive_directory_iterator&amp; <a href="#recursive_directory_iterator-non-member-functions">begin</a>(const recursive_directory_iterator&amp; iter);
recursive_directory_iterator <a href="#recursive_directory_iterator-non-member-functions">end</a>(const recursive_directory_iterator&amp;);
&nbsp;&nbsp;&nbsp; // enable BOOST_FOREACH
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator&amp; range_begin(recursive_directory_iterator&amp; iter);
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator range_begin(const recursive_directory_iterator&amp; iter);
&nbsp;&nbsp;&nbsp;&nbsp;recursive_directory_iterator range_end(const recursive_directory_iterator&amp;);
&nbsp;
enum <a name="file_type" href="#Enum-file_type">file_type</a>
{
status_error, file_not_found, regular_file, directory_file,
@ -1989,12 +2006,12 @@ directory_iterator&amp; increment(system::error_code&amp; ec);</pre>
<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p>
</blockquote>
<h3><code>directory_iterator</code> non-member functions</h3>
<pre>inline directory_iterator&amp; begin(directory_iterator&amp; iter);</pre>
<h3><a name="directory_iterator-non-member-functions"><code>directory_iterator</code> non-member functions</a></h3>
<pre>const directory_iterator&amp; begin(const directory_iterator&amp; iter);</pre>
<blockquote>
<p><i>Returns: </i><code>iter</code>.</p>
</blockquote>
<pre>inline directory_iterator end(const directory_iterator&amp;);</pre>
<pre>directory_iterator end(const directory_iterator&amp;);</pre>
<blockquote>
<p><i>Returns: </i><code>directory_iterator()</code>.</p>
</blockquote>
@ -2131,14 +2148,14 @@ is decremented and iteration of the parent directory resumes.</li>
<p>[<i>Note:</i> <code>no_push()</code> is used to prevent
unwanted recursion into a directory. <i>--end note</i>]</p>
</blockquote>
<h3><code>recursive_directory_iterator</code> non-member functions</h3>
<pre>inline recursive_directory_iterator&amp; begin(recursive_directory_iterator&amp; iter);</pre>
<h3><a name="recursive_directory_iterator-non-member-functions"><code>recursive_directory_iterator</code> non-member functions</a></h3>
<pre>const recursive_directory_iterator&amp; begin(const recursive_directory_iterator&amp; iter);</pre>
<blockquote>
<p><i>Returns: </i><code>iter</code>.</p>
</blockquote>
<pre>inline recursive_directory_iterator end(const recursive_directory_iterator&amp;);</pre>
<pre>recursive_directory_iterator end(const recursive_directory_iterator&amp;);</pre>
<blockquote>
<p><i>Returns: </i>recursive_<code>directory_iterator()</code>.</p>
<p><i>Returns: </i><code>recursive_directory_iterator()</code>.</p>
</blockquote>
<h3><a name="Operational-functions">Operational functions</a></h3>
<p>Operational functions query or modify files, including directories, in external

View File

@ -33,8 +33,9 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/iterator.hpp>
#include <boost/cstdint.hpp>
#include <boost/range/mutable_iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/assert.hpp>
#include <string>
#include <utility> // for pair
#include <ctime>
@ -721,14 +722,37 @@ namespace detail
{ return m_imp == rhs.m_imp; }
};
// enable range-base for statement use
// enable C++11 range-base for statement use ---------------------------------------//
// begin() and end() are only used by a range-based for statement in the context of
// auto - thus the top-level const is stripped - so returning const is harmless and
// emphasizes begin() is just a pass through.
inline
directory_iterator& begin(directory_iterator& iter) {return iter;}
const directory_iterator& begin(const directory_iterator& iter) {return iter;}
inline
directory_iterator end(const directory_iterator&) {return directory_iterator();}
// enable BOOST_FOREACH ------------------------------------------------------------//
inline
directory_iterator& range_begin(directory_iterator& iter) {return iter;}
inline
directory_iterator range_begin(const directory_iterator& iter) {return iter;}
inline
directory_iterator range_end(const directory_iterator&) {return directory_iterator();}
} // namespace filesystem
// namespace boost template specializations
template<>
struct range_mutable_iterator<boost::filesystem::directory_iterator>
{ typedef boost::filesystem::directory_iterator type; };
template<>
struct range_const_iterator <boost::filesystem::directory_iterator>
{ typedef boost::filesystem::directory_iterator type; };
namespace filesystem
{
//--------------------------------------------------------------------------------------//
// //
// recursive_directory_iterator helpers //
@ -975,14 +999,41 @@ namespace detail
};
// enable range-base for statement use
// enable C++11 range-base for statement use ---------------------------------------//
// begin() and end() are only used by a range-based for statement in the context of
// auto - thus the top-level const is stripped - so returning const is harmless and
// emphasizes begin() is just a pass through.
inline
recursive_directory_iterator& begin(recursive_directory_iterator& iter) {return iter;}
const recursive_directory_iterator& begin(const recursive_directory_iterator& iter)
{return iter;}
inline
recursive_directory_iterator end(const recursive_directory_iterator&)
{return recursive_directory_iterator();}
{return recursive_directory_iterator();}
// enable BOOST_FOREACH ------------------------------------------------------------//
inline
recursive_directory_iterator& range_begin(recursive_directory_iterator& iter)
{return iter;}
inline
recursive_directory_iterator range_begin(const recursive_directory_iterator& iter)
{return iter;}
inline
recursive_directory_iterator range_end(const recursive_directory_iterator&)
{return recursive_directory_iterator();}
} // namespace filesystem
// namespace boost template specializations
template<>
struct range_mutable_iterator<boost::filesystem::recursive_directory_iterator>
{ typedef boost::filesystem::recursive_directory_iterator type; };
template<>
struct range_const_iterator <boost::filesystem::recursive_directory_iterator>
{ typedef boost::filesystem::recursive_directory_iterator type; };
namespace filesystem
{
# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
typedef recursive_directory_iterator wrecursive_directory_iterator;

View File

@ -24,7 +24,7 @@ project
[ run locale_info.cpp : : : <test-info>always_show_run_output ]
[ run operations_test.cpp : : : <link>shared <test-info>always_show_run_output ]
[ run operations_test.cpp : : : <link>static : operations_test_static ]
[ run operations_unit_test.cpp : : : <link>shared ]
[ run operations_unit_test.cpp : : : <link>shared <test-info>always_show_run_output ]
[ run path_test.cpp : : : <link>shared ]
[ run path_test.cpp : : : <link>static : path_test_static ]
[ run path_unit_test.cpp : : : <link>shared ]

View File

@ -155,14 +155,22 @@ namespace
#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
for (directory_entry& x : directory_iterator("."))
{
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
const directory_iterator dir_itr(".");
for (directory_entry& x : dir_itr)
{
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
#endif
//BOOST_FOREACH(directory_entry& x, directory_iterator("."))
//{
// cout << " " << x.path() << "\n";
//}
BOOST_FOREACH(directory_entry& x, directory_iterator("."))
{
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
cout << "directory_iterator_test complete" << endl;
}
@ -208,10 +216,23 @@ namespace
#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
for (directory_entry& x : recursive_directory_iterator(".."))
{
cout << " " << x.path() << "\n";
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
const recursive_directory_iterator dir_itr("..");
for (directory_entry& x : dir_itr)
{
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
#endif
BOOST_FOREACH(directory_entry& x, recursive_directory_iterator(".."))
{
CHECK(!x.path().empty());
//cout << " " << x.path() << "\n";
}
cout << "recursive_directory_iterator_test complete" << endl;
}