After extensive discussion on the list with Dave Abrahams, Vladimir Prus, and others, rename basic_path::leaf() -> filename, branch_path -> parent_path, replace_leaf -> replace_filename. Add basic_path member functions stem, extension, replace_extension.

[SVN r47181]
This commit is contained in:
Beman Dawes 2008-07-07 12:20:04 +00:00
parent 001c15dd32
commit fb65347b54
9 changed files with 362 additions and 259 deletions

View File

@ -123,7 +123,6 @@
&nbsp; </code> &nbsp; </code>
<a href="#Suggestions-for-fstream">&nbsp;implementations</a><br> <a href="#Suggestions-for-fstream">&nbsp;implementations</a><br>
<a href="#Path-decomposition-table">Path decomposition table</a><br> <a href="#Path-decomposition-table">Path decomposition table</a><br>
<a href="#Issues">Issues</a><br>
<a href="#Acknowledgements">Acknowledgements</a><br> <a href="#Acknowledgements">Acknowledgements</a><br>
<a href="#References">References</a><br> <a href="#References">References</a><br>
&nbsp;</td> &nbsp;</td>
@ -417,7 +416,7 @@ error_code</code> with the value of ec.</span></p>
template &lt;class Path&gt; typename Path::string_type extension(const Path&amp; p); template &lt;class Path&gt; typename Path::string_type extension(const Path&amp; p);
template &lt;class Path&gt; typename Path::string_type basename(const Path&amp; p); template &lt;class Path&gt; typename Path::string_type basename(const Path&amp; p);
template &lt;class Path&gt; template &lt;class Path&gt;
Path replace_extension(const Path&amp; p, const typename Path::string_type&amp; new_extension); Path change_extension(const Path&amp; p, const typename Path::string_type&amp; new_extension);
} // namespace filesystem } // namespace filesystem
} // namespace boost</pre> } // namespace boost</pre>
@ -547,7 +546,8 @@ system. </p>
<span style="background-color: #FFFFFF">void clear(); <span style="background-color: #FFFFFF">void clear();
void swap( basic_path &amp; rhs );</span> void swap( basic_path &amp; rhs );</span>
basic_path&amp; remove_leaf(); basic_path&amp; remove_filename();
basic_path&amp; replace_extension(const string_type &amp; new_extension = &quot;&quot;);
// <a href="#basic_path-observers">observers</a> // <a href="#basic_path-observers">observers</a>
const string_type string() const; const string_type string() const;
@ -561,8 +561,12 @@ system. </p>
string_type root_directory() const; string_type root_directory() const;
basic_path root_path() const; basic_path root_path() const;
basic_path relative_path() const; basic_path relative_path() const;
string_type leaf() const;
basic_path branch_path() const; basic_path parent_path() const;
string_type filename() const;
string_type stem() const;
string_type extension() const;
bool empty() const; bool empty() const;
bool is_complete() const; bool is_complete() const;
@ -570,8 +574,8 @@ system. </p>
bool has_root_directory() const; bool has_root_directory() const;
bool has_root_path() const; bool has_root_path() const;
bool has_relative_path() const; bool has_relative_path() const;
bool has_leaf() const; bool has_filename() const;
bool has_branch_path() const; bool has_parent_path() const;
// <a href="#basic_path-iterators">iterators</a> // <a href="#basic_path-iterators">iterators</a>
class iterator; class iterator;
@ -856,9 +860,9 @@ basic_path&amp; append(InputIterator first, InputIterator last);</pre>
<p><i><span style="background-color: #FFFFFF">Complexity: </span></i> <p><i><span style="background-color: #FFFFFF">Complexity: </span></i>
<span style="background-color: #FFFFFF">constant time.</span></p> <span style="background-color: #FFFFFF">constant time.</span></p>
</blockquote> </blockquote>
<pre>basic_path&amp; remove_leaf();</pre> <pre>basic_path&amp; remove_filename();</pre>
<blockquote> <blockquote>
<p><i>Effects:</i> If <code>has_branch_path()</code> then remove the last <i>filename</i> from the stored path. If that leaves <p><i>Effects:</i> If <code>has_parent_path()</code> then remove the last <i>filename</i> from the stored path. If that leaves
the stored path with one or more trailing <i>slash</i> elements not the stored path with one or more trailing <i>slash</i> elements not
representing&nbsp; <i>root-directory</i>, remove them.</p> representing&nbsp; <i>root-directory</i>, remove them.</p>
<p><i>Returns:</i> <code>*this</code></p> <p><i>Returns:</i> <code>*this</code></p>
@ -866,6 +870,15 @@ basic_path&amp; append(InputIterator first, InputIterator last);</pre>
basic_directory_iterator</code>. It is made public to allow additional uses. <i>-- end basic_directory_iterator</code>. It is made public to allow additional uses. <i>-- end
note</i>]</p> note</i>]</p>
</blockquote> </blockquote>
<pre>basic_path&amp; replace_extension( const string_type &amp; new_extension = &quot;&quot; );</pre>
<blockquote>
<p><i>Postcondition: </i> <code>extension() == <i>replacement</i></code>,
where <code><i>replacement</i></code> is <code>new_extension</code> if <code>
new_extension.empty() || new_extension[0] ==</code> the dot character,
otherwise <code><i>replacement</i></code> is the dot character followed by
<code>new_extension</code>.</p>
<p><i>Returns:</i> <code>*this</code></p>
</blockquote>
<h4> <a name="basic_path-observers"> <code>basic_path</code> observers</a></h4> <h4> <a name="basic_path-observers"> <code>basic_path</code> observers</a></h4>
<blockquote> <blockquote>
<p><span style="background-color: #E0E0E0"><i>See the <p><span style="background-color: #E0E0E0"><i>See the
@ -931,11 +944,11 @@ excluded from the returned string.</p>
with the first <i>filename</i> after <i>root-path</i>. with the first <i>filename</i> after <i>root-path</i>.
Otherwise, an empty <code>basic_path</code>.</p> Otherwise, an empty <code>basic_path</code>.</p>
</blockquote> </blockquote>
<pre>string_type leaf() const;</pre> <pre>string_type filename() const;</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>empty() ? string_type() : *--end()</code></p> <p><i>Returns:</i> <code>empty() ? string_type() : *--end()</code></p>
</blockquote> </blockquote>
<pre>basic_path branch_path() const;</pre> <pre>basic_path parent_path() const;</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>(string().empty() || begin() == --end()) ? path_type(&quot;&quot;) : <p><i>Returns:</i> <code>(string().empty() || begin() == --end()) ? path_type(&quot;&quot;) :
<i>br</i></code>, where <code><i>br</i></code> is constructed as if by <i>br</i></code>, where <code><i>br</i></code> is constructed as if by
@ -943,6 +956,25 @@ Otherwise, an empty <code>basic_path</code>.</p>
operator/=</code> for each element in the range <code>begin()</code>, <code> operator/=</code> for each element in the range <code>begin()</code>, <code>
--end()</code>.</p> --end()</code>.</p>
</blockquote> </blockquote>
<pre>string_type stem(const Path &amp; p) const;</pre>
<blockquote>
<p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
the substring of <code>p.filename()</code> starting at its beginning and
ending at the last <i>dot</i> (the <i>dot</i> is not included). Otherwise,
returns <code>
p.filename()</code>.</p>
</blockquote>
<pre>string_type extension(const Path &amp; p) const;</pre>
<blockquote>
<p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
the substring of <code>p.filename()</code> starting at the rightmost <i>dot</i>
and ending at the string's end. Otherwise, returns an empty string. </p>
<p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that
it is possible to distinguish between no extension and an empty extension. </p>
<p>Implementations are permitted but not required to define additional
behavior for file systems which append additional elements to extensions, such
as alternate data stream or partitioned dataset names. <i>-- end note</i>]</p>
</blockquote>
<pre>bool empty() const;</pre> <pre>bool empty() const;</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>string().empty()</code>.</p> <p><i>Returns:</i> <code>string().empty()</code>.</p>
@ -968,13 +1000,13 @@ Otherwise, an empty <code>basic_path</code>.</p>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>!relative_path().empty()</code></p> <p><i>Returns:</i> <code>!relative_path().empty()</code></p>
</blockquote> </blockquote>
<pre>bool has_leaf() const;</pre> <pre>bool has_filename() const;</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>!leaf().empty()</code></p> <p><i>Returns:</i> <code>!filename().empty()</code></p>
</blockquote> </blockquote>
<pre>bool has_branch_path() const;</pre> <pre>bool has_parent_path() const;</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> <code>!branch_path().empty()</code></p> <p><i>Returns:</i> <code>!parent_path().empty()</code></p>
</blockquote> </blockquote>
<h4> <a name="basic_path-iterators"> <code>basic_path</code> iterators</a></h4> <h4> <a name="basic_path-iterators"> <code>basic_path</code> iterators</a></h4>
<p> A <code>basic_path::iterator</code> is a constant iterator satisfying all <p> A <code>basic_path::iterator</code> is a constant iterator satisfying all
@ -1364,7 +1396,7 @@ the <code>what</code> member function.</p>
// <a href="#basic_directory_entry-modifiers">modifiers</a> // <a href="#basic_directory_entry-modifiers">modifiers</a>
void assign(const path_type&amp; p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status()); void assign(const path_type&amp; p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
void replace_leaf(const string_type&amp; s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status()); void replace_filename(const string_type&amp; s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
// <a href="#basic_directory_entry-observers">observers</a> // <a href="#basic_directory_entry-observers">observers</a>
const Path&amp; path() const; const Path&amp; path() const;
@ -1474,7 +1506,7 @@ Unix variants that provide status during directory iteration.</i></span></p>
</tr> </tr>
</table> </table>
</blockquote> </blockquote>
<pre>void replace_leaf(const string_type&amp; s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre> <pre>void replace_filename(const string_type&amp; s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
<blockquote> <blockquote>
<p><i>Postconditions:</i></p> <p><i>Postconditions:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%"> <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%">
@ -1645,7 +1677,7 @@ int main(int argc, char* argv[])
{ {
for (directory_iterator itr(p); itr!=directory_iterator(); ++itr) for (directory_iterator itr(p); itr!=directory_iterator(); ++itr)
{ {
cout &lt;&lt; itr-&gt;path().leaf() &lt;&lt; ' '; // display filename only cout &lt;&lt; itr-&gt;path().filename() &lt;&lt; ' '; // display filename only
if (is_regular_file(itr-&gt;status())) cout &lt;&lt; &quot; [&quot; &lt;&lt; file_size(itr-&gt;path()) &lt;&lt; ']'; if (is_regular_file(itr-&gt;status())) cout &lt;&lt; &quot; [&quot; &lt;&lt; file_size(itr-&gt;path()) &lt;&lt; ']';
cout &lt;&lt; '\n'; cout &lt;&lt; '\n';
} }
@ -2298,11 +2330,18 @@ systems. <i>--end note</i>.]</p>
<p><i>Throws:</i>&nbsp; <code>basic_filesystem_error&lt;Path&gt;</code> if<code> <p><i>Throws:</i>&nbsp; <code>basic_filesystem_error&lt;Path&gt;</code> if<code>
exists(p) &amp;&amp; !is_directory(p)</code></p> exists(p) &amp;&amp; !is_directory(p)</code></p>
</blockquote> </blockquote>
<table border="1" cellpadding="5" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td>
<h4>Deprecated convenience functions</h4>
<p>The following functions have been replaced by <code>basic_path</code>
member functions <code>extension()</code>, <code>stem()</code>, and <code>
replace_extension()</code>.</p>
<pre>template &lt;class Path&gt; typename Path::string_type extension(const Path &amp; p);</pre> <pre>template &lt;class Path&gt; typename Path::string_type extension(const Path &amp; p);</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> if <code>p.leaf()</code> contains a <i>dot</i>, returns the <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
substring of <code>p.leaf()</code> starting at the rightmost <i>dot</i> and the substring of <code>p.filename()</code> starting at the rightmost <i>dot</i>
ending at the string's end. Otherwise, returns an empty string. </p> and ending at the string's end. Otherwise, returns an empty string. </p>
<p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that <p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that
it is possible to distinguish between no extension and an empty extension. </p> it is possible to distinguish between no extension and an empty extension. </p>
<p>Implementations are permitted but not required to define additional <p>Implementations are permitted but not required to define additional
@ -2311,10 +2350,11 @@ systems. <i>--end note</i>.]</p>
</blockquote> </blockquote>
<pre>template &lt;class Path&gt; typename Path::string_type basename(const Path &amp; p);</pre> <pre>template &lt;class Path&gt; typename Path::string_type basename(const Path &amp; p);</pre>
<blockquote> <blockquote>
<p><i>Returns:</i> if <code>p.leaf()</code> contains a <i>dot</i>, returns the <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
substring of <code>p.leaf()</code> starting at its beginning and ending at the the substring of <code>p.filename()</code> starting at its beginning and
last <i>dot</i> (the <i>dot</i> is not included). Otherwise, returns <code> ending at the last <i>dot</i> (the <i>dot</i> is not included). Otherwise,
p.leaf()</code>.</p> returns <code>
p.filename()</code>.</p>
</blockquote> </blockquote>
<pre>template &lt;class Path&gt; <pre>template &lt;class Path&gt;
Path change_extension(const Path &amp; p, const typename Path::string_type &amp; new_extension);</pre> Path change_extension(const Path &amp; p, const typename Path::string_type &amp; new_extension);</pre>
@ -2325,33 +2365,9 @@ systems. <i>--end note</i>.]</p>
that <code>new_extension</code> should include <i>dot</i> to achieve that <code>new_extension</code> should include <i>dot</i> to achieve
reasonable results. <i>-- end note</i>]</p> reasonable results. <i>-- end note</i>]</p>
</blockquote> </blockquote>
<h3><a name="header-cerrno">Additions</a> to header <code>&lt;cerrno&gt;</code></h3> </td>
<p>The header &lt;cerrno&gt; shall include an additional symbolic constant macro for
each of the values returned by the <a href="#to_errno">to_errno</a>
function. The macro names shall be as defined in <i>POSIX</i>
<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/errno.h.html">
errno.h</a>, with the additions below.</p>
<blockquote>
<p><i><span style="background-color: #E0E0E0">This codifies existing practice.
The required names are only a sub-set of those defined by POSIX, and are usually already
supplied in &lt;errno.h&gt; (as wrapped by &lt;cerrno&gt;) as shipped with POSIX and Windows compilers.
These implementations require no changes to their underlying C headers to conform with the above
requirement.</span></i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="33%">
<tr>
<td width="18%" align="center"><i><b>Name</b></i></td>
<td width="82%" align="center"><i><b>Meaning</b></i></td>
</tr>
<tr>
<td width="18%"><code>EBADHANDLE</code></td>
<td width="82%">Bad operating system handle.</td>
</tr>
<tr>
<td width="18%"><code>EOTHER</code></td>
<td width="82%">Other error.</td>
</tr> </tr>
</table> </table>
</blockquote>
<h3><a name="header-fstream">Additions</a> to header <code>&lt;fstream&gt;</code></h3> <h3><a name="header-fstream">Additions</a> to header <code>&lt;fstream&gt;</code></h3>
<blockquote> <blockquote>
<p><span style="background-color: #E0E0E0; font-style:italic">These additions have been carefully <p><span style="background-color: #E0E0E0; font-style:italic">These additions have been carefully
@ -2384,14 +2400,14 @@ add the above to the signature preceding paragraph 2, and replace the
sentence:</i></span></p> sentence:</i></span></p>
<blockquote> <blockquote>
<p><span style="background-color: #FFFFFF">It then opens a file, if possible, <p><span style="background-color: #FFFFFF">It then opens a file, if possible,
whose name is the NTBS s (“as if” by calling <code>std::fopen(s ,<i>modstr</i> whose name is the NTBS s (“as if” by calling <code>std::fopen(s ,<i>modstr</i>
))</code>.</span></p> ))</code>.</span></p>
</blockquote> </blockquote>
<p><span style="background-color: #FFFFFF"><i>with:</i></span></p> <p><span style="background-color: #FFFFFF"><i>with:</i></span></p>
<blockquote> <blockquote>
<p><span style="background-color: #FFFFFF">It then opens, if possible, the file <p><span style="background-color: #FFFFFF">It then opens, if possible, the file
that that
<code>p</code> or <code>path(s)</code> resolves to, “as if” by calling <code>std::fopen()</code> with a <code>p</code> or <code>path(s)</code> resolves to, “as if” by calling <code>std::fopen()</code> with a
second argument of <i>modstr</i>.</span></p> second argument of <i>modstr</i>.</span></p>
</blockquote> </blockquote>
<p><span style="background-color: #FFFFFF"><i>In 27.8.1.5 Class template <p><span style="background-color: #FFFFFF"><i>In 27.8.1.5 Class template
@ -2510,8 +2526,8 @@ implementations yield different results. The top value is the
<td width="48"><b><code>root_<br>name()</code></b></td> <td width="48"><b><code>root_<br>name()</code></b></td>
<td width="88"><b><code>root_<br>directory()</code></b></td> <td width="88"><b><code>root_<br>directory()</code></b></td>
<td width="96"><b><code>relative_<br>path()<br>.string()</code></b></td> <td width="96"><b><code>relative_<br>path()<br>.string()</code></b></td>
<td width="72"><b><code>branch_<br>path()<br>.string()</code></b></td> <td width="72"><b><code>parent_<br>path()<br>.string()</code></b></td>
<td width="72"><b><code>leaf()</code></b></td> <td width="72"><b><code>filename()</code></b></td>
</tr> </tr>
<tr> <tr>
<td width="112"><code>&quot;&quot;</code></td> <td width="112"><code>&quot;&quot;</code></td>
@ -3015,29 +3031,6 @@ new fstream classes in namespace <code>filesystem</code>, inheriting from the cu
classes, overriding the constructors and opens taking pathname arguments, and classes, overriding the constructors and opens taking pathname arguments, and
providing the additional overloads. In Lillehammer LWG members indicated lack of providing the additional overloads. In Lillehammer LWG members indicated lack of
support for this alternative, feeling that costs outweigh benefits.</span></p> support for this alternative, feeling that costs outweigh benefits.</span></p>
<h2><a name="Issues">Issues</a></h2>
<h3>1. Return type of certain basic_path members returning strings. [Howard
Hinnant]</h3>
<p>For member functions described as returning &quot;<code>const string_type</code>&quot;
or &quot;<code>const external_string_type</code>&quot;, implementations are permitted to
return &quot;<code>const string_type&amp;</code>&quot; or&nbsp; &quot;<code>const
external_string_type&amp;</code>&quot; respectively.</p>
<p>This allows implementations to avoid unnecessary copies. Return-by-value is
specified as
<code>const</code> to ensure programs won't break if moved to a
return-by-reference implementation.</p>
<p>For example, the Boost implementation keeps the internal representation of a
pathname in the portable format, so string() returns by reference and is inlined:</p>
<blockquote>
<pre>const string_type &amp; string() const { return m_path; }</pre>
</blockquote>
<p>Howard Hinnant comments: This may inhibit optimization if rvalue reference is
accepted.&nbsp; Const-qualified return types can't be moved from.&nbsp; I'd
rather see either the return type specified as
<code>const string_type&amp;</code> or <code>string_type</code>.</p>
<p>Beman Dawes comments: I can't make up my mind. Removing the const will bite
users, but not very often. OTOH, excessive copying is a real concern, and if
move semantics can alleviate that, I'm all for it. What does the LWG think?</p>
<h2><a name="Acknowledgements">Acknowledgements</a></h2> <h2><a name="Acknowledgements">Acknowledgements</a></h2>
<p>This Filesystem Library is dedicated to my wife, Sonda, who provided the <p>This Filesystem Library is dedicated to my wife, Sonda, who provided the
support necessary to see both a trial implementation and the proposal itself support necessary to see both a trial implementation and the proposal itself
@ -3047,8 +3040,7 @@ year of cancer treatment in the middle of it all.</p>
Boost Filesystem Library. See Boost Filesystem Library. See
<a href="http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements"> <a href="http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements">
http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements</a>.</p> http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements</a>.</p>
<p>Dietmar Kühl contributed the original Boost Filesystem Library <p>Dietmar Kuehl contributed the original Boost Filesystem Library directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas
directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas
Witt were particularly helpful in refining the library.</p> Witt were particularly helpful in refining the library.</p>
<p>The create_directories, extension, basename, and replace_extension functions <p>The create_directories, extension, basename, and replace_extension functions
were developed by Vladimir Prus.</p> were developed by Vladimir Prus.</p>
@ -3060,7 +3052,7 @@ final document.</p>
<tr> <tr>
<td width="16%" valign="top">[<a name="ISO_POSIX">ISO-POSIX</a>]</td> <td width="16%" valign="top">[<a name="ISO_POSIX">ISO-POSIX</a>]</td>
<td width="84%">ISO/IEC 9945:2003, IEEE&nbsp;Std&nbsp;1003.1-2001, and The Open Group <td width="84%">ISO/IEC 9945:2003, IEEE&nbsp;Std&nbsp;1003.1-2001, and The Open Group
Base Specifications, Issue 6. Also known as The Single Unix<font face="Times New Roman">® Base Specifications, Issue 6. Also known as The Single Unix<font face="Times New Roman">®
Specification, Version 3. Available from each of the organizations involved Specification, Version 3. Available from each of the organizations involved
in its creation. For example, read online or download from in its creation. For example, read online or download from
<a href="http://www.unix.org/single_unix_specification/"> <a href="http://www.unix.org/single_unix_specification/">
@ -3080,7 +3072,7 @@ final document.</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<p>Revised <p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->04 July 2008<!--webbot bot="Timestamp" endspan i-checksum="18826" --></p> <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->06 July 2008<!--webbot bot="Timestamp" endspan i-checksum="18830" --></p>
</body> </body>

View File

@ -74,7 +74,7 @@ int main( int argc, char * argv[] )
{ {
if ( fs::is_regular_file(it->status()) ) if ( fs::is_regular_file(it->status()) )
{ {
copy_file( *it, target_dir / it->leaf() ); copy_file( *it, target_dir / it->filename() );
} }
} }

View File

@ -51,24 +51,24 @@ int main( int argc, char* argv[] )
if ( fs::is_directory( dir_itr->status() ) ) if ( fs::is_directory( dir_itr->status() ) )
{ {
++dir_count; ++dir_count;
std::cout << dir_itr->leaf() << " [directory]\n"; std::cout << dir_itr->filename() << " [directory]\n";
} }
else if ( fs::is_regular_file( dir_itr->status() ) ) else if ( fs::is_regular_file( dir_itr->status() ) )
{ {
++file_count; ++file_count;
std::cout << dir_itr->leaf() << "\n"; std::cout << dir_itr->filename() << "\n";
} }
else else
{ {
++other_count; ++other_count;
std::cout << dir_itr->leaf() << " [other]\n"; std::cout << dir_itr->filename() << " [other]\n";
} }
} }
catch ( const std::exception & ex ) catch ( const std::exception & ex )
{ {
++err_count; ++err_count;
std::cout << dir_itr->leaf() << " " << ex.what() << std::endl; std::cout << dir_itr->filename() << " " << ex.what() << std::endl;
} }
} }
std::cout << "\n" << file_count << " files\n" std::cout << "\n" << file_count << " files\n"

View File

@ -50,20 +50,22 @@ namespace boost
} }
// First create branch, by calling ourself recursively // First create branch, by calling ourself recursively
create_directories(ph.branch_path()); create_directories(ph.parent_path());
// Now that parent's path exists, create the directory // Now that parent's path exists, create the directory
create_directory(ph); create_directory(ph);
return true; return true;
} }
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
BOOST_FS_FUNC_STRING extension(const Path& ph) BOOST_FS_FUNC_STRING extension(const Path& ph)
{ {
typedef BOOST_FS_TYPENAME Path::string_type string_type; typedef BOOST_FS_TYPENAME Path::string_type string_type;
string_type leaf = ph.leaf(); string_type filename = ph.filename();
BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.'); BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
if (n != string_type::npos) if (n != string_type::npos)
return leaf.substr(n); return filename.substr(n);
else else
return string_type(); return string_type();
} }
@ -71,14 +73,17 @@ namespace boost
BOOST_FS_FUNC_STRING basename(const Path& ph) BOOST_FS_FUNC_STRING basename(const Path& ph)
{ {
typedef BOOST_FS_TYPENAME Path::string_type string_type; typedef BOOST_FS_TYPENAME Path::string_type string_type;
string_type leaf = ph.leaf(); string_type filename = ph.filename();
BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.'); BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
return leaf.substr(0, n); return filename.substr(0, n);
} }
BOOST_FS_FUNC(Path) change_extension( const Path & ph, BOOST_FS_FUNC(Path) change_extension( const Path & ph,
const BOOST_FS_TYPENAME Path::string_type & new_extension ) const BOOST_FS_TYPENAME Path::string_type & new_extension )
{ return ph.branch_path() / (basename(ph) + new_extension); } { return ph.parent_path() / (basename(ph) + new_extension); }
# endif
# ifndef BOOST_FILESYSTEM_NARROW_ONLY # ifndef BOOST_FILESYSTEM_NARROW_ONLY

View File

@ -982,7 +982,7 @@ namespace boost
{ {
boost::throw_exception( basic_filesystem_error<Path>( boost::throw_exception( basic_filesystem_error<Path>(
"boost::filesystem::basic_directory_iterator increment", "boost::filesystem::basic_directory_iterator increment",
m_imp->m_directory_entry.path().branch_path(), ec ) ); m_imp->m_directory_entry.path().parent_path(), ec ) );
} }
if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end
if ( !(name[0] == dot<Path>::value // !(dot or dot-dot) if ( !(name[0] == dot<Path>::value // !(dot or dot-dot)
@ -990,7 +990,7 @@ namespace boost
|| (name[1] == dot<Path>::value || (name[1] == dot<Path>::value
&& name.size() == 2))) ) && name.size() == 2))) )
{ {
m_imp->m_directory_entry.replace_leaf( m_imp->m_directory_entry.replace_filename(
Path::traits_type::to_internal( name ), fs, symlink_fs ); Path::traits_type::to_internal( name ), fs, symlink_fs );
return; return;
} }
@ -1018,10 +1018,10 @@ namespace boost
file_status st, file_status symlink_st ) file_status st, file_status symlink_st )
{ m_path = p; m_status = st; m_symlink_status = symlink_st; } { m_path = p; m_status = st; m_symlink_status = symlink_st; }
void replace_leaf( const string_type & s, void replace_filename( const string_type & s,
file_status st, file_status symlink_st ) file_status st, file_status symlink_st )
{ {
m_path.remove_leaf(); m_path.remove_filename();
m_path /= s; m_path /= s;
m_status = st; m_status = st;
m_symlink_status = symlink_st; m_symlink_status = symlink_st;
@ -1038,9 +1038,9 @@ namespace boost
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
// deprecated functions preserve common use cases in legacy code // deprecated functions preserve common use cases in legacy code
typename Path::string_type leaf() const typename Path::string_type filename() const
{ {
return path().leaf(); return path().filename();
} }
typename Path::string_type string() const typename Path::string_type string() const
{ {

View File

@ -1,12 +1,17 @@
// boost/filesystem/path.hpp -----------------------------------------------// // boost/filesystem/path.hpp -----------------------------------------------//
// Copyright Beman Dawes 2002-2005 // Copyright Beman Dawes 2002-2005
// Copyright Vladimir Prus 2002
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem // See library home page at http://www.boost.org/libs/filesystem
// basic_path's stem(), extension(), and replace_extension() are based on
// basename(), extension(), and change_extension() from the original
// filesystem/convenience.hpp header by Vladimir Prus.
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_PATH_HPP #ifndef BOOST_FILESYSTEM_PATH_HPP
@ -197,7 +202,12 @@ namespace boost
# endif # endif
} }
basic_path & remove_leaf(); basic_path & remove_filename();
basic_path & replace_extension( const string_type & new_extension = "" );
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
basic_path & remove_leaf() { return remove_filename(); }
# endif
// observers // observers
const string_type & string() const { return m_path; } const string_type & string() const { return m_path; }
@ -211,8 +221,15 @@ namespace boost
string_type root_name() const; string_type root_name() const;
string_type root_directory() const; string_type root_directory() const;
basic_path relative_path() const; basic_path relative_path() const;
string_type leaf() const; basic_path parent_path() const;
basic_path branch_path() const; string_type filename() const;
string_type stem() const;
string_type extension() const;
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
string_type leaf() const { return filename(); }
basic_path branch_path() const { return parent_path(); }
# endif
bool empty() const { return m_path.empty(); } // name consistent with std containers bool empty() const { return m_path.empty(); } // name consistent with std containers
bool is_complete() const; bool is_complete() const;
@ -220,8 +237,8 @@ namespace boost
bool has_root_name() const; bool has_root_name() const;
bool has_root_directory() const; bool has_root_directory() const;
bool has_relative_path() const { return !relative_path().empty(); } bool has_relative_path() const { return !relative_path().empty(); }
bool has_leaf() const { return !m_path.empty(); } bool has_filename() const { return !m_path.empty(); }
bool has_branch_path() const { return !branch_path().empty(); } bool has_parent_path() const { return !parent_path().empty(); }
// iterators // iterators
class iterator : public boost::iterator_facade< class iterator : public boost::iterator_facade<
@ -698,13 +715,13 @@ namespace boost
; ;
} }
// leaf_pos helper ----------------------------------------------------// // filename_pos helper ----------------------------------------------------//
template<class String, class Traits> template<class String, class Traits>
typename String::size_type leaf_pos( typename String::size_type filename_pos(
const String & str, // precondition: portable generic path grammar const String & str, // precondition: portable generic path grammar
typename String::size_type end_pos ) // end_pos is past-the-end position typename String::size_type end_pos ) // end_pos is past-the-end position
// return 0 if str itself is leaf (or empty) // return 0 if str itself is filename (or empty)
{ {
typedef typename typedef typename
boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type;
@ -728,9 +745,9 @@ namespace boost
pos = str.find_last_of( colon<path_type>::value, end_pos-2 ); pos = str.find_last_of( colon<path_type>::value, end_pos-2 );
# endif # endif
return ( pos == String::npos // path itself must be a leaf (or empty) return ( pos == String::npos // path itself must be a filename (or empty)
|| (pos == 1 && str[0] == slash<path_type>::value) ) // or net || (pos == 1 && str[0] == slash<path_type>::value) ) // or net
? 0 // so leaf is entire string ? 0 // so filename is entire string
: pos + 1; // or starts after delimiter : pos + 1; // or starts after delimiter
} }
@ -876,10 +893,10 @@ namespace boost
// decomposition functions ----------------------------------------------// // decomposition functions ----------------------------------------------//
template<class String, class Traits> template<class String, class Traits>
String basic_path<String, Traits>::leaf() const String basic_path<String, Traits>::filename() const
{ {
typename String::size_type end_pos( typename String::size_type end_pos(
detail::leaf_pos<String, Traits>( m_path, m_path.size() ) ); detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
return (m_path.size() return (m_path.size()
&& end_pos && end_pos
&& m_path[end_pos] == slash<path_type>::value && m_path[end_pos] == slash<path_type>::value
@ -889,12 +906,31 @@ namespace boost
} }
template<class String, class Traits> template<class String, class Traits>
basic_path<String, Traits> basic_path<String, Traits>::branch_path() const String basic_path<String, Traits>::stem() const
{
string_type name = filename();
typename string_type::size_type n = name.rfind('.');
return name.substr(0, n);
}
template<class String, class Traits>
String basic_path<String, Traits>::extension() const
{
string_type name = filename();
typename string_type::size_type n = name.rfind('.');
if (n != string_type::npos)
return name.substr(n);
else
return string_type();
}
template<class String, class Traits>
basic_path<String, Traits> basic_path<String, Traits>::parent_path() const
{ {
typename String::size_type end_pos( typename String::size_type end_pos(
detail::leaf_pos<String, Traits>( m_path, m_path.size() ) ); detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
bool leaf_was_separator( m_path.size() bool filename_was_separator( m_path.size()
&& m_path[end_pos] == slash<path_type>::value ); && m_path[end_pos] == slash<path_type>::value );
// skip separators unless root directory // skip separators unless root directory
@ -907,7 +943,7 @@ namespace boost
; ;
--end_pos ) {} --end_pos ) {}
return (end_pos == 1 && root_dir_pos == 0 && leaf_was_separator) return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator)
? path_type() ? path_type()
: path_type( m_path.substr( 0, end_pos ) ); : path_type( m_path.substr( 0, end_pos ) );
} }
@ -1137,7 +1173,7 @@ namespace boost
&& (*itr)[0] == dot<path_type>::value && (*itr)[0] == dot<path_type>::value
&& (*itr)[1] == dot<path_type>::value ) // dot dot && (*itr)[1] == dot<path_type>::value ) // dot dot
{ {
string_type lf( temp.leaf() ); string_type lf( temp.filename() );
if ( lf.size() > 0 if ( lf.size() > 0
&& (lf.size() != 1 && (lf.size() != 1
|| (lf[0] != dot<path_type>::value || (lf[0] != dot<path_type>::value
@ -1152,7 +1188,7 @@ namespace boost
) )
) )
{ {
temp.remove_leaf(); temp.remove_filename();
// if not root directory, must also remove "/" if any // if not root directory, must also remove "/" if any
if ( temp.m_path.size() > 0 if ( temp.m_path.size() > 0
&& temp.m_path[temp.m_path.size()-1] && temp.m_path[temp.m_path.size()-1]
@ -1183,16 +1219,34 @@ namespace boost
# endif # endif
// remove_leaf ----------------------------------------------------------// // modifiers ------------------------------------------------------------//
template<class String, class Traits> template<class String, class Traits>
basic_path<String, Traits> & basic_path<String, Traits>::remove_leaf() basic_path<String, Traits> & basic_path<String, Traits>::remove_filename()
{ {
m_path.erase( m_path.erase(
detail::leaf_pos<String, Traits>( m_path, m_path.size() ) ); detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
return *this; return *this;
} }
template<class String, class Traits>
basic_path<String, Traits> &
basic_path<String, Traits>::replace_extension( const string_type & new_ext )
{
// erase existing extension if any
string_type old_ext = extension();
if ( !old_ext.empty() )
m_path.erase( m_path.size() - old_ext.size() );
if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value )
m_path += dot<path_type>::value;
m_path += new_ext;
return *this;
}
// path conversion functions --------------------------------------------// // path conversion functions --------------------------------------------//
template<class String, class Traits> template<class String, class Traits>
@ -1375,7 +1429,7 @@ namespace boost
; ;
--end_pos ) {} --end_pos ) {}
itr.m_pos = detail::leaf_pos<string_type, traits_type> itr.m_pos = detail::filename_pos<string_type, traits_type>
( itr.m_path_ptr->m_path, end_pos ); ( itr.m_path_ptr->m_path, end_pos );
itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos );
} }

View File

@ -68,7 +68,7 @@ namespace
} }
{ {
std::cout << " in test 4.1\n"; std::cout << " in test 4.1\n";
fs::ifstream tfs( p / p.leaf() ); // should fail fs::ifstream tfs( p / p.filename() ); // should fail
BOOST_CHECK( !tfs.is_open() ); BOOST_CHECK( !tfs.is_open() );
} }
{ {

View File

@ -477,7 +477,7 @@ int test_main( int argc, char * argv[] )
BOOST_CHECK( fs::is_directory( dir_itr->status() ) ); BOOST_CHECK( fs::is_directory( dir_itr->status() ) );
BOOST_CHECK( fs::is_directory( fs::symlink_status(*dir_itr) ) ); BOOST_CHECK( fs::is_directory( fs::symlink_status(*dir_itr) ) );
BOOST_CHECK( fs::is_directory( dir_itr->symlink_status() ) ); BOOST_CHECK( fs::is_directory( dir_itr->symlink_status() ) );
BOOST_CHECK( dir_itr->leaf() == "d1" ); BOOST_CHECK( dir_itr->filename() == "d1" );
} }
// create a second directory named d2 // create a second directory named d2
@ -497,21 +497,21 @@ int test_main( int argc, char * argv[] )
BOOST_CHECK( !fs::is_symlink(dir_itr->status()) ); BOOST_CHECK( !fs::is_symlink(dir_itr->status()) );
fs::directory_iterator dir_itr2( dir ); fs::directory_iterator dir_itr2( dir );
BOOST_CHECK( dir_itr->leaf() == "d1" BOOST_CHECK( dir_itr->filename() == "d1"
|| dir_itr->leaf() == "d2" ); || dir_itr->filename() == "d2" );
BOOST_CHECK( dir_itr2->leaf() == "d1" || dir_itr2->leaf() == "d2" ); BOOST_CHECK( dir_itr2->filename() == "d1" || dir_itr2->filename() == "d2" );
if ( dir_itr->leaf() == "d1" ) if ( dir_itr->filename() == "d1" )
{ {
BOOST_CHECK( (++dir_itr)->leaf() == "d2" ); BOOST_CHECK( (++dir_itr)->filename() == "d2" );
BOOST_CHECK( dir_itr2->leaf() == "d1" ); BOOST_CHECK( dir_itr2->filename() == "d1" );
BOOST_CHECK( (++dir_itr2)->leaf() == "d2" ); BOOST_CHECK( (++dir_itr2)->filename() == "d2" );
} }
else else
{ {
BOOST_CHECK( dir_itr->leaf() == "d2" ); BOOST_CHECK( dir_itr->filename() == "d2" );
BOOST_CHECK( (++dir_itr)->leaf() == "d1" ); BOOST_CHECK( (++dir_itr)->filename() == "d1" );
BOOST_CHECK( (dir_itr2)->leaf() == "d2" ); BOOST_CHECK( (dir_itr2)->filename() == "d2" );
BOOST_CHECK( (++dir_itr2)->leaf() == "d1" ); BOOST_CHECK( (++dir_itr2)->filename() == "d1" );
} }
BOOST_CHECK( ++dir_itr == fs::directory_iterator() ); BOOST_CHECK( ++dir_itr == fs::directory_iterator() );
BOOST_CHECK( dir_itr2 != fs::directory_iterator() ); BOOST_CHECK( dir_itr2 != fs::directory_iterator() );
@ -520,21 +520,21 @@ int test_main( int argc, char * argv[] )
{ // *i++ must work to meet the standard's InputIterator requirements { // *i++ must work to meet the standard's InputIterator requirements
fs::directory_iterator dir_itr( dir ); fs::directory_iterator dir_itr( dir );
BOOST_CHECK( dir_itr->leaf() == "d1" BOOST_CHECK( dir_itr->filename() == "d1"
|| dir_itr->leaf() == "d2" ); || dir_itr->filename() == "d2" );
if ( dir_itr->leaf() == "d1" ) if ( dir_itr->filename() == "d1" )
{ {
BOOST_CHECK( (*dir_itr++).leaf() == "d1" ); BOOST_CHECK( (*dir_itr++).filename() == "d1" );
BOOST_CHECK( dir_itr->leaf() == "d2" ); BOOST_CHECK( dir_itr->filename() == "d2" );
} }
else else
{ {
// Check C++98 input iterator requirements // Check C++98 input iterator requirements
BOOST_CHECK( (*dir_itr++).leaf() == "d2" ); BOOST_CHECK( (*dir_itr++).filename() == "d2" );
// input iterator requirements in the current WP would require this check: // input iterator requirements in the current WP would require this check:
// BOOST_CHECK( implicit_cast<std::string const&>(*dir_itr++).leaf() == "d1" ); // BOOST_CHECK( implicit_cast<std::string const&>(*dir_itr++).filename() == "d1" );
BOOST_CHECK( dir_itr->leaf() == "d1" ); BOOST_CHECK( dir_itr->filename() == "d1" );
} }
// test case reported in comment to SourceForge bug tracker [937606] // test case reported in comment to SourceForge bug tracker [937606]
@ -555,11 +555,11 @@ int test_main( int argc, char * argv[] )
fs::directory_iterator it( root_name_path ); fs::directory_iterator it( root_name_path );
BOOST_CHECK( it != fs::directory_iterator() ); BOOST_CHECK( it != fs::directory_iterator() );
BOOST_CHECK( fs::exists( *it ) ); BOOST_CHECK( fs::exists( *it ) );
BOOST_CHECK( it->path().branch_path() == root_name_path ); BOOST_CHECK( it->path().parent_path() == root_name_path );
bool found(false); bool found(false);
do do
{ {
if ( it->leaf() == temp_dir_name ) found = true; if ( it->filename() == temp_dir_name ) found = true;
} while ( ++it != fs::directory_iterator() ); } while ( ++it != fs::directory_iterator() );
BOOST_CHECK( found ); BOOST_CHECK( found );
} }

View File

@ -1,12 +1,18 @@
// path_test program -------------------------------------------------------// // path_test program -------------------------------------------------------//
// Copyright Beman Dawes 2002. // Copyright Beman Dawes 2002
// Copyright Vladimir Prus 2002
// Use, modification, and distribution is subject to the Boost Software // Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem // See library home page at http://www.boost.org/libs/filesystem
// basic_path's stem(), extension(), and replace_extension() tests are based
// on basename(), extension(), and change_extension() tests from the original
// convenience_test.cpp by Vladimir Prus.
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <iostream> #include <iostream>
@ -248,6 +254,18 @@ int test_main( int, char*[] )
path p5; path p5;
std::string s1( "//:somestring" ); std::string s1( "//:somestring" );
// verify deprecated names still available
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
p1.branch_path();
p1.leaf();
path p_remove_leaf;
p_remove_leaf.remove_leaf();
# endif
# ifndef BOOST_NO_MEMBER_TEMPLATES # ifndef BOOST_NO_MEMBER_TEMPLATES
// check the path member templates // check the path member templates
@ -290,10 +308,10 @@ int test_main( int, char*[] )
BOOST_CHECK( p1 != p4 ); BOOST_CHECK( p1 != p4 );
BOOST_CHECK( p1.string() == p2.string() ); BOOST_CHECK( p1.string() == p2.string() );
BOOST_CHECK( p1.string() == p3.string() ); BOOST_CHECK( p1.string() == p3.string() );
BOOST_CHECK( path( "foo" ).leaf() == "foo" ); BOOST_CHECK( path( "foo" ).filename() == "foo" );
BOOST_CHECK( path( "foo" ).branch_path().string() == "" ); BOOST_CHECK( path( "foo" ).parent_path().string() == "" );
BOOST_CHECK( p1.leaf() == "fum" ); BOOST_CHECK( p1.filename() == "fum" );
BOOST_CHECK( p1.branch_path().string() == "fe/fi/fo" ); BOOST_CHECK( p1.parent_path().string() == "fe/fi/fo" );
BOOST_CHECK( path( "" ).empty() == true ); BOOST_CHECK( path( "" ).empty() == true );
BOOST_CHECK( path( "foo" ).empty() == false ); BOOST_CHECK( path( "foo" ).empty() == false );
@ -336,7 +354,7 @@ int test_main( int, char*[] )
PATH_CHECK( "foo/bar", "foo/bar" ); PATH_CHECK( "foo/bar", "foo/bar" );
PATH_CHECK( path("foo") / path("bar"), "foo/bar" ); // path arg PATH_CHECK( path("foo") / path("bar"), "foo/bar" ); // path arg
PATH_CHECK( path("foo") / "bar", "foo/bar" ); // const char * arg PATH_CHECK( path("foo") / "bar", "foo/bar" ); // const char * arg
PATH_CHECK( path("foo") / path("woo/bar").leaf(), "foo/bar" ); // const std::string & arg PATH_CHECK( path("foo") / path("woo/bar").filename(), "foo/bar" ); // const std::string & arg
PATH_CHECK( "foo" / path("bar"), "foo/bar" ); PATH_CHECK( "foo" / path("bar"), "foo/bar" );
PATH_CHECK( "a/b", "a/b" ); // probe for length effects PATH_CHECK( "a/b", "a/b" ); // probe for length effects
@ -616,8 +634,8 @@ int test_main( int, char*[] )
p = ""; p = "";
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "" ); BOOST_CHECK( p.filename() == "" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -625,14 +643,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( !p.has_leaf() ); BOOST_CHECK( !p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "/"; p = "/";
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "/" ); BOOST_CHECK( p.filename() == "/" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "/" ); BOOST_CHECK( p.root_directory() == "/" );
BOOST_CHECK( p.root_path().string() == "/" ); BOOST_CHECK( p.root_path().string() == "/" );
@ -640,8 +658,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -649,8 +667,8 @@ int test_main( int, char*[] )
p = "//"; p = "//";
CHECK_EQUAL( p.relative_path().string(), "" ); CHECK_EQUAL( p.relative_path().string(), "" );
CHECK_EQUAL( p.branch_path().string(), "" ); CHECK_EQUAL( p.parent_path().string(), "" );
CHECK_EQUAL( p.leaf(), "//" ); CHECK_EQUAL( p.filename(), "//" );
CHECK_EQUAL( p.root_name(), "//" ); CHECK_EQUAL( p.root_name(), "//" );
CHECK_EQUAL( p.root_directory(), "" ); CHECK_EQUAL( p.root_directory(), "" );
CHECK_EQUAL( p.root_path().string(), "//" ); CHECK_EQUAL( p.root_path().string(), "//" );
@ -658,15 +676,15 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "///"; p = "///";
CHECK_EQUAL( p.relative_path().string(), "" ); CHECK_EQUAL( p.relative_path().string(), "" );
CHECK_EQUAL( p.branch_path().string(), "" ); CHECK_EQUAL( p.parent_path().string(), "" );
CHECK_EQUAL( p.leaf(), "/" ); CHECK_EQUAL( p.filename(), "/" );
CHECK_EQUAL( p.root_name(), "" ); CHECK_EQUAL( p.root_name(), "" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "/" ); CHECK_EQUAL( p.root_path().string(), "/" );
@ -674,8 +692,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -683,8 +701,8 @@ int test_main( int, char*[] )
p = "."; p = ".";
BOOST_CHECK( p.relative_path().string() == "." ); BOOST_CHECK( p.relative_path().string() == "." );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "." ); BOOST_CHECK( p.filename() == "." );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -692,14 +710,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = ".."; p = "..";
BOOST_CHECK( p.relative_path().string() == ".." ); BOOST_CHECK( p.relative_path().string() == ".." );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == ".." ); BOOST_CHECK( p.filename() == ".." );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -707,14 +725,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "foo"; p = "foo";
BOOST_CHECK( p.relative_path().string() == "foo" ); BOOST_CHECK( p.relative_path().string() == "foo" );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "foo" ); BOOST_CHECK( p.filename() == "foo" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -722,14 +740,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "/foo"; p = "/foo";
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "/" ); CHECK_EQUAL( p.parent_path().string(), "/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "" ); CHECK_EQUAL( p.root_name(), "" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "/" ); CHECK_EQUAL( p.root_path().string(), "/" );
@ -737,8 +755,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -746,8 +764,8 @@ int test_main( int, char*[] )
p = "/foo/"; p = "/foo/";
CHECK_EQUAL( p.relative_path().string(), "foo/" ); CHECK_EQUAL( p.relative_path().string(), "foo/" );
CHECK_EQUAL( p.branch_path().string(), "/foo" ); CHECK_EQUAL( p.parent_path().string(), "/foo" );
CHECK_EQUAL( p.leaf(), "." ); CHECK_EQUAL( p.filename(), "." );
CHECK_EQUAL( p.root_name(), "" ); CHECK_EQUAL( p.root_name(), "" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "/" ); CHECK_EQUAL( p.root_path().string(), "/" );
@ -755,8 +773,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -764,8 +782,8 @@ int test_main( int, char*[] )
p = "///foo"; p = "///foo";
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "/" ); CHECK_EQUAL( p.parent_path().string(), "/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "" ); CHECK_EQUAL( p.root_name(), "" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "/" ); CHECK_EQUAL( p.root_path().string(), "/" );
@ -773,8 +791,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -782,8 +800,8 @@ int test_main( int, char*[] )
p = "foo/bar"; p = "foo/bar";
BOOST_CHECK( p.relative_path().string() == "foo/bar" ); BOOST_CHECK( p.relative_path().string() == "foo/bar" );
BOOST_CHECK( p.branch_path().string() == "foo" ); BOOST_CHECK( p.parent_path().string() == "foo" );
BOOST_CHECK( p.leaf() == "bar" ); BOOST_CHECK( p.filename() == "bar" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -791,14 +809,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "../foo"; p = "../foo";
BOOST_CHECK( p.relative_path().string() == "../foo" ); BOOST_CHECK( p.relative_path().string() == "../foo" );
BOOST_CHECK( p.branch_path().string() == ".." ); BOOST_CHECK( p.parent_path().string() == ".." );
BOOST_CHECK( p.leaf() == "foo" ); BOOST_CHECK( p.filename() == "foo" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "" ); BOOST_CHECK( p.root_path().string() == "" );
@ -806,14 +824,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "..///foo"; p = "..///foo";
CHECK_EQUAL( p.relative_path().string(), "..///foo" ); CHECK_EQUAL( p.relative_path().string(), "..///foo" );
CHECK_EQUAL( p.branch_path().string(), ".." ); CHECK_EQUAL( p.parent_path().string(), ".." );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "" ); CHECK_EQUAL( p.root_name(), "" );
CHECK_EQUAL( p.root_directory(), "" ); CHECK_EQUAL( p.root_directory(), "" );
CHECK_EQUAL( p.root_path().string(), "" ); CHECK_EQUAL( p.root_path().string(), "" );
@ -821,14 +839,14 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = "/foo/bar"; p = "/foo/bar";
BOOST_CHECK( p.relative_path().string() == "foo/bar" ); BOOST_CHECK( p.relative_path().string() == "foo/bar" );
BOOST_CHECK( p.branch_path().string() == "/foo" ); BOOST_CHECK( p.parent_path().string() == "/foo" );
BOOST_CHECK( p.leaf() == "bar" ); BOOST_CHECK( p.filename() == "bar" );
BOOST_CHECK( p.root_name() == "" ); BOOST_CHECK( p.root_name() == "" );
BOOST_CHECK( p.root_directory() == "/" ); BOOST_CHECK( p.root_directory() == "/" );
BOOST_CHECK( p.root_path().string() == "/" ); BOOST_CHECK( p.root_path().string() == "/" );
@ -836,8 +854,8 @@ int test_main( int, char*[] )
BOOST_CHECK( !p.has_root_name() ); BOOST_CHECK( !p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
if ( platform == "POSIX" ) if ( platform == "POSIX" )
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
else else
@ -852,8 +870,8 @@ int test_main( int, char*[] )
p = path( "//net" ); p = path( "//net" );
CHECK_EQUAL( p.string(), "//net" ); CHECK_EQUAL( p.string(), "//net" );
CHECK_EQUAL( p.relative_path().string(), "" ); CHECK_EQUAL( p.relative_path().string(), "" );
CHECK_EQUAL( p.branch_path().string(), "" ); CHECK_EQUAL( p.parent_path().string(), "" );
CHECK_EQUAL( p.leaf(), "//net" ); CHECK_EQUAL( p.filename(), "//net" );
CHECK_EQUAL( p.root_name(), "//net" ); CHECK_EQUAL( p.root_name(), "//net" );
CHECK_EQUAL( p.root_directory(), "" ); CHECK_EQUAL( p.root_directory(), "" );
CHECK_EQUAL( p.root_path().string(), "//net" ); CHECK_EQUAL( p.root_path().string(), "//net" );
@ -861,14 +879,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = path( "//net/" ); p = path( "//net/" );
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "//net" ); BOOST_CHECK( p.parent_path().string() == "//net" );
BOOST_CHECK( p.leaf() == "/" ); BOOST_CHECK( p.filename() == "/" );
BOOST_CHECK( p.root_name() == "//net" ); BOOST_CHECK( p.root_name() == "//net" );
BOOST_CHECK( p.root_directory() == "/" ); BOOST_CHECK( p.root_directory() == "/" );
BOOST_CHECK( p.root_path().string() == "//net/" ); BOOST_CHECK( p.root_path().string() == "//net/" );
@ -876,14 +894,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "//net/foo" ); p = path( "//net/foo" );
BOOST_CHECK( p.relative_path().string() == "foo" ); BOOST_CHECK( p.relative_path().string() == "foo" );
BOOST_CHECK( p.branch_path().string() == "//net/" ); BOOST_CHECK( p.parent_path().string() == "//net/" );
BOOST_CHECK( p.leaf() == "foo" ); BOOST_CHECK( p.filename() == "foo" );
BOOST_CHECK( p.root_name() == "//net" ); BOOST_CHECK( p.root_name() == "//net" );
BOOST_CHECK( p.root_directory() == "/" ); BOOST_CHECK( p.root_directory() == "/" );
BOOST_CHECK( p.root_path().string() == "//net/" ); BOOST_CHECK( p.root_path().string() == "//net/" );
@ -891,14 +909,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "//net///foo" ); p = path( "//net///foo" );
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "//net/" ); CHECK_EQUAL( p.parent_path().string(), "//net/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "//net" ); CHECK_EQUAL( p.root_name(), "//net" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "//net/" ); CHECK_EQUAL( p.root_path().string(), "//net/" );
@ -906,8 +924,8 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
if ( platform == "Windows" ) if ( platform == "Windows" )
@ -959,8 +977,8 @@ int test_main( int, char*[] )
p = path( "c:" ); p = path( "c:" );
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "c:" ); BOOST_CHECK( p.filename() == "c:" );
BOOST_CHECK( p.root_name() == "c:" ); BOOST_CHECK( p.root_name() == "c:" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "c:" ); BOOST_CHECK( p.root_path().string() == "c:" );
@ -968,14 +986,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = path( "c:foo" ); p = path( "c:foo" );
BOOST_CHECK( p.relative_path().string() == "foo" ); BOOST_CHECK( p.relative_path().string() == "foo" );
BOOST_CHECK( p.branch_path().string() == "c:" ); BOOST_CHECK( p.parent_path().string() == "c:" );
BOOST_CHECK( p.leaf() == "foo" ); BOOST_CHECK( p.filename() == "foo" );
BOOST_CHECK( p.root_name() == "c:" ); BOOST_CHECK( p.root_name() == "c:" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "c:" ); BOOST_CHECK( p.root_path().string() == "c:" );
@ -983,14 +1001,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = path( "c:/" ); p = path( "c:/" );
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "c:" ); BOOST_CHECK( p.parent_path().string() == "c:" );
BOOST_CHECK( p.leaf() == "/" ); BOOST_CHECK( p.filename() == "/" );
BOOST_CHECK( p.root_name() == "c:" ); BOOST_CHECK( p.root_name() == "c:" );
BOOST_CHECK( p.root_directory() == "/" ); BOOST_CHECK( p.root_directory() == "/" );
BOOST_CHECK( p.root_path().string() == "c:/" ); BOOST_CHECK( p.root_path().string() == "c:/" );
@ -998,14 +1016,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "c:.." ); p = path( "c:.." );
BOOST_CHECK( p.relative_path().string() == ".." ); BOOST_CHECK( p.relative_path().string() == ".." );
BOOST_CHECK( p.branch_path().string() == "c:" ); BOOST_CHECK( p.parent_path().string() == "c:" );
BOOST_CHECK( p.leaf() == ".." ); BOOST_CHECK( p.filename() == ".." );
BOOST_CHECK( p.root_name() == "c:" ); BOOST_CHECK( p.root_name() == "c:" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "c:" ); BOOST_CHECK( p.root_path().string() == "c:" );
@ -1013,14 +1031,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = path( "c:/foo" ); p = path( "c:/foo" );
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "c:/" ); CHECK_EQUAL( p.parent_path().string(), "c:/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "c:" ); CHECK_EQUAL( p.root_name(), "c:" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "c:/" ); CHECK_EQUAL( p.root_path().string(), "c:/" );
@ -1028,14 +1046,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "c://foo" ); p = path( "c://foo" );
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "c:/" ); CHECK_EQUAL( p.parent_path().string(), "c:/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "c:" ); CHECK_EQUAL( p.root_name(), "c:" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "c:/" ); CHECK_EQUAL( p.root_path().string(), "c:/" );
@ -1043,14 +1061,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "c:\\foo\\bar" ); p = path( "c:\\foo\\bar" );
CHECK_EQUAL( p.relative_path().string(), "foo/bar" ); CHECK_EQUAL( p.relative_path().string(), "foo/bar" );
CHECK_EQUAL( p.branch_path().string(), "c:/foo" ); CHECK_EQUAL( p.parent_path().string(), "c:/foo" );
CHECK_EQUAL( p.leaf(), "bar" ); CHECK_EQUAL( p.filename(), "bar" );
CHECK_EQUAL( p.root_name(), "c:" ); CHECK_EQUAL( p.root_name(), "c:" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "c:/" ); CHECK_EQUAL( p.root_path().string(), "c:/" );
@ -1058,14 +1076,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
p = path( "prn:" ); p = path( "prn:" );
BOOST_CHECK( p.relative_path().string() == "" ); BOOST_CHECK( p.relative_path().string() == "" );
BOOST_CHECK( p.branch_path().string() == "" ); BOOST_CHECK( p.parent_path().string() == "" );
BOOST_CHECK( p.leaf() == "prn:" ); BOOST_CHECK( p.filename() == "prn:" );
BOOST_CHECK( p.root_name() == "prn:" ); BOOST_CHECK( p.root_name() == "prn:" );
BOOST_CHECK( p.root_directory() == "" ); BOOST_CHECK( p.root_directory() == "" );
BOOST_CHECK( p.root_path().string() == "prn:" ); BOOST_CHECK( p.root_path().string() == "prn:" );
@ -1073,14 +1091,14 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( !p.has_root_directory() ); BOOST_CHECK( !p.has_root_directory() );
BOOST_CHECK( !p.has_relative_path() ); BOOST_CHECK( !p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( !p.has_branch_path() ); BOOST_CHECK( !p.has_parent_path() );
BOOST_CHECK( !p.is_complete() ); BOOST_CHECK( !p.is_complete() );
p = path( "\\\\net\\\\\\foo" ); p = path( "\\\\net\\\\\\foo" );
CHECK_EQUAL( p.relative_path().string(), "foo" ); CHECK_EQUAL( p.relative_path().string(), "foo" );
CHECK_EQUAL( p.branch_path().string(), "//net/" ); CHECK_EQUAL( p.parent_path().string(), "//net/" );
CHECK_EQUAL( p.leaf(), "foo" ); CHECK_EQUAL( p.filename(), "foo" );
CHECK_EQUAL( p.root_name(), "//net" ); CHECK_EQUAL( p.root_name(), "//net" );
CHECK_EQUAL( p.root_directory(), "/" ); CHECK_EQUAL( p.root_directory(), "/" );
CHECK_EQUAL( p.root_path().string(), "//net/" ); CHECK_EQUAL( p.root_path().string(), "//net/" );
@ -1088,8 +1106,8 @@ int test_main( int, char*[] )
BOOST_CHECK( p.has_root_name() ); BOOST_CHECK( p.has_root_name() );
BOOST_CHECK( p.has_root_directory() ); BOOST_CHECK( p.has_root_directory() );
BOOST_CHECK( p.has_relative_path() ); BOOST_CHECK( p.has_relative_path() );
BOOST_CHECK( p.has_leaf() ); BOOST_CHECK( p.has_filename() );
BOOST_CHECK( p.has_branch_path() ); BOOST_CHECK( p.has_parent_path() );
BOOST_CHECK( p.is_complete() ); BOOST_CHECK( p.is_complete() );
itr_ck = path( "c:" ); itr_ck = path( "c:" );
@ -1283,6 +1301,40 @@ int test_main( int, char*[] )
BOOST_CHECK( acs2 >= a ); BOOST_CHECK( acs2 >= a );
BOOST_CHECK( a2 >= as ); BOOST_CHECK( a2 >= as );
BOOST_CHECK( a2 >= acs ); BOOST_CHECK( a2 >= acs );
// extension() tests
BOOST_CHECK( path("a/b").extension() == "" );
BOOST_CHECK( path("a/b.txt").extension() == ".txt" );
BOOST_CHECK( path("a/b.").extension() == "." );
BOOST_CHECK( path("a.b.c").extension() == ".c" );
BOOST_CHECK( path("a.b.c.").extension() == "." );
BOOST_CHECK( path("").extension() == "" );
BOOST_CHECK( path("a/").extension() == "." );
// stem() tests
BOOST_CHECK( path("b").stem() == "b" );
BOOST_CHECK( path("a/b.txt").stem() == "b" );
BOOST_CHECK( path("a/b.").stem() == "b" );
BOOST_CHECK( path("a.b.c").stem() == "a.b" );
BOOST_CHECK( path("a.b.c.").stem() == "a.b.c" );
BOOST_CHECK( path("").stem() == "" );
// replace_extension() tests
BOOST_CHECK( path("a.txt").replace_extension("").string() == "a" );
BOOST_CHECK( path("a.txt").replace_extension(".").string() == "a." );
BOOST_CHECK( path("a.txt").replace_extension(".tex").string() == "a.tex" );
BOOST_CHECK( path("a.txt").replace_extension("tex").string() == "a.tex" );
BOOST_CHECK( path("a.").replace_extension(".tex").string() == "a.tex" );
BOOST_CHECK( path("a.").replace_extension("tex").string() == "a.tex" );
BOOST_CHECK( path("a").replace_extension(".txt").string() == "a.txt" );
BOOST_CHECK( path("a").replace_extension("txt").string() == "a.txt" );
BOOST_CHECK( path("a.b.txt" ).replace_extension(".tex").string() == "a.b.tex" );
BOOST_CHECK( path("a.b.txt" ).replace_extension("tex").string() == "a.b.tex" );
// see the rationale in html docs for explanation why this works
BOOST_CHECK( path("").replace_extension(".png").string() == ".png" );
// inserter and extractor tests // inserter and extractor tests
# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier