Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78065 - in trunk: boost/filesystem libs/filesystem/doc libs/filesystem/doc/src libs/filesystem/test
From: bdawes_at_[hidden]
Date: 2012-04-18 10:46:17


Author: bemandawes
Date: 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
New Revision: 78065
URL: http://svn.boost.org/trac/boost/changeset/78065

Log:
Filesystem: Add path::operator+= and concat functions to tack on things like suffixes or numbers. Suggested by Ed Smith-Rowland and others.
Text files modified:
   trunk/boost/filesystem/path.hpp | 50 +++++++++++++
   trunk/libs/filesystem/doc/reference.html | 144 +++++++++++++++++++++++----------------
   trunk/libs/filesystem/doc/release_history.html | 4
   trunk/libs/filesystem/doc/src/source.html | 146 +++++++++++++++++++++++----------------
   trunk/libs/filesystem/doc/src/tr2_snippets.html | 11 ++
   trunk/libs/filesystem/test/path_unit_test.cpp | 68 ++++++++++++++++++
   6 files changed, 301 insertions(+), 122 deletions(-)

Modified: trunk/boost/filesystem/path.hpp
==============================================================================
--- trunk/boost/filesystem/path.hpp (original)
+++ trunk/boost/filesystem/path.hpp 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -30,6 +30,7 @@
 #include <boost/io/detail/quoted_manip.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/functional/hash_fwd.hpp>
+#include <boost/type_traits/is_integral.hpp>
 #include <string>
 #include <iterator>
 #include <cstring>
@@ -235,6 +236,55 @@
       return *this;
     }
 
+ // ----- concatenation -----
+
+ path& operator+=(const path& p) {m_pathname += p.m_pathname; return *this;}
+ path& operator+=(const string_type& s) {m_pathname += s; return *this;}
+ path& operator+=(const value_type* ptr) {m_pathname += ptr; return *this;}
+ path& operator+=(value_type c) {m_pathname += c; return *this;}
+
+ template <class Source>
+ typename boost::enable_if<path_traits::is_pathable<
+ typename boost::decay<Source>::type>, path&>::type
+ operator+=(Source const& source)
+ {
+ return concat(source, codecvt());
+ }
+
+ template <class CharT>
+ typename boost::enable_if<is_integral<CharT>, path&>::type
+ operator+=(CharT c)
+ {
+ CharT tmp[2];
+ tmp[0] = c;
+ tmp[1] = 0;
+ return concat(tmp, codecvt());
+ }
+
+ template <class Source>
+ path& concat(Source const& source, const codecvt_type& cvt)
+ {
+ path_traits::dispatch(source, m_pathname, cvt);
+ return *this;
+ }
+
+ template <class InputIterator>
+ path& concat(InputIterator begin, InputIterator end)
+ {
+ return concat(begin, end, codecvt());
+ }
+
+ template <class InputIterator>
+ path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt)
+ {
+ if (begin == end)
+ return *this;
+ std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+ s(begin, end);
+ path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
+ return *this;
+ }
+
     // ----- appends -----
 
     // if a separator is added, it is the preferred separator for the platform;

Modified: trunk/libs/filesystem/doc/reference.html
==============================================================================
--- trunk/libs/filesystem/doc/reference.html (original)
+++ trunk/libs/filesystem/doc/reference.html 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -94,7 +94,8 @@
 &nbsp;&nbsp;&nbsp; path requirements<br>
     &nbsp;&nbsp;&nbsp; path constructors<br>
 &nbsp;&nbsp;&nbsp; path assignments<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
+ &nbsp;&nbsp; &nbsp;path concatenation<br>
 &nbsp;&nbsp;&nbsp;&nbsp;path modifiers<br>
 &nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-native-format-observers"><code>path</code> native
     format observers</a><br>
@@ -192,7 +193,7 @@
 
 <p>This reference documentation describes components that perform operations on file systems and
 their components, such as paths, regular files, and directories.</p>
-<p dir="ltr">Operating systems such as <i>Linux, MAC OS, UNIX</i>, and <i>Windows</i> are
+<p>Operating systems such as <i>Linux, MAC OS, UNIX</i>, and <i>Windows</i> are
 mentioned in this reference documentation for purposes of illustration or to give guidance to
 implementers. No slight to other operating systems is implied or intended.</p>
 <p><span style="background-color: #E0E0E0">Footnote:</span> Linux® is a
@@ -382,7 +383,7 @@
     bool lexicographical_compare(path::iterator first1, path::iterator last1,
       path::iterator first2, path::iterator last2);
       
-<pre> void swap(path&amp; lhs, path&amp; rhs);
+void swap(path&amp; lhs, path&amp; rhs);
     std::size_t hash_value(const path&amp; p);
 
     bool operator==(const path&amp; lhs, const path&amp; rhs);
@@ -672,6 +673,22 @@
         template &lt;class InputIterator&gt;
           path&amp; append(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt=codecvt());
 
+ // concatenation
+ path&amp; operator+=(const path&amp; x);
+ path&amp; operator+=(const string_type&amp; x);
+ path&amp; operator+=(const value_type* x);
+ path&amp; operator+=(value_type x);
+ template &lt;class Source&gt;
+ path&amp; operator+=(Source const&amp; x);
+ template &lt;class CharT&gt;
+ path&amp; operator+=(CharT x);
+ template &lt;class Source&gt;
+ path&amp; concat(Source const&amp; x, const codecvt_type&amp; cvt);
+ template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end);
+ template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt);
+
         // modifiers
         void clear();
         path&amp; make_absolute(const path&amp; base);
@@ -910,7 +927,7 @@
   or <code>source</code> is not <code>value_type</code>, conversion is performed
   by <code>cvt</code>.</p>
   </blockquote>
-<h3> <a name="path-appends"><code><font size="4"> path</font></code> appends</a></h3>
+<h3><a name="path-appends"><code><font size="4"> path</font></code> appends</a></h3>
   <p>The append operations use <code>operator/=</code> to denote their semantic
   effect of appending the platform's preferred directory separator when needed. The
   preferred
@@ -966,9 +983,34 @@
   <p><i>Returns: </i><code>*this</code></p>
   </blockquote>
   
-<h3> <a name="path-modifiers"> <code>
-<font size="4">path</font></code> modifiers</a></h3>
-<pre>void <a name="path-clear">clear</a>();</pre>
+<h3><a name="path-concatenation"><code>path</code> concatenation</a></h3>
+<pre>path&amp; operator+=(const path&amp; x);
+path&amp; operator+=(const string_type&amp; x);
+path&amp; operator+=(const value_type* x);
+path&amp; operator+=(value_type x);
+template &lt;class Source&gt;
+ path&amp; operator+=(Source const&amp; x);
+template &lt;class CharT&gt;
+ path&amp; operator+=(CharT x);
+template &lt;class Source&gt;
+ path&amp; concat(Source const&amp; x, const codecvt_type&amp; cvt);
+template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end);
+template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt);</pre>
+<blockquote><p><i>Postcondition:</i> <code>native() == prior_native + <i>effective-argument</i></code>,
+ where <code>prior_native</code> is <code>native()</code> prior to the call to <code>operator+=</code>,
+ and <code><i>effective-argument</i></code> is:</p>
+ <ul><li><code>x.native()</code> if <code>x</code> is present and is <code>const path&amp;</code>, otherwise</li>
+ <li><code>s</code>, where <code>s</code> is
+ <code>std::basic_string&lt;typename std::iterator_traits&lt;InputIterator&gt;::value_type&gt;<br>s(begin, end)</code>,
+ if <code>begin</code> and <code>end</code> arguments are present, otherwise</li>
+ <li><code>x</code>.</li></ul><p>If the value type of <code><i>effective-argument</i></code> would not be <code>path::value_type</code>, the actual argument or argument range is first
+ converted so that <code><i>effective-argument</i></code> has value type <code>path::value_type</code>.</li> </p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<h3><a name="path-modifiers"> <code>
+path</code> modifiers</a></h3><pre>void <a name="path-clear">clear</a>();</pre>
 <blockquote>
 <p><i>Postcondition:</i> <code>this-&gt;empty()</code> is true.</p>
 </blockquote>
@@ -1342,8 +1384,7 @@
 </pre>
 <blockquote>
   <p><i>Effects:&nbsp; </i><code>&nbsp;std::basic_string&lt;Char&gt; str;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is &gt;&gt; boost::io::quoted(str,
- static_cast&lt;Char&gt;('&amp;'));<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is &gt;&gt; boost::io::quoted(str, static_cast&lt;Char&gt;('&amp;'));<br>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p = str;</code></p>
   <p><i>Returns:</i> <code>is</code></p>
   </blockquote>
@@ -1559,7 +1600,7 @@
   </tr>
 
 <tr><td>
- <p dir="ltr"><code>no_perms</code></td><td><code>0</code></td><td></td>
+ <p><code>no_perms</code></td><td><code>0</code></td><td></td>
   <td>There are no permissions set for the file. Note: <code>file_not_found</code> is <code>no_perms</code> rather than <code>perms_not_known</code></td>
 </tr>
 <tr><td><code>owner_read</code></td><td><code>0400</code></td><td> <code>S_IRUSR</code></td>
@@ -1584,8 +1625,7 @@
   <td> Execute/search permission, group</td>
 </tr>
 <tr><td><code>group_all</code></td><td><code>070</code></td><td> <code>S_IRWXG</code></td>
- <td> Read, write, execute/search by group; <code>group_read | group_write |
- group_exe</code></td>
+ <td> Read, write, execute/search by group; <code>group_read | group_write | group_exe</code></td>
 </tr>
 <tr><td><code>others_read</code></td><td><code>04</code></td><td> <code>S_IROTH</code></td>
   <td> Read permission, others</td>
@@ -1618,8 +1658,8 @@
   is created without specifying the permissions</td>
 </tr>
 <tr><td>
- <p dir="ltr"><code>add_perms</code></td><td><code>0x1000</code></td><td></td><td>
- <p dir="ltr"><code>permissions()</code> adds the argument permission bits to the
+ <p><code>add_perms</code></td><td><code>0x1000</code></td><td></td><td>
+ <p><code>permissions()</code> adds the argument permission bits to the
   file's current bits</td>
 </tr>
 <tr><td><code>remove_perms</code></td><td><code>0x2000</code></td><td></td><td>
@@ -1663,17 +1703,16 @@
 } // namespace boost</pre>
 <p>An object of type <code>file_status</code> stores information about the type
 and permissions of a file.</p>
-<h4 dir="ltr"><a name="file_status-constructors"><code>file_status</code> constructors</a></h4>
+<h4><a name="file_status-constructors"><code>file_status</code> constructors</a></h4>
 <pre>explicit file_status() noexcept;</pre>
 <blockquote>
   <p><i>Postconditions:</i> <code>type() == status_error</code>, <code>permissions() == perms_not_known</code>.</p>
 </blockquote>
 <pre>explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;</pre>
 <blockquote>
- <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() ==
- prms</code>.</p>
+ <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() == prms</code>.</p>
 </blockquote>
- <h4 dir="ltr"><a name="file_status-observers"><code>file_status</code> observers</a></h4>
+ <h4><a name="file_status-observers"><code>file_status</code> observers</a></h4>
 <pre>file_type type() const noexcept;</pre>
 <blockquote>
   <p><i>Returns: </i>The value of <code>type()</code> specified by the <i>postconditions</i> of the most recent call to a constructor, operator=, or <code>type(file_type)</code> function.</p>
@@ -1682,17 +1721,17 @@
 <blockquote>
   <p><i>Returns: </i>The value of <code>permissions()</code> specified by the <i>postconditions</i> of the most recent call to a constructor, operator=, or <code>permissions(perms)</code> function.</p>
 </blockquote>
-<h4 dir="ltr"><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4>
+<h4><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4>
 <pre>void type(file_type ft) noexcept;</pre>
 <blockquote>
- <p dir="ltr"><i>Postconditions:</i> <code>type() == ft</code>.</p>
+ <p><i>Postconditions:</i> <code>type() == ft</code>.</p>
 </blockquote>
 <pre>void permissions(perms prms) noexcept;</pre>
 <blockquote>
- <p dir="ltr"><i>Postconditions:</i> <code>permissions() == prms</code>.</p>
+ <p><i>Postconditions:</i> <code>permissions() == prms</code>.</p>
 </blockquote>
 <h3><a name="Class-directory_entry">Class <code>directory_entry</code></a></h3>
-<div dir="ltr">
+<div>
 <pre>namespace boost
 {
   namespace filesystem
@@ -1881,33 +1920,27 @@
 </blockquote>
 <pre>bool operator==(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path ==
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path == rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator!=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path !=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path != rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&lt; (const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &lt;
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &lt; rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&lt;=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &lt;=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &lt;= rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&gt; (const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &gt;
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &gt; rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&gt;=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &gt;=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &gt;= rhs.m_path</code>.</p>
 </blockquote>
 <h3><a name="Class-directory_iterator">Class <code>directory_iterator</code></a></h3>
 <p>Objects of type <code>directory_iterator</code> provide standard library
@@ -2086,7 +2119,7 @@
 <p><i>Effects:</i>&nbsp; Constructs a iterator representing the first
 entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p>
 
-<p dir="ltr"><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 &amp;&amp; no_push_pending() == false &amp;&amp; m_options == opt</code>.
+<p><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 &amp;&amp; no_push_pending() == false &amp;&amp; m_options == opt</code>.
 For the signature without a <code>symlink_option</code> argument, <code>opt</code> is assumed to be <code>symlink_option::none</code>.</p>
 
 <p><i>Throws:</i> As specified in Error reporting.</p>
@@ -2114,11 +2147,10 @@
 except:</p>
 
 <ul>
- <li dir="ltr">
+ <li>
 
-<p dir="ltr">if <code>!no_push_pending() &amp;&amp; is_directory(this-&gt;status())
-&amp;&amp; (!is_symlink(this-&gt;symlink_status()) || (m_options
-&amp; symlink_option::recurse) != 0)</code> then&nbsp; <code>m_level</code> is incremented and directory <code>(*this)-&gt;path()</code> is recursively iterated into.<br>
+<p>if <code>!no_push_pending() &amp;&amp; is_directory(this-&gt;status())
+&amp;&amp; (!is_symlink(this-&gt;symlink_status()) || (m_options &amp; symlink_option::recurse) != 0)</code> then&nbsp; <code>m_level</code> is incremented and directory <code>(*this)-&gt;path()</code> is recursively iterated into.<br>
 &nbsp;</p>
 
   </li>
@@ -2171,8 +2203,7 @@
     <tr>
       <td align="center"><b><code>p.has_root_name()</code></b></td>
       <td align="center"><code>return p</code></td>
- <td align="center"><code>return p.root_name() /
- absolute(base).root_directory()<br>
+ <td align="center"><code>return p.root_name() / absolute(base).root_directory()<br>
       / absolute(base).relative_path() / p.relative_path()</code></td>
     </tr>
     <tr>
@@ -2182,7 +2213,7 @@
       <td align="center"><code>return absolute(base) / p</code></td>
     </tr>
   </table>
- <p dir="ltr">[<i>Note:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true. <i>-- end note</i>]</p>
+ <p>[<i>Note:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true. <i>-- end note</i>]</p>
   <p><i>Throws:</i> If <code>base.is_absolute()</code> is true, throws only if
   memory allocation fails.</p>
 </blockquote>
@@ -2234,8 +2265,7 @@
 <pre>void copy_file(const path&amp; from, const path&amp; to);
 void copy_file(const path&amp; from, const path&amp; to, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects: </i><code>copy_file(from, to,
- copy_option::fail_if_exists</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
+ <p><i>Effects: </i><code>copy_file(from, to, copy_option::fail_if_exists</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
   
   <p><i>Throws:</i> As specified in Error reporting.</p>
   
@@ -2243,15 +2273,13 @@
 <pre>void <a name="copy_file">copy_file</a>(const path&amp; from, const path&amp; to, copy_option option);
 void <a name="copy_file2">copy_file</a>(const path&amp; from, const path&amp; to, copy_option option, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists
- &amp;&amp; exists(to)</code>, an error is reported. Otherwise, the contents and attributes of the file <code>from</code> resolves to are copied to the file <code>to</code> resolves to.</p>
+ <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists &amp;&amp; exists(to)</code>, an error is reported. Otherwise, the contents and attributes of the file <code>from</code> resolves to are copied to the file <code>to</code> resolves to.</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
 </blockquote>
 <pre>void <a name="copy_symlink">copy_symlink</a>(const path&amp; existing_symlink, const path&amp; new_symlink);
 void copy_symlink(const path&amp; existing_symlink, const path&amp; new_symlink, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects: </i><code>create_symlink(read_symlink(existing_symlink</code><i>[</i><code>, ec</code><i>]</i><code>),
- new_symlink</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
+ <p><i>Effects: </i><code>create_symlink(read_symlink(existing_symlink</code><i>[</i><code>, ec</code><i>]</i><code>), new_symlink</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
   
   <p><i>Throws:</i> As specified in Error reporting.</p>
   
@@ -2283,7 +2311,7 @@
   Postcondition:</i> <code>new_symlink</code> resolves to a symbolic link file that
   contains an unspecified representation of <code>to</code>.</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
- <p dir="ltr">[<i>Note:</i> Some operating systems, such as Windows, require symlink creation to
+ <p>[<i>Note:</i> Some operating systems, such as Windows, require symlink creation to
   identify that the link is to a directory. Portable code should use <code>create_directory_symlink()</code> to create directory symlinks rather than <code>create_symlink()</code> <i>-- end note</i>]</p>
   <p>[<i>Note:</i> Some operating systems do not support symbolic links at all or support
   them only for regular files.
@@ -2379,7 +2407,7 @@
   <p><i>Throws:</i> <code>filesystem_error</code> if <code>(!exists(s1) &amp;&amp; !exists(s2)) || (is_other(s1) &amp;&amp; is_other(s2))</code>,
   otherwise as specified in Error reporting.</p>
 </blockquote>
-<div dir="ltr">
+<div>
 <pre>uintmax_t <a name="file_size">file_size</a>(const path&amp; p);
 uintmax_t <a name="file_size2">file_size</a>(const path&amp; p, system::error_code&amp; ec);</pre>
 </div>
@@ -2417,7 +2445,7 @@
 <pre><code>bool <a name="is_directory2">is_directory</a>(const path&amp; p);
 bool <a name="is_directory3">is_directory</a>(const path&amp; p, system::error_code&amp; ec) noexcept;</code></pre>
 <blockquote>
- <p dir="ltr"><i>Returns:</i> <code>is_directory(status(p))</code> or <code>is_directory(status(p, ec))</code>,
+ <p><i>Returns:</i> <code>is_directory(status(p))</code> or <code>is_directory(status(p, ec))</code>,
   respectively.</p>
 <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&amp;</code> throws
 nothing.</p>
@@ -2427,8 +2455,7 @@
 <blockquote>
   <p><i>Effects:</i> Determines <code>file_status s</code>, as if by <code>status(p, ec)</code>.</p>
   <p><i>Returns:</i> <code>is_directory(s)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?
- directory_iterator(p) == directory_iterator()<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ? directory_iterator(p) == directory_iterator()<br>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : file_size(p) == 0;</code></p>
 </blockquote>
 <pre>bool <code><a name="is_regular_file">is_regular_file</a></code>(file_status s) noexcept;</pre>
@@ -2484,16 +2511,15 @@
   <p><i>Effects:</i> Sets the time of last data modification of the file
   resolved to by <code>p</code> to <code>new_time</code>, as if by <i>POSIX</i> <code>stat()</code> followed by <i>POSIX</i> utime().</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
- <p>[<i>Note:</i> A postcondition of <code>last_write_time(p) ==
- new_time</code> is not specified since it might not hold for file systems
+ <p>[<i>Note:</i> A postcondition of <code>last_write_time(p) == new_time</code> is not specified since it might not hold for file systems
   with coarse time granularity. <i>-- end note</i>]</p>
 </blockquote>
 <pre>void <a name="permissions">permissions</a>(const path&amp; p, perms prms);
 void permissions(const path&amp; p, perms prms, system::error_code&amp; ec);</pre>
 <blockquote>
- <p dir="ltr">
+ <p>
   <i>Requires:</i> <code>!((prms &amp; add_perms) &amp;&amp; (prms &amp; remove_perms))</code>.</p>
- <p dir="ltr"><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> to the file <code>p</code> resolves to, as if by <i>POSIX</i> <code>fchmodat()</code>. The effective permission bits are determined as
+ <p><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> to the file <code>p</code> resolves to, as if by <i>POSIX</i> <code>fchmodat()</code>. The effective permission bits are determined as
   specified by the following table. </p>
   <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
     <tr>
@@ -2507,7 +2533,7 @@
     <tr>
       <td><code>add_perms</code></td>
       <td>
- <p dir="ltr"><code>status(p).permissions() | (prms &amp; perms_mask)</code> </td>
+ <p><code>status(p).permissions() | (prms &amp; perms_mask)</code> </td>
     </tr>
     <tr>
       <td><code>remove_perms</code></td>
@@ -2521,7 +2547,7 @@
 <pre>path <a name="read_symlink">read_symlink</a>(const path&amp; p);
 path read_symlink(const path&amp; p, system::error_code&amp; ec);</pre>
 <blockquote>
- <p dir="ltr"><i>Returns:</i>&nbsp; If <code>p</code> resolves to a symbolic
+ <p><i>Returns:</i>&nbsp; If <code>p</code> resolves to a symbolic
   link, a <code>path</code> object containing the contents of that symbolic
   link. Otherwise an empty <code>path</code> object.</p>
   <p><i>Throws:</i> As specified in Error reporting. [<i>Note:</i> It is an error if <code>p</code> does not

Modified: trunk/libs/filesystem/doc/release_history.html
==============================================================================
--- trunk/libs/filesystem/doc/release_history.html (original)
+++ trunk/libs/filesystem/doc/release_history.html 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -68,6 +68,8 @@
   <a href="http://svn.boost.org/trac/boost/ticket/4889">#4889</a>,
   <a href="http://svn.boost.org/trac/boost/ticket/6320">#6320</a>, for these
   compilers if static linking is used.</li>
+ <li>Add path::operator+= and concat functions to tack on things like suffixes
+ or numbers. Suggested by Ed Smith-Rowland.</li>
 </ul>
 
 <h2>1.49.0</h2>
@@ -152,7 +154,7 @@
 </ul>
 <hr>
 <p>Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->15 April, 2012<!--webbot bot="Timestamp" endspan i-checksum="29863" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->18 April, 2012<!--webbot bot="Timestamp" endspan i-checksum="29869" --></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">

Modified: trunk/libs/filesystem/doc/src/source.html
==============================================================================
--- trunk/libs/filesystem/doc/src/source.html (original)
+++ trunk/libs/filesystem/doc/src/source.html 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -62,7 +62,8 @@
 &nbsp;&nbsp;&nbsp; path requirements<br>
     &nbsp;&nbsp;&nbsp; path constructors<br>
 &nbsp;&nbsp;&nbsp; path assignments<br>
-&nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;path appends<br>
+ &nbsp;&nbsp; &nbsp;path concatenation<br>
 &nbsp;&nbsp;&nbsp;&nbsp;path modifiers<br>
 &nbsp;&nbsp;&nbsp;&nbsp;<a href="#path-native-format-observers"><code>path</code> native
     format observers</a><br>
@@ -155,7 +156,7 @@
 
 <p>This $WHAT; describes components that perform operations on file systems and
 their components, such as paths, regular files, and directories.</p>
-<p dir="ltr">Operating systems such as <i>Linux, MAC OS, UNIX</i>, and <i>Windows</i> are
+<p>Operating systems such as <i>Linux, MAC OS, UNIX</i>, and <i>Windows</i> are
 mentioned in this $WHAT; for purposes of illustration or to give guidance to
 implementers. No slight to other operating systems is implied or intended.</p>
 <p><span style="background-color: #E0E0E0">Footnote:</span> Linux® is a
@@ -343,8 +344,8 @@
       path::iterator first2, path::iterator last2);
       
 $endif
-
-<pre> void swap(path&amp; lhs, path&amp; rhs);
+
+ void swap(path&amp; lhs, path&amp; rhs);
     std::size_t hash_value(const path&amp; p);
 
     bool operator==(const path&amp; lhs, const path&amp; rhs);
@@ -630,6 +631,22 @@
         template &lt;class InputIterator&gt;
           path&amp; append(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt=codecvt());
 
+ // concatenation
+ path&amp; operator+=(const path&amp; x);
+ path&amp; operator+=(const string_type&amp; x);
+ path&amp; operator+=(const value_type* x);
+ path&amp; operator+=(value_type x);
+ template &lt;class Source&gt;
+ path&amp; operator+=(Source const&amp; x);
+ template &lt;class CharT&gt;
+ path&amp; operator+=(CharT x);
+ template &lt;class Source&gt;
+ path&amp; concat(Source const&amp; x, const codecvt_type&amp; cvt);
+ template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end);
+ template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt);
+
         // modifiers
         void clear();
         path&amp; make_absolute(const path&amp; base);
@@ -867,7 +884,7 @@
   or <code>source</code> is not <code>value_type</code>, conversion is performed
   by <code>cvt</code>.</p>
   </blockquote>
-<h3> <a name="path-appends"><code><font size="4"> path</font></code> appends</a></h3>
+<h3><a name="path-appends"><code><font size="4"> path</font></code> appends</a></h3>
   <p>The append operations use <code>operator/=</code> to denote their semantic
   effect of appending the platform's preferred directory separator when needed. The
   preferred
@@ -923,9 +940,34 @@
   <p><i>Returns: </i><code>*this</code></p>
   </blockquote>
   
-<h3> <a name="path-modifiers"> <code>
-<font size="4">path</font></code> modifiers</a></h3>
-<pre>void <a name="path-clear">clear</a>();</pre>
+<h3><a name="path-concatenation"><code>path</code> concatenation</a></h3>
+<pre>path&amp; operator+=(const path&amp; x);
+path&amp; operator+=(const string_type&amp; x);
+path&amp; operator+=(const value_type* x);
+path&amp; operator+=(value_type x);
+template &lt;class Source&gt;
+ path&amp; operator+=(Source const&amp; x);
+template &lt;class CharT&gt;
+ path&amp; operator+=(CharT x);
+template &lt;class Source&gt;
+ path&amp; concat(Source const&amp; x, const codecvt_type&amp; cvt);
+template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end);
+template &lt;class InputIterator&gt;
+ path&amp; concat(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt);</pre>
+<blockquote><p><i>Postcondition:</i> <code>native() == prior_native + <i>effective-argument</i></code>,
+ where <code>prior_native</code> is <code>native()</code> prior to the call to <code>operator+=</code>,
+ and <code><i>effective-argument</i></code> is:</p>
+ <ul><li><code>x.native()</code> if <code>x</code> is present and is <code>const path&amp;</code>, otherwise</li>
+ <li><code>s</code>, where <code>s</code> is
+ <code>std::basic_string&lt;typename std::iterator_traits&lt;InputIterator&gt;::value_type&gt;<br>s(begin, end)</code>,
+ if <code>begin</code> and <code>end</code> arguments are present, otherwise</li>
+ <li><code>x</code>.</li></ul><p>If the value type of <code><i>effective-argument</i></code> would not be <code>path::value_type</code>, the actual argument or argument range is first
+ converted so that <code><i>effective-argument</i></code> has value type <code>path::value_type</code>.</li> </p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<h3><a name="path-modifiers"> <code>
+path</code> modifiers</a></h3><pre>void <a name="path-clear">clear</a>();</pre>
 <blockquote>
 <p><i>Postcondition:</i> <code>this-&gt;empty()</code> is true.</p>
 </blockquote>
@@ -1302,8 +1344,7 @@
 </pre>
 <blockquote>
   <p><i>Effects:&nbsp; </i><code>&nbsp;std::basic_string&lt;Char&gt; str;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is &gt;&gt; boost::io::quoted(str,
- static_cast&lt;Char&gt;('&amp;'));<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is &gt;&gt; boost::io::quoted(str, static_cast&lt;Char&gt;('&amp;'));<br>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p = str;</code></p>
   <p><i>Returns:</i> <code>is</code></p>
   </blockquote>
@@ -1515,7 +1556,7 @@
   </tr>
 
 <tr><td>
- <p dir="ltr"><code>no_perms</code></td><td><code>0</code></td><td></td>
+ <p><code>no_perms</code></td><td><code>0</code></td><td></td>
   <td>There are no permissions set for the file. Note: <code>file_not_found</code> is <code>no_perms</code> rather than <code>perms_not_known</code></td>
 </tr>
 <tr><td><code>owner_read</code></td><td><code>0400</code></td><td> <code>S_IRUSR</code></td>
@@ -1540,8 +1581,7 @@
   <td> Execute/search permission, group</td>
 </tr>
 <tr><td><code>group_all</code></td><td><code>070</code></td><td> <code>S_IRWXG</code></td>
- <td> Read, write, execute/search by group; <code>group_read | group_write |
- group_exe</code></td>
+ <td> Read, write, execute/search by group; <code>group_read | group_write | group_exe</code></td>
 </tr>
 <tr><td><code>others_read</code></td><td><code>04</code></td><td> <code>S_IROTH</code></td>
   <td> Read permission, others</td>
@@ -1574,8 +1614,8 @@
   is created without specifying the permissions</td>
 </tr>
 <tr><td>
- <p dir="ltr"><code>add_perms</code></td><td><code>0x1000</code></td><td></td><td>
- <p dir="ltr"><code>permissions()</code> adds the argument permission bits to the
+ <p><code>add_perms</code></td><td><code>0x1000</code></td><td></td><td>
+ <p><code>permissions()</code> adds the argument permission bits to the
   file's current bits</td>
 </tr>
 <tr><td><code>remove_perms</code></td><td><code>0x2000</code></td><td></td><td>
@@ -1615,17 +1655,16 @@
 $NAMESPACE_END;</pre>
 <p>An object of type <code>file_status</code> stores information about the type
 and permissions of a file.</p>
-<h4 dir="ltr"><a name="file_status-constructors"><code>file_status</code> constructors</a></h4>
+<h4><a name="file_status-constructors"><code>file_status</code> constructors</a></h4>
 <pre>explicit file_status() noexcept;</pre>
 <blockquote>
   <p><i>Postconditions:</i> <code>type() == status_error</code>, <code>permissions() == perms_not_known</code>.</p>
 </blockquote>
 <pre>explicit file_status(file_type ft, perms prms = perms_not_known) noexcept;</pre>
 <blockquote>
- <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() ==
- prms</code>.</p>
+ <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() == prms</code>.</p>
 </blockquote>
- <h4 dir="ltr"><a name="file_status-observers"><code>file_status</code> observers</a></h4>
+ <h4><a name="file_status-observers"><code>file_status</code> observers</a></h4>
 <pre>file_type type() const noexcept;</pre>
 <blockquote>
   <p><i>Returns: </i>The value of <code>type()</code> specified by the <i>postconditions</i> of the most recent call to a constructor, operator=, or <code>type(file_type)</code> function.</p>
@@ -1634,17 +1673,17 @@
 <blockquote>
   <p><i>Returns: </i>The value of <code>permissions()</code> specified by the <i>postconditions</i> of the most recent call to a constructor, operator=, or <code>permissions(perms)</code> function.</p>
 </blockquote>
-<h4 dir="ltr"><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4>
+<h4><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4>
 <pre>void type(file_type ft) noexcept;</pre>
 <blockquote>
- <p dir="ltr"><i>Postconditions:</i> <code>type() == ft</code>.</p>
+ <p><i>Postconditions:</i> <code>type() == ft</code>.</p>
 </blockquote>
 <pre>void permissions(perms prms) noexcept;</pre>
 <blockquote>
- <p dir="ltr"><i>Postconditions:</i> <code>permissions() == prms</code>.</p>
+ <p><i>Postconditions:</i> <code>permissions() == prms</code>.</p>
 </blockquote>
 <h3><a name="Class-directory_entry">Class <code>directory_entry</code></a></h3>
-<div dir="ltr">
+<div>
 <pre>$NAMESPACE_BEGIN;
       class directory_entry
       {
@@ -1829,33 +1868,27 @@
 </blockquote>
 <pre>bool operator==(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path ==
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path == rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator!=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path !=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path != rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&lt; (const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &lt;
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &lt; rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&lt;=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &lt;=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &lt;= rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&gt; (const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &gt;
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &gt; rhs.m_path</code>.</p>
 </blockquote>
 <pre>bool operator&gt;=(const directory_entry&amp; rhs);</pre>
 <blockquote>
- <p><i>Returns:</i> <code>m_path &gt;=
- rhs.m_path</code>.</p>
+ <p><i>Returns:</i> <code>m_path &gt;= rhs.m_path</code>.</p>
 </blockquote>
 <h3><a name="Class-directory_iterator">Class <code>directory_iterator</code></a></h3>
 <p>Objects of type <code>directory_iterator</code> provide standard library
@@ -2026,7 +2059,7 @@
 <p><i>Effects:</i>&nbsp; Constructs a iterator representing the first
 entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p>
 
-<p dir="ltr"><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 &amp;&amp; no_push_pending() == false &amp;&amp; m_options == opt</code>.
+<p><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 &amp;&amp; no_push_pending() == false &amp;&amp; m_options == opt</code>.
 For the signature without a <code>symlink_option</code> argument, <code>opt</code> is assumed to be <code>symlink_option::none</code>.</p>
 
 <p><i>Throws:</i> As specified in Error reporting.</p>
@@ -2054,11 +2087,10 @@
 except:</p>
 
 <ul>
- <li dir="ltr">
+ <li>
 
-<p dir="ltr">if <code>!no_push_pending() &amp;&amp; is_directory(this-&gt;status())
-&amp;&amp; (!is_symlink(this-&gt;symlink_status()) || (m_options
-&amp; symlink_option::recurse) != 0)</code> then&nbsp; <code>m_level</code> is incremented and directory <code>(*this)-&gt;path()</code> is recursively iterated into.<br>
+<p>if <code>!no_push_pending() &amp;&amp; is_directory(this-&gt;status())
+&amp;&amp; (!is_symlink(this-&gt;symlink_status()) || (m_options &amp; symlink_option::recurse) != 0)</code> then&nbsp; <code>m_level</code> is incremented and directory <code>(*this)-&gt;path()</code> is recursively iterated into.<br>
 &nbsp;</p>
 
   </li>
@@ -2111,8 +2143,7 @@
     <tr>
       <td align="center"><b><code>p.has_root_name()</code></b></td>
       <td align="center"><code>return p</code></td>
- <td align="center"><code>return p.root_name() /
- absolute(base).root_directory()<br>
+ <td align="center"><code>return p.root_name() / absolute(base).root_directory()<br>
       / absolute(base).relative_path() / p.relative_path()</code></td>
     </tr>
     <tr>
@@ -2122,7 +2153,7 @@
       <td align="center"><code>return absolute(base) / p</code></td>
     </tr>
   </table>
- <p dir="ltr">[<i>Note:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true. <i>-- end note</i>]</p>
+ <p>[<i>Note:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true. <i>-- end note</i>]</p>
   <p><i>Throws:</i> If <code>base.is_absolute()</code> is true, throws only if
   memory allocation fails.</p>
 </blockquote>
@@ -2174,8 +2205,7 @@
 <pre>void copy_file(const path&amp; from, const path&amp; to);
 void copy_file(const path&amp; from, const path&amp; to, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects: </i><code>copy_file(from, to,
- copy_option::fail_if_exists</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
+ <p><i>Effects: </i><code>copy_file(from, to, copy_option::fail_if_exists</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
   
   <p><i>Throws:</i> As specified in Error reporting.</p>
   
@@ -2183,15 +2213,13 @@
 <pre>void <a name="copy_file">copy_file</a>(const path&amp; from, const path&amp; to, copy_option option);
 void <a name="copy_file2">copy_file</a>(const path&amp; from, const path&amp; to, copy_option option, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists
- &amp;&amp; exists(to)</code>, an error is reported. Otherwise, the contents and attributes of the file <code>from</code> resolves to are copied to the file <code>to</code> resolves to.</p>
+ <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists &amp;&amp; exists(to)</code>, an error is reported. Otherwise, the contents and attributes of the file <code>from</code> resolves to are copied to the file <code>to</code> resolves to.</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
 </blockquote>
 <pre>void <a name="copy_symlink">copy_symlink</a>(const path&amp; existing_symlink, const path&amp; new_symlink);
 void copy_symlink(const path&amp; existing_symlink, const path&amp; new_symlink, system::error_code&amp; ec);</pre>
 <blockquote>
- <p><i>Effects: </i><code>create_symlink(read_symlink(existing_symlink</code><i>[</i><code>, ec</code><i>]</i><code>),
- new_symlink</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
+ <p><i>Effects: </i><code>create_symlink(read_symlink(existing_symlink</code><i>[</i><code>, ec</code><i>]</i><code>), new_symlink</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
   
   <p><i>Throws:</i> As specified in Error reporting.</p>
   
@@ -2223,7 +2251,7 @@
   Postcondition:</i> <code>new_symlink</code> resolves to a symbolic link file that
   contains an unspecified representation of <code>to</code>.</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
- <p dir="ltr">[<i>Note:</i> Some operating systems, such as Windows, require symlink creation to
+ <p>[<i>Note:</i> Some operating systems, such as Windows, require symlink creation to
   identify that the link is to a directory. Portable code should use <code>create_directory_symlink()</code> to create directory symlinks rather than <code>create_symlink()</code> <i>-- end note</i>]</p>
   <p>[<i>Note:</i> Some operating systems do not support symbolic links at all or support
   them only for regular files.
@@ -2319,7 +2347,7 @@
   <p><i>Throws:</i> <code>filesystem_error</code> if <code>(!exists(s1) &amp;&amp; !exists(s2)) || (is_other(s1) &amp;&amp; is_other(s2))</code>,
   otherwise as specified in Error reporting.</p>
 </blockquote>
-<div dir="ltr">
+<div>
 <pre>uintmax_t <a name="file_size">file_size</a>(const path&amp; p);
 uintmax_t <a name="file_size2">file_size</a>(const path&amp; p, system::error_code&amp; ec);</pre>
 </div>
@@ -2357,7 +2385,7 @@
 <pre><code>bool <a name="is_directory2">is_directory</a>(const path&amp; p);
 bool <a name="is_directory3">is_directory</a>(const path&amp; p, system::error_code&amp; ec) noexcept;</code></pre>
 <blockquote>
- <p dir="ltr"><i>Returns:</i> <code>is_directory(status(p))</code> or <code>is_directory(status(p, ec))</code>,
+ <p><i>Returns:</i> <code>is_directory(status(p))</code> or <code>is_directory(status(p, ec))</code>,
   respectively.</p>
 <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&amp;</code> throws
 nothing.</p>
@@ -2367,8 +2395,7 @@
 <blockquote>
   <p><i>Effects:</i> Determines <code>file_status s</code>, as if by <code>status(p, ec)</code>.</p>
   <p><i>Returns:</i> <code>is_directory(s)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?
- directory_iterator(p) == directory_iterator()<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ? directory_iterator(p) == directory_iterator()<br>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : file_size(p) == 0;</code></p>
 </blockquote>
 <pre>bool <code><a name="is_regular_file">is_regular_file</a></code>(file_status s) noexcept;</pre>
@@ -2424,16 +2451,15 @@
   <p><i>Effects:</i> Sets the time of last data modification of the file
   resolved to by <code>p</code> to <code>new_time</code>, as if by <i>POSIX</i> <code>stat()</code> followed by <i>POSIX</i> utime().</p>
   <p><i>Throws:</i> As specified in Error reporting.</p>
- <p>[<i>Note:</i> A postcondition of <code>last_write_time(p) ==
- new_time</code> is not specified since it might not hold for file systems
+ <p>[<i>Note:</i> A postcondition of <code>last_write_time(p) == new_time</code> is not specified since it might not hold for file systems
   with coarse time granularity. <i>-- end note</i>]</p>
 </blockquote>
 <pre>void <a name="permissions">permissions</a>(const path&amp; p, perms prms);
 void permissions(const path&amp; p, perms prms, system::error_code&amp; ec);</pre>
 <blockquote>
- <p dir="ltr">
+ <p>
   <i>Requires:</i> <code>!((prms &amp; add_perms) &amp;&amp; (prms &amp; remove_perms))</code>.</p>
- <p dir="ltr"><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> to the file <code>p</code> resolves to, as if by <i>POSIX</i> <code>fchmodat()</code>. The effective permission bits are determined as
+ <p><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> to the file <code>p</code> resolves to, as if by <i>POSIX</i> <code>fchmodat()</code>. The effective permission bits are determined as
   specified by the following table. </p>
   <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
     <tr>
@@ -2447,7 +2473,7 @@
     <tr>
       <td><code>add_perms</code></td>
       <td>
- <p dir="ltr"><code>status(p).permissions() | (prms &amp; perms_mask)</code> </td>
+ <p><code>status(p).permissions() | (prms &amp; perms_mask)</code> </td>
     </tr>
     <tr>
       <td><code>remove_perms</code></td>
@@ -2461,7 +2487,7 @@
 <pre>path <a name="read_symlink">read_symlink</a>(const path&amp; p);
 path read_symlink(const path&amp; p, system::error_code&amp; ec);</pre>
 <blockquote>
- <p dir="ltr"><i>Returns:</i>&nbsp; If <code>p</code> resolves to a symbolic
+ <p><i>Returns:</i>&nbsp; If <code>p</code> resolves to a symbolic
   link, a <code>path</code> object containing the contents of that symbolic
   link. Otherwise an empty <code>path</code> object.</p>
   <p><i>Throws:</i> As specified in Error reporting. [<i>Note:</i> It is an error if <code>p</code> does not

Modified: trunk/libs/filesystem/doc/src/tr2_snippets.html
==============================================================================
--- trunk/libs/filesystem/doc/src/tr2_snippets.html (original)
+++ trunk/libs/filesystem/doc/src/tr2_snippets.html 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -20,7 +20,7 @@
     <tr>
       <td width="153" align="left" valign="top">Date:</td>
       <td width="426">
- <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2012-03-20<!--webbot bot="Timestamp" endspan i-checksum="12168" --></td>
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2012-04-18<!--webbot bot="Timestamp" endspan i-checksum="12247" --></td>
     </tr>
     <tr>
       <td width="153" align="left" valign="top">Project:</td>
@@ -48,7 +48,14 @@
 <h2>Revision history</h2>
 
 
-<p><span style="background-color: #FFFF00">D????=12-????</span></p>
+<p><span style="background-color: #FFFF00">D????=12-???? </span>, Filesystem
+Library Proposal (Revision 3). Changes include:</p>
+
+
+<ul>
+ <li>Add path::operator+= and concat functions to tack on things like suffixes
+ or numbers. Suggested by Ed Smith-Rowland and others.</li>
+</ul>
 
 
 <p>N3365=12-0055, Filesystem Library Proposal (Revision

Modified: trunk/libs/filesystem/test/path_unit_test.cpp
==============================================================================
--- trunk/libs/filesystem/test/path_unit_test.cpp (original)
+++ trunk/libs/filesystem/test/path_unit_test.cpp 2012-04-18 10:46:15 EDT (Wed, 18 Apr 2012)
@@ -343,6 +343,73 @@
     PATH_IS(x, BOOST_FS_FOO L"wstring");
    }
 
+ // test_concats --------------------------------------------------------------------//
+
+ void test_concats()
+ {
+ std::cout << "testing concats..." << std::endl;
+
+ x = "/foo";
+ x += path(""); // empty path
+ PATH_IS(x, L"/foo");
+
+ x = "/foo";
+ x += path("/"); // slash path
+ PATH_IS(x, L"/foo/");
+
+ x = "/foo";
+ x += path("boo"); // slash path
+ PATH_IS(x, L"/fooboo");
+
+ x = "foo";
+ x += x; // self-append
+ PATH_IS(x, L"foofoo");
+
+ x = "foo-";
+ x += path("yet another path"); // another path
+ PATH_IS(x, L"foo-yet another path");
+
+ x = "foo-";
+ x.concat(l.begin(), l.end()); // iterator range char
+ PATH_IS(x, L"foo-string");
+
+ x = "foo-";
+ x.concat(wl.begin(), wl.end()); // iterator range wchar_t
+ PATH_IS(x, L"foo-wstring");
+
+ x = "foo-";
+ x += string("std::string"); // container char
+ PATH_IS(x, L"foo-std::string");
+
+ x = "foo-";
+ x += wstring(L"std::wstring"); // container wchar_t
+ PATH_IS(x, L"foo-std::wstring");
+
+ x = "foo-";
+ x += "array char"; // array char
+ PATH_IS(x, L"foo-array char");
+
+ x = "foo-";
+ x += L"array wchar"; // array wchar_t
+ PATH_IS(x, L"foo-array wchar");
+
+ x = "foo-";
+ x += s.c_str(); // const char* null terminated
+ PATH_IS(x, L"foo-string");
+
+ x = "foo-";
+ x += ws.c_str(); // const wchar_t* null terminated
+ PATH_IS(x, L"foo-wstring");
+
+ x = "foo-";
+ x += 'x'; // char
+ PATH_IS(x, L"foo-x");
+
+ x = "foo-";
+ x += L'x'; // wchar
+ PATH_IS(x, L"foo-x");
+ }
+
   // test_observers ------------------------------------------------------------------//
 
   void test_observers()
@@ -1009,6 +1076,7 @@
   test_constructors();
   test_assignments();
   test_appends();
+ test_concats();
   test_modifiers();
   test_observers();
   test_relationals();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk