diff options
Diffstat (limited to 'libs/filesystem/doc')
22 files changed, 11375 insertions, 0 deletions
diff --git a/libs/filesystem/doc/Jamfile.v2 b/libs/filesystem/doc/Jamfile.v2 new file mode 100644 index 0000000000..4de58f538c --- /dev/null +++ b/libs/filesystem/doc/Jamfile.v2 @@ -0,0 +1,19 @@ +# Boost Filesystem Library Example Jamfile + +# Copyright Beman Dawes 2010 + +# Distributed under the Boost Software License, Version 1.0. +# See www.boost.org/LICENSE_1_0.txt + +# Library home page: http://www.boost.org/libs/filesystem + +project + : requirements + <library>/boost/filesystem//boost_filesystem + <library>/boost/system//boost_system + <toolset>msvc:<asynch-exceptions>on + <link>static + ; + +exe path_table : path_table.cpp ; +install path_table-copy : path_table : <location>. ;
\ No newline at end of file diff --git a/libs/filesystem/doc/POSIX_filename_encoding.txt b/libs/filesystem/doc/POSIX_filename_encoding.txt new file mode 100644 index 0000000000..14c45c07f2 --- /dev/null +++ b/libs/filesystem/doc/POSIX_filename_encoding.txt @@ -0,0 +1,55 @@ +http://www.linuxfromscratch.org/blfs/view/svn/introduction/locale-issues.html + +"The POSIX standard mandates that the filename encoding is the encoding implied by the current LC_CTYPE locale category." + +------- + +http://mail.nl.linux.org/linux-utf8/2001-02/msg00103.html + +From: Markus Kuhn + +Tom Tromey wrote on 2001-02-05 00:36 UTC: +> Kai> IMAO, a *real* filesystem should use some encoding of ISO 10646 - +> Kai> UTF-8, UTF-16, or UTF-32 are all viable options. The same should +> Kai> be true for the kernel filename interfaces. +> +> I like this, but what should I do right now? + +The POSIX kernel file system interface is engraved into stone and +extremely unlikely to change. File names are arbitrary binary strings, +with only the '/' and '\0' bytes having any special semantics. You can +use arbitrary coded character sets on it as long as they do not +introduce '/' and '\0' bytes spuriously. Writers and readers have to +somehow agree on what encoding to use and the only really practical way +is to use the same encoding on all systems that share files. Eventually, +everyone will be using UTF-8 for file names on POSIX systems. Right now, +I would recommend users to use only ASCII for filenames, as this is +already UTF-8 and therefore simplifies migration. Using the ISO 8859, +JIS, etc. filenames should soon be considered deprecated practice. + +> I work on libgcj, the runtime component of gcj, the Java front end to +> GCC. In libgcj of course we use UCS-2 everywhere, since that is what +> Java does. Currently, for Unixy systems, we assume that all file +> names are UTF-8. + +The best solution is to assume that the file names are in the +locale-specific multi-byte encoding. Simply use mbrtowc and wcrtomb to +convert between Unicode and the locale-dependent multi-byte encoding +used in file names and text files if the ISO C 99 symbol +__STDC_ISO_10646__ is defined (which guarantees that wchar_t = UCS). On +Linux, this has been the case since glibc 2.2. + +> (Actually, we do something notably worse, which is +> assume that file names are Java-style UTF-8, with the weird encoding +> for \u0000.) + +\u0000 = NUL was never a character allowed in filenames under POSIX. +Raise an exception if someone tries to use it in a filename. Problem +solved. + +I never understood, why Java found it necessary to introduce two +distinct ASCII NUL characters. + +------ + +Interesting idea. Use iconv to create shift-jis or other mbcs test cases. diff --git a/libs/filesystem/doc/deprecated.html b/libs/filesystem/doc/deprecated.html new file mode 100644 index 0000000000..ed553447e8 --- /dev/null +++ b/libs/filesystem/doc/deprecated.html @@ -0,0 +1,385 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem Deprecated Features</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Deprecated Features</font> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> +</table> + +<h2><a name="Deprecated-names">Deprecated names</a> and features</h2> +<p style="font-size: 10pt">As the library evolves over time, names sometimes +change or old features are removed to make way for new features. To ease transition, Boost.Filesystem deprecates +the old names and features, but by default continues to provide many of them. +The deprecated names and other workarounds can be suppressed by defining macro <code> +BOOST_FILESYSTEM_NO_DEPRECATED</code>, and this is recommended for all new code.</p> +<p style="font-size: 10pt">In the table, ✔ indicates a synonym or other +workaround is provided unless <code> +BOOST_FILESYSTEM_NO_DEPRECATED</code> is defined.</p> +<table border="1" cellpadding="5" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td style="font-size: 10pt" valign="top"> + <b><i>Component or location</i></b></td> + <td style="font-size: 10pt" valign="top"> + <p style="font-size: 10pt"><b><i>Old name, now deprecated</i></b></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <p style="font-size: 10pt"><b><i>New name</i></b></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>branch_path()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>parent_path()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>canonize()</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>default_name_check()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>default_name_check(name_check)</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>default_name_check_writable()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>directory_string()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>string</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>external_directory_string()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>native()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>external_file_string()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>native()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>file_string()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>string()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>has_branch_path()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>has_parent_path()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>has_leaf()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>has_filename()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>is_complere()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>is_absolute()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"><code>class path</code></td> + <td style="font-size: 10pt" valign="top"><code>leaf()</code></td> + <td style="font-size: 10pt" valign="top">✔</td> + <td style="font-size: 10pt" valign="top"><code>filename()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>native_directory_string()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <code>string()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>native_file_string()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <code>string()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>normalize()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>path(const string_type& str, name_check)</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed. Workaround ignores </i><code>name_check</code><i> + argument.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <code>path(const string_type::value_type* s, name_check)</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed. Workaround ignores </i><code>name_check</code><i> + argument.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + <td style="font-size: 10pt" valign="top"> + <p style="font-size: 10pt"><code>remove_leaf()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <p style="font-size: 10pt"><code>remove_filename()</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>path.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>template<class String, class Traits><br> + class basic_path;</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + Class template <code>basic_path</code> is replaced by <code>class path</code>. + No workaround for an explicitly coded <code>basic_path</code> is provided, + but see the next row - <code>path</code>.</td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>path.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>typedef basic_path<std::string, path_traits> path</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <code>class path</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>path.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>typedef basic_path<std::wstring, wpath_traits> wpath</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Removed; use </i><code>class path</code><i> instead. Workaround provides + </i><code>typedef path wpath</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>operations.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>initial_path()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>operations.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <p dir="ltr"><code>template <class Path><br> + Path complete(const Path& p,<br> + const Path& base=<br> + initial_path<Path>())</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <p dir="ltr"><code>path absolute(const path& p, const path& base=<br> + current_path())</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>operations.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>is_regular(file_status f)</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <p dir="ltr"> + <code>is_regular_file(file_status f)</code></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>operations.hpp</code></td> + <td style="font-size: 10pt" valign="top"> + <code>symbolic_link_exists(const path& ph)</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class directory_entry</code></td> + <td style="font-size: 10pt" valign="top"> + <code>filename()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed, use </i><code>path().filename()</code><i> instead.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class directory_entry</code></td> + <td style="font-size: 10pt" valign="top"> + <code>leaf()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed, use </i><code>path().filename()</code><i> instead.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + <code>class directory_entry</code></td> + <td style="font-size: 10pt" valign="top"> + <code>string()</code></td> + <td style="font-size: 10pt" valign="top"> + ✔</td> + <td style="font-size: 10pt" valign="top"> + <i>Function removed, use </i><code>path().string()</code><i> instead.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + Macro definitions</td> + <td style="font-size: 10pt" valign="top"> + <code>BOOST_WINDOW_API</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>No longer supported; API selection is always automatic.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + Macro definitions</td> + <td style="font-size: 10pt" valign="top"> + <code>BOOST_POSIX_API</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>No longer supported; API selection is always automatic.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + Macro definitions</td> + <td style="font-size: 10pt" valign="top"> + <code>BOOST_WINDOW_PATH</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>No longer supported; native path format selection is always automatic.</i></td> + </tr> + <tr> + <td style="font-size: 10pt" valign="top"> + Macro definitions</td> + <td style="font-size: 10pt" valign="top"> + <code>BOOST_POSIX_PATH</code></td> + <td style="font-size: 10pt" valign="top"> + </td> + <td style="font-size: 10pt" valign="top"> + <i>No longer supported; native path format selection is always automatic.</i></td> + </tr> +</table> + +<h2>Deprecation rationale</h2> +<h3><code>initial_path</code> function</h3> +<p dir="ltr">Full implementation of <code>initial_path()</code> would require +support from the C++ runtime startup code, and that doesn't seem likely to +happen. Depending on the user to call <code>initial_path()</code> at the +beginning of <code>main()</code> is too error prone. An equivalent +function can trivially be provided by a user.</p> + +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> + +<p>© Copyright Beman Dawes, 2002-2005, 2010</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"> +www.boost.org/LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/design.htm b/libs/filesystem/doc/design.htm new file mode 100644 index 0000000000..a44b2b23ea --- /dev/null +++ b/libs/filesystem/doc/design.htm @@ -0,0 +1,353 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Boost Filesystem Library Design</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body bgcolor="#FFFFFF"> + +<h1> +<img border="0" src="../../../boost.png" align="center" width="277" height="86">Filesystem +Library Design</h1> + +<p><a href="#Introduction">Introduction</a><br> +<a href="#Requirements">Requirements</a><br> +<a href="#Realities">Realities</a><br> +<a href="#Rationale">Rationale</a><br> +<a href="#Abandoned_Designs">Abandoned_Designs</a><br> +<a href="#References">References</a></p> + +<h2><a name="Introduction">Introduction</a></h2> + +<p>The primary motivation for beginning work on the Filesystem Library was +frustration with Boost administrative tools. Scripts were written in +Python, Perl, Bash, and Windows command languages. There was no single +scripting language familiar and acceptable to all Boost administrators. Yet they +were all skilled C++ programmers - why couldn't C++ be used as the scripting +language?</p> + +<p>The key feature C++ lacked for script-like applications was the ability to +perform portable filesystem operations on directories and their contents. The +Filesystem Library was developed to fill that void.</p> + +<p>The intent is not to compete with traditional scripting languages, but to +provide a solution for situations where C++ is already the language +of choice..</p> + +<h2><a name="Requirements">Requirements</a></h2> +<ul> + <li>Be able to write portable script-style filesystem operations in modern + C++.<br> + <br> + Rationale: This is a common programming need. It is both an + embarrassment and a hardship that this is not possible with either the current + C++ or Boost libraries. The need is particularly acute + when C++ is the only toolset allowed in the tool chain. File system + operations are provided by many languages used on multiple platforms, + such as Perl and Python, as well as by many platform specific scripting + languages. All operating systems provide some form of API for filesystem + operations, and the POSIX bindings are increasingly available even on + operating systems not normally associated with POSIX, such as the Mac, z/OS, + or OS/390.<br> + </li> + <li>Work within the <a href="#Realities">realities</a> described below.<br> + <br> + Rationale: This isn't a research project. The need is for something that works on + today's platforms, including some of the embedded operating systems + with limited file systems. Because of the emphasis on portability, such a + library would be much more useful if standardized. That means being able to + work with a much wider range of platforms that just Unix or Windows and their + clones.<br> + </li> + <li>Avoid dangerous programming practices. Particularly, all-too-easy-to-ignore error notifications + and use of global variables. If a dangerous feature is provided, identify it as such.<br> + <br> + Rationale: Normally this would be covered by "the usual Boost requirements...", + but it is mentioned explicitly because the equivalent native platform and + scripting language interfaces often depend on all-too-easy-to-ignore error + notifications and global variables like "current + working directory".<br> + </li> + <li>Structure the library so that it is still useful even if some functionality + does not map well onto a given platform or directory tree. Particularly, much + useful functionality should be portable even to flat +(non-hierarchical) filesystems.<br> + <br> + Rationale: Much functionality which does not + require a hierarchical directory structure is still useful on flat-structure + filesystems. There are many systems, particularly embedded systems, + where even very limited functionality is still useful.</li> +</ul> +<ul> + <li>Interface smoothly with current C++ Standard Library input/output + facilities. For example, paths should be + easy to use in std::basic_fstream constructors.<br> + <br> + Rationale: One of the most common uses of file system functionality is to + manipulate paths for eventual use in input/output operations. + Thus the need to interface smoothly with standard library I/O.<br> + </li> + <li>Suitable for eventual standardization. The implication of this requirement + is that the interface be close to minimal, and that great care be take + regarding portability.<br> + <br> + Rationale: The lack of file system operations is a serious hole + in the current standard, with no other known candidates to fill that hole. + Libraries with elaborate interfaces and difficult to port specifications are much less likely to be accepted for + standardization.<br> + </li> + <li>The usual Boost <a href="http://www.boost.org/more/lib_guide.htm">requirements and + guidelines</a> apply.<br> + </li> + <li>Encourage, but do not require, portability in path names.<br> + <br> + Rationale: For paths which originate from user input it is unreasonable to + require portable path syntax.<br> + </li> + <li>Avoid giving the illusion of portability where portability in fact does not + exist.<br> + <br> + Rationale: Leaving important behavior unspecified or "implementation defined" does a + great disservice to programmers using a library because it makes it appear + that code relying on the behavior is portable, when in fact there is nothing + portable about it. The only case where such under-specification is acceptable is when both users and implementors know from + other sources exactly what behavior is required, yet for some reason it isn't + possible to specify it exactly.</li> +</ul> +<h2><a name="Realities">Realities</a></h2> +<ul> + <li>Some operating systems have a single directory tree root, others have + multiple roots.<br> + </li> + <li>Some file systems provide both a long and short form of filenames.<br> + </li> + <li>Some file systems have different syntax for file paths and directory + paths.<br> + </li> + <li>Some file systems have different rules for valid file names and valid + directory names.<br> + </li> + <li>Some file systems (ISO-9660, level 1, for example) use very restricted + (so-called 8.3) file names.<br> + </li> + <li>Some operating systems allow file systems with different + characteristics to be "mounted" within a directory tree. Thus a + ISO-9660 or Windows + file system may end up as a sub-tree of a POSIX directory tree.<br> + </li> + <li>Wide-character versions of directory and file operations are available on some operating + systems, and not available on others.<br> + </li> + <li>There is no law that says directory hierarchies have to be specified in + terms of left-to-right decent from the root.<br> + </li> + <li>Some file systems have a concept of file "version number" or "generation + number". Some don't.<br> + </li> + <li>Not all operating systems use single character separators in path names. Some use + paired notations. A typical fully-specified OpenVMS filename + might look something like this:<br> + <br> + <code> DISK$SCRATCH:[GEORGE.PROJECT1.DAT]BIG_DATA_FILE.NTP;5<br> + </code><br> + The general OpenVMS format is:<br> + <br> + + <i>Device:[directories.dot.separated]filename.extension;version_number</i><br> + </li> + <li>For common file systems, determining if two descriptors are for same + entity is extremely difficult or impossible. For example, the concept of + equality can be different for each portion of a path - some portions may be + case or locale sensitive, others not. Case sensitivity is a property of the + pathname itself, and not the platform. Determining collating sequence is even + worse.<br> + </li> + <li>Race-conditions may occur. Directory trees, directories, files, and file attributes are in effect shared between all threads, processes, and computers which have access to the + filesystem. That may well include computers on the other side of the + world or in orbit around the world. This implies that file system operations + may fail in unexpected ways. For example:<br> + <br> + <code> assert( exists("foo") == exists("foo") ); + // may fail!<br> + assert( is_directory("foo") == is_directory("foo"); + // may fail!<br> + </code><br> + In the first example, the file may have been deleted between calls to + exists(). In the second example, the file may have been deleted and then + replaced by a directory of the same name between the calls to is_directory().<br> + </li> + <li>Even though an application may be portable, it still will have to traffic + in system specific paths occasionally; user provided input is a common + example.<br> + </li> + <li><a name="symbolic-link-use-case">Symbolic</a> links cause canonical and + normal form of some paths to represent different files or directories. For + example, given the directory hierarchy <code>/a/b/c</code>, with a symbolic + link in <code>/a</code> named <code>x</code> pointing to <code>b/c</code>, + then under POSIX Pathname Resolution rules a path of <code>"/a/x/.."</code> + should resolve to <code>"/a/b"</code>. If <code>"/a/x/.."</code> were first + normalized to <code>"/a"</code>, it would resolve incorrectly. (Case supplied + by Walter Landry.)</li> +</ul> + +<h2><a name="Rationale">Rationale</a></h2> + +<p>The <a href="#Requirements">Requirements</a> and <a href="#Realities"> +Realities</a> above drove much of the C++ interface design. In particular, +the desire to make script-like code straightforward caused a great deal of +effort to go into ensuring that apparently simple expressions like <i>exists( "foo" +)</i> work as expected.</p> + +<p>See the <a href="faq.htm">FAQ</a> for the rationale behind many detailed +design decisions.</p> + +<p>Several key insights went into the <i>path</i> class design:</p> +<ul> + <li>Decoupling of the input formats, internal conceptual (<i>vector<string></i> + or other sequence) + model, and output formats.</li> + <li>Providing two input formats (generic and O/S specific) broke a major + design deadlock.</li> + <li>Providing several output formats solved another set of previously + intractable problems.</li> + <li>Several non-obvious functions (particularly decomposition and composition) + are required to support portable code. (Peter Dimov, Thomas Witt, Glen + Knowles, others.)</li> +</ul> + +<p>Error checking was a particularly difficult area. One key insight was that +with file and directory names, portability isn't a universal truth. +Rather, the programmer must think out the question "What operating systems do I +want this path to be portable to?" By providing support for several +answers to that question, the Filesystem Library alerts programmers of the need +to ask it in the first place.</p> +<h2><a name="Abandoned_Designs">Abandoned Designs</a></h2> +<h3>operations.hpp</h3> +<p>Dietmar Kühl's original dir_it design and implementation supported +wide-character file and directory names. It was abandoned after extensive +discussions among Library Working Group members failed to identify portable +semantics for wide-character names on systems not providing native support. See +<a href="faq.htm#wide-character_names">FAQ</a>.</p> +<p>Previous iterations of the interface design used explicitly named functions providing a +large number of convenience operations, with no compile-time or run-time +options. There were so many function names that they were very confusing to use, +and the interface was much larger. Any benefits seemed theoretical rather than +real. </p> +<p>Designs based on compile time (rather than runtime) flag and option selection +(via policy, enum, or int template parameters) became so complicated that they +were abandoned, often after investing quite a bit of time and effort. The need +to qualify attribute or option names with namespaces, even aliases, made use in +template parameters ugly; that wasn't fully appreciated until actually writing +real code.</p> +<p>Yet another set of convenience functions ( for example, <i>remove</i> with +permissive, prune, recurse, and other options, plus predicate, and possibly +other, filtering features) were abandoned because the details became both +complex and contentious.</p> + +<p>What is left is a toolkit of low-level operations from which the user can +create more complex convenience operations, plus a very small number of +convenience functions which were found to be useful enough to justify inclusion.</p> + +<h3>path.hpp</h3> + +<p>There were so many abandoned path designs, I've lost track. Policy-based +class templates in several flavors, constructor supplied runtime policies, +operation specific runtime policies, they were all considered, often +implemented, and ultimately abandoned as far too complicated for any small +benefits observed.</p> + +<p>Additional design considerations apply to <a href="v3_design.html">Internationalization</a>. </p> + +<h3>error checking</h3> + +<p>A number of designs for the error checking machinery were abandoned, some +after experiments with implementations. Totally automatic error checking was +attempted in particular. But automatic error checking tended to make the overall +library design much more complicated.</p> + +<p>Some designs associated error checking mechanisms with paths. Some with +operations functions. A policy-based error checking template design was +partially implemented, then abandoned as too complicated for everyday +script-like programs.</p> + +<p>The final design, which depends partially on explicit error checking function +calls, is much simpler and straightforward, although it does depend to +some extent on programmer discipline. But it should allow programmers who +are concerned about portability to be reasonably sure that their programs will +work correctly on their choice of target systems.</p> + +<h2><a name="References">References</a></h2> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="13%" valign="top">[<a name="IBM-01">IBM-01</a>]</td> + <td width="87%">IBM Corporation, <i>z/OS V1R3.0 C/C++ Run-Time +Library Reference</i>, SA22-7821-02, 2001, +<a href="http://www-1.ibm.com/servers/eserver/zseries/zos/bkserv/"> + www-1.ibm.com/servers/eserver/zseries/zos/bkserv/</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="ISO-9660">ISO-9660</a>]</td> + <td width="87%">International Standards Organization, 1988</td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="Kuhn">Kuhn</a>]</td> + <td width="87%">UTF-8 and Unicode FAQ for Unix/Linux, +<a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html"> + www.cl.cam.ac.uk/~mgk25/unicode.html</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="MSDN">MSDN</a>] </td> + <td width="87%">Microsoft Platform SDK for Windows, Storage Start +Page, +<a href="http://msdn.microsoft.com/library/en-us/fileio/base/storage_start_page.asp"> + msdn.microsoft.com/library/en-us/fileio/base/storage_start_page.asp</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="POSIX-01">POSIX-01</a>]</td> + <td width="87%">IEEE Std 1003.1-2001, ISO/IEC 9945:2002, and The Open Group 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 in its creation. For + example, read online or download from + <a href="http://www.unix.org/single_unix_specification/"> + www.unix.org/single_unix_specification/</a>.</font> The ISO JTC1/SC22/WG15 - POSIX +homepage is <a href="http://www.open-std.org/jtc1/sc22/WG15/"> + www.open-std.org/jtc1/sc22/WG15/</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="URI">URI</a>]</td> + <td width="87%">RFC-2396, Uniform Resource Identifiers (URI): Generic +Syntax, <a href="http://www.ietf.org/rfc/rfc2396.txt"> + www.ietf.org/rfc/rfc2396.txt</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="UTF-16">UTF-16</a>]</td> + <td width="87%">Wikipedia, UTF-16, +<a href="http://en.wikipedia.org/wiki/UTF-16"> + en.wikipedia.org/wiki/UTF-16</a></td> + </tr> + <tr> + <td width="13%" valign="top">[<a name="Wulf-Shaw-73">Wulf-Shaw-73</a>]</td> + <td width="87%">William Wulf, Mary Shaw, <i>Global +Variable Considered Harmful</i>, ACM SIGPLAN Notices, 8, 2, 1973, pp. 23-34</td> + </tr> +</table> + +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> + +<p>© Copyright Beman Dawes, 2002</p> +<p> Use, modification, and distribution are subject to the Boost Software +License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> +LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> +www.boost.org/LICENSE_1_0.txt</a>)</p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/do_list.html b/libs/filesystem/doc/do_list.html new file mode 100644 index 0000000000..6558803279 --- /dev/null +++ b/libs/filesystem/doc/do_list.html @@ -0,0 +1,146 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Do List</title> +<style type="text/css"> + body { font-family: sans-serif; margin: 1em; } + p, td, li, blockquote { font-size: 10pt; } + pre { font-size: 9pt; } +</style> +</head> + +<body> + +<h1>Boost Filesystem Do List<br> +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->24 June 2010<!--webbot bot="Timestamp" endspan i-checksum="17552" --></h1> + +<h2>Beta 1 comments</h2> +<ul> + <li dir="ltr"> + +<p dir="ltr">Zach Laine:</li> +</ul> +<blockquote> + <pre dir="ltr">The descriptions for portable_name() and portable_directory_name() +appear to be at odds. + +portable_name() : ... && (name is "." or "..", and the first character +not a period or hyphen) + +portable_directory_name(): ... && (name is "." or ".." or contains no periods) + +Should portable_name() be "... && (name is "." or "..", or contains no +periods) && (first character not a hyphen)"? Maybe I'm missing +something?</pre> +</blockquote> +<ul> + <li dir="ltr"> +<p dir="ltr">Scott McMurray - treat as Wish List:</li> +</ul> +<blockquote> + <pre dir="ltr">- uncomplete(p, base) + +My pet request. It may be useful to simplify other functions as well, +since there's no current way to go from an absolute path to a relative +one, meaning that most functions need to handle relative ones even +when that might not be natural. With this functionality, +preconditions requiring absolute paths would be less onerous. + + Precondition: p.is_absolute() && base.is_absolute() + + Effects: Extracts a path, rp, from p relative to base such that +canonical(p) == complete(rp, base). Any ".." path elements in rp form +a prefix. + + Returns: The extracted path. + + Postconditions: For the returned path, rp, rp.is_relative() == +(p.root_name() == b.root_name()). + +[Notes: This function simplifies paths by omitting context. It is +particularly useful for serializing paths such that it can be usefully +moved between hosts where the context may be different, such as inside +source control trees. It can also be helpful for display to users, +such as in shells where paths are often shown relative to $HOME. + +In the presence of symlinks, the result of this function may differ +between implementations, as some may expand symlinks that others may +not. The simplest implementation uses canonical to expand both p and +base, then removes the common prefix and prepends the requisite ".." +elements. Smarter implementations will avoid expanding symlinks +unnecessarily. No implementation is expected to discover new symlinks +to return paths with fewer elements.]</pre> +</blockquote> +<h2 dir="ltr">Docs</h2> +<ul> + <li>Reorganize files - delete examples that no longer apply.</li> + <li>Should minimal.css be changed to used relative font sizes? See + <a href="http://www.w3schools.com/CSS/pr_font_font-size.asp/">http://www.w3schools.com/CSS/pr_font_font-size.asp\</a></li> + <li>Document behavior of path::replace_extension has change WRT argument w/o a + dot.</li> + <li style="font-size: 10pt">Document leading //: no longer treated specially. + But is that really correct?</li> + <li style="font-size: 10pt">Behavior of root_path() has been changed. Change + needs to be propagated to trunk?</li> + <li style="font-size: 10pt">Regenerate path decomposition table.</li> +</ul> + +<h2>Code</h2> +<h3>All</h3> +<ul> + <li style="font-size: 10pt">Move semantics.</li> + <li style="font-size: 10pt">Use BOOST_DELETED, BOOST_DEFAULTED, where + appropriate.</li> + <li style="font-size: 10pt">Other C++0x features.</li> +</ul> +<h3>Class path</h3> +<ul> + <li>Windows, POSIX, conversions for char16_t, char32_t for C++0x compilers.</li> + <li>Add Windows Alternate Data Stream test cases. See http://en.wikipedia.org/wiki/NTFS + Features.</li> + <li>Add test case: relational operators on paths differing only in trailing + separator. Rationale?</li> + <li>Provide the name check functions for more character types? Templatize? + take a path argument?</li> + <li style="font-size: 10pt">Add codepage 936/950/etc test cases.</li> + <li style="font-size: 10pt">Should UDT's be supported?</li> + <li style="font-size: 10pt">Should path iteration to a separator result in:<br> + -- the actual separator used<br> + -- the preferred separator<br> + -- the generic separator <-- makes it easier to write portable code<br> + -- a dot</li> +</ul> +<h3>Operations</h3> +<ul> + <li>Would complete(), system_complete() be clearer if renamed absolute(), + absolute_system() (or absolute_native())?</li> + <li>Review all operations.cpp code for race conditions similar to #2925. Fix + or document.</li> + <li>Enable all BOOST_FILESYSTEM_NO_DEPRECATED code.</li> + <li>rename and remove names are problems. If users says "using + namespace boost::filesystem"<br> + and some header included stdio, there is just too much chance of silent error.</li> + <li>create_directories error handling needs work.</li> + <li>Fold convenience.hpp into operations.hpp</li> + <li>Two argument recursive_directory_iterator ctor isn't recognizing throws(). + Would it be better to fold into a single two argument ctor with default?</li> + <li>Add the push_directory class from tools/release/required_files.cpp</li> +</ul> + +<h3>Miscellaneous</h3> +<ul> + <li style="font-size: 10pt"><i>Regular</i> classes need hash functions.</li> +</ul> + +<hr> +<p>© Copyright Beman Dawes, 2010</p> +<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> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/faq.htm b/libs/filesystem/doc/faq.htm new file mode 100644 index 0000000000..85b64dc0ea --- /dev/null +++ b/libs/filesystem/doc/faq.htm @@ -0,0 +1,147 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem FAQ</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem FAQ</font> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<h1 dir="ltr"> +Frequently Asked Questions</h1> +<h2>General questions</h2> +<p><b>Why not support a concept of specific kinds of file systems, such as posix_file_system or windows_file_system.</b></p> +<p>Portability is one of the most important requirements for the +library. Features specific to a particular operating system or file system +can always be accessed by using the operating system's API.</p> + +<h2 dir="ltr"> +Class <code><font size="6">path</font></code> questions </h2> +<p><b>Why base the generic pathname format on POSIX?</b></p> +<p><a href="design.htm#POSIX-01">POSIX</a> is an ISO Standard. It is the basis for the most familiar +pathname formats, +not just for POSIX-based operating systems but also for Windows and the +URL portion of URI's. It is ubiquitous and +familiar. On many systems, it is very easy to implement because it is +either the native operating system format (Unix and Windows) or via a +operating system supplied +POSIX library (z/OS, OS/390, and many more.)</p> +<p><b>Why not use a full URI (Universal Resource Identifier) based path?</b></p> +<p><a href="design.htm#URI">URI's</a> would promise more than the Filesystem Library can actually deliver, +since URI's extend far beyond what most operating systems consider a file or a +directory. Thus for the primary "portable script-style file system +operations" requirement of the Filesystem Library, full URI's appear to be over-specification.</p> +<p><b>Why isn't <i>path</i> a base class with derived <i>directory_path</i> and +<i>file_path</i> classes?</b></p> +<p>Why bother? The behavior of all three classes is essentially identical. +Several early versions did require users to identify each path as a file or +directory path, and this seemed to increase coding errors and decrease code +readability. There was no apparent upside benefit.</p> +<p><b>Why do path decomposition functions yielding a single element return a +path rather than a string?</b></p> +<p>Interface simplicity. If they returned strings, flavors would be needed for +<code>string</code>, <code>wstring</code>, <code>u16string</code>, <code> +u32string</code>, and generic strings.</p> +<p><b>Why don't path member functions have overloads with error_code& arguments?</b></p> +<p>They have not been requested by users; the need for error reporting via +error_code seems limited to operations failures rather than path failures.</p> +<h2>Operations function questions</h2> +<p><b>Why not supply a 'handle' type, and let the file and directory operations +traffic in it?</b></p> +<p>It isn't clear there is any feasible way to meet the "portable script-style +file system operations" requirement with such a system. File systems exist where operations are usually performed on + some non-string handle type. The classic Mac OS has been mentioned explicitly as a case where +trafficking in paths isn't always natural. </p> +<p>The case for the "handle" (opaque data type to identify a file) +style may be strongest for directory iterator value type. (See Jesse Jones' Jan 28, +2002, Boost postings). However, as class path has evolved, it seems sufficient +even as the directory iterator value type.</p> +<p><b>Why are the operations functions so low-level?</b></p> +<p>To provide a toolkit from which higher-level functionality can be created.</p> +<p>An +extended attempt to add convenience functions on top of, or as a replacement +for, the low-level functionality failed because there is no widely acceptable +set of simple semantics for most convenience functions considered. +Attempts to provide alternate semantics via either run-time options or +compile-time polices became overly complicated in relation to the value +delivered, or became contentious. OTOH, the specific functionality needed for several trial +applications was very easy for the user to construct from the lower-level +toolkit functions. See <a href="design.htm#Abandoned_Designs">Failed +Attempts</a>.</p> +<p><b>Isn't it inconsistent then to provide a few convenience functions?</b></p> +<p>Yes, but experience with both this library, POSIX, and Windows, indicates +the utility of certain convenience functions, and that it is possible to provide +simple, yet widely acceptable, semantics for them. For example, <code>remove_all()</code>.</p> +<p><b>Why are there directory_iterator overloads for operations.hpp +predicate functions? Isn't two ways to do the same thing poor design?</b></p> +<p>Yes, two ways to do the same thing is often a poor design practice. But the +iterator versions are often much more efficient. Calling status() during +iteration over a directory containing 15,000 files took 6 seconds for the path +overload, and 1 second for the iterator overload, for tests on a freshly booted +machine. Times were .90 seconds and .30 seconds, for tests after prior use of +the directory. This performance gain is large enough to justify deviating from +preferred design practices. Neither overload alone meets all needs.</p> +<p><b>Why are the operations functions so picky about errors?</b></p> +<p>Safety. The default is to be safe rather than sorry. This is particularly +important given the reality that on many computer systems files and directories +are globally shared resources, and thus subject to +race conditions.</p> +<p><b>Why are attributes accessed via named functions rather than property maps?</b></p> +<p>For commonly used attributes (existence, directory or file, emptiness), +simple syntax and guaranteed presence outweigh other considerations. Because +access to many other attributes is inherently system dependent, +property maps are viewed as the best hope for access and modification, but it is +better design to provide such functionality in a separate library. (Historical +note: even the apparently simple attribute "read-only" turned out to be so +system depend as to be disqualified as a "guaranteed presence" operation.)</p> +<p><b>Why isn't automatic name portability error detection provided?</b></p> +<p>A number (at least six) of designs for name validity error +detection were evaluated, including at least four complete implementations. +While the details for rejection differed, all of the more powerful name validity checking +designs distorted other +otherwise simple aspects of the library. Even the simple name checking provided +in prior library versions was a constant source of user complaints. While name checking can be helpful, it +isn't important enough to justify added a lot of additional complexity.</p> +<p><b>Why are paths sometimes manipulated by member functions and sometimes by +non-member functions?</b></p> +<p>The design rule is that purely lexical operations are supplied as <i>class +path</i> member +functions, while operations performed by the operating system are provided as +free functions.</p> +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> +<p>© Copyright Beman Dawes, 2002</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"> +www.boost.org/LICENSE_1_0.txt</a></p>
\ No newline at end of file diff --git a/libs/filesystem/doc/index.htm b/libs/filesystem/doc/index.htm new file mode 100644 index 0000000000..acfad58844 --- /dev/null +++ b/libs/filesystem/doc/index.htm @@ -0,0 +1,463 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem Home</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Library<br> + Version 3</font> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> + <a href="#Introduction">Introduction</a><br> + <a href="#Documentation">Documentation</a><br> + <a href="#Using">Using the library</a><br> + <a href="#Coding-guidelines">Coding guidelines</a><br> + <a href="#Cautions">Cautions</a><br> + <a href="#Headers">Headers</a><br> + <a href="#Examples">Example programs</a><br> + <a href="#Implementation">Implementation</a><br> + <a href="#Macros">Macros</a><br> + <a href="#Building">Building the object-library</a><br> + <a href="#Cgywin">Notes for Cygwin users</a><br> + <a href="#Change-history">Version history<br> + with acknowledgements</a></td> + </tr> + </table> + +<div align="center"> + <center> + <table border="1" cellpadding="10" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td> + <p align="left">This is Version 3 of the Filesystem library. Version 2 is + not longer supported. 1.49.0 was the last release of Boost to supply + Version 2</p> + </td> + </tr> + </table> + </center> +</div> + +<h2><a name="Introduction">Introduction</a></h2> +<p>The Boost.Filesystem library provides facilities to manipulate files and directories, +and the paths that identify them.</p> + +<p>The features of the library include:</p> + +<ul> + <li><b>A modern C++ interface, highly compatible with the C++ standard + library.</b></li> +</ul> +<blockquote> + <blockquote> + +<p>Many users say the interface is their primary motivation for using +Boost.Filesystem. They like its use of familiar idioms based on standard library +containers, iterators, and algorithms. They like having errors reported by +throwing exceptions.</p> + + </blockquote> +</blockquote> +<ul> + <li><b>Portability between operating systems.</b><br> + <ul> + <li>At the C++ syntax level, it is convenient to learn and use one interface + regardless of the operating system.</li> + <li>At the semantic level, behavior of code is reasonably portable across + operating systems.</li> + <li>Dual generic or native path format support encourages program + portability, yet still allows communication with users in system specific + formats.<br> + </li> + </ul> + </li> + <li><b>Error handling and reporting via C++ exceptions (the default) or error + codes.</b><br> + <ul> + <li>C++ exceptions are the preferred error reporting mechanism for most + applications. The exception thrown includes the detailed error code + information important for diagnosing the exact cause of file system errors.</li> + <li>Error reporting via error code allows user code that provides detailed + error recovery to avoid becoming so littered with try-catch blocks as to be + unmaintainable. <br> + </li> + </ul> + </li> + <li><b>Suitable for a broad spectrum of applications, ranging from simple + script-like operations to extremely complex production code.</b><br> + <ul> + <li>At the simple script-like end of the spectrum, the intent is not to + compete with Python, Perl, or shell languages, but rather to provide + filesystem operations when C++ is already the language of choice.</li> + <li>Finer grained control over operations and error handling is available to + support more complex applications or other cases where throwing exceptions + isn't desired.</li> + </ul> + </li> +</ul> + +<p>A proposal, +<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html"> +N1975</a>, to include Boost.Filesystem in Technical Report 2 has been accepted +by the C++ Standards Committee. That proposal was based on version 2 of +Boost.Filesystem; presumably the final TR2 form will be based on version 3.</p> + +<h2><a name="Documentation">Documentation</a></h2> + +<p><b><a href="tutorial.html">Tutorial</a></b> - A gentle introduction to +the library, with example programs provided for you to experiment with.</p> + +<p><b><a href="reference.html">Reference</a></b> - Formal documentation in the +style of the C++ standard for +every component of the library.</p> + +<p><b><a href="faq.htm">FAQ</a></b> - Frequently asked questions.</p> + +<p><b><a href="portability_guide.htm">Portability Guide</a></b> - Help for those +concerned with writing code to run on multiple operating systems.</p> + +<p><b><a href="deprecated.html">Deprecated Features</a></b> - Identifies +deprecated features and their replacements.</p> + +<p><b><a href="v3.html">Version 3 Introduction</a></b> - Aimed at users of prior +Boost.Filesystem versions.</p> + +<p><b><a href="v3_design.html">Version 3 Design</a></b> - Historical document +from the start of the Version 3 design process.</p> + +<p><b><a href="design.htm">Original Design</a></b> - Historical document from +the start of the Version 1 design process.</p> + +<p><b><a href="do_list.html">Do List</a></b> - Boost.Filesystem development work +in the pipeline.</p> + +<h2><a name="Using">Using</a> the library</h2> +<p>Boost.Filesystem is implemented as a separately compiled library, so you must install +binaries in a location that can be found by your linker. If you followed the +<a href="http://www.boost.org/doc/libs/release/more/getting_started/index.html">Boost Getting Started</a> instructions, that's already been done for you.</p> +<h2><a name="Coding-guidelines">Coding guidelines</a></h2> +<p>For new code, defining <code>BOOST_FILESYSTEM_NO_DEPRECATED</code> before +including filesystem headers is strongly recommended. This prevents inadvertent +use of old features, particularly legacy function names, that have been replaced +and are going to go away in the future.</p> +<h2><a name="Cautions">Cautions</a></h2> +<p>After reading the tutorial you can dive right into simple, +script-like programs using the Filesystem Library! Before doing any serious +work, however, there a few cautions to be aware of:</p> +<h4><b>Effects and Postconditions not guaranteed in the presence of race-conditions</b></h4> +<p>Filesystem function specifications follow the C++ Standard Library form, specifying behavior in terms of +effects and postconditions. If +a <a href="reference.html#Race-condition">race-condition</a> exists, a function's +postconditions may no longer be true by the time the function returns to the +caller.</p> +<blockquote> +<p><b><i>Explanation: </i></b>The state of files and directories is often +globally shared, and thus may be changed unexpectedly by other threads, +processes, or even other computers having network access to the filesystem. As an +example of the difficulties this can cause, note that the following asserts +may fail:</p> +<blockquote> +<p><code>assert( exists( "foo" ) == exists( "foo" ) ); // +(1)<br> +<br> +remove_all( "foo" );<br> +assert( !exists( "foo" ) ); // (2)<br> +<br> +assert( is_directory( "foo" ) == is_directory( "foo" ) ); // +(3)</code></p> +</blockquote> +<p>(1) will fail if a non-existent "foo" comes into existence, or an +existent "foo" is removed, between the first and second call to <i>exists()</i>. +This could happen if, during the execution of the example code, another thread, +process, or computer is also performing operations in the same directory.</p> +<p>(2) will fail if between the call to <i>remove_all()</i> and the call to +<i>exists()</i> a new file or directory named "foo" is created by another +thread, process, or computer.</p> +<p>(3) will fail if another thread, process, or computer removes an +existing file "foo" and then creates a directory named "foo", between the +example code's two calls to <i>is_directory()</i>.</p> +</blockquote> +<h4><b>May throw exceptions</b></h4> +<p>Unless otherwise specified, Boost.Filesystem functions throw <i> +<a href="reference.html#basic_filesystem_error-constructors">basic_filesystem_error</a></i> +exceptions if they cannot successfully complete their operational +specifications. Also, implementations may use C++ Standard Library functions, +which may throw <i>std::bad_alloc</i>. These exceptions may be thrown even +though the error condition leading to the exception is not explicitly specified +in the function's "Throws" paragraph.</p> +<p>All exceptions thrown by the Filesystem +Library are implemented by calling <a href="../../utility/throw_exception.html"> +boost::throw_exception()</a>. Thus exact behavior may differ depending on +BOOST_NO_EXCEPTIONS at the time the filesystem source files are compiled.</p> +<p>Non-throwing versions are provided of several functions that are often used +in contexts where error codes may be the preferred way to report an error.</p> + +<h2><a name="Headers">Headers</a></h2> + +<p>The Boost.Filesystem library provides several headers:</p> + +<ul> + <li>Header <<a href="../../../boost/filesystem.hpp">boost/filesystem.hpp</a>> + provides access to all features of the library, except file streams.<br> + </li> + <li>Header <<a href="../../../boost/filesystem/fstream.hpp">boost/filesystem<i>/</i>fstream.hpp</a>> + inherits the same components as the C++ Standard + Library's <i>fstream</i> header, but files are identified by <code>const path&</code> + arguments rather that <code>const char*</code> arguments.</li> +</ul> +<h2><a name="Examples">Example programs</a></h2> +<p>See the <a href="tutorial.html">tutorial</a> for example programs.</p> +<h3>Other examples</h3> +<p>The programs used to generate the Boost regression test status tables use the +Filesystem Library extensively. See:</p> +<ul> + <li><a href="../../../tools/regression/src/process_jam_log.cpp">process_jam_log.cpp</a></li> + <li><a href="../../../tools/regression/src/compiler_status.cpp">compiler_status.cpp</a></li> +</ul> +<h2><a name="Implementation">Implementation</a></h2> +<p>The current implementation supports operating systems which provide +the POSIX or Windows API's.</p> +<p>The library is in regular use on Apple OS X, HP-UX, IBM AIX, Linux, +Microsoft Windows, SGI IRIX, and Sun Solaris operating systems using a variety +of compilers.</p> +<h2><a name="Macros">Macros</a></h2> +<p>Users may defined the following macros if desired. Sensible defaults are +provided, so users can ignore these macros unless they have special needs.</p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b><i>Macro Name</i></b></td> + <td><b><i>Default</i></b></td> + <td><b><i>Effect if defined</i></b></td> + </tr> + <tr> + <td valign="top"><code>BOOST_FILESYSTEM_NO_DEPRECATED</code></td> + <td valign="top">Not defined.</td> + <td valign="top">Deprecated features are excluded from headers.</td> + </tr> + <tr> + <td valign="top"><code>BOOST_FILESYSTEM_DYN_LINK</code></td> + <td valign="top">Defined if <code>BOOST_ALL_DYN_LINK</code> is defined, + otherwise not defined.</td> + <td valign="top">The Boost.Filesystem library is dynamically linked. If not defined, + static linking is assumed.</td> + </tr> + <tr> + <td valign="top"><code>BOOST_FILESYSTEM_NO_LIB</code></td> + <td valign="top">Defined if <code>BOOST_ALL_NO_LIB</code> is defined, + otherwise not defined.</td> + <td valign="top">Boost.Filesystem library does not use the Boost auto-link + facility.</td> + </tr> + </table> +<p>User-defined BOOST_POSIX_API and BOOST_WINDOWS_API macros are no longer +supported.</p> +<h2><a name="Building">Building</a> the object-library</h2> +<p>The object-library will be built automatically if you are using the Boost +build system. See +<a href="../../../more/getting_started.html">Getting Started</a>. It can also be +built manually using a <a href="../build/Jamfile.v2">Jamfile</a> +supplied in directory libs/filesystem/build, or the user can construct an IDE +project or make file which includes the object-library source files.</p> +<p>The object-library source files are +supplied in directory <a href="src">libs/filesystem/src</a>. These source files implement the +library for POSIX or Windows compatible operating systems; no implementation is +supplied for other operating systems. Note that many operating systems not +normally thought of as POSIX systems, such as mainframe legacy +operating systems or embedded operating systems, support POSIX compatible file +systems and so will work with the Filesystem Library.</p> +<p>The object-library can be built for static or dynamic (shared/dll) linking. +This is controlled by the BOOST_ALL_DYN_LINK or BOOST_FILESYSTEM_DYN_LINK +macros. See the <a href="http://www.boost.org/development/separate_compilation.html">Separate +Compilation</a> page for a description of the techniques used.</p> +<h3>Note for <a name="Cgywin">Cygwin</a> users</h3> +<p> <a href="http://www.cygwin.com/">Cygwin</a> version 1.7 or later is +required because only versions of GCC with wide character strings are supported.</p> + +<p> The library's implementation code treats Cygwin as a Windows platform, and +thus uses the Windows API and uses Windows path syntax as the native path +syntax.</p> + +<h2><a name="Change-history">Version history</a></h2> + +<h3>Version 3</h3> + +<p>Boost <span style="background-color: #FFFF00">1.??.0 - ???, 2010</span> - Internationalization via single class <code>path</code>. +More uniform error handling.</p> + +<p>Peter Dimov suggested use of a single path class rather than a <code>basic_path</code> +class template. That idea was the basis for the Version 3 redesign.</p> + +<p>Thanks for comments from Robert Stewart, Zach Laine, Peter Dimov, Gregory +Peele, Scott McMurray, John Bytheway, Jeff Flinn, Jeffery Bosboom.</p> + +<h3>Version 2</h3> + +<p>Boost 1.34.0 - May, 2007 - Internationalization via <code>basic_path</code> +template.</p> + +<p>So many people have contributed comments and bug reports that it isn't any +longer possible to acknowledge them individually. That said, Peter Dimov and Rob +Stewart need to be specially thanked for their many constructive criticisms and +suggestions. Terence +Wilson and Chris Frey contributed timing programs which helped illuminate +performance issues.</p> + +<h3>Version 1</h3> + +<p>Boost 1.30.0 - March, 2003 - Initial official Boost release.</p> + +<p>The Filesystem Library was designed and implemented by Beman Dawes. The +original <i>directory_iterator</i> and <i>filesystem_error</i> classes were +based on prior work from Dietmar Kuehl, as modified by Jan Langer. Thomas Witt +was a particular help in later stages of initial development. Peter Dimov and +Rob Stewart made many useful suggestions and comments over a long period of +time. Howard Hinnant helped with internationalization issues.</p> + +<p>Key <a href="design.htm#Requirements">design requirements</a> and +<a href="design.htm#Realities">design realities</a> were developed during +extensive discussions on the Boost mailing list, followed by comments on the +initial implementation. Numerous helpful comments were then received during the +Formal Review.<p>Participants included +Aaron Brashears, +Alan Bellingham, +Aleksey Gurtovoy, +Alex Rosenberg, +Alisdair Meredith, +Andy Glew, +Anthony Williams, +Baptiste Lepilleur, +Beman Dawes, +Bill Kempf, +Bill Seymour, +Carl Daniel, +Chris Little, +Chuck Allison, +Craig Henderson, +Dan Nuffer, +Dan'l Miller, +Daniel Frey, +Darin Adler, +David Abrahams, +David Held, +Davlet Panech, +Dietmar Kuehl, +Douglas Gregor, +Dylan Nicholson, +Ed Brey, +Eric Jensen, +Eric Woodruff, +Fedder Skovgaard, +Gary Powell, +Gennaro Prota, +Geoff Leyland, +George Heintzelman, +Giovanni Bajo, +Glen Knowles, +Hillel Sims, +Howard Hinnant, +Jaap Suter, +James Dennett, +Jan Langer, +Jani Kajala, +Jason Stewart, +Jeff Garland, +Jens Maurer, +Jesse Jones, +Jim Hyslop, +Joel de Guzman, +Joel Young, +John Levon, +John Maddock, +John Williston, +Jonathan Caves, +Jonathan Biggar, +Jurko, +Justus Schwartz, +Keith Burton, +Ken Hagen, +Kostya Altukhov, +Mark Rodgers, +Martin Schuerch, +Matt Austern, +Matthias Troyer, +Mattias Flodin, +Michiel Salters, +Mickael Pointier, +Misha Bergal, +Neal Becker, +Noel Yap, +Parksie, +Patrick Hartling, Pavel Vozenilek, +Pete Becker, +Peter Dimov, +Rainer Deyke, +Rene Rivera, +Rob Lievaart, +Rob Stewart, +Ron Garcia, +Ross Smith, +Sashan, +Steve Robbins, +Thomas Witt, +Tom Harris, +Toon Knapen, +Victor Wagner, +Vincent Finn, +Vladimir Prus, and +Yitzhak Sapir + +<p>A lengthy discussion on the C++ committee's library reflector illuminated the "illusion +of portability" problem, particularly in postings by PJ Plauger and Pete Becker.</p> + +<p>Walter Landry provided much help illuminating symbolic link use cases for +version 1.31.0. </p> + +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> + +<p>© Copyright Beman Dawes, 2002-2005</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"> +www.boost.org/LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/path_table.cpp b/libs/filesystem/doc/path_table.cpp new file mode 100644 index 0000000000..cb811cacfe --- /dev/null +++ b/libs/filesystem/doc/path_table.cpp @@ -0,0 +1,260 @@ +// Generate an HTML table showing path decomposition ---------------------------------// + +// Copyright Beman Dawes 2005. + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/filesystem for documentation. + +// For purposes of generating the table, support both POSIX and Windows paths + +#include "boost/filesystem.hpp" +#include <iostream> +#include <fstream> + +using boost::filesystem::path; +using std::string; +using std::cout; + +namespace +{ + std::ifstream infile; + std::ofstream posix_outfile; + std::ifstream posix_infile; + std::ofstream outfile; + + bool posix; + + const string empty_string; + + struct column_base + { + virtual string heading() const = 0; + virtual string cell_value( const path & p ) const = 0; + }; + + struct c0 : public column_base + { + string heading() const { return string("<code>string()</code>"); } + string cell_value( const path & p ) const { return p.string(); } + } o0; + + struct c1 : public column_base + { + string heading() const { return string("<code>generic_<br>string()</code>"); } + string cell_value( const path & p ) const { return p.generic_string(); } + } o1; + + struct c2 : public column_base + { + string heading() const { return string("Iteration<br>over<br>Elements"); } + string cell_value( const path & p ) const + { + string s; + for( path::iterator i(p.begin()); i != p.end(); ++i ) + { + if ( i != p.begin() ) s += ','; + s += (*i).string(); + } + return s; + } + } o2; + + struct c3 : public column_base + { + string heading() const { return string("<code>root_<br>path()</code>"); } + string cell_value( const path & p ) const { return p.root_path().string(); } + } o3; + + struct c4 : public column_base + { + string heading() const { return string("<code>root_<br>name()</code>"); } + string cell_value( const path & p ) const { return p.root_name().string(); } + } o4; + + struct c5 : public column_base + { + string heading() const { return string("<code>root_<br>directory()</code>"); } + string cell_value( const path & p ) const { return p.root_directory().string(); } + } o5; + + struct c6 : public column_base + { + string heading() const { return string("<code>relative_<br>path()</code>"); } + string cell_value( const path & p ) const { return p.relative_path().string(); } + } o6; + + struct c7 : public column_base + { + string heading() const { return string("<code>parent_<br>path()</code>"); } + string cell_value( const path & p ) const { return p.parent_path().string(); } + } o7; + + struct c8 : public column_base + { + string heading() const { return string("<code>filename()</code>"); } + string cell_value( const path & p ) const { return p.filename().string(); } + } o8; + + const column_base * column[] = { &o2, &o0, &o1, &o3, &o4, &o5, &o6, &o7, &o8 }; + + // do_cell ---------------------------------------------------------------// + + void do_cell( const string & test_case, int i ) + { + string temp = column[i]->cell_value(path(test_case)); + string value; + outfile << "<td>"; + if (temp.empty()) + value = "<font size=\"-1\"><i>empty</i></font>"; + else + value = string("<code>") + temp + "</code>"; + + if (posix) + posix_outfile << value << '\n'; + else + { + std::getline(posix_infile, temp); + if (value != temp) // POSIX and Windows differ + { + value.insert(0, "<br>"); + value.insert(0, temp); + value.insert(0, "<span style=\"background-color: #CCFFCC\">"); + value += "</span>"; + } + outfile << value; + } + outfile << "</td>\n"; + } + +// do_row ------------------------------------------------------------------// + + void do_row( const string & test_case ) + { + outfile << "<tr>\n"; + + if (test_case.empty()) + outfile << "<td><font size=\"-1\"><i>empty</i></font></td>\n"; + else + outfile << "<td><code>" << test_case << "</code></td>\n"; + + for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i ) + { + do_cell( test_case, i ); + } + + outfile << "</tr>\n"; + } + +// do_table ----------------------------------------------------------------// + + void do_table() + { + outfile << + "<h1>Path Decomposition Table</h1>\n" + "<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>\n" + "implementations yield different results. The top value is the\n" + "<i>POSIX</i> result and the bottom value is the <i>Windows</i> result.\n" + "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n" + "<p>\n" + ; + + // generate the column headings + + outfile << "<tr><td><b>Constructor<br>argument</b></td>\n"; + + for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i ) + { + outfile << "<td><b>" << column[i]->heading() << "</b></td>\n"; + } + + outfile << "</tr>\n"; + + // generate a row for each input line + + string test_case; + while ( std::getline( infile, test_case ) ) + { + if (!test_case.empty() && *--test_case.end() == '\r') + test_case.erase(test_case.size()-1); + if (test_case.empty() || test_case[0] != '#') + do_row( test_case ); + } + + outfile << "</table>\n"; + } + +} // unnamed namespace + +// main ------------------------------------------------------------------------------// + +#define BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE +#include <boost/test/included/prg_exec_monitor.hpp> + +int cpp_main( int argc, char * argv[] ) // note name! +{ + if ( argc != 5 ) + { + std::cerr << + "Usage: path_table \"POSIX\"|\"Windows\" input-file posix-file output-file\n" + "Run on POSIX first, then on Windows\n" + " \"POSIX\" causes POSIX results to be saved in posix-file;\n" + " \"Windows\" causes POSIX results read from posix-file\n" + " input-file contains the paths to appear in the table.\n" + " posix-file will be used for POSIX results\n" + " output-file will contain the generated HTML.\n" + ; + return 1; + } + + infile.open( argv[2] ); + if ( !infile ) + { + std::cerr << "Could not open input file: " << argv[2] << std::endl; + return 1; + } + + if (string(argv[1]) == "POSIX") + { + posix = true; + posix_outfile.open( argv[3] ); + if ( !posix_outfile ) + { + std::cerr << "Could not open POSIX output file: " << argv[3] << std::endl; + return 1; + } + } + else + { + posix = false; + posix_infile.open( argv[3] ); + if ( !posix_infile ) + { + std::cerr << "Could not open POSIX input file: " << argv[3] << std::endl; + return 1; + } + } + + outfile.open( argv[4] ); + if ( !outfile ) + { + std::cerr << "Could not open output file: " << argv[2] << std::endl; + return 1; + } + + outfile << "<html>\n" + "<head>\n" + "<title>Path Decomposition Table</title>\n" + "</head>\n" + "<body bgcolor=\"#ffffff\" text=\"#000000\">\n" + ; + + do_table(); + + outfile << "</body>\n" + "</html>\n" + ; + + return 0; +} diff --git a/libs/filesystem/doc/path_table.txt b/libs/filesystem/doc/path_table.txt new file mode 100644 index 0000000000..40809c6774 --- /dev/null +++ b/libs/filesystem/doc/path_table.txt @@ -0,0 +1,50 @@ +# Paths for the reference.html Path Decomposition Table +# +# This is the input file for path_table, which generates the actual html +# +# Copyright Beman Dawes 2010 +# +# Distributed under the Boost Software License, Version 1.0. +# See www.boost.org/LICENSE_1_0.txt +# +# Note that an empty line is treated as input rather than as a comment + +. +.. +foo +/ +/foo +foo/ +/foo/ +foo/bar +/foo/bar +//net +//net/foo +///foo/// +///foo///bar +/. +./ +/.. +../ +foo/. +foo/.. +foo/./ +foo/./bar +foo/.. +foo/../ +foo/../bar +c: +c:/ +c:foo +c:/foo +c:foo/ +c:/foo/ +c:/foo/bar +prn: +c:\ +c:foo +c:\foo +c:foo\ +c:\foo\ +c:\foo/ +c:/foo\bar diff --git a/libs/filesystem/doc/portability_guide.htm b/libs/filesystem/doc/portability_guide.htm new file mode 100644 index 0000000000..54b5a748cb --- /dev/null +++ b/libs/filesystem/doc/portability_guide.htm @@ -0,0 +1,241 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Portability Guide</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body bgcolor="#FFFFFF"> + +<h1> +<img border="0" src="../../../boost.png" align="center" width="300" height="86">Path +Name Portability +Guide</h1> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<p> +<a href="#Introduction">Introduction</a><br> +<a href="#name_check_functions">name_check functions</a><br> +<a href="#recommendations">File and directory name recommendations</a></p> +<h2><a name="Introduction">Introduction</a></h2> +<p>Like any other C++ program which performs I/O operations, there is no +guarantee that a program using Boost.Filesystem will be portable between +operating systems. Critical aspects of I/O such as how the operating system +interprets paths are unspecified by the C and C++ Standards.</p> +<p>It is not possible to know if a file or directory name will be +valid (and thus portable) for an unknown operating system. There is always the possibility that an operating system could use +names which are unusual (numbers less than 4096, for example) or very +limited in size (maximum of six character names, for example). In other words, +portability is never absolute; it is always relative to specific operating +systems or +file systems.</p> +<p>It is possible, however, to know in advance if a directory or file name is likely to be valid for a particular +operating system. It is also possible to construct names which are +likely to be portable to a large number of modern and legacy operating systems.</p> + +<p>Almost all modern operating systems support multiple file systems. At the +minimum, they support a native file system plus a CD-ROM file system (Generally +ISO-9669, often with Juliet extensions).</p> + +<p>Each file system +may have its own naming rules. For example, modern versions of Windows support NTFS, FAT, FAT32, and ISO-9660 file systems, among others, and the naming rules +for those file systems differ. Each file system may also have +differing rules for overall path validity, such as a maximum length or number of +sub-directories. Some legacy systems have different rules for directory names +versus regular file names.</p> + +<p>As a result, Boost.Filesystem's <i>name_check</i> functions +cannot guarantee directory and file name portability. Rather, they are intended to +give the programmer a "fighting chance" to achieve portability by early +detection of common naming problems.</p> + +<h2><a name="name_check_functions">name_check functions</a></h2> + +<p>A <i>name_check</i> function +returns true if its argument is valid as a directory and regular file name for a +particular operating or file system. A number of these functions are provided.</p> + +<p>The <a href="#portable_name">portable_name</a> function is of particular +interest because it has been carefully designed to provide wide +portability yet not overly restrict expressiveness.</p> + +<table border="1" cellpadding="5" cellspacing="0"> + <tr> + <td align="center" colspan="2"><b>Library Supplied name_check Functions</b></td> + </tr> + <tr> + <td align="center"><b>Function</b></td> + <td align="center"><b>Description</b></td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="portable_posix_name">portable_posix_name</a>(const + std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> <i>true</i> if <code>!name.empty() && name</code> contains only the characters + specified in<i> Portable Filename Character Set</i> rules as defined in by + POSIX (<a href="http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html">www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html</a>).<br> + The allowed characters are <code>0-9</code>, <code>a-z</code>, <code>A-Z</code>, + <code>'.'</code>, <code>'_'</code>, and <code>'-'</code>.<p><b>Use:</b> + applications which must be portable to any POSIX system.</td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="windows_name">windows_name</a>(const + std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> <i>true</i> if <code>!name.empty() && name</code> contains + only the characters specified by the Windows platform SDK as valid + regardless of the file system <code>&& (name</code> is <code>"."</code> or + <code>".."</code> or does not end with a trailing space or period<code>)</code>. + The allowed characters are anything except <code>0x0-0x1F</code>, <code>'<'</code>, + <code>'>'</code>, <code>':'</code>, <code>'"'</code>, <code>'/'</code>, + <code>'\'</code>, and <code>'|'</code>.<p> + <b>Use:</b> applications which must be portable to Windows.</p> + <p><b>Note:</b> Reserved device names are not valid as file names, but are + not being detected because they are still valid as a path. Specifically, + CON, PRN, AUX, CLOCK$, NUL, COM[1-9], LPT[1-9], and these names followed by + an extension (for example, NUL.tx7).</td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="portable_name">portable_name</a>(const + std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> <code> windows_name(name) && portable_posix_name(name) + && (name</code> is <code>"."</code> or <code>".."</code>, and the first character not a period or hyphen<code>)</code>.<p><b>Use:</b> applications which must be portable to a wide variety of + modern operating systems, large and small, and to some legacy O/S's. The + first character not a period or hyphen restriction is a requirement of + several older operating systems.</td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="portable_directory_name"> + portable_directory_name</a>(const std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> <code>portable_name(name) && (name</code> is <code>"."</code> + or <code>".."</code> or contains no periods<code>)</code>.<p><b>Use:</b> applications + which must be portable to a wide variety of platforms, including OpenVMS.</td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="portable_file_name"> + portable_file_name</a>(const std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> <code>portable_name(name) && </code>any period is followed by one to three additional + non-period characters.<p><b>Use:</b> + applications which must be portable to a wide variety of platforms, + including OpenVMS and other systems which have a concept of "file extension" + but limit its length.</td> + </tr> + <tr> + <td align="left" valign="top"><code><a name="native">native</a>(const + std::string&<i> name</i>)</code></td> + <td><b>Returns:</b> Implementation defined. Returns <i> + true</i> for names considered valid by the operating system's native file + systems.<p><b>Note:</b> May return <i>true</i> for some names not considered valid + by the operating system under all conditions (particularly on operating systems which support + multiple file systems.)</td> + </tr> +</table> + +<h2>File and directory name <a name="recommendations">recommendations</a></h2> + +<table border="1" cellpadding="5" cellspacing="0"> + + <tr> + <td align="center" valign="top"><strong>Recommendation</strong></td> + <td align="center" valign="top"><strong>Rationale</strong></td> + </tr> + <tr> + <td valign="top">Limit file and directory names to the characters A-Z, a-z, 0-9, period, hyphen, and + underscore.<p>Use any of the "portable_" <a href="#name_check_functions"> + name check functions</a> to enforce this recommendation.</td> + <td valign="top">These are the characters specified by the POSIX standard for portable directory and + file names, and are also valid for Windows, Mac, and many other modern file systems.</td> + </tr> + <tr> + <td valign="top">Do not use a period or hyphen as the first + character of a name. Do not use period as the last character of a name.<p> + Use <a href="#portable_name">portable_name</a>, + <a href="#portable_directory_name">portable_directory_name</a>, or + <a href="#portable_file_name">portable_file_name</a> to enforce this + recommendation.</td> + <td valign="top">Some operating systems treat have special rules for the + first character of names. POSIX, for example. Windows does not permit period + as the last character.</td> + </tr> + <tr> + <td valign="top">Do not use periods in directory names.<p>Use + <a href="#portable_directory_name">portable_directory_name</a> to enforce + this recommendation.</td> + <td valign="top">Requirement for ISO-9660 without Juliet extensions, OpenVMS filesystem, and other legacy systems.</td> + </tr> + <tr> + <td valign="top">Do not use more that one period in a file name, and limit + the portion after the period to three characters.<p>Use + <a href="#portable_file_name">portable_file_name</a> to enforce this + recommendation.</td> + <td valign="top">Requirement for ISO-9660 level 1, OpenVMS filesystem, and + other legacy systems. </td> + </tr> + <tr> + <td valign="top">Do not assume names are case sensitive. For example, do not expected a directory to be + able to hold separate elements named "Foo" and "foo". </td> + <td valign="top">Some file systems are case insensitive. For example, Windows + NTFS is case preserving in the way it stores names, but case insensitive in + searching for names (unless running under the POSIX sub-system, it which + case it does case sensitive searches). </td> + </tr> + <tr> + <td valign="top">Do not assume names are case insensitive. For example, do not expect a file + created with the name of "Foo" to be opened successfully with the name of "foo".</td> + <td valign="top">Some file systems are case sensitive. For example, POSIX.</td> + </tr> + <tr> + <td valign="top">Don't use hyphens in names.</td> + <td valign="top">ISO-9660 level 1, and possibly some legacy systems, do not permit + hyphens.</td> + </tr> + <tr> + <td valign="top">Limit the length of the string returned by path::string() to + 255 characters. + Note that ISO 9660 has an explicit directory tree depth limit of 8, although + this depth limit is removed by the Juliet extensions.</td> + <td valign="top">Some operating systems place limits on the total path length. For example, + Windows 2000 limits paths to 260 characters total length.</td> + </tr> + <tr> + <td valign="top">Limit the length of any one name in a path. Pick the specific limit according to + the operating systems and or file systems you wish portability to:<br> + Not a concern:: POSIX, Windows, MAC OS X.<br> + 31 characters: Classic Mac OS<br> + 8 characters + period + 3 characters: ISO 9660 level 1<br> + 32 characters: ISO 9660 level 2 and 3<br> + 128 characters (64 if Unicode): ISO 9660 with Juliet extensions</td> + <td valign="top">Limiting name length can markedly reduce the expressiveness of file names, yet placing + only very high limits on lengths inhibits widest portability.</td> + </tr> +</table> + +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> + +<p>© Copyright Beman Dawes, 2002, 2003</p> +<p> Use, modification, and distribution are subject to the Boost Software +License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> +LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> +www.boost.org/LICENSE_1_0.txt</a>)</p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/reference.html b/libs/filesystem/doc/reference.html new file mode 100644 index 0000000000..7d6b11fb30 --- /dev/null +++ b/libs/filesystem/doc/reference.html @@ -0,0 +1,3481 @@ +<html> +<!-- © Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010, 2011 --> +<!-- Distributed under the Boost Software License, Version 1.0. --> +<!-- See http://www.boost.org/LICENSE_1_0.txt --> +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title> + + Filesystem Reference + </title> +<style type="text/css"> +/* + + © Copyright Beman Dawes, 2007 + + Distributed under the Boost Software License, Version 1.0. + See www.boost.org/LICENSE_1_0.txt + +*/ + +body { + font-family: sans-serif; + margin: 1em; + max-width : 8.5in; + } + +table { margin: 0.5em; } + +pre { background-color:#D7EEFF } + +ins { background-color:#A0FFA0 } +del { background-color:#FFA0A0 } + +/*** end ***/ +</style> +</head> + +<body> + + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Library<br> + </font> + <font size="6">Version 3</font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </td> + </tr> +</table> + +<h1>Reference Documentation</h1> + + + +<h2><a name="TOC">Table of Contents</a></h2> + +<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="33%" valign="top"><a href="#Introduction">Introduction</a><br> + <a href="#Definitions">Definitions</a><br> + <a href="#Conformance">Conformance</a><br> + <a href="#Header-filesystem-synopsis"> + Header <code><boost/filesystem.hpp></code> synopsis</a><br> + <a href="#Error-reporting">Error reporting</a><br> + <a href="#class-path">Class <code>path</code></a><br> + <a href="#path-Conversions"><code>path</code> conversions</a><br> + <a href="#path-Conversions-to-native-format"><code>path</code> + conversions to native format</a><br> + <a href="#path-Conversions-to-generic-format"><code>path</code> + conversions to generic format</a><br> + <a href="#path-Encoding-conversions"><code>path</code> + encoding conversions</a><br> + <a href="#path-Requirements"><code>path</code> requirements</a><br> + <a href="#path-constructors"><code>path</code> constructors</a><br> + <a href="#path-assignments"><code>path</code> assignments</a><br> + <a href="#path-appends"><code>path</code> appends</a><br> + <a href="#path-concatenation"><code>path</code> concatenation</a><br> + <a href="#path-modifiers"><code>path</code> modifiers</a><br> + <a href="#path-native-format-observers"><code>path</code> native + format observers</a><br> + <a href="#path-generic-format-observers"><code>path</code> generic + format observers</a><br> + <a href="#path-compare"><code>path</code> compare</a><br> + <a href="#path-decomposition"><code>path</code> decomposition</a><br> + <a href="#path-query"><code>path</code> query</a><br> + <a href="#path-iterators"><code>path</code> iterators</a><br> + + <a href="#path-deprecated-functions"><code>path</code> deprecated functions</a><br> + <a href="#path-non-member-functions"><code>path</code> non-member functions</a><br> + <a href="#path-inserter-extractor"><code>path</code> inserters and extractors</a><br> + <a href="#Class-filesystem_error">Class <code>filesystem_error</code></a><br> + <a href="#filesystem_error-members"><code>filesystem_error</code> + constructors</a><br> + <code>f</code><a href="#filesystem_error-path1"><code>ilesystem_error</code> path1</a><br> + <a href="#filesystem_error-path2"><code>filesystem_error</code> path2</a><br> + <a href="#filesystem_error-what"><code>filesystem_error</code><code> + </code>what</a></td> + <td width="33%" valign="top"> + <a href="#Enum-file_type">Enum <code>file_type</code></a><br> + <a href="#Enum-perms">Enum <code>perms</code></a><br> + <a href="#file_status">Class + <code>file_status</code></a><br> + + <a href="#file_status"> + <code>file_status</code></a><a href="#file_status-constructors"> constructors</a><br> + <code><a href="#file_status-modifiers">file_status-modifiers</a></code><a href="#directory_entry-observers"> observers</a><br> + <code><a href="#file_status-observers">file_status-observers</a></code><a href="#directory_entry-modifiers"> modifiers</a><br> +<a href="#Class-directory_entry">Class <code>directory_entry</code></a><br> + +<a href="#directory_entry-constructors"><code>directory_entry</code> constructors</a><br> + <a href="#directory_entry-observers"><code>directory_entry</code> observers</a><br> + <a href="#directory_entry-modifiers"><code>directory_entry</code> modifiers</a><br> +<a href="#Class-directory_iterator">Class <code>directory_iterator</code></a><br> + <a href="#directory_iterator-members"><code>directory_iterator</code> + members</a><br> +<a href="#Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a><br> + <a href="#Operational-functions"> + Operational functions</a><br> + <code>   <a href="#absolute">absolute</a><br> + <a href="#canonical">canonical</a><br> + <a href="#copy">copy</a><br> + <a href="#copy_directory">copy_directory</a><br> + <a href="#copy_file">copy_file</a><br> + <a href="#copy_symlink">copy_symlink</a><br> +   <a href="#create_directories">create_directories</a><br> +   <a href="#create_directory">create_directory</a><br> +   <a href="#create_hard_link">create_hard_link</a><br> +   <a href="#create_symlink">create_symlink</a><br> +   <a href="#current_path">current_path</a><br> +   <a href="#exists">exists</a><br> +   <a href="#equivalent">equivalent</a><br> +   <a href="#file_size">file_size</a><br> + <a href="#hard_link_count">hard_link_count</a><br> + <a href="#initial_path">initial_path</a></code></td> + <td width="34%" valign="top"> + <code> i<a href="#is_directory">s_directory</a><br> +   <a href="#is_empty">is_empty</a><br> +   <a href="#is_other">is_other</a><br> +   <a href="#is_regular_file">is_regular_file</a><br> +   <a href="#is_symlink">is_symlink</a><br> +   <a href="#last_write_time">last_write_time</a><br> + <a href="#permissions">permissions</a><br> + <a href="#read_symlink">read_symlink</a><br> +   <a href="#remove">remove</a><br> +   <a href="#remove_all">remove_all</a><br> +   <a href="#rename">rename</a><br> + <a href="#resize_file">resize_file</a><br> +   <a href="#space">space</a><br> +   <a href="#status">status</a><br> +   <a href="#status_known">status_known</a><br> +   <a href="#symlink_status">symlink_status</a><br> +   <a href="#system_complete">system_complete</a><br> +   <a href="#temp_directory_path">temp_directory_path</a><br> + </code> <code> <a href="#unique_path">unique_path</a></code><br> + <a href="#File-streams">File streams</a><br> +<a href="#Path-decomposition-table">Path decomposition table</a><br> + <a href="#long-path-warning">Warning: Long paths on Windows and the + extended-length <b>\\?\ </b>prefix</a><br> +<a href="#Acknowledgements">Acknowledgements</a><br> +<a href="#References">References</a><br> + </td> + </tr> +</table> + + +<h2><a name="Introduction">Introduction</a></h2> + +<p>This reference documentation describes components that C++ programs may use +to perform operations involving file systems, including paths, regular files, +and directories.</p> + + +<p>This reference documentation describes components that perform operations on file systems and +their components, such as paths, regular files, and directories.</p> + +<h2><a name="Conformance">Conformance</a></h2> +<p>Behavior is sometimes specified by reference to ISO/IEC 9945. How such behavior is actually implemented is unspecified.</p> +<blockquote> +<p>[<i>Note:</i> This constitutes an "as if" rule for implementation of +operating system dependent behavior. In practice implementations will usually call native +operating system API's. <i>--end note</i>]</p> +</blockquote> +<p>Implementations are encouraged, but not required, to prove such behavior + +as it is defined by ISO/IEC 9945. Implementations shall document any +behavior that differs from the ISO/IEC 9945 defined behavior. Implementations that do not support exact +ISO/IEC 9945 behavior are +encouraged to provide behavior as close to ISO/IEC 9945 behavior as is reasonable given the +limitations of actual operating systems and file systems. If an implementation cannot provide any +reasonable behavior, the implementation shall report an error in an +implementation-defined manner.</p> +<blockquote> +<p>[<i>Note:</i> Such errors might be reported by an #error directive, a <code> +static_assert</code>, a <code>filesystem_error</code> exception, a special +return value, or some other manner. <i>--end note</i>]</p> +</blockquote> +<p>Implementations are not required to provide behavior that is not supported by +a particular file system.</p> +<blockquote> +<p>[<i>Example:</i> The <a href="http://en.wikipedia.org/wiki/FAT_filesystem"> +FAT file system</a> used by some memory cards, camera memory, and floppy discs +does not support hard links, symlinks, and many other features of more capable +file systems. Implementations are only required to support the FAT features +supported by the host operating system. <i>-- end example</i>]</p> +</blockquote> +<p>The behavior of functions described in this +reference +may differ from their specification in +the presence of <a href="#Race-condition">file system races</a>. No diagnostic is required.</p> +<p>If the possibility of a file system race would make it unreliable for a program to +test for a precondition before calling a function described in this reference documentation, <i> +Requires</i> is not specified for the condition. Instead, the condition is +specified as a <i>Throws</i> condition.</p> +<blockquote> +<p>[<i>Note:</i> As a design practice, preconditions are not specified when it +is unreasonable for a program to detect them prior to calling the function. <i> +-- end note</i>]</p> +</blockquote> +<h2><a name="Definitions">Definitions</a></h2> +<p>The following definitions shall apply throughout this reference documentation:</p> +<p><i><b><a name="File">File</a>:</b> </i>An object that can be written to, or read from, or both. A file +has certain attributes, including type. File types include regular files +and directories. Other types of files, such as symbolic links, may be supported by the +implementation.</p> +<p><b><i><a name="File-system">File system</a>:</i></b> A collection of files and certain of their attributes.</p> +<p><b><i><a name="Filename">Filename</a>:</i></b> The name of a file. Slash and +0x00 +characters are not permitted. Implementations may define additional +characters or specific names that are not permitted. Filenames <code>.</code> +and <code>..</code> have special meaning. Implementations may define +additional filenames that have special meaning.</p> +<blockquote> + <p><i>[Note:</i> Many operating systems prohibit the ASCII control characters + (0x00-0x1F) in filenames.</p> + <p>One widely used operating system prohibits the characters 0x00-0x1F, <code>"</code>,<code> + *</code>,<code> :</code>,<code> <</code>,<code> ></code>,<code> ?</code>,<code> + \</code>,<code> /</code>, and<code> |</code> <i>--end note]</i></p> +</blockquote> +<p><b><i><a name="Path">Path</a>:</i></b> A sequence of elements that identify +the location of a file within a filesystem. The elements are the <i>root-name<sub>opt</sub></i>, <i> +root-directory<sub>opt</sub></i>, and an optional sequence of filenames. [<i>Note:</i> +A <a href="#Pathname">pathname</a> is the concrete representation of a path. <i>--end note</i>]</p> +<p><b><i>POSIX API systems:</i></b> Operating systems that use the ISO/IEC 9945 +API as their native application program interface.</p> +<p><b><i>Windows API systems:</i></b> Operating systems that use the Windows API +as their native application program interface.</p> +<p><b><i><a name="Absolute-path">Absolute path</a>:</i></b> A path that +unambiguously +identifies the location of a file without reference to an additional starting +location. The elements of a path that determine if it is absolute are +implementation defined.</p> +<blockquote> + <p dir="ltr"><i>[Note:</i> For POSIX API systems, paths that begin with one or + more <i>directory-specifier</i> characters are absolute paths.</p> + <p>For Windows API systems, paths that begin with a drive specifier (i.e. a + single letter followed by a colon) followed by one or more <i>directory-specifier</i> + characters, or begin with two <i>directory-specifier</i> characters, are absolute paths. <i>--end + note]</i></p> +</blockquote> +<p><i><b><a name="Relative-path">Relative path</a>:</b></i> A path that only +unambiguously +identifies the location of a file when resolved relative to +a starting location. The format is implementation defined. [<i>Note:</i> +Paths "." and ".." are considered to be relative paths. <i>--end note</i>]</p> +<p><i><b><a name="Canonical-path">Canonical path</a>:</b></i> An absolute path that has +no elements which are symbolic links, and no dot or dot dot elements.</p> +<p><i><b><a name="Pathname">Pathname</a>:</b> </i>A character string that represents a +path. Pathnames are formatted according to the generic pathname format or an implementation defined +native pathname format.</p> +<p><b><i><a name="generic-pathname-format">Generic pathname format:</a></i></b></p> +<blockquote> +<p><i>pathname:<br> + root-name<sub>opt</sub> +root-directory<sub>opt</sub> relative-path<sub>opt</sub></i></p> +<p><i>root-name:<br> + +implementation-defined</i></p> +<blockquote> + <blockquote> +<p>[<i>Note:</i> Many operating systems define a name +beginning with two <i>directory-separator</i> characters as a <i>root-name</i> +that identifies network locations. <span style="background-color: #FFFF00">Some +operating systems</span> defines a single letter followed by a colon as a drive +specifier; a <i>root-name</i> identifying a specific device such as a disc drive. <i>--end note</i>]</p> + </blockquote> +</blockquote> +<p><i>root-directory:<br> + +directory-separator</i></p> +<p><i>relative-path:<br> + +filename<br> + relative-path +directory-separator<br> + relative-path +directory-separator filename</i></p> +<p><i>filename:<br> + name<br> + </i><code>"."</code><i><br> + </i><code> +".."</code></p> +<p><i>preferred-separator:<sub>opt</sub><br> + +implementation-defined</i></p> +<p><i>directory-separator:<br> + <code>"/"<br> + "/"</code> directory-separator<br> + +preferred-separator<br> + +preferred-separator directory-separator</i></p> +<p>Multiple successive <i>directory-separator</i> characters are considered to +be the same as one <i>directory-separator</i> character.</p> +<p>The <i>filename</i> +<code>"."</code> is considered to be a reference to the current directory. The +<i>filename</i> <code>".."</code> is considered to be a reference to the +parent +directory. Specific <i>filenames</i> may have special meanings for a particular +operating system. </p> +</blockquote> +<p><b><i><a name="native-pathname-format">Native pathname format:</a></i></b> +An implementation defined format. [<i>Note:</i> For ISO/IEC 9945 compliant operating +systems, the native format is the same as the generic format. For one widely +used non-ISO/IEC 9945 compliant operating system, the +native format is similar to the generic format, but the directory-separator +characters can be either slashes or backslashes. <i>--end note</i>]</p> +<p><i><b><a name="Link">Link</a>:</b> </i>A directory entry object that associates a +filename with a file. On some file systems, several directory entries can +associate names with the same file.</p> +<p><b><i><a name="Hard-link">Hard link</a>:</i></b> A link to an existing file. Some +file systems support multiple hard links to a file. If the last hard link to a +file is removed, the file itself is removed.</p> +<blockquote> +<p>[<i>Note:</i> A hard link can be thought of as a shared-ownership smart +pointer to a file.<i> -- end note</i>]<i> </i></p> +</blockquote> +<p><i><a name="Symbolic-link">S<b>ymbolic link</b></a><b>:</b> </i>A type of file with the +property that when the file is encountered during pathname resolution, a string +stored by the file is used to modify the pathname resolution.</p> +<blockquote> +<p>[<i>Note:</i> A symbolic link can be thought of as a raw pointer to a file. +If the file pointed to does not exist, the symbolic link is said to be a +"dangling" symbolic link.<i> -- end note</i>]<i> </i></p> +</blockquote> +<p><b><i><a name="Race-condition">File system race</a>:</i></b> The condition that occurs +when multiple threads, processes, or computers interleave access and +modification of +the same object within a file system.</p> +<p><b><i><a name="Dot">Dot</a>, Dot Dot:</i></b> Synonyms for the filenames <code>"."</code> +and <code>".."</code>, respectively. The dot filename names the current +directory. The dot dot filename names the parent directory.</p> +<h2><a name="Header-filesystem-synopsis">Header <code><boost/filesystem.hpp></code> synopsis</a></h2> +<pre>namespace boost +{ + namespace filesystem + { + class <a href="#class-path">path</a>; + + bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2); + +void swap(path& lhs, path& rhs); + std::size_t <a href="#hash_value">hash_value</a>(const path& p); + + bool operator==(const path& lhs, const path& rhs); + bool operator!=(const path& lhs, const path& rhs); + bool operator< (const path& lhs, const path& rhs); + bool operator<=(const path& lhs, const path& rhs); + bool operator> (const path& lhs, const path& rhs); + bool operator>=(const path& lhs, const path& rhs); + + path operator/ (const path& lhs, const path& rhs); + + std::ostream& operator<<( std::ostream& os, const path& p ); + std::wostream& operator<<( std::wostream& os, const path& p ); + std::istream& operator>>( std::istream& is, path& p ); + std::wistream& operator>>( std::wistream& is, path& p ) + + class <a href="#Class-filesystem_error">filesystem_error</a>; + class <a href="#Class-directory_entry">directory_entry</a>; + + class <a href="#Class-directory_iterator">directory_iterator</a>; + + // enable c++11 range-based for statements + const directory_iterator& <a href="#directory_iterator-non-member-functions">begin</a>(const directory_iterator& iter); + directory_iterator <a href="#directory_iterator-non-member-functions">end</a>(const directory_iterator&); + + // enable BOOST_FOREACH + directory_iterator& range_begin(directory_iterator& iter); + directory_iterator range_begin(const directory_iterator& iter); + directory_iterator range_end(const directory_iterator&); + + class <a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a>; + + // enable c++11 range-based for statements + const recursive_directory_iterator& <a href="#recursive_directory_iterator-non-member-functions">begin</a>(const recursive_directory_iterator& iter); + recursive_directory_iterator <a href="#recursive_directory_iterator-non-member-functions">end</a>(const recursive_directory_iterator&); + + // enable BOOST_FOREACH + recursive_directory_iterator& range_begin(recursive_directory_iterator& iter); + recursive_directory_iterator range_begin(const recursive_directory_iterator& iter); + recursive_directory_iterator range_end(const recursive_directory_iterator&); + + enum <a name="file_type" href="#Enum-file_type">file_type</a> + { + status_error, file_not_found, regular_file, directory_file, + symlink_file, block_file, character_file, fifo_file, socket_file, + type_unknown + }; + + enum <a href="#Enum-perms">perms</a> + { + no_perms, + owner_read, owner_write, owner_exe, owner_all, + group_read, group_write, group_exe, group_all, + others_read, others_write, others_exe, others_all, all_all, + set_uid_on_exe, set_gid_on_exe, sticky_bit, + perms_mask, perms_not_known, + add_perms, remove_perms, symlink_perms + }; + + class <a href="#file_status">file_status</a>; + + struct <a name="space_info">space_info</a> // returned by <a href="#space" style="text-decoration: none">space</a> function + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; // free space available to a non-privileged process + }; + + enum class <a name="copy_option">copy_option</a> + { + none + fail_if_exists = none, + overwrite_if_exists + }; + + enum class <a name="symlink_option">symlink_option</a> + { + none + no_recurse = none, + recurse + }; + + // <a href="#Operational-functions">operational functions</a> + + path <a href="#absolute">absolute</a>(const path& p, const path& base=current_path()); + + path <a href="#canonical">canonical</a>(const path& p, const path& base = current_path()); + path <a href="#canonical">canonical</a>(const path& p, system::error_code& ec); + path <a href="#canonical">canonical</a>(const path& p, const path& base, system::error_code& ec); + + void <a href="#copy">copy</a>(const path& from, const path& to); + void <a href="#copy">copy</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#create_directory">copy_directory</a>(const path& from, const path& to); + void <a href="#create_directory">copy_directory</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#copy_file">copy_file</a>(const path& from, const path& to); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, system::error_code& ec); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option, + system::error_code& ec); + + void <a href="#copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink); + void <a href="#copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink, system::error_code& ec); + + bool <a href="#create_directories">create_directories</a>(const path& p); + bool <a href="#create_directories">create_directories</a>(const path& p, system::error_code& ec); + + bool <a href="#create_directory">create_directory</a>(const path& p); + bool <a href="#create_directory">create_directory</a>(const path& p, system::error_code& ec); + + void <a href="#create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink); + void <a href="#create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink, system::error_code& ec); + + void <a href="#create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link); + void <a href="#create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link, system::error_code& ec); + + void <a href="#create_symlink">create_symlink</a>(const path& to, const path& new_symlink); + void <a href="#create_symlink">create_symlink</a>(const path& to, const path& new_symlink, system::error_code& ec); + + path <a href="#current_path">current_path</a>(); + path <a href="#current_path">current_path</a>(system::error_code& ec); + void <a href="#current_path">current_path</a>(const path& p); + void <a href="#current_path">current_path</a>(const path& p, system::error_code& ec); + + bool <a href="#exists">exists</a>(file_status s) noexcept; + bool <a href="#exists">exists</a>(const path& p); + bool <a href="#exists">exists</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#equivalent">equivalent</a>(const path& p1, const path& p2); + bool <a href="#equivalent">equivalent</a>(const path& p1, const path& p2, system::error_code& ec); + + uintmax_t <a href="#file_size">file_size</a>(const path& p); + uintmax_t <a href="#file_size">file_size</a>(const path& p, system::error_code& ec); + + uintmax_t <a href="#hard_link_count">hard_link_count</a>(const path& p); + uintmax_t <a href="#hard_link_count">hard_link_count</a>(const path& p, system::error_code& ec); + + const path& <a href="#initial_path">initial_path</a>(); + const path& <a href="#initial_path">initial_path</a>(<code>system::error_code& ec</code>); + + bool <a href="#is_directory">is_directory</a>(file_status s) noexcept; + bool <a href="#is_directory2">is_directory</a>(const path& p); + bool <a href="#is_directory2">is_directory</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_empty">is_empty</a>(const path& p); + bool <a href="#is_empty">is_empty</a>(const path& p, system::error_code& ec); + + bool <a href="#is_other">is_other</a>(file_status s) noexcept; + bool <a href="#is_other2">is_other</a>(const path& p,); + bool <a href="#is_other2">is_other</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_regular_file">is_regular_file</a>(file_status s) noexcept; + bool i<a href="#is_regular_file2">s_regular_file</a>(const path& p); + bool i<a href="#is_regular_file2">s_regular_file</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_symlink">is_symlink</a>(file_status s noexcept); + bool <a href="#is_symlink2">is_symlink</a>(const path& p); + bool <a href="#is_symlink2">is_symlink</a>(const path& p, system::error_code& ec) noexcept; + + std::time_t <a href="#last_write_time">last_write_time</a>(const path& p); + std::time_t <a href="#last_write_time">last_write_time</a>(const path& p, system::error_code& ec); + void <a href="#last_write_time2">last_write_time</a>(const path& p, const std::time_t new_time); + void <a href="#last_write_time2">last_write_time</a>(const path& p, const std::time_t new_time, system::error_code& ec); + + path <a href="#read_symlink">read_symlink</a>(const path& p); + path <a href="#read_symlink">read_symlink</a>(const path& p, system::error_code& ec); + + bool <a href="#remove">remove</a>(const path& p); + bool <a href="#remove">remove</a>(const path& p, system::error_code& ec); + + uintmax_t <a href="#remove_all">remove_all</a>(const path& p); + uintmax_t <a href="#remove_all">remove_all</a>(const path& p, system::error_code& ec); + + void <a href="#rename">rename</a>(const path& from, const path& to); + void <a href="#rename">rename</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#resize_file">resize_file</a>(const path& p, uintmax_t size); + void <a href="#resize_file2">resize_file</a>(const path& p, uintmax_t size, system::error_code& ec); + + <a href="#space_info">space_info</a> <a href="#space">space</a>(const path& p); + <a href="#space_info">space_info</a> <a href="#space">space</a>(const path& p, system::error_code& ec); + + <a href="#file_status">file_status</a> <a href="#status">status</a>(const path& p); + <a href="#file_status">file_status</a> <a href="#status">status</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#status_known">status_known</a>(file_status s) noexcept; + + <a href="#file_status">file_status</a> <a href="#symlink_status">symlink_status</a>(const path& p); + <a href="#file_status">file_status</a> <a href="#symlink_status">symlink_status</a>(const path& p, system::error_code& ec) noexcept; + + path <a href="#system_complete">system_complete</a>(const path& p); + path <a href="#system_complete">system_complete</a>(const path& p, system::error_code& ec); + + path <a href="#temp_directory_path">temp_directory_path</a>(); + path <a href="#temp_directory_path">temp_directory_path</a>(system::error_code& ec); + + path <a href="#unique_path">unique_path</a>(const path& model="%%%%-%%%%-%%%%-%%%%"); + path <a href="#unique_path">unique_path</a>(const path& model, system::error_code& ec); + + } // namespace filesystem +} // namespace boost</pre> +<h2><a name="Error-reporting">Error reporting</a></h2> +<p>Filesystem library functions often provide two overloads, one that +throws an exception to report file system errors, and another that sets an <code>error_code</code>.</p> +<blockquote> +<p>[<i>Note:</i> This supports two common use cases:</p> +<ul> + <li>Uses where file system +errors are truly exceptional and indicate a serious failure. Throwing an + exception is the most appropriate response. This is the preferred default for + most everyday programming.<br> + </li> + <li>Uses where file system system errors are routine and do not necessarily represent + failure. Returning an error code is the most appropriate response. This allows + application specific error handling, including simply ignoring the error.</li> +</ul> + <p><i>--end note</i>]</p> +</blockquote> +<p>Functions <b>not</b> having an argument of type <code>system::error_code&</code> report errors as follows, unless otherwise specified:</p> + <ul> + <li>When a call by the + implementation to an operating system or other underlying API results in an + error that prevents the function from meeting its specifications, an exception + of type +<code>filesystem_error</code> is thrown.<br> + </li> + <li>Failure to allocate storage is reported by throwing an exception as described in the C++ standard, + 17.6.4.10 [res.on.exception.handling].<br> + </li> + <li>Destructors throw nothing.</li> + </ul> + <p>Functions having an argument of type <code>system::error_code&</code> report errors as follows, unless otherwise + specified:</p> +<ul> + <li>If a call by the + implementation to an operating system or other underlying API results in an + error that prevents the function from meeting its specifications, the +<code>system::error_code&</code> argument is set as + appropriate appropriate for the specific error. Otherwise, <code>clear()</code> + is called on the +<code>system::error_code&</code> argument.<br> + </li> + <li>Failure to allocate storage is reported by + throwing an exception as described in the C++ standard, + 17.6.4.10 [res.on.exception.handling].</li> +</ul> +<h2><a name="class-path">Class <code>path</code></a></h2> +<p>An object of class <code>path</code> represents a <a href="#Path">path</a>, +and contains a <a href="#Pathname">pathname</a> Such an object is concerned only with the lexical and syntactic aspects +of a path. The path does not necessarily exist in external storage, and the +pathname is not necessarily valid for the current operating +system or for a particular file system.</p> +<pre>namespace boost +{ + namespace filesystem + { + class path + { + public: + typedef <b><i><a href="#value_type">see below</a></i></b> value_type; // char for ISO/IEC 9945, wchar_t for Windows + typedef std::basic_string<value_type> string_type; + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + constexpr value_type preferred_separator; + + // <a href="#path-constructors">constructors</a> and destructor + path(); + path(const path& p); + path(path&& p) noexcept; + + template <class <a href="#Source">Source</a>> + path(Source const& source, const codecvt_type& cvt=codecvt()); + + template <class <a href="#InputIterator">InputIterator</a>> + path(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt()); + + ~path(); + + // <a href="#path-assignments">assignments</a> + path& operator=(const path& p); + path& operator=(path&& p) noexcept; + + template <class <a href="#Source">Source</a>> + path& operator=(Source const& source); + + template <class <a href="#Source">Source</a>> + path& assign(Source const& source, const codecvt_type& cvt) + + template <class <a href="#InputIterator">InputIterator</a>> + path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt()); + + // <a href="#path-appends">appends</a> + path& operator/=(const path& p); + + template <class <a href="#Source">Source</a>> + path& operator/=(Source const& source); + + template <class <a href="#Source">Source</a>> + path& append(Source const& source, const codecvt_type& cvt); + + template <class <a href="#InputIterator">InputIterator</a>> + path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt()); + + // <a href="#path-concatenation">concatenation</a> + path& operator+=(const path& x); + path& operator+=(const string_type& x); + path& operator+=(const value_type* x); + path& operator+=(value_type x); + template <class Source> + path& operator+=(Source const& x); + template <class CharT> + path& operator+=(CharT x); + template <class Source> + path& concat(Source const& x, const codecvt_type& cvt); + template <class InputIterator> + path& concat(InputIterator begin, InputIterator end); + template <class InputIterator> + path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt); + + // <a href="#path-modifiers">modifiers</a> + void <a href="#path-clear">clear</a>(); + path& <a href="#absolute">make_absolute</a>(const path& base); + path& <a href="#path-make_preferred">make_preferred</a>(); // ISO/IEC 9945: no effect. Windows: convert slashes to backslashes + path& <a href="#path-remove_filename">remove_filename</a>(); + path& <a href="#path-replace_extension">replace_extension</a>(const path& new_extension = path()); + void <a href="#path-swap">swap</a>(path& rhs); + + // <a href="#path-native-format-observers">native format observers</a> + const string_type& <a href="#native">native</a>() const noexcept; // native format, encoding + const value_type* <a href="#c_str">c_str</a>() const noexcept; // native().c_str() + + template <class String> + String <a href="#string-template">string</a>(const codecvt_type& cvt=codecvt()) const; // native format + + const string <a href="#string">string</a>(const codecvt_type& cvt=codecvt()) const; // native format + const wstring <a href="#wstring">wstring</a>(const codecvt_type& cvt=codecvt()) const; // ditto + const u16string <a href="#u16string">u16string</a>() const; // ditto + const u32string <a href="#u32wstring">u32string</a>() const; // ditto + + // <a href="#path-generic-format-observers">generic format observers</a> + template <class String> + String <a href="#generic_string-template">generic_string</a>() const; + + const string <a href="#generic_string">generic_string</a>(const codecvt_type& cvt=codecvt()) const; // generic format + const wstring <a href="#generic_wstring">generic_wstring</a>(const codecvt_type& cvt=codecvt()) const; // ditto + const u16string <a href="#generic_u16string">generic_u16string</a>() const; // ditto + const u32string <a href="#generic_u32wstring">generic_u32string</a>() const; // ditto + + // <a href="#path-compare">compare</a> + int <a href="#path-compare">compare</a>(const path& p) const noexcept; + int <a href="#path-compare">compare</a>(const std::string& s) const; + int <a href="#path-compare">compare</a>(const value_type* s) const; + + // <a href="#path-decomposition">decomposition</a> + path <a href="#path-root_name">root_name</a>() const; + path <a href="#path-root_directory">root_directory</a>() const; + path <a href="#path-root_path">root_path</a>() const; + path <a href="#path-relative_path">relative_path</a>() const; + path <a href="#path-parent_path">parent_path</a>() const; + path <a href="#path-filename">filename</a>() const; + path <a href="#path-stem">stem</a>() const; + path <a href="#path-extension">extension</a>() const; + + // <a href="#path-query">query</a> + bool <a href="#path-query">empty</a>() const; + bool <a href="#path-has_root_name">has_root_name</a>() const; + bool <a href="#path-has_root_directory">has_root_directory</a>() const; + bool <a href="#path-has_root_path">has_root_path</a>() const; + bool <a href="#path-has_relative_path">has_relative_path</a>() const; + bool <a href="#path-has_parent_path">has_parent_path</a>() const; + bool <a href="#path-has_filename">has_filename</a>() const; + bool <a href="#path-has_stem">has_stem</a>() const; + bool <a href="#path-has_extension">has_extension</a>() const; + bool <a href="#path-is_absolute">is_absolute</a>() const; + bool <a href="#path-is_relative">is_relative</a>() const; + + // <a href="#path-iterators">iterators</a> + class iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + // <a href="#path_encoding">encoding conversion</a> + static std::locale <a href="#path-imbue">imbue</a>( const std::locale& loc ); + static const codecvt_type & <a href="#path-codecvt">codecvt</a>(); + + private: + string_type pathname; // <b><i>exposition only</i></b> + }; + + } // namespace filesystem +} // namespace boost</pre> +<p><code><a name="value_type">value_type</a></code> is an implementation-defined <code>typedef</code> for the +character type used by the operating system to represent pathnames.</p> +<p>Member functions described as returning <code>const string</code>, <code>const wstring</code>, <code>const u16string</code>, or <code>const u32string</code> are permitted to return <code>const string&</code>, <code>const +wstring&</code>, <code>const u16string&</code>, or <code>const u32string&</code>, +respectively.</p> +<blockquote> +<p>[<i>Note:</i> This allows implementations to avoid unnecessary copies when no +conversion is required. +Return-by-value is specified as <code>const</code> to ensure programs won't break if moved to a return-by-reference +implementation. <i>-- +end note</i>]</p> +</blockquote> +<h3><a name="path-Conversions"><code>path</code> Conversions</a></h3> +<h4><a name="path-Conversions-to-native-format"><code>path</code> Conversions to +native format</a></h4> +<p>Member function arguments that take character sequences representing paths +may use the <a href="#generic-pathname-format">generic pathname format</a> or +the <a href="#native-pathname-format">native pathname format</a>. If such an +argument uses the generic format, an implementation defined conversion to native format is performed +during the processing of the argument. </p> +<blockquote> +<p>[<i>Note:</i> No conversion occurs on ISO/IEC 9945 and Windows since they have +native formats that conform to the generic format. <i>--end note</i>]</p> +<p>[<i>Rationale:</i> There is no unambiguous way for an implementation to +always be able distinguish between native format and generic format arguments. +This is by design as it simplifies use. Should an implementation encounter an +operating system where disambiguation is required, an implementation defined +native format prefix can be introduced to identify the native format. <i>-- end +rationale</i>]</p> +</blockquote> + +<div align="center"> + <center> + +<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#E0E0E0" width="90%"> + <tr> + <td> + <i>Class <code>path</code> does not currently map invalid characters in + filenames to valid characters. In the future we might add something like + this:</i><blockquote> +<p><i>When converting filenames to the native operating system format, +implementations are encouraged, but not required, to convert otherwise invalid +characters or character sequences to valid characters or character sequences. +Such conversions are implementation-defined.</i></p> +<blockquote> +<p><i>[Note: Filename conversion allows much wider portability of both +programs and filenames that would otherwise be possible.</i></p> +<p><i>Implementations are encouraged to base conversion on existing standards or +practice. Examples include the Uniform Resource Locator escape syntax of a percent sign (<code>'%'</code>) +followed by two hex digits representing the character value. On OpenVMS, which does not allow percent signs in filenames, a dollar sign (<code>'$'</code>) +followed by two hex digits is the existing practice, as is converting lowercase +letters to uppercase. -- end note.]</i></p> +</blockquote> + </blockquote> + </td> + </tr> +</table> + + </center> +</div> + +<p>If the native format requires +paths for regular files to be formatted differently from paths for directories, the +path shall be treated as a directory path if last element is a separator, +otherwise it shall be treated as a regular file path.</p> + +<blockquote> + +<p>[<i>Note</i>: The above paragraph does not apply to ISO/IEC 9945 and Windows since +they use the same format +for both regular file and directory pathnames. <i>--end note</i>]</p> + +<p>[<i>Example:</i> On <a href="http://en.wikipedia.org/wiki/OpenVMS">OpenVMS</a>, a path +constructed from <code>"/cats/jane"</code> would considered a regular file +path, and have a native format of <code>"[CATS]JANE"</code>, while a +path constructed from <code>"/cats/jane/"</code> would be considered a +directory path, and have a native format of <code>"[CATS.JANE]"</code>. <i>--end example</i>]</p> + +</blockquote> +<h4><a name="path-Conversions-to-generic-format"><code>path</code> Conversions +to generic format</a></h4> +<p><a href="#path-generic-format-observers">Generic format observer</a> functions return strings formatted according to the <a href="#generic-pathname-format">generic pathname format</a>. The conversion +from generic to native formats is implementation defined.</p> +<blockquote> +<p>[<i>Note:</i> For ISO/IEC 9945, no conversion is performed. For Windows, backslashes are converted to +forward slashes. <i>-- end note</i>]</p> +</blockquote> +<h4><a name="path-Encoding-conversions"><code>path</code> Encoding conversions</a></h4> +<p>If the value type of member function arguments that are character sequences +representing paths is not <code>value_type</code>, +and no <code>cvt</code> argument is supplied, conversion to <code>value_type</code> occurs using an imbued locale. This imbued locale is initialized with a <code>codecvt</code> facet appropriate for the operating system.</p> +<blockquote> +<p>For Apple OS X implementations, <code>path::value_type</code> is <code>char</code>. The default imbued locale provides a UTF-8 <code>codecvt</code> facet. [<i>Rationale:</i> "All BSD system functions expect their string +parameters to be in UTF-8 encoding and nothing else." See <a href="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html">Apple docs</a>. <i>-- end rationale</i>]</p> +<p>For Windows-like implementations, including <a href="http://www.mingw.org/">MinGW</a>, <code>path::value_type</code> is <code>wchar_t</code>. The default imbued locale provides a <code>codecvt</code> facet +that invokes Windows <code>MultiByteToWideChar</code> or <code>WideCharToMultiByte</code> API with a codepage of <code>CP_THREAD_ACP</code> if Windows <code>AreFileApisANSI()</code>is true, otherwise codepage <code>CP_OEMCP</code>. [<i>Rationale:</i> this is the current behavior of C and C++ +programs that perform file operations using narrow character string to identify +paths. Changing this in the Filesystem library would be too surprising, +particularly where user input is involved. <i>-- end rationale</i>]</p> +<p>For all other implementations, including<b> </b>Linux, <code>path::value_type</code> is <code>char</code>. The default imbued locale is <code>std::locale("")</code>. +[<i>Rationale:</i> ISO C specifies this as "the locale-specific native +environment", while ISO/IEC 9945 says it "Specifies an implementation-defined native +environment." <i>-- end rationale</i>]</p> +</blockquote> +<h3><a name="path-Requirements"><code>path</code> Requirements</a></h3> +<p>Template parameters named <code><a name="InputIterator">InputIterator</a></code> are required meet the +requirements for a C++ standard library <code>RandomIterator</code> compliant iterator. The iterator's value type is required to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</p> +<p>Template parameters named <code><a name="Source">Source</a></code> are required to be one of:</p> +<ul> + <li>A container with a value type of <code>char</code>, <code> + wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li> + <li>An iterator for a null terminated byte-string. The value type is required + to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code> + char32_t</code>.</li> + <li>A C-array. The value type is required to be <code>char</code>, <code> + wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li> + <li>A <code>boost::filesystem::directory_entry</code>.</li> +</ul> + +<h3> <a name="path-constructors"> <code> +<font size="4">path</font></code> constructors</a></h3> +<pre><span style="background-color: #D7EEFF">path();</span></pre> +<blockquote> + <p><i>Postcondition:</i> <code>empty()</code>.</p> + </blockquote> +<pre>template <class <a href="#Source">Source</a>> + path(Source const& source, const codecvt_type& cvt=codecvt());</pre> +<pre>template <class <a href="#InputIterator">InputIterator</a>> + path(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());</pre> +<blockquote> + <p><i>Effects:</i> Stores the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> in <code>pathname</code>. If the contents are in the + generic format and the generic format is unacceptable to the operating + system's API, they are converted to the native format. [<i>Note:</i> For + ISO/IEC 9945 and Windows implementations, the generic format is already + acceptable as a native format, so no generic to native conversion is + performed. <i>--end note</i>]</p> + <p> + <i>Remarks:</i> If the value type of [<code>begin</code>,<code>end</code>) + or <code>source</code> is not <code>value_type</code>, conversion is performed + by <code>cvt</code>.</p> +</blockquote> +<h3> <a name="path-assignments"> <code> +<font size="4">path</font></code> assignments</a></h3> +<pre>template <class <a href="#Source">Source</a>> + path& operator=(Source const& source);</pre> +<pre>template <class <a href="#Source">Source</a>> + path& assign(Source const& source, const codecvt_type& cvt);</pre> +<pre>template <class <a href="#InputIterator">InputIterator</a>> + path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());</pre> +<blockquote> + <p><i>Effects:</i> Stores the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> in <code>pathname</code>. If the contents are in the + generic format, they are converted to the native format. [<i>Note:</i> For + ISO/IEC 9945 and Windows based implementations, the generic format is already + acceptable as a native format, so no generic to native conversion is + performed. <i>--end note</i>]</p> + <p> + <i>Returns: </i><code>*this</code></p> + <p> + <i>Remarks:</i> If the value type of [<code>begin</code>,<code>end</code>) + 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> + <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 + directory separator is implementation-defined.</p> +<blockquote> + <p align="left">[<i>Note: </i>For ISO/IEC 9945-like implementations, including<b> </b>Unix variants, Linux, and Mac OS X, the preferred directory separator is a + single forward slash.</p> + <p align="left">For Windows-like implementations, including <a href="http://www.cygwin.com/">Cygwin</a> and <a href="http://www.mingw.org/">MinGW</a>, the preferred directory + separator is a single backslash.<i>--end note</i>]</p> + </blockquote> +<pre>path& operator/=(const path& p);</pre> +<blockquote> + <p><i>Effects:</i></p> + <blockquote> + Appends the preferred directory separator to the contained pathname, unless:<ul> + <li>an added separator + would be redundant, or</li> + <li>would change an relative path to an absolute path, or</li> + <li><code>p.empty()</code>, or</li> + <li><code>*p.native().cbegin()</code> is a directory separator.</li> + </ul> + <p>Appends <code>p.native()</code> to <code>pathname</code>.</p> + </blockquote> + <p><i>Returns: </i><code>*this</code></p> +</blockquote> +<pre>template <class <a href="#Source">Source</a>> + path& operator/=(Source const & source);</pre> +<pre>template <class <a href="#Source">Source</a>> + path& append(Source const & source, const codecvt_type& cvt);</pre> +<pre>template <class <a href="#InputIterator">InputIterator</a>> + path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt());</pre> +<blockquote> + <p><i>Effects:</i></p> + <blockquote> + <p>Appends a native directory separator to the contained pathname, unless:</p> + <ul> + <li>an added separator + would be redundant, or</li> + <li>would change an relative path to an absoute path, or</li> + <li><code>p.empty()</code>, or</li> + <li><code>*p.native().cbegin()</code> is a separator.</li> + </ul> + <p>Appends the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> to <code>pathname</code>. If the contents are in the + generic format, they are converted to the native format. [<i>Note:</i> For + ISO/IEC 9945 and Windows based implementations, the generic format is already + acceptable as a native format, so no generic to native conversion is + performed. <i>--end note</i>]</p> + </blockquote> + <p><i>Remarks:</i> If the value type of [<code>begin</code>,<code>end</code>) + or <code>source</code> is not <code>value_type</code>, conversion is performed + by <code>cvt</code>.</p> + <p><i>Returns: </i><code>*this</code></p> + </blockquote> + +<h3><a name="path-concatenation"><code>path</code> concatenation</a></h3> +<pre>path& operator+=(const path& x); +path& operator+=(const string_type& x); +path& operator+=(const value_type* x); +path& operator+=(value_type x); +template <class Source> + path& operator+=(Source const& x); +template <class CharT> + path& operator+=(CharT x); +template <class Source> + path& concat(Source const& x, const codecvt_type& cvt); +template <class InputIterator> + path& concat(InputIterator begin, InputIterator end); +template <class InputIterator> + path& concat(InputIterator begin, InputIterator end, const codecvt_type& 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&</code>, otherwise</li> + <li><code>s</code>, where <code>s</code> is + <code>std::basic_string<typename std::iterator_traits<InputIterator>::value_type><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->empty()</code> is true.</p> +</blockquote> +<pre>path& <a name="path-make_preferred">make_preferred</a>();</pre> +<blockquote> + <p><i>Effects:</i> The contained pathname is converted to the preferred native + format. [<i>Note:</i> On Windows, the effect is to replace slashes with + backslashes. On ISO/IEC 9945, there is no effect. <i>-- end note</i>]</p> + <p><i>Returns:</i> <code>*this</code></p> +</blockquote> + +<pre>path& <a name="path-remove_filename">remove_filename</a>();</pre> +<blockquote> + <p><i>Returns: </i>As if, <code>*this = parent_path();</code></p> + <p>[<i>Note:</i> This function is needed to efficiently implement <code>directory_iterator</code>. It is exposed to allow additional uses. The actual + implementation may be much more efficient than <code>*this = parent_path()</code> <i>-- end + note</i>]</p> +</blockquote> +<pre>path& <a name="path-replace_extension">replace_extension</a>(const path& new_extension = path());</pre> +<blockquote> + <p><i>Effects:</i></p> + <ul> + <li>Any existing <code>extension()</code> is removed from the stored path, + then</li> + <li>iff + <code>new_extension</code> is not empty and does not begin with a dot + character, a dot character is appended to the stored path, then</li> + <li> + <code>new_extension</code> is appended to the stored path.</li> + </ul> + <p><i>Returns:</i> <code>*this</code></p> +</blockquote> +<pre><code>void <a name="path-swap">swap</a>(path& rhs) noexcept;</code></pre> +<blockquote> + <p><i>Effects:</i> Swaps the contents of the two paths.</p> + <p><i>Complexity: </i>constant time.</p> +</blockquote> + +<h3> <a name="path-native-format-observers"><code><font size="4">path</font></code> native format observers</a></h3> +<p>The string returned by all native format observers is in the <a href="#native-pathname-format">native pathname format</a>.</p> +<pre>const string_type& <a name="native">native</a>() const noexcept;</pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +</blockquote> +<pre>const value_type* <a name="c_str">c_str</a>() const noexcept;</pre> +<blockquote> +<p><i>Returns:</i> <code>pathname.c_str()</code>.</p> +</blockquote> +<pre>template <class String> +String <a name="string-template">string</a>(const codecvt_type& cvt=codecvt()) const;</pre> +<blockquote> + <p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than <code>String</code>, conversion is performed by <code>cvt</code>.</p> +</blockquote> +<pre>const string <a name="string">string</a>(const codecvt_type& cvt=codecvt()) const; +const wstring <a name="wstring">wstring</a>(const codecvt_type& cvt=codecvt()) const; +const u16string <a name="u16string">u16string</a>() const; +const u32wstring <a name="u32wstring">u32wstring</a>() const; </pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than +function's return type, conversion is performed by <code>cvt</code>.</p> +<p>If <code>string_type</code> is the same type as the +function's return type, the function is permitted to return by <code>const&</code> rather than <code>const</code> value. [<i>Note:</i> For +ISO/IEC 9945, this occurs for <code>string()</code>, for Windows, <code>wstring()</code>. <i>--end note</i>]</p> +</blockquote> + +<h3> <a name="path-generic-format-observers"><code><font size="4">path</font></code> generic format observers</a></h3> +<p>The string returned by all generic format observers is in the <a href="#generic-pathname-format">generic pathname format</a>.</p> +<p>[<i>Note:</i> For ISO/IEC 9945, no conversion occurs, since the native format and +generic format are the same. For Windows, backslashes are converted to slashes <i>--end note</i>]</p> +<pre>template <class String> +String <a name="generic_string-template">generic_string</a>(const codecvt_type& cvt=codecvt()) const;</pre> +<blockquote> + <p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than <code>String</code>, conversion is performed by <code>cvt</code>.</p> +</blockquote> +<pre>const string <a name="generic_string">generic_string</a>(const codecvt_type& cvt=codecvt()) const; +const wstring <a name="generic_wstring">generic_wstring</a>(const codecvt_type& cvt=codecvt()) const; +const u16string <a name="generic_u16string">generic_u16string</a>() const; +const u32wstring <a name="generic_u32wstring">generic_u32wstring</a>() const; </pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than +function's return type, conversion is performed by <code>cvt</code>.</p> +<p>If <code>string_type</code> is of the same type as the +function's return type, and the generic format is the same as the native format, +the function is permitted to return by <code>const&</code> rather than <code>const</code> value. [<i>Note:</i> For +ISO/IEC 9945, this occurs for <code>string()</code>. +It never occurs for Windows, because backslashes must be converted to slashes. <i>--end note</i>]</p> +</blockquote> + +<h3> <a name="path-compare"><code>path</code> compare</a></h3> +<pre>int compare(const path& p) const noexcept;</pre> +<blockquote> + <p><i>Returns:</i> A value less than 0 if the elements of <code>*this</code> are lexicographically less than the elements of <code>p</code>, otherwise a + value greater than 0 if the elements of <code>*this</code> are + lexicographically greater than the elements of <code>p</code>, otherwise 0.</p> + <p>Remark: The elements are determined as if by iteration over the half-open + range [<code>begin()</code>, <code>end()</code>) for <code>*this</code> and <code>p</code>.</p> +</blockquote> +<pre>int compare(const std::string& s) const</pre> +<blockquote> + <p><i>Returns:</i> <code>compare(path(s))</code>.</p> +</blockquote> +<pre>int compare(const value_type* s) const</pre> +<blockquote> + <p><i>Returns:</i> <code>compare(path(s))</code>.</p> +</blockquote> +<h3> <a name="path-decomposition"> <code><font size="4">path</font></code> decomposition</a></h3> +<p><span style="background-color: #E0E0E0"><i>See the <a href="#Path-decomposition-table">Path decomposition table</a> for examples +for values returned by decomposition functions. The <a href="tutorial.html#Using-path-decomposition">Tutorial</a> may also be +helpful.</i></span></p> +<pre>path <a name="path-root_name">root_name</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> <i>root-name,</i> if <code>pathname</code> includes <i>root-name</i>, otherwise <code>path()</code>. </p> +</blockquote> +<pre>path <a name="path-root_directory">root_directory</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> <i>root-directory</i>, if <code>pathname</code> includes <i>root-directory</i>, otherwise <code>path()</code>.</p> +<p>If <i>root-directory</i> is composed of <i>slash name</i>, <i>slash</i> is +excluded from the returned string.</p> +</blockquote> +<pre>path <a name="path-root_path">root_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>root_name() / root_directory()</code></p> +</blockquote> +<pre>path <a name="path-relative_path">relative_path</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> A <code>path</code> composed from <code>pathname</code>, if <code>!empty()</code>, beginning +with the first <i>filename</i> after <i>root-path</i>. Otherwise, <code>path()</code>.</p> +</blockquote> +<pre>path <a name="path-parent_path">parent_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>(empty() || begin() == --end()) ? path() : <i>pp</i></code>, where <code><i>pp</i></code> is constructed as if by + starting with an empty <code>path</code> and successively applying <code>operator/=</code> for each element in the range <code>begin()</code>, <code>--end()</code>.</p> +</blockquote> +<pre>path <a name="path-filename">filename</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>empty() ? path() : *--end()</code></p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").filename();</code> // outputs "<code>bar.txt</code>"</pre> + </blockquote> + <p> <i>--end example</i>]</p> +</blockquote> +<pre>path <a name="path-stem">stem</a>(const path& p) const;</pre> +<blockquote> + <p><i>Returns:</i> if <code>p.filename()</code>contains a dot but does not + consist solely of one or to two dots, returns + the substring of <code>p.filename()</code> starting at its beginning and + ending at the last dot (the dot is not included). Otherwise, + returns <code>p.filename()</code>.</p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").stem();</code> // outputs "<code>bar</code>" +path p = "foo.bar.baz.tar"; +for (; !p.extension().empty(); p = p.stem()) + std::cout << p.extension() << '\n'; + // outputs: .tar + // .baz + // .bar</pre> + </blockquote> + <p> <i>--end example</i>]</p> +</blockquote> +<pre>path <a name="path-extension">extension</a>(const path& p) const;</pre> +<blockquote> + <p><i>Returns:</i> if <code>p.filename()</code> contains a dot but does not + consist solely of one or to two dots, returns + the substring of <code>p.filename()</code> starting at the rightmost dot + and ending at the path's end. Otherwise, returns an empty <code>path</code> object. </p> + <p><i>Remarks:</i> Implementations are permitted but not required to define additional + behavior for file systems which append additional elements to extensions, such + as alternate data streams or partitioned dataset names.</p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").extension(); //</code> outputs "<code>.txt</code>"</pre> + </blockquote> + <p> <i>--end example</i>]</p> + <p>[<i>Note:<b> </b></i>The dot is included in the return value so that + it is possible to distinguish between no extension and an empty extension. See <a href="http://permalink.gmane.org/gmane.comp.lib.boost.devel/199744">http://permalink.gmane.org/gmane.comp.lib.boost.devel/199744</a> for more + extensive rationale. <i>-- end note</i>]</p> +</blockquote> +<h3> <a name="path-query"> <code><font size="4">path</font></code> query</a></h3> +<pre>bool <a name="path-empty">empty</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>m_pathname.empty()</code>.</p> +</blockquote> +<pre>bool <a name="path-has_root_path">has_root_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_path">root_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_root_name">has_root_name</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_name">root_name</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_root_directory">has_root_directory</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_directory">root_directory</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_relative_path">has_relative_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-has_relative_path">relative_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_parent_path">has_parent_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-parent_path">parent_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_filename">has_filename</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-filename">filename</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_stem">has_stem</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-stem">stem</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_extension">has_extension</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-has_extension">extension</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-is_absolute">is_absolute</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>true</code> if the elements of <code>root_path()</code> uniquely identify a directory, else <code>false</code>.</p> + <p>[<i>Note:</i> On ISO/IEC 9945,<code> path("/foo").is_absolute()</code> returns <code>true</code>. On Windows, <code>path("/foo").is_absolute()</code> returns <code>false</code>. <i>--end note</i>]</p> +</blockquote> +<pre>bool <a name="path-is_relative">is_relative</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!is_absolute()</code>.</p> +</blockquote> +<h3> <a name="path-iterators"> <code> +<font size="4">path</font></code> iterators</a></h3> +<p> Path iterators iterate over the elements of the stored pathname.</p> +<p> A <code>path::iterator</code> is a constant iterator satisfying all +the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional +iterators [lib.bidirectional.iterators]). Its <code>value_type</code> is <code>path</code>.</p> + <p>Calling any non-const member function of a <code>path</code> object + invalidates all iterators referring to elements of that object.</p> +<p> The forward traversal order is as follows:</p> +<ul> + <li>The <i>root-name</i> element, if present.</li> + <li>The <i>root-directory</i> element, if present, in the generic format. <i> + [note:</i> the generic format is required to ensure lexicographical + comparison works correctly. <i>-- end note</i>]</li> + <li>Each successive <i>filename</i> element, if present.</li> + <li><i>Dot</i>, if one or more trailing non-root <i>slash</i> + characters are present.</li> +</ul> + <p>The backward traversal order is the reverse of forward traversal.</p> + <pre>iterator begin() const;</pre> +<blockquote> + <p><i>Returns:</i> An iterator for the first present element in the traversal + list above. If no elements are present, the end iterator.</p> +</blockquote> +<pre>iterator end() const;</pre> +<blockquote> + <p><i>Returns:</i> The end iterator.</p> +</blockquote> + <h3><a name="path_encoding"><code><font size="4"> path</font></code> encoding</a> conversion</h3> + <pre>static std::locale <a name="path-imbue">imbue</a>(const std::locale& loc);</pre> +<blockquote> + <p><i>Effects:</i> Stores <code>loc</code> as the default locale for all + objects of type <code>path</code>.</p> + <p><i>Returns:</i> The previous default locale for all objects of type <code>path</code>.</p> +</blockquote> +<pre>static const codecvt_type& <a name="path-codecvt">codecvt</a>();</pre> +<blockquote> + <p><i>Returns:</i> The <code>codecvt</code> facet for the default locale for + all objects of type <code>path</code>.</p> +</blockquote> + + +<h3> <a name="path-deprecated-functions"><code><font size="4"> path</font></code> deprecated functions</a></h3> +<p> Several member functions from previous versions of <code>class path</code> have been deprecated, either because they have been renamed or because the +functionality is no longer desirable or has become obsolete.</p> +<p> Deprecated functions available by default; will be suppressed if <code>BOOST_FILESYSTEM_NO_DEPRECATED</code> is defined:</p> +<blockquote> + <pre>path& remove_leaf() { return remove_filename(); } +path leaf() const { return filename(); } +path branch_path() const { return parent_path(); } +bool has_leaf() const { return !m_path.empty(); } +bool has_branch_path() const { return !parent_path().empty(); }</pre> +</blockquote> +<p> Deprecated functions not available by default; will be supplied if <code>BOOST_FILESYSTEM_DEPRECATED</code> is defined:</p> +<blockquote> +<pre>const std::string file_string() const { return native_string(); } +const std::string directory_string() const { return native_string(); } +const std::string native_file_string() const { return native_string(); } +const std::string native_directory_string() const { return native_string(); } +const string_type external_file_string() const { return native(); } +const string_type external_directory_string() const { return native(); }</pre> +</blockquote> + +<h3> <a name="path-non-member-functions"> <code><font size="4">path</font></code> non-member functions</a></h3> + + <pre>bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2);</pre> +<blockquote> + <p><i>Returns:</i> <code>true</code> if the sequence of <code>native()</code> strings for the elements defined by the half-open range <code>[first1,last1)</code> is + lexicographically less than the sequence of <code>native()</code> strings for + the elements defined by the half-open range <code>[first2,last2)</code>. Returns <code>false</code> otherwise.</p> + <p><i>Remarks:</i> If two sequences have the same number of elements and their + corresponding elements are equivalent, then neither sequence is + lexicographically less than the other. If one sequence is a prefix of the + other, then the shorter sequence is lexicographically less than the longer + sequence. Otherwise, the lexicographical comparison of the sequences yields + the same result as the comparison of the first corresponding pair of elements + that are not equivalent.</p> + <p>[<i>Note:</i> A <code>path</code> aware <code>lexicographical_compare</code> algorithm is provided for historical reasons. <i>--end note</i>]</p> +</blockquote> +<pre>void swap( path& lhs, path& rhs )</pre> +<blockquote> + <p><i>Effects: </i><code>lhs.swap(rhs)</code>.</p> +</blockquote> +<pre>std::size_t <a name="hash_value">hash_value</a> (const path& p);</pre> +<blockquote> + <p><i>Returns:</i> A hash value for the path <code>p</code>. If + for two paths, <code>p1 == p2</code> then <code>hash_value(p1) == hash_value(p2)</code>.</p> + <p>This allows paths to be used with <a href="../../functional/hash/index.html">Boost.Hash</a>.</p> +</blockquote> +<pre>bool operator< (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>return lhs.compare(rhs.begin) < 0</code>.</p> +</blockquote> +<pre>bool operator<=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(rhs < lhs)</code>.</p> +</blockquote> +<pre>bool operator> (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>rhs < lhs</code>.</p> +</blockquote> +<pre>bool operator>=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs < rhs)</code>.</p> +</blockquote> +<pre>bool operator==(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs < rhs) && !(rhs < lhs)</code>.</p> + <p>[<i>Note:</i> <a name="Path-equality">Path equality</a> and path + equivalence have different semantics.</p> + <p>Equality is determined by the <code>path</code> non-member <code>operator==</code>, which considers the two path's lexical + representations only. Thus <code>path("foo") == "bar"</code> is never <code>true</code>.</p> + <p>Equivalence is determined by the <a href="#equivalent"><code>equivalent()</code></a> non-member function, which determines if two paths <a href="#Path">resolve</a> to the same file system entity. + Thus <code>equivalent("foo", "bar")</code> will be <code>true</code> when both paths resolve to the same file.</p> + <p>Programmers wishing to determine if two paths are "the same" must decide if + "the same" means "the same representation" or "resolve to the same actual + file", and choose the appropriate function accordingly. <i>-- end note</i>]</p> +</blockquote> +<pre>bool operator!=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs == rhs)</code>.</p> +</blockquote> +<pre>path operator/ (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>path(lhs) /= rhs</code>.</p> +</blockquote> +<h3> <a name="path-non-member-operators"><code><font size="4">path</font></code></a><a name="path-inserter-extractor"> inserter + and extractor</a></h3> +<p> The inserter and extractor delimit the string with double-quotes (<code>"</code>) +to ensure that paths with embedded spaces will round trip correctly. Ampersand (<code>&</code>) +is used as an escape character, so the path can itself contain double quotes.</p> +<pre>template <class Char, class Traits> +std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, + const path& p) +</pre> +<blockquote> + <p><i>Effects:</i> <code>os << <a href="../../io/doc/quoted_manip.html">boost::io::quoted</a>(p.string<std::basic_string<Char>>(), static_cast<Char>('&'));</code></p> + <p><i>Returns:</i> <code>os</code></p> +</blockquote> +<pre>template <class Char, class Traits> +inline std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is, + path& p) +</pre> +<blockquote> + <p><i>Effects: </i><code> std::basic_string<Char> str;<br> + is >> <a href="../../io/doc/quoted_manip.html">boost::io::quoted</a>(str, static_cast<Char>('&'));<br> + p = str;</code></p> + <p><i>Returns:</i> <code>is</code></p> + </blockquote> +<h3><a name="Class-filesystem_error">Class <code>filesystem_error</code></a></h3> +<pre>namespace boost +{ + namespace filesystem + { + class filesystem_error : public system_error + { + public: + filesystem_error(); + filesystem_error(const filesystem_error&); + <a href="#filesystem_error-2-arg">filesystem_error</a>(const std::string& what_arg, + system::error_code ec); + <a href="#filesystem_error-3-arg">filesystem_error</a>(const std::string& what_arg, + const path& p1, system::error_code ec); + <a href="#filesystem_error-4-arg">filesystem_error</a>(const std::string& what_arg, + const path& p1, const path& p2, system::error_code ec); + + filesystem_error& filesystem_error(const filesystem_error&); + ~filesystem_error(); + + filesystem_error& operator=(const filesystem_error&); + + const path& <a href="#filesystem_error-path1">path1</a>() const; + const path& <a href="#filesystem_error-path2">path2</a>() const; + + const char * <a href="#filesystem_error-what">what</a>() const; + }; + } // namespace filesystem +} // namespace boost</pre> +<p>The class template <code>filesystem_error</code> defines the type of +objects thrown as exceptions to report file system errors from functions described in this +reference documentation.</p> +<h4> <a name="filesystem_error-members"> <code>filesystem_error</code> members</a></h4> +<pre><a name="filesystem_error-2-arg">filesystem_error</a>(const std::string& what_arg, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%" bgcolor="#FFFFFF"><code> + runtime_error::what()</code></td> + <td width="82%" bgcolor="#FFFFFF"> + <code><i>what_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%"><code>path1().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + <tr> + <td width="18%"><code>path2().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + </table> +</blockquote> +<pre><a name="filesystem_error-3-arg">filesystem_error</a>(const std::string& what_arg, const path_type& p1, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%" valign="top"><code> + runtime_error::what()</code></td> + <td width="82%"> + <code><i>what_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>path1()</code></td> + <td width="82%">Reference to stored copy of <code>p1</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>path2().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + </table> +</blockquote> +<pre><a name="filesystem_error-4-arg">filesystem_error</a>(const std::string& what_arg, const path_type& p1, const path_type& p2, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code> + runtime_error::what()</code></td> + <td width="82%"> + <u> + <code><i>w</i></code></u><code><i>hat_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%"><code>path1()</code></td> + <td width="82%">Reference to stored copy of <code>p1</code></td> + </tr> + <tr> + <td width="18%"><code>path2()</code></td> + <td width="82%">Reference to stored copy of <code>p2</code></td> + </tr> + </table> +</blockquote> +<pre>const path& <a name="filesystem_error-path1">path1</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> Reference to copy of <code>p1</code> stored by the + constructor, or, if none, an empty path.</p> +</blockquote> +<pre>const path& <a name="filesystem_error-path2">path2</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> Reference to copy of <code>p2</code> stored by the + constructor, or, if none, an empty path.</p> +</blockquote> +<pre>const char* <a name="filesystem_error-what">what</a>() const;</pre> +<blockquote> + <p><i>Returns: </i>A string containing <code>runtime_error::what()</code>. The exact format is unspecified. + Implementations are encouraged but not required to include <code>path1.native_string()</code>if not empty, <code>path2.native_string()</code>if + not empty, and <code>system_error::what()</code> strings in the returned + string.</p> +</blockquote> +<h3><a name="Enum-file_type">Enum file_type</a></h3> +<p>This enum specifies constants uses to identify file types.</p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>Constant Name</b></td> + <td><b>Meaning</b></td> + </tr> + <tr> + <td><code>status_error</code></td> + <td>An error occurred while trying to obtain the status of the file. The + file simply not being found is <b><u>not</u></b> considered a status error. </td> + </tr> + <tr> + <td><code>file_not_found</code></td> + <td>The file could not be found</td> + </tr> + <tr> + <td><code>regular_file</code></td> + <td>Regular file</td> + </tr> + <tr> + <td><code>directory_file</code></td> + <td>Directory file</td> + </tr> + <tr> + <td><code>symlink_file</code></td> + <td>Symbolic link file</td> + </tr> + <tr> + <td><code>block_file</code></td> + <td>Block special file</td> + </tr> + <tr> + <td><code>character_file</code></td> + <td>Character special file</td> + </tr> + <tr> + <td><code>fifo_file</code></td> + <td>FIFO or pipe file</td> + </tr> + <tr> + <td><code>socket_file</code></td> + <td>Socket file</td> + </tr> + <tr> + <td><code>type_unknown</code></td> + <td>The file exists, but it is of a system specific type not covered by any + of the above cases.</td> + </tr> +</table> +<h3><a name="Enum-perms">Enum perms</a></h3> +<p>This enum specifies bitmask constants uses to identify file +permissions. The ISO/IEC 9945 standard specifies actual values, and those values have +been adopted here because they are very familiar and ingrained for many ISO/IEC +9945 +users.</p> +<blockquote> +<p>Caution: Operating systems do not always support permissions as described in +the table.</p> +<p>There is much variation in the meaning of <code><a href="#sticky_bit">sticky_bit</a></code>; do not use it unless you understand what it means for +your operating system.</p> +<p>There is much variation in how operating systems treat symlinks. See <code><a href="#symlink_perms">symlink_perms</a></code>.</p> +<p>Windows: All permissions except write are currently ignored. There is only a +single write permission; setting write permission for owner, group, or others +sets write permission for all, and removing write permission for owner, group, +or others removes write permission for all. </p> +</blockquote> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>Name</b></td> + <td align="center"><b>Value<br> + (octal)</b></td> + <td align="center"><b>ISO/IEC 9945<br> + macro</b></td> + <td><b>Definition or notes</b></td> + </tr> + +<tr><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> + <td> Read permission, owner</td> +</tr> +<tr><td><code>owner_write</code></td><td><code>0200</code></td><td> <code>S_IWUSR</code></td> + <td> Write permission, owner</td> +</tr> +<tr><td><code>owner_exe</code></td><td><code>0100</code></td><td> <code>S_IXUSR</code></td> + <td> Execute/search permission, owner</td> +</tr> +<tr><td><code>owner_all</code></td><td><code>0700</code></td><td> <code>S_IRWXU</code></td> + <td> Read, write, execute/search by owner; <code>owner_read | owner_write | owner_exe</code></td> +</tr> +<tr><td><code>group_read</code></td><td><code>040</code></td><td> <code>S_IRGRP</code></td> + <td> Read permission, group</td> +</tr> +<tr><td><code>group_write</code></td><td><code>020</code></td><td> <code>S_IWGRP</code></td> + <td> Write permission, group</td> +</tr> +<tr><td><code>group_exe</code></td><td><code>010</code></td><td> <code>S_IXGRP</code></td> + <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> +</tr> +<tr><td><code>others_read</code></td><td><code>04</code></td><td> <code>S_IROTH</code></td> + <td> Read permission, others</td> +</tr> +<tr><td><code>others_write</code></td><td><code>02</code></td><td> <code>S_IWOTH</code></td> + <td> Write permission, others</td> +</tr> +<tr><td><code>others_exe</code></td><td><code>01</code></td><td> <code>S_IXOTH</code></td> + <td> Execute/search permission, others</td> +</tr> +<tr><td><code>others_all</code></td><td><code>07</code></td><td> <code>S_IRWXO</code></td> + <td>Read, write, execute/search by others; <code>others_read | others_write | others_exe</code></td> +</tr> +<tr><td><code>all_all</code></td><td><code>0777</code></td><td> </td><td><code>owner_all | group_all | others_all</code></td> +</tr> +<tr><td><code>set_uid_on_exe</code></td><td><code>04000</code></td><td> <code>S_ISUID</code></td> + <td> Set-user-ID on execution</td> +</tr> +<tr><td><code>set_gid_on_exe</code></td><td><code>02000</code></td><td> <code>S_ISGID</code></td> + <td> Set-group-ID on execution</td> +</tr> +<tr><td><code><a name="sticky_bit">sticky_bit</a> </code></td><td><code>01000</code></td><td> <code>S_ISVTX</code></td> + <td> Meaning varies; see <a href="http://en.wikipedia.org/wiki/Sticky_bit">http:en.wikipedia.org/wiki/Sticky_bit</a></td> +</tr> +<tr><td><code><a name="perms_mask">perms_mask</a></code></td><td><code>07777</code></td><td> </td> + <td><code>all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit</code></td> +</tr> +<tr><td><code>perms_not_known</code></td><td><code>0xFFFF</code></td><td></td><td> + The permissions are not known, such as when a <code>file_status</code> object + is created without specifying the permissions</td> +</tr> +<tr><td> + <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> + <code>permissions()</code> removes the argument permission bits from the + file's current bits</td> +</tr> +<tr><td><code><a name="symlink_perms">symlink_perms</a></code></td><td><code>0x4000</code></td><td></td><td> + On ISO/IEC 9945 <code>permissions()</code> resolves symlinks unless <code>symlink_perms</code> is specified. + Meaningless on Windows as <code>permissions()</code> never resolves symlinks. + Meaningless on Mac OS X and some other BSD systems as <code>permissions()</code> always resolves symlinks. Get over it.</td> +</tr> + +</table> +<h3><a name="file_status">Class file_status</a></h3> +<pre>namespace boost +{ + namespace filesystem + { + class file_status + { + public: + + // <a href="#file_status-constructors">constructors</a> + file_status() noexcept; + explicit file_status(<a href="#file_type">file_type</a> ft, <a href="#Enum-perms">perms</a> prms = perms_not_known) noexcept; + + // compiler generated + file_status(const file_status&) noexcept; + file_status& operator=(const file_status&) noexcept; + ~file_status() noexcept; + + // <a href="#file_status-observers">observers</a> + <a href="#file_type">file_type</a> type() const noexcept; + <a href="#Enum-perms">perms</a> permissions() const noexcept; + + // <a href="#file_status-modifiers">modifiers</a> + void type(<a href="#file_type">file_type</a> ft) noexcept; + void permissions(<a href="#Enum-perms">perms</a> prms) noexcept; + }; + } // namespace filesystem +} // namespace boost</pre> +<p>An object of type <code>file_status</code> stores information about the type +and permissions of a file.</p> +<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(<a href="#file_type">file_type</a> ft, <a href="#Enum-perms">perms</a> prms = perms_not_known) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() == prms</code>.</p> +</blockquote> + <h4><a name="file_status-observers"><code>file_status</code> observers</a></h4> +<pre><a href="#file_type">file_type</a> 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> +</blockquote> +<pre><a href="#Enum-perms">perms</a> permissions() const noexcept;</pre> +<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><a name="file_status-modifiers"><code>file_status</code> modifiers</a></h4> +<pre>void type(<a href="#file_type">file_type</a> ft) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>type() == ft</code>.</p> +</blockquote> +<pre>void permissions(<a href="#Enum-perms">perms</a> prms) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>permissions() == prms</code>.</p> +</blockquote> +<h3><a name="Class-directory_entry">Class <code>directory_entry</code></a></h3> +<div> +<pre>namespace boost +{ + namespace filesystem + { + class directory_entry + { + public: + + // <a href="#directory_entry-constructors">constructors</a> and destructor + directory_entry(); + directory_entry(const directory_entry&); + explicit directory_entry(const path_type& p, file_status st=file_status(), + file_status symlink_st=file_status()); + ~directory_entry(); + + // <a href="#directory_entry-modifiers">modifiers</a> + directory_entry& operator=(const directory_entry&); + void assign(const path_type& p, file_status st=file_status(), + file_status symlink_st=file_status()); + void replace_filename(const path& p, file_status st=file_status(), + file_status symlink_st=file_status()); + + // <a href="#directory_entry-observers">observers</a> + const path& path() const; + file_status status() const; + file_status status(system::error_code& ec) const; + file_status symlink_status() const; + file_status symlink_status(system::error_code& ec) const; + + bool operator< (const directory_entry& rhs); + bool operator==(const directory_entry& rhs); + bool operator!=(const directory_entry& rhs); + bool operator< (const directory_entry& rhs); + bool operator<=(const directory_entry& rhs); + bool operator> (const directory_entry& rhs); + bool operator>=(const directory_entry& rhs); + private: + path_type m_path; // for exposition only + mutable file_status m_status; // for exposition only; stat()-like + mutable file_status m_symlink_status; // for exposition only; lstat()-like + }; + + } // namespace filesystem +} // namespace boost</pre> +</div> +<p>A <code>directory_entry</code> object stores a <code>path object</code>, +a <code>file_status</code> object for non-symbolic link status, and a <code>file_status</code> object for symbolic link status. The <code>file_status</code> objects act as value caches.</p> +<blockquote> +<p>[<i>Note:</i> Because <code>status()</code>on a pathname may be a very expensive operation, +some operating systems provide status information as a byproduct of directory +iteration. Caching such status information can result is significant time savings. Cached and +non-cached results may differ in the presence of file system races. <i>-- end note</i>]</p> +<p><span style="background-color: #E0E0E0"><i>Actual cold-boot timing of iteration over +a directory with 15,047 entries was six seconds for non-cached status queries +versus one second for cached status queries. Windows XP, 3.0 GHz processor, with +a moderately fast hard-drive. Similar speedups are expected on Linux and BSD-derived +systems that provide status as a by-product of directory iteration.</i></span></p> +</blockquote> +<h4> <a name="directory_entry-constructors"> <code>directory_entry </code>constructors</a></h4> +<pre>directory_entry();</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>file_status()</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>file_status()</code></td> + </tr> + </table> +</blockquote> +<pre>explicit directory_entry(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>p</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<h4> <a name="directory_entry-modifiers"> <code>directory_entry </code>modifiers</a></h4> +<pre>void assign(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>p</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<pre>void replace_filename(const path& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>path().branch() / s</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<h4> <a name="directory_entry-observers"> <code>directory_entry</code> observers</a></h4> +<pre>const path& path() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path</code></p> +</blockquote> +<pre>file_status status() const; +file_status status(system::error_code& ec) const;</pre> +<blockquote> +<p><i>Effects:</i> As if,</p> + <blockquote> + <pre>if ( !status_known( m_status ) ) +{ + if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) ) + { m_status = m_symlink_status; } + else { m_status = status(m_path<i>[, ec]</i>); } +}</pre> + </blockquote> + <p><i>Returns:</i> <code>m_status</code></p> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>file_status symlink_status() const; +file_status symlink_status(system::error_code& ec) const;</pre> +<blockquote> +<p> + <i>Effects:</i> As if,</p> + <blockquote> + <pre>if ( !status_known( m_symlink_status ) ) +{ + m_symlink_status = symlink_status(m_path<i>[, ec]</i>); +}</pre> + </blockquote> + <p><i>Returns:</i> <code>m_symlink_status</code></p> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>bool operator==(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path == rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator!=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path != rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator< (const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path < rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator<=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path <= rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator> (const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path > rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator>=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path >= 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 +compliant iteration over the contents of a directory. Also see class <code><a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a></code>.</p> +<pre>namespace boost +{ + namespace filesystem + { + class directory_iterator + { + public: + // <a href="#directory_iterator-members">member functions</a> + + directory_iterator() noexcept; // creates the "end" iterator + directory_iterator(const directory_iterator&); + explicit directory_iterator(const path& p); + directory_iterator(const path& p, system::error_code& ec); + ~directory_iterator(); + + directory_iterator& operator=(const directory_iterator&); + + directory_iterator& operator++(); + directory_iterator& increment(system::error_code& ec); + + // other members as required by + // C++ Std, 24.1.1 Input iterators [input.iterators] + }; + + } // namespace filesystem +} // namespace boost</pre> +<p> <code>directory_iterator</code> satisfies the requirements of an +input iterator (C++ Std, 24.2.1, Input iterators [input.iterators]).</p> +<p>A <code>directory_iterator</code> reads successive elements from the directory for +which it was constructed, as if by calling <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/readdir_r.html">readdir_r()</a></code>. After a <code>directory_iterator</code> is constructed, and every time <code>operator++</code> is called, +it reads a directory element and stores information about it in a object of type <code><a href="#Class-directory_entry">directory_entry</a></code>. <code>operator++</code> is not equality preserving; that is, <code>i == j</code> does not imply that <code>++i == ++j</code>. </p> +<blockquote> +<p>[<i>Note:</i> The practical consequence of not preserving equality is that directory iterators +can only be used for single-pass algorithms. <i>--end note</i>]</p> +</blockquote> +<p>If the end of the directory elements is reached, the iterator becomes equal to +the end iterator value. The constructor <code>directory_iterator()</code> with no arguments always constructs an end iterator object, which is the only +legitimate iterator to be used for the end condition. The result of <code>operator*</code> on an end iterator is not defined. For any other iterator value +a <code>const directory_entry&</code> is returned. The result of <code>operator-></code> on an end iterator is not defined. For any other iterator value a <code>const directory_entry*</code> is +returned. </p> +<p>Two end iterators are always equal. An end iterator is not equal to a non-end +iterator.</p> +<blockquote> +<p><i><span style="background-color: #E0E0E0">The above wording is based on the +Standard Library's istream_iterator wording.</span></i></p> +</blockquote> +<p>The result of calling the <code>path()</code> member of the <code>directory_entry</code> object obtained by dereferencing a <code>directory_iterator</code> is a reference to a <code>path</code> object composed of the directory argument from which the iterator was +constructed with filename of the directory entry appended as if by <code>operator/=</code>. </p> +<p>Directory iteration shall not yield directory entries for the current (<i>dot</i>) +and parent (<i>dot dot</i>) directories.</p> +<p>The order of directory entries obtained by dereferencing successive +increments of a <code>directory_iterator</code> is unspecified.</p> +<blockquote> +<p>[<i>Note:</i> Programs performing directory iteration may wish to test if the +path obtained by dereferencing a directory iterator actually exists. It could be +a +symbolic link to a non-existent file. Programs recursively +walking directory trees for purposes of removing and renaming entries may wish +to avoid following symbolic links.</p> +<p>If a file is removed from or added to a directory after the +construction of a <code>directory_iterator</code> for the directory, it is +unspecified whether or not subsequent incrementing of the iterator will ever +result in an iterator whose value is the removed or added directory entry. See <i> +ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/readdir_r.html">readdir_r()</a></code>. <i>--end note</i>]</p> +</blockquote> +<h4><a name="directory_iterator-members"><code>directory_iterator</code> members</a></h4> + +<p><code><a name="directory_iterator-default-ctor">directory_iterator</a>() +noexcept;</code></p> + +<blockquote> + +<p><i>Effects:</i> Constructs the end iterator.</p> + +</blockquote> + +<pre><code>explicit <a name="directory_iterator-ctor-path">directory_iterator</a>(</code>const path& p<code>); +directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre> +<blockquote> + +<p><i>Effects:</i> Constructs a iterator representing the first +entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +<p>[<i>Note:</i> To iterate over the current directory, use <code>directory_iterator(".")</code> rather than <code>directory_iterator("")</code>. <i>-- end note</i>]</p> +</blockquote> +<pre>directory_iterator& <a name="directory_iterator-increment">operator++</a>(); +directory_iterator& increment(system::error_code& ec);</pre> +<blockquote> + +<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators]</p> + +<p><i>Returns:</i> <code>*this</code>.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<h3><a name="Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a></h3> +<p>Objects of type <code>recursive_directory_iterator</code> provide standard library +compliant iteration over the contents of a directory, including recursion into +its sub-directories.</p> +<pre>namespace boost +{ + namespace filesystem + { + class recursive_directory_iterator : + public iterator<input_iterator_tag, directory_entry> + { + public: + + // constructors and destructor + recursive_directory_iterator() noexcept; + recursive_directory_iterator(const recursive_directory_iterator&); + explicit recursive_directory_iterator(const path& p, + <a href="#symlink_option">symlink_option</a> opt = symlink_option::none); + recursive_directory_iterator(const path& p, + <a href="#symlink_option">symlink_option</a> opt, system::error_code& ec); + recursive_directory_iterator(const path& p, system::error_code& ec); + ~recursive_directory_iterator(); + + // observers + int level() const noexcept; + bool no_push<code>_pending</code>() const noexcept; + + // modifiers + recursive_directory_iterator& operator=(const recursive_directory_iterator&); + + recursive_directory_iterator& operator++(); + recursive_directory_iterator& increment(system::error_code& ec); + + void pop(); + void no_push(bool value=true); + + // other members as required by + // C++ Std, Input iterators [input.iterators] + + private: +<i><b> // actual data members will probably be stored in a shared object, + // or some similar mechanism, to achieve the required input iterator + // copy semantics +</b></i> int m_level; <b><i> // for exposition only</i></b> + bool m_no_<code>push</code>; <i><b>// for exposition only + </b></i><a href="#symlink_option">symlink_option</a> m_options; <i><b>// for exposition only</b></i> + }; + + } // namespace filesystem +} // namespace boost</pre> + +<p>The behavior of a <code>recursive_directory_iterator</code> is the same +as a <code>directory_iterator</code> unless otherwise specified.</p> +<ul> + <li>Incrementing a <code>recursive_directory_iterator</code> pointing to a + directory causes that directory itself to be iterated ovee, as specified by + the <code>operator++</code> and <code>increment</code> functions.<br> + </li> + <li>When a <code>recursive_directory_iterator</code> reaches the end of the directory currently being iterated + over, or when <code>pop()</code> is called, <code>m_level</code> is + decremented, and iteration of the parent directory continues.</li> +</ul> +<pre>recursive_directory_iterator() noexcept;</pre> +<blockquote> + +<p><i>Effects:</i> Constructs the end iterator.</p> + +</blockquote> + +<pre>explicit recursive_directory_iterator(const path& p, <a href="#symlink_option">symlink_option</a> opt = symlink_option::none); +recursive_directory_iterator(const path& p, <a href="#symlink_option">symlink_option</a> opt, system::error_code& ec); +recursive_<code>directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre> +<blockquote> + +<p><i>Effects:</i> Constructs a iterator representing the first +entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p> + +<p><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 && no_push_pending() == false && 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 <a href="#Error-reporting">Error reporting</a>.</p> + +<p>[<i>Note:</i> To iterate over the current directory, use <code>recursive_directory_iterator(".")</code> rather than <code>recursive_directory_iterator("")</code>. <i>-- end note</i>]</p> + +<p>[<i>Note:</i> By default, <code>recursive_directory_iterator</code> does not +follow directory symlinks. To follow directory symlinks, specify <code>opt</code> as <code>symlink_option::recurse</code> <i>-- end note</i>]</p> +</blockquote> +<pre>int level() const noexcept;</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Returns:</i> <code>m_level</code>.</p> +</blockquote> +<pre>bool <code>no_push_pending</code>() const noexcept;</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Returns:</i> <code>m_no_push</code>.</p> +</blockquote> +<pre><code>recursive_directory_iterator</code>& <a name="recursive_directory_iterator-increment">operator++</a>(); +recursive_directory_iterator& increment(system::error_code& ec);</pre> +<blockquote> + +<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators], +except:</p> + +<ul> + <li> + +<p>if <code>!no_push_pending() && is_directory(this->status()) +&& (!is_symlink(this->symlink_status()) || (m_options & symlink_option::recurse) != 0)</code> then <code>m_level</code> is incremented and directory <code>(*this)->path()</code> is recursively iterated into.<br> + </p> + + </li> + <li>if there are no more directory entries at this level then <code>m_level</code> +is decremented and iteration of the parent directory resumes.</li> +</ul> + +<p><i>Postcondition:</i> <code>no_push_pending() == false</code>.</p> + +<p><i>Returns:</i> <code>*this</code>.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void pop();</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Effects:</i> If <code>level() == 0</code>, set <code>*this</code> to <code>recursive_directory_iterator()</code>. + Otherwise, <code>--m_level</code>, cease iteration of the directory currently being + iterated over, and continue iteration over the parent directory.</p> +</blockquote> +<pre>void no_push(bool value=true);</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> +<p><i>Postcondition:</i> <code>no_push_pending() == value</code>.</p> + <p>[<i>Note:</i> <code>no_push()</code> is used to prevent + unwanted recursion into a directory. <i>--end note</i>]</p> +</blockquote> +<h3><a name="Operational-functions">Operational functions</a></h3> +<p>Operational functions query or modify files, including directories, in external +storage.</p> +<p>Operational functions access a file by resolving an +object of class <code>path</code> to a particular file in a file hierarchy. The +path is resolved as if by the <i>ISO/IEC 9945</i> <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">Pathname Resolution</a> mechanism.</p> +<p>[<i>Note: </i>Because hardware failures, network failures, <a href="#Race-condition">file system races</a>, and many +other kinds of errors occur frequently in file system operations, users should be aware +that any filesystem operational function, no matter how apparently innocuous, may encounter +an error. See <a href="#Error-reporting">Error reporting</a>. <i>-- end note</i>]</p> +<h4><a name="Function-specifications">Operational function specifications</a></h4> +<pre>path <a name="absolute">absolute</a>(const path& p, const path& base=current_path());</pre> + <blockquote> + <p><i>Returns:</i> A <a href="#Absolute-path">absolute path</a> composed according to the + following table</p> + <table border="1" cellpadding="5" cellspacing="0" bordercolor="#111111" style="border-collapse: collapse"> + <tr> + <td align="center"> </td> + <td align="center"><b><code>p.has_root_directory()</code></b></td> + <td align="center"><b><code>!p.has_root_directory()</code></b></td> + </tr> + <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> + / absolute(base).relative_path() / p.relative_path()</code></td> + </tr> + <tr> + <td align="center"><b><code>!p.has_root_name()</code></b></td> + <td align="center"><code>return absolute(base).root_name()<br> + / p</code></td> + <td align="center"><code>return absolute(base) / p</code></td> + </tr> + </table> + <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> +<pre>path <a name="canonical">canonical</a>(const path& p, const path& base = current_path()); +path canonical(const path& p, system::error_code& ec); +path canonical(const path& p, const path& base, system::error_code& ec);</pre> +<blockquote> +<p><i>Overview:</i> Converts <code>p</code>, which must exist, to an absolute +path that has no symbolic link, <a href="#Dot">dot</a>, +or <a href="#Dot">dot-dot</a> elements. </p> +<p><i>Returns:</i> A <a href="#Canonical-path">canonical path</a> that refers to +the same file system object as <code>absolute(p,base)</code>. For the overload +without a <code>base</code> argument, <code>base</code> is <code>current_path()</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + + <p><i>Remarks:</i> <code>!exists(p)</code> is an error.</p> + + <p>[<i>Note:</i> Canonical pathnames allow security checking of a path (eg. + does this path live in /home/goodguy or /home/badguy?) -- end note]</p> + +</blockquote> +<pre>void <a name="copy">copy</a>(const path& from, const path& to); +void copy(const path& from, const path& to, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> As if</p> + + <blockquote> + <pre>file_status s(symlink_status(from<i>[</i><code>, ec</code><i>]</i>)); +if(is_symlink(s)) + copy_symlink(from, to<i>[</i><code>, ec</code><i>]</i>); +else if(is_directory(s)) + copy_directory(from, to<i>[</i><code>, ec</code><i>]</i>); +else if(is_regular_file(s)) + copy_file(from, to, copy_option::fail_if_exists<i>[</i><code>, ec</code><i>]</i>); +else +<i> Report error as specified in <a href="#Error-reporting">Error reporting</a>.</i></pre> + </blockquote> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void <a name="copy_directory">copy_directory</a>(const path& from, const path& to); +void copy_directory(const path& from, const path& to, system::error_code& ec);</pre> +<blockquote> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" width="90%" bgcolor="#E0E0E0"> + <tr> + <td width="100%"> + <p><i>This function is poorly named; it should probably be an overload of + <code>create_directory</code> with an additional argument.</i></td> + </tr> + </table> + + <p><i>Effects: </i>Creates directory <code>to</code>, with + attributes copied from directory <code>from</code>. The set of attributes + copied is operating system dependent.</p> + +<blockquote> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" width="90%" bgcolor="#E8FFE8"> + <tr> + <td width="100%"> + <p>[<i>Note:</i> For ISO 9945/POSIX based operating systems the + attributes are those copied by native API <code>stat(from.c_str(), &from_stat)</code> + followed by <code>mkdir(to.c_str(),from_stat.st_mode)</code>. For + Windows based operating systems the attributes are those copied by native + API <code>CreateDirectoryExW(from.c_str(), to.c_str(), 0)</code>. <i> + --end note</i>]</td> + </tr> + </table> +</blockquote> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void copy_file(const path& from, const path& to); +void copy_file(const path& from, const path& to, system::error_code& 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>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void <a name="copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option); +void <a name="copy_file2">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists && 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 <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink); +void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& 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>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>bool <a name="create_directories">create_directories</a>(const path& p); +bool <a name="create_directories2">create_directories</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition by calling <code> + create_directory()</code> for any element of <code>p</code> that does not + exist.</p> + <p><i>Postcondition:</i> <code>is_directory(p)</code></p> + <p><i>Returns:</i> <code>true</code> if a new directory was created, otherwise <code> + false</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Complexity:</i> <i>O(n+1)</i> where <i>n</i> is the number of elements + of <code>p</code> that do not exist.</p> +</blockquote> +<pre>bool <a name="create_directory">create_directory</a>(const path& p); +bool <a name="create_directory2">create_directory</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition by attempting to create the + directory <code>p</code> resolves to, as if by<i> ISO/IEC 9945 </i><code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/mkdir.html"> + mkdir()</a></code> with a second argument of S_IRWXU|S_IRWXG|S_IRWXO. Creation + failure because <code>p</code> resolves to an existing directory shall not be + treated as an error. </p> + <p><i>Postcondition:</i> <code>is_directory(p)</code></p> + <p><i>Returns:</i> <code>true</code> if a new directory was created, otherwise <code>false</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink); +void create_directory_symlink(const path& to, const path& new_symlink, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">symlink()</a></code>.</p> + <p><i> + 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 <a href="#Error-reporting">Error reporting</a>.</p> + <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. + Some file systems do not + support + symbolic links regardless of the operating system - the FAT file system used on + memory cards and flash drives, for example. <i>-- end note</i>]</p> + </blockquote> +<pre>void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link); +void <a name="create_hard_link2">create_hard_link</a>(const path& to, const path& new_hard_link, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">link()</a></code>.</p> + <p><i>Postcondition:</i></p> + <ul> + <li> <code>exists(to) && + exists(</code><code>new_hard_link</code><code>) && equivalent(to, + + </code><code>new_hard_link</code><code>)</code></li> + <li>The contents of the file or directory + <code>to</code> resolves to are unchanged.</li> + </ul> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> Some operating systems do not support hard links at all or support + them only for regular files. Some file systems do not support hard + links regardless of the operating system - the FAT file system used on memory + cards and flash drives, for example. Some file systems limit the number of + links per file. <i>-- end note</i>]</p> + </blockquote> +<pre>void <a name="create_symlink">create_symlink</a>(const path& to, const path& new_symlink); +void <a name="create_symlink2">create_symlink</a>(const path& to, const path& new_symlink, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">symlink()</a></code>.</p> + <p><i> + 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 <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> Some operating systems do not support symbolic links at all or support + them only for regular files. + Some file systems do not + support + symbolic links regardless of the operating system - the FAT system used on + memory cards and flash drives, for example. <i>-- end note</i>]</p> + </blockquote> +<pre>path <a name="current_path">current_path</a>(); +path <a name="current_path2">current_path</a>(system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> The current working directory path, as if by <i>ISO/IEC + 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/getcwd.html">getcwd()</a></code>. <code>is_absolute()</code> is true for the returned path.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The <code>current_path()</code> name was chosen to emphasize that the return is a + path, not just a single directory name.</p> + <p>The current path as returned by many operating systems is a dangerous + global variable. It may be changed unexpectedly by a third-party or system + library functions, or by another thread. <i>-- end note</i>]</p> +</blockquote> +<pre>void current_path(const path& p); +void current_path(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/chdir.html">chdir()</a></code>.</p> +<p><i>Postcondition:</i> <code>equivalent(p, current_path())</code>.</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The current path for many operating systems is a dangerous + global state. It may be changed unexpectedly by a third-party or system + library functions, or by another thread. <i>-- end note</i>]</p> +</blockquote> +<pre>bool <a name="exists">exists</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>status_known(s) && s.type() != file_not_found</code></p> +</blockquote> +<pre>bool <a name="exists2">exists</a>(const path& p); +bool <a name="exists3">exists</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p dir="ltr"><i>Returns:</i> <code>exists(status(p))</code> or <code>exists(status(p, ec))</code>, + respectively. If ec != 0 and an error</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre><code>bool <a name="equivalent">equivalent</a>(const path& p1, const path& p2); +bool <a name="equivalent2">equivalent</a>(const path& p1, const path& p2, system::error_code& ec);</code></pre> +<blockquote> + <p><i>Effects:</i> Determines <code>file_status s1</code> and <code>s2</code>, as if by <code>status(p1)</code> and <code>status(p2)</code>, + respectively.</p> + <p><i>Returns:</i> <code>true</code>, if <code>sf1 == + sf2</code> and <code>p1</code> and <code>p2</code> resolve to the same file + system entity, else <code>false</code>.</p> + <blockquote> + <p>Two paths are considered to resolve to the same + file system entity if two candidate entities reside on the same device at the + same location. This is determined as if by the values of the <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure<code>,</code> obtained as if by <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code> for the two paths, having equal <code>st_dev</code> values + and equal <code>st_ino</code> values.</p> + <p>[<i>Note:</i> <i>ISO/IEC 9945</i> requires that <i>"st_dev</i> must be unique within a Local Area Network". Conservative <i> + ISO/IEC 9945</i> implementations may also wish to check for equal <code>st_size</code> and <code>st_mtime</code> values. <i>Windows</i> implementations may use <code>GetFileInformationByHandle()</code> as a surrogate for <code>stat()</code>, + and consider "same" to be equal values for <code>dwVolumeSerialNumber</code>, <code>nFileIndexHigh</code>, <code>nFileIndexLow</code>, <code>nFileSizeHigh</code>, <code>nFileSizeLow</code>, <code>ftLastWriteTime.dwLowDateTime</code>, and <code>ftLastWriteTime.dwHighDateTime</code>. <i>-- end note</i>]</p> + </blockquote> + <p><i>Throws:</i> <code>filesystem_error</code> if <code>(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))</code>, + otherwise as specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<div> +<pre>uintmax_t <a name="file_size">file_size</a>(const path& p); +uintmax_t <a name="file_size2">file_size</a>(const path& p, system::error_code& ec);</pre> +</div> +<blockquote> + <p><i>Returns:</i> If <code>exists(p) && is_regular_file(p)</code>, the size + in bytes + of the file <code>p</code> resolves to, determined as if by the value of + the <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure member <code>st_size</code> obtained as if by <i> + ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>. + Otherwise, <code>static_cast<uintmax_t>(-1)</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>uintmax_t <a name="hard_link_count">hard_link_count</a>(const path& p); +uintmax_t hard_link_count(const path& p, system::error_code& ec);</pre> +<blockquote> + + <p><i>Returns:</i> The number of hard links for <code>p</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> + +<pre>const path& <a name="initial_path">initial_path</a>(); +const path& <a name="initial_path2">initial_path</a>(<code>system::error_code& ec</code>);</pre> +<blockquote> + <p><i>Returns:</i> <code>current_path()</code> as of the first call to <code>initial_path()</code>.</p> + <p>[<i>Note:</i> <code>initial_path()</code> is not thread safe, and may return an undesirable result + if called subsequent to a change to the current directory. These problems can + be avoided by calling <code>initial_path()</code> immediately on entry to + main(). <i>--end note</i>]</p> + <p><i>Throws:</i> For the first call, as specified in <a href="#Error-reporting">Error reporting</a>. Subsequent calls throw nothing.</p> +</blockquote> +<pre>bool <code><a name="is_directory">is_directory</a></code>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() == directory_file</code></p> +</blockquote> +<pre><code>bool <a name="is_directory2">is_directory</a>(const path& p); +bool <a name="is_directory3">is_directory</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <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&</code> throws +nothing.</p> +</blockquote> +<pre><code>bool <a name="is_empty">is_empty</a>(const path& p); +bool <a name="is_empty2">is_empty</a></a>(const path& p, system::error_code& ec);</code></pre> +<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> + ? directory_iterator(p) == directory_iterator()<br> + : 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> +<blockquote> + <p><i>Returns:</i> <code>s.type() == regular_file</code></p> +</blockquote> +<pre><code>bool <a name="is_regular_file2">is_regular_file</a>(const path& p);</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_regular_file(status(p))</code>.</p> + <p><i>Throws:</i> <code>filesystem_error</code> if <code>status(p)</code> would throw <code>filesystem_error.</code></p> + </blockquote> +<pre><code>bool <a name="is_regular_file3">is_regular_file</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Effects:</i> Sets <code>ec</code> as if by <code>status(p, ec)</code>. [<i>Note:</i> <code>status_error</code>, <code>file_not_found</code> and <code>type_unknown</code> cases set <code>ec</code> to error values. To distinguish between cases, call the <code>status</code> function directly. <i>-- end + note</i>] </p> + <p><i>Returns:</i> <code>is_regular_file(status(p, ec))</code>.</p> +</blockquote> +<pre>bool <a name="is_other">is_other</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)</code></p> +</blockquote> +<pre><code>bool <a name="is_other2">is_other</a>(const path& p); +bool <a name="is_other3">is_other</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_other(status(p))</code> or <code>is_other(status(p, ec))</code>, + respectively.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>bool <a name="is_symlink">is_symlink</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() == symlink_file</code></p> +</blockquote> +<pre><code>bool <a name="is_symlink2">is_symlink</a>(const path& p); +bool <a name="is_symlink3">is_symlink</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_symlink(symlink_status(p))</code> or <code>is_symlink(symlink_status(p, ec))</code>, + respectively.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>std::time_t <a name="last_write_time">last_write_time</a>(const path& p); +std::time_t <a name="last_write_time2">last_write_time</a>(const path& p<code>, system::error_code& ec</code>);</pre> +<blockquote> + <p><i>Returns:</i> The time of last data modification of <code>p</code>, determined as if by the + value of the <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure member <code>st_mtime</code> obtained + as if by <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="last_write_time3">last_write_time</a>(const path& p, const std::time_t new_time); +void <a name="last_write_time4">last_write_time</a>(const path& p, const std::time_t new_time<code>, system::error_code& ec</code>);</pre> +<blockquote> + <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>ISO/IEC + 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code> followed by <i> + ISO/IEC 9945</i> <a href="http://www.opengroup.org/onlinepubs/000095399/functions/utime.html"><code>utime()</code></a>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</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 + with coarse time granularity. <i>-- end note</i>]</p> +</blockquote> +<pre>void <a name="permissions">permissions</a>(const path& p, <a href="#symlink_perms">perms</a> prms); +void permissions(const path& p, <a href="#symlink_perms">perms</a> prms, system::error_code& ec);</pre> +<blockquote> + <p> + <i>Requires:</i> <code>!((prms & add_perms) && (prms & remove_perms))</code>.</p> + <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> + ISO/IEC 9945</i> <code><a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html">fchmodat()</a></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> + <td><b>bits present in <code>prms</code></b></td> + <td><b>Effective bits applied</b></td> + </tr> + <tr> + <td>Neither <code>add_perms</code> nor <code>remove_perms</code></td> + <td><code>prms & perms_mask</code></td> + </tr> + <tr> + <td><code>add_perms</code></td> + <td> + <p><code>status(p).permissions() | (prms & <a href="#perms_mask">perms_mask</a>)</code> </td> + </tr> + <tr> + <td><code>remove_perms</code></td> + <td><code>status(p)</code><code>.permissions() & ~(prms & <a href="#perms_mask">perms_mask</a>) </code></td> + </tr> + </table> + <p>[<i>Note:</i> Conceptually permissions are viewed as bits, but the actual + implementation may use some other mechanism. -- <i>end note</i>]</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>path <a name="read_symlink">read_symlink</a>(const path& p); +path read_symlink(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> 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 <a href="#Error-reporting">Error reporting</a>. [<i>Note:</i> It is an error if <code>p</code> does not + resolve to a symbolic link. <i>-- end note</i>]</p> +</blockquote> +<pre>bool <a name="remove">remove</a>(const path& p); +bool <a name="remove2">remove</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> If <code>exists(symlink_status(p,ec))</code>, it is + removed + as if by<i> ISO/IEC 9945 </i><code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/remove.html">remove()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it + resolves to being removed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Postcondition:</i> <code>!exists(symlink_status(p))</code>.</p> + <p><i>Returns:</i> <code>false</code> if p did not exist in the first + place, otherwise <code>true</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>uintmax_t <a name="remove_all">remove_all</a>(const path& p); +uintmax_t <a name="remove_all2">remove_all</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Recursively deletes the contents of p if it exists, + then deletes file <code>p</code> itself, + as if by<i> ISO/IEC 9945 </i><code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/remove.html">remove()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it + resolves to being removed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Postcondition:</i> <code>!exists(p)</code></p> + <p><i>Returns:</i> The number of files removed.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="rename">rename</a>(const path& old_p, const path& new_p); +void <a name="rename2">rename</a>(const path& old_p, const path& new_p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Renames <code>old_p</code> to <code>new_p</code>, as if by <i> + ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/rename.html">rename()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> If <code>old_p</code> and <code>new_p</code> resolve to the + same existing file, no action is taken. Otherwise, if <code>new_p</code> resolves to an + existing non-directory file, it is removed, while if <code>new_p</code> resolves to an + existing directory, it is removed if empty on ISO/IEC 9945 but is an error on Windows. A symbolic link is itself renamed, rather than + the file it resolves to being renamed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="resize_file">resize_file</a>(const path& p, uintmax_t new_size); +void <a name="resize_file2">resize_file</a>(const path& p, uintmax_t new_size, system::error_code& ec);</pre> +<blockquote> +<p><i>Postcondition:</i> <code>file_size() == new_size</code>.</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Remarks:</i> Achieves its postconditions as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/truncate.html">truncate()</a></code>.</p> +</blockquote> +<pre>space_info <a name="space">space</a>(const path& p); +space_info <a name="space2">space</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> An object of type <code><a href="#space_info">space_info</a></code>. The value of the <code>space_info</code> object is determined as if by + using <i>ISO/IEC 9945</i> <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/statvfs.html" style="text-decoration: none">statvfs()</a></code> to obtain a <i> + ISO/IEC 9945</i> struct <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/statvfs.h.html" style="text-decoration: none">statvfs</a></code>, and then multiplying its <code>f_blocks</code>, <code>f_bfree</code>, and <code>f_bavail</code> members by its <code>f_frsize</code> member, and assigning the results to the <code>capacity</code>, <code>free</code>, + and <code>available</code> members respectively. Any members for which the + value cannot be determined shall be set to -1.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre><a href="#file_status">file_status</a> <a name="status">status</a>(const path& p);</pre> +<blockquote> + <p><i>Effects: </i>As if:</p> + <blockquote> + <pre>system::error_code ec; +file_status result = status(p, ec); +if (result == status_error) + throw filesystem_error(<i>implementation-supplied-message</i>, p, ec); +return result;</pre> + </blockquote> + <p><i>Returns:</i> See above.</p> + <p><i>Throws:</i> <code>filesystem_error</code>. +[<i>Note:</i> <code>result</code> values of <code>file_status(file_not_found)</code>and <code>file_status(type_unknown)</code> are not considered failures and do not + cause an exception to be +thrown.<i> -- end note</i>] </p> + </blockquote> +<pre><a href="#file_status">file_status</a> <a name="status2">status</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p><i>Effects: </i></p> + <blockquote> + <p>If possible, determines the attributes + of the file <code>p</code> resolves to, as if by<i> ISO/IEC 9945 </i><code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>.</p> + If, during attribute determination, the underlying file system API reports + an error, sets <code>ec</code> to indicate the specific error reported. + Otherwise, <code>ec.clear()</code>.<blockquote> + <p>[<i>Note:</i> This allows users to inspect the specifics of underlying + API errors even when the value returned by <code>status()</code> is not <code>file_status(status_error)</code>. <i>--end note</i>]</p> + </blockquote> + </blockquote> + <p><i>Returns:</i></p> + <blockquote> + <p>If <code>ec != error_code()</code>:</p> + <ul> + <li>If the specific error indicates that <code>p</code> cannot be resolved + because some element of the path does not exist, return <code> + file_status(file_not_found)</code>. [<i>Note:</i> ISO/IEC 9945 errors that + indicate this are ENOENT or ENOTDIR. Windows equivalents + include ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, ERROR_INVALID_NAME, + ERROR_INVALID_PARAMETER, ERROR_BAD_PATHNAME, and ERROR_BAD_NETPATH. <i>-- + end note</i>]<br> + </li> + <li>Otherwise, if the specific error indicates that <code>p</code> can be resolved + but the attributes cannot be determined, return <code> + file_status(type_unknown)</code>. [<i>Note: </i>For example, Windows + ERROR_SHARING_VIOLATION errors. For ISO/IEC 9945, the case never arises. <i>-- end + note</i>]<br> + </li> + <li>Otherwise, return <code> + file_status(status_error)</code>.</li> + </ul> + <blockquote> + <p>[<i>Note:</i> These semantics distinguish between <code>p</code> being known not to exist, <code>p</code> existing but not being able to determine its attributes, + and there being an error that prevents even knowing if <code>p</code> exists. These + distinctions are important to some use cases. <i>--end note</i>]</p> + </blockquote> + <p>Otherwise,</p> + <ul> + <li>If the attributes indicate a regular file, as if by <i>ISO/IEC 9945</i> <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISREG()</a>, + return <code> + file_status(regular_file)</code>. [<i>Note:</i> <code> +regular_file</code> implies appropriate <code><fstream></code> operations + would succeed, assuming no hardware, permission, access, or file system + race + errors. Lack of +<code>regular_file</code> does not necessarily imply <code><fstream></code> operations would +fail on a directory. +<i>-- end note</i>]<br> + </li> + <li>Otherwise, if the attributes indicate a directory, as if by <i>ISO/IEC + 9945</i> + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISDIR()</a>, + return <code> + file_status(directory_file)</code>. [<i>Note:</i> <code>directory_file</code> implies <code> +directory_iterator(p)</code>would succeed. +<i>-- end note</i>]<br> + </li> + <li>Otherwise, if the attributes indicate a block special file, as if by <i> + ISO/IEC 9945</i> + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISBLK()</a>, + return <code> + file_status(block_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a character special file, as if by <i> + ISO/IEC 9945</i> + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISCHR()</a>, + return <code> + file_status(character_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a fifo or pipe file, as if by <i> + ISO/IEC 9945</i> + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISFIFO()</a>, + return <code> + file_status(fifo_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a socket, as if by <i>ISO/IEC + 9945</i> + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISSOCK()</a>, + return <code> + file_status(socket_file)</code>.<br> + </li> + <li>Otherwise, return <code> + file_status(type_unknown)</code>.</li> + </ul> + </blockquote> + <p><i>Remarks:</i> If a symbolic link is encountered during pathname + resolution, + pathname resolution continues using the contents of the symbolic link.</p> +</blockquote> +<pre>bool <a name="status_known">status_known</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() != status_error</code></p> +</blockquote> +<pre>file_status <a name="symlink_status">symlink_status</a>(const path& p); +file_status <a name="symlink_status2">symlink_status</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p><i>Effects:</i> Same as <a href="#status">status()</a>, above, + except that the attributes + of <code>p</code> are determined as if by<i> ISO/IEC 9945 </i><code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html">lstat()</a></code>.</p> +</blockquote> +<blockquote> + <p><i>Returns:</i> Same as <a href="#status">status()</a>, above, except + that if the attributes indicate a symbolic link, as if by <i>ISO/IEC 9945</i> <a class="external" href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISLNK()</a>, return <code>file_status(symlink_file)</code>.</p> + <p><i>Remarks:</i> Pathname resolution terminates if <code>p</code> names a symbolic link.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>path <a name="system_complete">system_complete</a>(const path& p); +path <a name="system_complete2">system_complete</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Composes an absolute path from <code>p</code>, using the + same rules used by the operating system to resolve a path passed as the + filename argument to standard library open functions.</p> + <p><i>Returns:</i> The composed path.</p> + <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> For <i>ISO/IEC 9945</i>, <code>system_complete(p)</code> has the same semantics as <code>complete(p, current_path())</code>.</p> + <p><a name="windows_effects">For <i>Windows</i></a>, <code>system_complete(p)</code> has the + same semantics as <code>complete(ph, current_path())</code> if <code>p.is_absolute() || !p.has_root_name()</code> or <code>p</code> and <code>base</code> have the same <code>root_name()</code>. + Otherwise it acts like <code>complete(p, kinky)</code>, where <code>kinky</code> is the current directory for the <code>p.root_name()</code> drive. This will + be the current directory of that drive the last time it was set, and thus may + be <b>residue left over from a prior program</b> run by the command + processor! Although these semantics are often useful, they are also very + error-prone.</p> + <p>See <a href="#complete_note"><i>complete()</i> note</a> for usage suggestions. <i>-- end note</i>]</p> +</blockquote> +<pre>path <a name="temp_directory_path">temp_directory_path</a>(); +path temp_directory_path(system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> A directory path suitable for temporary files under the + conventions of the operating system. The specifics of how this path is + determined are implementation defined. An error shall be reported if<code> !exists(p) + || !is_directory(p)</code>, where <code>p</code> is the path to be returned.</p> + <p><i>ISO/IEC 9945:</i> The path supplied by the first environment variable found in the + list TMPDIR, TMP, TEMP, TEMPDIR. If none of these are found, <code>"/tmp"</code>.</p> + <p><i>Windows:</i> The path reported by the <i>Windows</i> <code>GetTempPath</code> API function.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The <code>temp_directory_path()</code> name was chosen to emphasize that the return is a + path, not just a single directory name. <i>-- end note</i>]</p> +</blockquote> +<pre>path <a name="unique_path">unique_path</a>(const path& model="%%%%-%%%%-%%%%-%%%%"); +path unique_path(const path& model, system::error_code& ec);</pre> +<blockquote> + <p>The <code>unique_path</code> function generates a path name suitable for + creating temporary files, including directories. The name is based + on a model that uses the percent sign character to specify replacement by a + random hexadecimal digit. [<i>Note:</i> The more bits of randomness in the + generated path name, the less likelihood of prior existence or being guessed. + Each replacement hexadecimal digit in the model adds four bits of randomness. + The default model thus provides 64 bits of randomness. This is sufficient for + most applications. <i>--end note</i>]</p> + <p><i>Returns:</i> A path identical to <code>model</code>, except that each + occurrence of a percent sign character is replaced by a random hexadecimal + digit character in the range 0-9, a-f.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Remarks:</i> Implementations are encouraged to obtain the required + randomness via a <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">cryptographically secure pseudo-random number generator</a>, such as one + provided by the operating system. [<i>Note</i>: Such generators may block + until sufficient entropy develops. <i>--end note</i>]</p> +</blockquote> + +<h3><a name="File-streams">File streams</a> - +<a href="../../../boost/filesystem/fstream.hpp"><boost/filesystem/fstream.hpp></a></h3> +<p>Replacements are provided for the file stream classes from the C++ standard +library's <code><fstream></code> header. These replacement classes +publicly inherit from the standard library classes. In the Boost.Filesystem +version, constructors and open functions take <code>const path&</code> arguments +instead of <code> +const char*</code> arguments. There are no other differences in syntax or +semantics.</p> +<pre>namespace boost +{ + namespace filesystem + { + template < class charT, class traits = std::char_traits<charT> > + class basic_filebuf : public std::basic_filebuf<charT,traits> + { + public: + basic_filebuf<charT,traits>* + open(const path& p, std::ios_base::openmode mode); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ifstream : public std::basic_ifstream<charT,traits> + { + public: + explicit basic_ifstream(const path& p, std::ios_base::openmode mode=std::ios_base::in) + void open(const path& p, std::ios_base::openmode mode=std::ios_base::in); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ofstream : public std::basic_ofstream<charT,traits> + { + public: + explicit basic_ofstream(const path& p, std::ios_base::openmode mode=std::ios_base::out); + void open(const path& p, std::ios_base::openmode mode=std::ios_base::out); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_fstream : public std::basic_fstream<charT,traits> + { + public: + explicit basic_fstream(const path& p, + std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out); + void open(const path& p, + std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out); + }; + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_fstream<wchar_t> wfstream; + typedef basic_ofstream<wchar_t> wofstream; + + } // namespace filesystem +} // namespace boost</pre> + + + +<h2><a name="Path-decomposition-table">Path decomposition table</a></h2> +<p>The table is generated by a program compiled with the Boost implementation.</p> +<p>Shaded entries indicate cases where <i>ISO/IEC 9945</i> and <i>Windows</i> implementations yield different results. The top value is the <i> +ISO/IEC 9945</i> result and the bottom value is the <i>Windows</i> result. <br> +<table border="1" cellspacing="0" cellpadding="5"> +<p> +<tr><td><b>Constructor<br>argument</b></td> +<td><b>Iteration<br>over<br>Elements</b></td> +<td><b><code>string()</code></b></td> +<td><b><code>generic_<br>string()</code></b></td> +<td><b><code>root_<br>path()</code></b></td> +<td><b><code>root_<br>name()</code></b></td> +<td><b><code>root_<br>directory()</code></b></td> +<td><b><code>relative_<br>path()</code></b></td> +<td><b><code>parent_<br>path()</code></b></td> +<td><b><code>filename()</code></b></td> +</tr> +<tr> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +</tr> +<tr> +<td><code>.</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>..</code></td> +<td><code>..</code></td> +<td><code>..</code></td> +<td><code>..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +</tr> +<tr> +<td><code>/foo</code></td> +<td><code>/,foo</code></td> +<td><code>/foo</code></td> +<td><code>/foo</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo</code></td> +<td><code>/</code></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>foo/</code></td> +<td><code>foo,.</code></td> +<td><code>foo/</code></td> +<td><code>foo/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/</code></td> +<td><code>foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>/foo/</code></td> +<td><code>/,foo,.</code></td> +<td><code>/foo/</code></td> +<td><code>/foo/</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo/</code></td> +<td><code>/foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/bar</code></td> +<td><code>foo,bar</code></td> +<td><code>foo/bar</code></td> +<td><code>foo/bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/bar</code></td> +<td><code>foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>/foo/bar</code></td> +<td><code>/,foo,bar</code></td> +<td><code>/foo/bar</code></td> +<td><code>/foo/bar</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo/bar</code></td> +<td><code>/foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>//net</code></td> +</tr> +<tr> +<td><code>//net/foo</code></td> +<td><code>//net,/,foo</code></td> +<td><code>//net/foo</code></td> +<td><code>//net/foo</code></td> +<td><code>//net/</code></td> +<td><code>//net</code></td> +<td><code>/</code></td> +<td><code>foo</code></td> +<td><code>//net/</code></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>///foo///</code></td> +<td><code>/,foo,.</code></td> +<td><code>///foo///</code></td> +<td><code>///foo///</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo///</code></td> +<td><code>///foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>///foo///bar</code></td> +<td><code>/,foo,bar</code></td> +<td><code>///foo///bar</code></td> +<td><code>///foo///bar</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo///bar</code></td> +<td><code>///foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>/.</code></td> +<td><code>/,.</code></td> +<td><code>/.</code></td> +<td><code>/.</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>.</code></td> +<td><code>/</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>./</code></td> +<td><code>.,.</code></td> +<td><code>./</code></td> +<td><code>./</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>./</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>/..</code></td> +<td><code>/,..</code></td> +<td><code>/..</code></td> +<td><code>/..</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>..</code></td> +<td><code>/</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>../</code></td> +<td><code>..,.</code></td> +<td><code>../</code></td> +<td><code>../</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>../</code></td> +<td><code>..</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/.</code></td> +<td><code>foo,.</code></td> +<td><code>foo/.</code></td> +<td><code>foo/.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/.</code></td> +<td><code>foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/..</code></td> +<td><code>foo,..</code></td> +<td><code>foo/..</code></td> +<td><code>foo/..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/..</code></td> +<td><code>foo</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo/./</code></td> +<td><code>foo,.,.</code></td> +<td><code>foo/./</code></td> +<td><code>foo/./</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/./</code></td> +<td><code>foo/.</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/./bar</code></td> +<td><code>foo,.,bar</code></td> +<td><code>foo/./bar</code></td> +<td><code>foo/./bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/./bar</code></td> +<td><code>foo/.</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>foo/..</code></td> +<td><code>foo,..</code></td> +<td><code>foo/..</code></td> +<td><code>foo/..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/..</code></td> +<td><code>foo</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo/../</code></td> +<td><code>foo,..,.</code></td> +<td><code>foo/../</code></td> +<td><code>foo/../</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/../</code></td> +<td><code>foo/..</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/../bar</code></td> +<td><code>foo,..,bar</code></td> +<td><code>foo/../bar</code></td> +<td><code>foo/../bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/../bar</code></td> +<td><code>foo/..</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><font size="-1"><i>empty</i></font></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>c:</code></td> +</tr> +<tr> +<td><code>c:/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,.</code><br><code>c:,/</code></span></td> +<td><code>c:/</code></td> +<td><code>c:/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/</code><br><font size="-1"><i>empty</i></font></span></td> +<td><code>c:</code></td> +<td><span style="background-color: #CCFFCC"><code>.</code><br><code>/</code></span></td> +</tr> +<tr> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>c:,foo</code></span></td> +<td><code>c:foo</code></td> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:/foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo</code><br><code>c:,/,foo</code></span></td> +<td><code>c:/foo</code></td> +<td><code>c:/foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><code>c:/</code></span></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>c:foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo,.</code><br><code>c:,foo,.</code></span></td> +<td><code>c:foo/</code></td> +<td><code>c:foo/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo/</code><br><code>foo/</code></span></td> +<td><code>c:foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo,.</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:/foo/</code></td> +<td><code>c:/foo/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo/</code><br><code>foo/</code></span></td> +<td><code>c:/foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo/bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo,bar</code><br><code>c:,/,foo,bar</code></span></td> +<td><code>c:/foo/bar</code></td> +<td><code>c:/foo/bar</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo/bar</code><br><code>foo/bar</code></span></td> +<td><code>c:/foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>prn:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>prn:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>prn:</code><br><font size="-1"><i>empty</i></font></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>prn:</code></td> +</tr> +<tr> +<td><code>c:\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>c:,/</code></span></td> +<td><code>c:\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><font size="-1"><i>empty</i></font></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>\</code></span></td> +</tr> +<tr> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>c:,foo</code></span></td> +<td><code>c:foo</code></td> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:\foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>c:,/,foo</code></span></td> +<td><code>c:\foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>c:/foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>c:,foo,.</code></span></td> +<td><code>c:foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>c:foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>foo\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>.</code></span></td> +</tr> +<tr> +<td><code>c:\foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:\foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>c:/foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>foo\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>.</code></span></td> +</tr> +<tr> +<td><code>c:\foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo,.</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:\foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo/</code><br><code>c:/foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo/</code><br><code>foo/</code></span></td> +<td><code>c:\foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo\bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo\bar</code><br><code>c:,/,foo,bar</code></span></td> +<td><code>c:/foo\bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo\bar</code><br><code>c:/foo/bar</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo\bar</code><br><code>foo\bar</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><code>c:/foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>foo\bar</code><br><code>bar</code></span></td> +</tr> +</table> +<h2><a name="long-path-warning"></a>Warning: Long paths on Windows and the +extended-length <b>\\?\ </b>prefix</h2> +<p>The Microsoft Windows "Maximum Path Length Limitation" specifies:</p> +<blockquote> +<p>In the Windows API (with some exceptions ...), the maximum length for a path +is MAX_PATH, which is defined as 260 characters.</p> +<p>The Windows API has many functions that also have Unicode versions to permit +an extended-length path for a maximum total path length of 32,767 characters. +... To specify an extended-length path, use the <b>"\\?\" prefix</b>. For +example, "\\?\D:\<em>very long path</em>". <i>[C++ string literals require backslashes be doubled, of course.]</i></p> +</blockquote> +<p>Because most Boost.Filesystem operational functions just pass the contents of +a class path object to the Windows API, they do work with the extended-length +prefixes. But some won't work, because to the limitations imposed by Windows. +Read the following cautions carefully!</p> +<h3>Cautions for paths with extended-length prefixes</h3> +<ul> + <li>Individual components of a path are still are limited to whatever is + supported for the particular filesystem, commonly 255 characters.</li> + <li>Only backslashes only are acceptable as directory separators. Slashes are + not treated as separators.</li> + <li>All paths must be absolute - relative paths are not allowed.</li> + <li>Once an absolute path grows beyond 260 characters, it is essentially + poisoned and all operations must use extended-length prefixes. So even a + simple operation like <code>create_directory("a")</code> will fail if the + absolute path of the resulting directory would exceed 260 characters.</li> + <li>Certain Boost.Filesystem functions that decompose their argument path and + then work on individual relative directories or files will not work properly + with extended-length prefix paths.</li> +</ul> +<h2><a name="Acknowledgements">Acknowledgements</a></h2> +<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 +through to completion. She gave me the strength to continue after a difficult +year of cancer treatment in the middle of it all.</p> +<p>Many people contributed technical comments, ideas, and suggestions to the +Boost Filesystem Library. See <a href="http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements">http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements</a>.</p> +<p>Dietmar Kuehl contributed the original Boost Filesystem Library directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas +Witt were particularly helpful in refining the library.</p> +<p>The create_directories, extension, basename, and replace_extension functions +were developed by Vladimir Prus. The temp_directory_path function was +contributed by Jeff Flinn. David Svoboda suggested the canonical function and +provided psuedo-code.</p> +<p>Howard Hinnant and John Maddock reviewed a draft of the version 2 proposal, and +identified a number of mistakes or weaknesses, resulting in a more polished +final document.</p> +<p>Peter Dimov suggested a single class path, with member templates to adapt to +multiple string types. His idea became the basis for the version 3 path design.</p> +<h2><a name="References">References</a></h2> +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="16%" valign="top">[<a name="ISO_POSIX">ISO-ISO/IEC 9945</a>]</td> + <td width="84%">ISO/IEC 9945:2003, IEEE Std 1003.1-2001, and The Open Group + 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 + in its creation. For example, read online or download from <a href="http://www.unix.org/single_unix_specification/">www.unix.org/single_unix_specification/</a>.</font> The ISO JTC1/SC22/WG15 - + POSIX homepage is <a href="http://www.open-std.org/jtc1/sc22/WG15/">www.open-std.org/jtc1/sc22/WG15/</a></td> + </tr> + <tr> + <td width="16%" valign="top">[Abrahams]</td> + <td width="84%">Dave Abrahams, Error and Exception Handling, <a href="http://www.boost.org/more/error_handling.html">www.boost.org/more/error_handling.html</a></td> + </tr> +</table> +<hr> +> +<p><font size="2">© Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010, 2011</font></p> +<p><font size="2">Distributed under the Boost Software License, Version 1.0. See +</font> +<a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p> +<p><font size="2">Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->09 August 2012<!--webbot bot="Timestamp" endspan i-checksum="31334" --></font></p> + + +</body></html>
\ No newline at end of file diff --git a/libs/filesystem/doc/release_history.html b/libs/filesystem/doc/release_history.html new file mode 100644 index 0000000000..abc32ea9ed --- /dev/null +++ b/libs/filesystem/doc/release_history.html @@ -0,0 +1,181 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem Release History</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Release History</font> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="../../../index.htm">Boost Home</a> + <a href="index.htm">Library Home</a> <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<h2>1.51.0</h2> +<ul> + <li>Fix a Linux fchmodat problem affecting symlink permissions reported during + discussion of <a href="https://svn.boost.org/trac/boost/ticket/6659">#6659</a>.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/6659">#6659</a> and + <a href="https://svn.boost.org/trac/boost/ticket/7051">#7051</a>, fchmodat + supported only on Solaris 11. Fix for both Sun and GCC compilers. </li> + <li>Add missing copy_directory semantics docs. Fixes + <a href="https://svn.boost.org/trac/boost/ticket/5879">#5879</a>.</li> +</ul> + +<h2>1.50.0</h2> +<ul> + <li>Remove Filesystem Version 2 from the distribution. Version 3 is now the + only distributed version. Those still using V2 are urged to migrate to V3 as + soon as possible.</li> + <li>Add <code>constexpr value_type preferred_separator</code> to class path.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5118">#5118</a>, + <code>replace_extension</code> doesn't work as specified in documentation. The + documentation, implementation, and test cases have all had fixes applied. The + documentation had failed to mention that any existing extension is removed. + The behavior for simple cases has been reverted to the Version 2 behavior, but + with corrections so that complex replacements now work. Two test cases from + #5118 have been added.</li> + <li>Fix <a href="http://svn.boost.org/trac/boost/ticket/3737">#3737</a>, + Boost.Filesystem does not compile on Windows Mobile. On Windows, <sys/stat.h> + is no longer included.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/4065">#4065</a>, + Boost Filesystem lexicographic path comparison inconsistent. This required + multiple source code bug fixes and code cleanup, correcting problems not + related to lexicographical issues.</li> + <li>Add class path member function <code>compare</code> for consistency with + std::string.</li> + <li>Tighten BOOST_FILESYSTEM_DYN_LINK and BOOST_FILESYSTEM_STATIC_LINK logic + in filesystem/config.hpp so that one or the other is always defined, and both + being defined is a #error.</li> + <li>Fix <a href="http://svn.boost.org/trac/boost/ticket/6690">#6690</a> and + <a href="http://svn.boost.org/trac/boost/ticket/6737">#6737</a>, resolving + static linking related problems with VC++ 8 through 11. Note that this fix may + reintroduce codecvt thread safety problems + <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 and others.</li> + <li>Fix <a href="http://svn.boost.org/trac/boost/ticket/6809">#6809</a>, + Implementation of filesystem::rename() method for MS Windows is wrong, by + adding MOVEFILE_COPY_ALLOWED to deal with renames across drives, volumes, file + systems. Fix has no effect on non-Windows systems.</li> + <li>Fix <a href="http://svn.boost.org/trac/boost/ticket/6819">#6819</a>, A path operand with a source that was a one character array was + treated as empty, even if it wasn't empty. Such arrays can occur in unions or + in code using C variable length array idioms.</li> + <li>Fix <a href="http://svn.boost.org/trac/boost/ticket/6932">#6932</a>, + create_directories throws exception even if error_code is specified.</li> +</ul> + +<h2>1.49.0</h2> +<ul> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/3714">#3714</a>, + Added test cases and fixes for class path errors when assignment or append + used self or portion of self as source. </li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/4889">#4889</a>, + <a href="https://svn.boost.org/trac/boost/ticket/6320">#6320</a>, Locale codecvt_facet not thread safe on Windows. Move + Windows, Mac OS X, locale and codecvt facet back to namespace scope. POSIX + except OS X uses local static initialization (IE lazy) to ensure exceptions + are catchable if environmental variables are misconfigured and to avoid use of + locale("") if not actually used.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5652">#5652</a>, + recursive_directory_iterator fails on cyclic symbolic links. Thanks to Daniel + Aarno for the patch.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5653">#5653</a>, + recursive_directory_iterator(error_code) can still throw filesystem_error.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5900">#5900</a>, directory_iterator + access violation on Windows if error is thrown. Thanks to Andreas Eckleder for the patch.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5900#comment:2">#5900 + comment 2</a>, a bug in director_iterator construction with error_code argument that + caused increment to be called without the ec argument being passed.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5900">#5989</a> by cleaning up test suite path_test.cpp code even + though the ticket itself was not a defect, and clarifying docs; iteration over a path yields + generic format.</li> + <li>Fix <a href="https://svn.boost.org/trac/boost/ticket/5592">#5592</a>, Change Windows codecvt processing from CP_THREAD_ACP to CP_ACP.</li> + <li>Operations function fixes for PGI compiler, thanks to Noel Belcourt.</li> + <li>Relax permissions test to reflect reality, particularly on the Sandia test + platforms.</li> +</ul> + +<h2>1.48.0</h2> +<ul> + <li>Added operational function <a href="reference.html#canonical">canonical()</a>, + suggested by David Svoboda, who also provided pseudo-code.</li> + <li>Added <a href="reference.html#hash_value">hash_value()</a> function for + paths. (Daniel James)</li> + <li>Fix path inserter problem (<a href="https://svn.boost.org/trac/boost/ticket/5764">#5764</a>) + reported for QNX6.3.2 host (gcc-3.3.5)</li> + <li>Fix problem of locale("") exception being thrown before main() starts on + poorly configured (e.g. LANG="bad name") POSIX systems. Resolves the most + serious aspect of tickets + <a href="https://svn.boost.org/trac/boost/ticket/4688">#4688</a>, + <a href="https://svn.boost.org/trac/boost/ticket/5100">#5100</a>, + <a href="https://svn.boost.org/trac/boost/ticket/5289">#5289</a>.</li> +</ul> + +<h2>1.47.0</h2> +<ul> + <li>Program file_status.cpp added (V3). See boost-root/libs/filesystem/v3/example. + Useful both as an example and to explore how Boost.Filesystem treats various + status errors. Run "bjam" (NOT "bjam install") in the example directory + to install in example/bin.</li> +</ul> + +<h2>1.46.1</h2> + +<ul> + <li>Fix fstream problem for STLPort masquerading as Dinkumware (<a href="https://svn.boost.org/trac/boost/ticket/5217">#5217</a>).</li> +</ul> + +<h2>1.46.0</h2> +<ul> + <li>Version 3 of the library is now the default.</li> + <li>IBM vacpp: Workaround for compiler bug affecting iterator_facade. (<a href="https://svn.boost.org/trac/boost/ticket/4912">#4912</a>)</li> + <li>Verify, clarify, document that <boost/config/user.hpp> can be used to + specify BOOST_FILESYSTEM_VERSION. (<a href="https://svn.boost.org/trac/boost/ticket/4891">#4891</a>)</li> + <li>Replaced C-style assert with BOOST_ASSERT.</li> + <li>Undeprecated unique_path(). Instead, add a note mentioning the workaround + for lack of thread safety and possible change to cwd. unique_path() is just + too convenient to deprecate!</li> + <li>Cleared several GCC warnings.</li> + <li>Changed V2 code to use BOOST_THROW_EXCEPTION.</li> + <li>Windows: Fix status() to report non-symlink reparse point correctly.</li> + <li>Add <code>symlink_option</code> to <code>recursive_directory_iterator</code>, + allowing control over recursion into directory symlinks. Note that the default + is changed to not recurse into directory symlinks.</li> + <li><a href="reference.html">Reference</a> documentation cleanup, including + fixing missing and broken links, and adding missing functions.</li> + <li>Miscellaneous implementation code cleanup. </li> +</ul> +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->13 August, 2012<!--webbot bot="Timestamp" endspan i-checksum="34443" --></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"> +www.boost.org/LICENSE_1_0.txt</a></p>
\ No newline at end of file diff --git a/libs/filesystem/doc/src/README b/libs/filesystem/doc/src/README new file mode 100644 index 0000000000..7b2433e0e9 --- /dev/null +++ b/libs/filesystem/doc/src/README @@ -0,0 +1,14 @@ +This directory contains the source files used to generate the Filesystem library +reference documentation and the TR2 filesystem proposal. The generated HTML files +contain much common material that would be difficult to keep in sync if maintained +as separate files. + +Generation is performed by the Minimal Macro Processor, available from +https://github.com/Beman/mmp + +------------ + +Copyright Beman Dawes 2012 + +Distributed under the Boost Software Licence Version 1.0. +See http://www.boost.org/LICENSE_1_0.txt diff --git a/libs/filesystem/doc/src/boost-no-inspect b/libs/filesystem/doc/src/boost-no-inspect new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/libs/filesystem/doc/src/boost-no-inspect diff --git a/libs/filesystem/doc/src/boost_snippets.html b/libs/filesystem/doc/src/boost_snippets.html new file mode 100644 index 0000000000..d0a38d143d --- /dev/null +++ b/libs/filesystem/doc/src/boost_snippets.html @@ -0,0 +1,199 @@ +<html> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>New Page 1</title> +</head> + +<body> +$id frontmatter= + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Library<br> + </font> + <font size="6">Version 3</font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </td> + </tr> +</table> + +<h1>Reference Documentation</h1> + +$endid + +$id wording_prefix= +<h2><a name="Introduction">Introduction</a></h2> + +<p>This reference documentation describes components that C++ programs may use +to perform operations involving file systems, including paths, regular files, +and directories.</p> + +<blockquote> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td width="100%" align="center" colspan="2"> + <p align="center"><b>C++11 Support</b><p align="left">This reference + documentation is written as if all compilers supported C++11. Where + possible, the implementation falls back to C++03 if a C++11 feature is not + available.</td> + </tr> + <tr> + <td width="35%" align="center"> + <b>C++11 Feature</b></td> + <td width="65%" align="center"> + <b>Action if not supported by compiler</b></td> + </tr> + <tr> + <td width="35%" align="left"> + <code>noexcept</code></td> + <td width="65%" align="left"> + Keyword omitted.</td> + </tr> + <tr> + <td width="35%" align="left"> + <code>constexpr</code></td> + <td width="65%" align="left"> + Keyword omitted.</td> + </tr> + <tr> + <td width="35%" align="left"> + <p dir="rtl">R-value references</td> + <td width="65%" align="left"> + Function signature omitted.</td> + </tr> + <tr> + <td width="35%" align="left"> + New character types</td> + <td width="65%" align="left"> + <p dir="ltr">The <code>boost::filesystem</code> interface doesn't use the + new types directly. It does use <code>u16string</code> and <code>u32string</code> + in namespace <code>boost</code>. These are typedefs to <code>std::u16string</code> + and <code>std::u32string</code> for C++11, or to <code> + std::basic_string<boost::u16_t></code> and <code> + std::basic_string<boost::u32_t></code> for C++03.</td> + </tr> + <tr> + <td width="35%" align="left"> + Defaulted and deleted functions</td> + <td width="65%" align="left"> + Workaround replacement functions provided.</td> + </tr> + <tr> + <td width="35%" align="left"> + Initializer lists</td> + <td width="65%" align="left"> + Not currently used.</td> + </tr> + <tr> + <td width="35%" align="left"> + Variadic templates</td> + <td width="65%" align="left"> + Not currently used.</td> + </tr> + <tr> + <td width="35%" align="left"> + Range-based for statements</td> + <td width="65%" align="left"> + Supporting functions always provided; they do no harm even for C++03 + compilers.</td> + </tr> +</table> +</blockquote> + +$endid + +$id wording_suffix= +<h3><a name="File-streams">File streams</a> - +<a href="../../../boost/filesystem/fstream.hpp"><boost/filesystem/fstream.hpp></a></h3> +<p>Replacements are provided for the file stream classes from the C++ standard +library's <code><fstream></code> header. These replacement classes +publicly inherit from the standard library classes. In the Boost.Filesystem +version, constructors and open functions take <code>const path&</code> arguments +instead of <code> +const char*</code> arguments. There are no other differences in syntax or +semantics.</p> +<pre>$NAMESPACE_BEGIN; + template < class charT, class traits = std::char_traits<charT> > + class basic_filebuf : public std::basic_filebuf<charT,traits> + { + public: + basic_filebuf<charT,traits>* + open(const path& p, std::ios_base::openmode mode); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ifstream : public std::basic_ifstream<charT,traits> + { + public: + explicit basic_ifstream(const path& p, std::ios_base::openmode mode=std::ios_base::in) + void open(const path& p, std::ios_base::openmode mode=std::ios_base::in); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ofstream : public std::basic_ofstream<charT,traits> + { + public: + explicit basic_ofstream(const path& p, std::ios_base::openmode mode=std::ios_base::out); + void open(const path& p, std::ios_base::openmode mode=std::ios_base::out); + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_fstream : public std::basic_fstream<charT,traits> + { + public: + explicit basic_fstream(const path& p, + std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out); + void open(const path& p, + std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out); + }; + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_fstream<wchar_t> wfstream; + typedef basic_ofstream<wchar_t> wofstream; + +$NAMESPACE_END;</pre> + +$endid + +$id backmatter=> +<p><font size="2">© Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010, 2011</font></p> +<p><font size="2">Distributed under the Boost Software License, Version 1.0. See +</font> +<a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p> +<p><font size="2">Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->16 July 2012<!--webbot bot="Timestamp" endspan i-checksum="18787" --></font></p> + +$endid + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/src/build.bat b/libs/filesystem/doc/src/build.bat new file mode 100644 index 0000000000..95b7f40d0f --- /dev/null +++ b/libs/filesystem/doc/src/build.bat @@ -0,0 +1,8 @@ +@echo off +rem Copyright Beman Dawes 2012 +rem Distributed under the Boost Software License, Version 1.0. +del tr2.html 2>nul +mmp TARGET=TR2 source.html tr2.html +del reference.html 2>nul +mmp TARGET=BOOST source.html reference.html +echo run "hoist" to hoist reference.html to doc directory diff --git a/libs/filesystem/doc/src/hoist.bat b/libs/filesystem/doc/src/hoist.bat new file mode 100644 index 0000000000..2d84c16b3a --- /dev/null +++ b/libs/filesystem/doc/src/hoist.bat @@ -0,0 +1,5 @@ +@echo off +rem Copyright Beman Dawes 2012 +rem Distributed under the Boost Software License, Version 1.0. +copy /y reference.html .. +echo reference.html copied to .. diff --git a/libs/filesystem/doc/src/source.html b/libs/filesystem/doc/src/source.html new file mode 100644 index 0000000000..9e0f4480a2 --- /dev/null +++ b/libs/filesystem/doc/src/source.html @@ -0,0 +1,3499 @@ +<html> +<!-- © Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010, 2011 --> +<!-- Distributed under the Boost Software License, Version 1.0. --> +<!-- See http://www.boost.org/LICENSE_1_0.txt --> + +<!-- generate-section-numbers=false --> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title> +$if $TARGET; == BOOST + Filesystem Reference + $def WHAT "reference documentation" + $def SNIPPET_FILE "boost_snippets.html" + $def HEADER "boost/filesystem.hpp" + $def NAMESPACE boost + $def SUBNAMESPACE filesystem + $def NAMESPACE_BEGIN "namespace boost +{ + namespace filesystem + {" + $def NAMESPACE_END " } // namespace filesystem +} // namespace boost" + $def CODECVT_ARG "const codecvt_type& cvt" + $def CODECVT_ARG2 ", const codecvt_type& cvt" + $def CODECVT_DEFAULT "=codecvt()" +$else + Filesystem Proposal + $def WHAT "Clause" + $def SNIPPET_FILE "tr2_snippets.html" + $def HEADER "filesystem" + $def NAMESPACE std + $def SUBNAMESPACE filesystem + $def NAMESPACE_BEGIN "namespace std { namespace tbd { namespace filesystem { +" + $def NAMESPACE_END "} } } // namespaces std::tbd::filesystem" + $def CODECVT_ARG "" + $def CODECVT_ARG2 "" + $def CODECVT_DEFAULT "" +$endif +</title> +<style type="text/css"> +$include "../../../../doc/src/minimal.css" +</style> +</head> + +<body> + +$snippet frontmatter "$SNIPPET_FILE;" + +<h2><a name="TOC">Table of Contents</a></h2> + +<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="33%" valign="top"><a href="#Introduction">Introduction</a><br> + <a href="#Definitions">Definitions</a><br> + <a href="#Conformance">Conformance</a><br> + <a href="#Header-filesystem-synopsis"> + Header <code><$HEADER;></code> synopsis</a><br> + <a href="#Error-reporting">Error reporting</a><br> + <a href="#class-path">Class <code>path</code></a><br> + <a href="#path-Conversions"><code>path</code> conversions</a><br> + <a href="#path-Conversions-to-native-format"><code>path</code> + conversions to native format</a><br> + <a href="#path-Conversions-to-generic-format"><code>path</code> + conversions to generic format</a><br> + <a href="#path-Encoding-conversions"><code>path</code> + encoding conversions</a><br> + <a href="#path-Requirements"><code>path</code> requirements</a><br> + <a href="#path-constructors"><code>path</code> constructors</a><br> + <a href="#path-assignments"><code>path</code> assignments</a><br> + <a href="#path-appends"><code>path</code> appends</a><br> + <a href="#path-concatenation"><code>path</code> concatenation</a><br> + <a href="#path-modifiers"><code>path</code> modifiers</a><br> + <a href="#path-native-format-observers"><code>path</code> native + format observers</a><br> + <a href="#path-generic-format-observers"><code>path</code> generic + format observers</a><br> + <a href="#path-compare"><code>path</code> compare</a><br> + <a href="#path-decomposition"><code>path</code> decomposition</a><br> + <a href="#path-query"><code>path</code> query</a><br> + <a href="#path-iterators"><code>path</code> iterators</a><br> +$if $TARGET; == BOOST + <a href="#path-deprecated-functions"><code>path</code> deprecated functions</a><br> +$endif + <a href="#path-non-member-functions"><code>path</code> non-member functions</a><br> + <a href="#path-inserter-extractor"><code>path</code> inserters and extractors</a><br> + <a href="#Class-filesystem_error">Class <code>filesystem_error</code></a><br> + <a href="#filesystem_error-members"><code>filesystem_error</code> + constructors</a><br> + <code>f</code><a href="#filesystem_error-path1"><code>ilesystem_error</code> path1</a><br> + <a href="#filesystem_error-path2"><code>filesystem_error</code> path2</a><br> + <a href="#filesystem_error-what"><code>filesystem_error</code><code> + </code>what</a></td> + <td width="33%" valign="top"> + <a href="#Enum-file_type">Enum <code>file_type</code></a><br> + <a href="#Enum-perms">Enum <code>perms</code></a><br> + <a href="#file_status">Class + <code>file_status</code></a><br> + + <a href="#file_status"> + <code>file_status</code></a><a href="#file_status-constructors"> constructors</a><br> + <code><a href="#file_status-modifiers">file_status-modifiers</a></code><a href="#directory_entry-observers"> observers</a><br> + <code><a href="#file_status-observers">file_status-observers</a></code><a href="#directory_entry-modifiers"> modifiers</a><br> +<a href="#Class-directory_entry">Class <code>directory_entry</code></a><br> + +<a href="#directory_entry-constructors"><code>directory_entry</code> constructors</a><br> + <a href="#directory_entry-observers"><code>directory_entry</code> observers</a><br> + <a href="#directory_entry-modifiers"><code>directory_entry</code> modifiers</a><br> +<a href="#Class-directory_iterator">Class <code>directory_iterator</code></a><br> + <a href="#directory_iterator-members"><code>directory_iterator</code> + members</a><br> +<a href="#Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a><br> + <a href="#Operational-functions"> + Operational functions</a><br> + <code>   <a href="#absolute">absolute</a><br> + <a href="#canonical">canonical</a><br> + <a href="#copy">copy</a><br> + <a href="#copy_directory">copy_directory</a><br> + <a href="#copy_file">copy_file</a><br> + <a href="#copy_symlink">copy_symlink</a><br> +   <a href="#create_directories">create_directories</a><br> +   <a href="#create_directory">create_directory</a><br> +   <a href="#create_hard_link">create_hard_link</a><br> +   <a href="#create_symlink">create_symlink</a><br> +   <a href="#current_path">current_path</a><br> +   <a href="#exists">exists</a><br> +   <a href="#equivalent">equivalent</a><br> +   <a href="#file_size">file_size</a><br> + <a href="#hard_link_count">hard_link_count</a><br> + <a href="#initial_path">initial_path</a><br> +   i<a href="#is_directory">s_directory</a><br> +   <a href="#is_empty">is_empty</a></code></td> + <td width="34%" valign="top"> + <code>   <a href="#is_other">is_other</a><br> +   <a href="#is_regular_file">is_regular_file</a><br> +   <a href="#is_symlink">is_symlink</a><br> +   <a href="#last_write_time">last_write_time</a><br> + <a href="#permissions">permissions</a><br> + <a href="#read_symlink">read_symlink</a><br> +   <a href="#remove">remove</a><br> +   <a href="#remove_all">remove_all</a><br> +   <a href="#rename">rename</a><br> + <a href="#resize_file">resize_file</a><br> +   <a href="#space">space</a><br> +   <a href="#status">status</a><br> +   <a href="#status_known">status_known</a><br> +   <a href="#symlink_status">symlink_status</a><br> +   <a href="#system_complete">system_complete</a><br> +   <a href="#temp_directory_path">temp_directory_path</a><br> + </code> <code> <a href="#unique_path">unique_path</a></code><br> + <a href="#File-streams">File streams</a><br> +<a href="#Path-decomposition-table">Path decomposition table</a><br> + <a href="#long-path-warning">Warning: Long paths on Windows and the + extended-length <b>\\?\ </b>prefix</a><br> +<a href="#Acknowledgements">Acknowledgements</a><br> +<a href="#References">References</a><br> + </td> + </tr> +</table> + +$snippet wording_prefix "$SNIPPET_FILE;" + +<h2><a name="Conformance">Conformance</a> [fs.conformance]</h2> + +<h3>ISO/IEC 9945 conformance [fs.conform.9945]</h3> +<p>Some behavior in this $WHAT; is specified by reference to ISO/IEC 9945. How such behavior is actually implemented is unspecified.</p> +<blockquote> +<p>[<i>Note:</i> This constitutes an "as if" rule for implementation of +operating system dependent behavior. In practice implementations will usually call native +operating system API's. <i>--end note</i>]</p> +</blockquote> +<p>Implementations are encouraged to provide such behavior + +as it is defined by ISO/IEC 9945. Implementations shall document any +behavior that differs from the behavior defined by ISO/IEC 9945. Implementations that do not support exact +ISO/IEC 9945 behavior are +encouraged to provide behavior as close to ISO/IEC 9945 behavior as is reasonable given the +limitations of actual operating systems and file systems. If an implementation cannot provide any +reasonable behavior, the implementation shall report an error in an +implementation-defined manner.</p> +<blockquote> +<p>[<i>Note:</i> Such errors might be reported by an #error directive, a <code> +static_assert</code>, a <code>filesystem_error</code> exception, a special +return value, or some other manner. <i>--end note</i>]</p> +</blockquote> +<p>Implementations are not required to provide behavior that is not supported by +a particular file system.</p> +<blockquote> +<p>[<i>Example:</i> The <a href="http://en.wikipedia.org/wiki/FAT_filesystem"> +FAT file system</a> used by some memory cards, camera memory, and floppy discs +does not support hard links, symlinks, and many other features of more capable +file systems. Implementations are only required to support the FAT features +supported by the host operating system. <i>-- end example</i>]</p> +</blockquote> +<p>The behavior of functions described in this +reference +may differ from their specification in +the presence of <a href="#Race-condition">file system races</a>. No diagnostic is required.</p> +<p>If the possibility of a file system race would make it unreliable for a program to +test for a precondition before calling a function described in this $WHAT;, <i> +Requires</i> is not specified for the condition. Instead, the condition is +specified as a <i>Throws</i> condition.</p> +<blockquote> +<p>[<i>Note:</i> As a design practice, preconditions are not specified when it +is unreasonable for a program to detect them prior to calling the function. <i> +-- end note</i>]</p> +</blockquote> +<h3>Operating system dependent conformance [fs.conform.os]</h3> +<p>Some behavior is specified in this $WHAT; as being +operating system dependent ([fs.def.osdep]). The operation system an +implementation is dependent upon is implementation defined.</p> +<p>It is permissible for an implementation to be dependent upon an operating +system emulator rather than the actual operating system.</p> +<blockquote> +<p>[<i>Example:</i> An implementation uses Cygwin, a Linux® API emulator for +some Windows® operating system versions. The implementation would define Cygwin +as its operating system. Users could refer to the Cygwin documentation to find +details of the operating system dependent behavior. <i>--end example</i>]</p> +<p><span style="background-color: #E0E0E0"><i>It is user and conformance test +detectable that such an implementation is running on Cygwin. Users would be +misled and conformance tests would fail if the implementation defined Linux or +Windows rather than Cygwin as the operating system, since real behavior is a +blend of the two.</i></span> </p> +</blockquote> +<h2><a name="Definitions">Definitions</a> [fs.definitions]</h2> +<p>The following definitions shall apply throughout this $WHAT;:</p> +<h3><a name="operating system dependent">operating system dependent</a> behavior +[fs.def.osdep]</h3> +<p>Behavior that is dependent upon the behavior +and characteristics of an operating system. See [fs.conform.os].</p> +<h3><a name="file">file</a> [fs.def.file]</h3> +<p>An object that can be written to, or read from, or both. A file +has certain attributes, including type. File types include regular files +and directories. Other types of files, such as symbolic links, may be supported by the +implementation.</p> +<h3><a name="file-system">file system</a> [fs.def.filesystem]</h3> +<p>A collection of files and certain of their attributes.</p> +<h3><a name="filename">filename</a> [fs.def.filename]</h3> + <p>The name of a file. Filenames <code> + "."</code> +and <code>".."</code> have special meaning. The follow characteristics of + filenames are operating system dependent:</p> +<ul> + <li> + <p>The permitted characters. See [<a href="#Operating-system-examples">fs.os.example</a>s].</p> + </li> + <li> + <p>Specific filenames that are not permitted.</p> + </li> + <li> + <p>Additional filenames that have special meaning.</p> + </li> + <li> + <p>Case awareness and sensitivity during path resolution.</p> + </li> + <li> + <p>Special rules that may apply to file types other than regular + files, such as directories.</p> + </li> +</ul> +<h3><a name="path">path</a> [fs.def.path]</h3> +<p>A sequence of elements that identify +the location of a file within a filesystem. The elements are the <i>root-name<sub>opt</sub></i>, <i> +root-directory<sub>opt</sub></i>, and an optional sequence of filenames. [<i>Note:</i> +A <a href="#Pathname">pathname</a> is the concrete representation of a path. <i>--end note</i>]</p> + +<h3><a name="Absolute-path">absolute path</a> [fs.def.absolute-path]</h3> +<p>A path that +unambiguously +identifies the location of a file without reference to an additional starting +location. The elements of a path that determine if it is absolute are +operating system dependent.</p> + +<h3><a name="Relative-path">relative path</a> [fs.def.relative-path]</h3> +<p>A path that +is not absolute, and so only +unambiguously +identifies the location of a file when resolved relative to +an implied starting location. The elements of a path that determine if it is +relative are operating system dependent. [<i>Note:</i> +Paths <code>"."</code> and <code>".."</code> are relative paths. <i>--end note</i>]</p> +<h3><a name="canonical-path">canonical path</a> [fs.def.cannonical-path]</h3> +<p>An absolute path that has +no elements that are symbolic links, and no <code>"."</code> or <code>".."</code> elements.</p> +<h3>pathname [fs.def.pathname]</h3> +<p>A character string that represents +the name of a +path. Pathnames are formatted according to the generic pathname grammar or an +operating system dependent +native pathname format.</p> + +<h3>native pathname format [fs.def.native]</h3> +<p>The operating system dependent pathname format accepted by the host operating system.</p> +<h3><a name="link">link</a> [fs.def.link]</h3> +<p>A directory entry object that associates a +filename with a file. On some file systems, several directory entries can +associate names with the same file.</p> +<h3><a name="hard-link">hard link</a> [fs.def.hardlink]</h3> +<p>A link to an existing file. Some +file systems support multiple hard links to a file. If the last hard link to a +file is removed, the file itself is removed.</p> +<blockquote> +<p>[<i>Note:</i> A hard link can be thought of as a shared-ownership smart +pointer to a file.<i> -- end note</i>]<i> </i></p> +</blockquote> +<h3><a name="symbolic-link">symbolic link</a> [fs.def.symlink]</h3> +<p>A type of file with the +property that when the file is encountered during pathname resolution, a string +stored by the file is used to modify the pathname resolution.</p> +<blockquote> +<p>[<i>Note:</i> A symbolic link can be thought of as a raw pointer to a file. +If the file pointed to does not exist, the symbolic link is said to be a +"dangling" symbolic link.<i> -- end note</i>]<i> </i></p> +</blockquote> +<h3><a name="file-system-race">file system race</a> [fs.def.race]</h3> +<p>The condition that occurs +when multiple threads, processes, or computers interleave access and +modification of +the same object within a file system.</p> +<h2><a name="Generic-pathname-grammar">Generic pathname format</a> [path.generic]</h2> +<p><i>pathname:<br> + root-name<sub>opt</sub> +root-directory<sub>opt</sub> relative-path<sub>opt</sub></i></p> +<p><i>root-name:<br> + </i>An +operating system dependent name that identifies the starting location for +absolute paths. </p> +<blockquote> + <blockquote> +<p>[<i>Note:</i> Many operating systems define a name +beginning with two <i>directory-separator</i> characters as a <i>root-name</i> +that identifies network or other resource locations. Some operating systems define a single letter followed by a colon as a drive +specifier - a <i>root-name</i> identifying a specific device such as a disc drive. <i>--end note</i>]</p> + </blockquote> +</blockquote> +<p><i>root-directory:<br> + +directory-separator</i></p> +<p><i>relative-path:<br> + +filename<br> + relative-path +directory-separator<br> + relative-path +directory-separator filename</i></p> +<p><i>filename:<br> + name<br> + </i><code>"."</code><i><br> + </i><code> +".."</code></p> +<p><i>preferred-separator:<br> + </i>An +operating system dependent directory separator character. May be a synonym for <i> <code>"/"</code>.</i></p> +<p><i>directory-separator:<br> + <code>"/"<br> + "/"</code> directory-separator<br> + +preferred-separator<br> + +preferred-separator directory-separator</i></p> +<p>Multiple successive <i>directory-separator</i> characters are considered to +be the same as one <i>directory-separator</i> character.</p> +<p>The <i>filename</i> +<code>"."</code> is considered to be a reference to the current directory. The +<i>filename</i> <code>".."</code> is considered to be a reference to the +parent +directory. Specific <i>filenames</i> may have special meanings for a particular +operating system.</p> +<h2><a name="Operating-system-examples">Operating system dependent examples</a> (Informative) [fs.os.examples]</h2> +<p>Certain features are specified in this $WHAT; as being operating system dependent. The following table shows the application of those +specifications for operating systems that use the ISO/IEC 9945 or Windows® application program interfaces +(APIs).<sup>[footnote1]</sup></p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>Feature</b></td> + <td><b>Section</b></td> + <td><b>ISO/IEC 9945 API</b></td> + <td><b>Windows</b>®<b> API</b></td> + <td><b>Notes</b></td> + </tr> + <tr> + <td><code>path::value_type</code></td> + <td>[<a href="#class-path">class.path</a>]</td> + <td><code>char</code></td> + <td><code>wchar_t</code></td> + <td> </td> + </tr> + <tr> + <td><code>path::preferred_separator</code></td> + <td>[<a href="#class-path">class.path</a>]</td> + <td><code>'/'</code></td> + <td><code>L'\\'</code> (single backslash)</td> + <td> </td> + </tr> + <tr> + <td><code>path("/").is_absolute()<br> + path("c:/").is_absolute()</code></td> + <td>[<a href="#path-query">path.query</a>]</td> + <td><code>true<br> + false</code></td> + <td><code>false<br> + true</code></td> + <td> </td> + </tr> + <tr> + <td><code>path</code> argument disambiguation between generic format and + native format</td> + <td>[<a href="#path-Conversions-to-native-format">path.arg.fmt.cvt</a>]</td> + <td>Not required</td> + <td>Not required</td> + <td>There is no need to distinguish between the generic format and native + format for these operating systems.</td> + </tr> + <tr> + <td><code>path</code> argument format conversion</td> + <td>[<a href="#path-Conversions-to-native-format">path.arg.fmt.cvt</a>]</td> + <td>No conversion performed</td> + <td>No conversion performed</td> + <td>The generic format is already acceptable to the native API of these operating systems.</td> + </tr> + <tr> + <td valign="top"> + <p><code>path("/cats/jane").c_str()<br> + path("/cats/jane/").c_str()</code></td> + <td>[<a href="#path-Conversions-to-native-format">path.arg.fmt.cvt</a>]</td> + <td valign="top"> <code>"/cats/jane"<br> + "/cats/jane/"</code></td> + <td valign="top"> + <p><code>L"/cats/jane"<br> + L"/cats/jane/"</code></td> + <td>These operating systems accept the same native separator between + directory names and a final file name, so no format conversion is performed. + Other operating systems might require conversion.</td> + </tr> + <tr> + <td>Format conversion by <code>path</code> native format observers</td> + <td>[<a href="#path-native-format-observers">path.native.obs</a>]</td> + <td>No conversion performed</td> + <td>No conversion performed</td> + <td>For efficiency, <code>path</code> objects are required to store pathnames in the native + format regardless of operating system.</td> + </tr> + <tr> + <td> + <p>Format conversion by <code>path</code> generic format observers</td> + <td>[<a href="#path-generic-format-observers">path.generic.obs</a>]</td> + <td>No conversion performed</td> + <td>Backslashes converted to slashes</td> + <td> </td> + </tr> + <tr> + <td><code>p.make_preferred()</code></td> + <td>[<a href="#path-modifiers">fs.path.modifiers</a>]</td> + <td>No change</td> + <td>Slashes converted to backslashes</td> + <td> </td> + </tr> + <tr> + <td>Characters prohibited in filenames</td> + <td>[<a href="#filename">fs.def.filename</a>]</td> + <td>0x00, <code>'/'</code></td> + <td>0x00-0x1F, <code>'"'</code>, <code>'*'</code>,<code> '*'</code>, + <code>'<'</code>, + <code>'>'</code>, <code>'?'</code>, <code>'\\'</code> (single backslash), + <code>'/'</code>, <code>'|'</code></td> + <td>Many operating systems prohibit the ASCII control characters (0x00-0x1F) + in filenames.</td> + </tr> + <tr> + <td>Initial imbued <code>path</code> locale</td> + <td>[<a href="#path-imbued-locale">path.imbued.locale</a>]</td> + <td> <code>std::locale("")<br> + </code><sup>[footnote 2]</sup></td> + <td>Implementation supplied locale using <code>MultiByteToWideChar</code> + and <code>WideCharToMultiByte</code> with a codepage of <code>CP_ACP</code> + if <code>AreFileApisANSI()</code>is true, otherwise codepage <code>CP_OEMCP</code>.<sup>[footnote + 3]</sup></td> + <td>Apple OS X®: Implementation supplied locale providing UTF-8 <code>codecvt</code> + facet.<sup>[footnote 4]</sup></td> + </tr> +</table> +<p><sup>[footnote1]</sup> OS X® and Windows® are examples of commercially +available operating systems. This information is given for the convenience of +users of this document and does not constitute an endorsement by ISO or IEC of +these products.</p> +<p><sup>[footnote 2] </sup>Rationale: ISO C specifies <code>std::locale("")</code> as "the locale-specific native +environment", while ISO/IEC 9945 says it "Specifies an implementation-defined native +environment."</p> +<p><sup>[footnote 3] </sup>Rationale: This is the current behavior of C and C++ +standard library functions that perform file operations using narrow character +strings to identify paths. Changing this behavior would be surprising and at +variance with existing code, particularly where user input is involved.</p> +<p><sup>[footnote 4]</sup> Rationale: Vendor's documentation states "All BSD +system functions expect their string parameters to be in UTF-8 encoding and +nothing else."</p> +<h2><a name="Header-filesystem-synopsis">Header <code><$HEADER;></code> synopsis</a> +[filesystem.synopsis]</h2> +<pre>$NAMESPACE_BEGIN; + class <a href="#class-path">path</a>; + +$if $TARGET; == BOOST bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2); +$endif; void swap(path& lhs, path& rhs); + std::size_t <a href="#hash_value">hash_value</a>(const path& p); + + bool operator==(const path& lhs, const path& rhs); + bool operator!=(const path& lhs, const path& rhs); + bool operator< (const path& lhs, const path& rhs); + bool operator<=(const path& lhs, const path& rhs); + bool operator> (const path& lhs, const path& rhs); + bool operator>=(const path& lhs, const path& rhs); + + path operator/ (const path& lhs, const path& rhs); + + std::ostream& operator<<( std::ostream& os, const path& p ); + std::wostream& operator<<( std::wostream& os, const path& p ); + std::istream& operator>>( std::istream& is, path& p ); + std::wistream& operator>>( std::wistream& is, path& p ) + + class <a href="#Class-filesystem_error">filesystem_error</a>; + class <a href="#Class-directory_entry">directory_entry</a>; + + class <a href="#Class-directory_iterator">directory_iterator</a>; + + // enable c++11 range-based for statements + const directory_iterator& <a href="#directory_iterator-non-member-functions">begin</a>(const directory_iterator& iter); + directory_iterator <a href="#directory_iterator-non-member-functions">end</a>(const directory_iterator&); + +$if $TARGET; == BOOST + // enable BOOST_FOREACH + directory_iterator& range_begin(directory_iterator& iter); + directory_iterator range_begin(const directory_iterator& iter); + directory_iterator range_end(const directory_iterator&); + +$endif + class <a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a>; + + // enable c++11 range-based for statements + const recursive_directory_iterator& <a href="#recursive_directory_iterator-non-member-functions">begin</a>(const recursive_directory_iterator& iter); + recursive_directory_iterator <a href="#recursive_directory_iterator-non-member-functions">end</a>(const recursive_directory_iterator&); + +$if $TARGET; == BOOST + // enable BOOST_FOREACH + recursive_directory_iterator& range_begin(recursive_directory_iterator& iter); + recursive_directory_iterator range_begin(const recursive_directory_iterator& iter); + recursive_directory_iterator range_end(const recursive_directory_iterator&); + +$endif + enum <a name="file_type" href="#Enum-file_type">file_type</a> + { + status_error, file_not_found, regular_file, directory_file, + symlink_file, block_file, character_file, fifo_file, socket_file, + type_unknown + }; + + enum <a href="#Enum-perms">perms</a> + { + no_perms, + owner_read, owner_write, owner_exe, owner_all, + group_read, group_write, group_exe, group_all, + others_read, others_write, others_exe, others_all, all_all, + set_uid_on_exe, set_gid_on_exe, sticky_bit, + perms_mask, perms_not_known, + add_perms, remove_perms, symlink_perms + }; + + class <a href="#file_status">file_status</a>; + + struct <a name="space_info">space_info</a> // returned by <a href="#space" style="text-decoration: none">space</a> function + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; // free space available to a non-privileged process + }; + + enum class <a name="copy_option">copy_option</a> + { + none + fail_if_exists = none, + overwrite_if_exists + }; + + enum class <a name="symlink_option">symlink_option</a> + { + none + no_recurse = none, + recurse + }; + + // <a href="#Operational-functions">operational functions</a> + + path <a href="#absolute">absolute</a>(const path& p, const path& base=current_path()); + + path <a href="#canonical">canonical</a>(const path& p, const path& base = current_path()); + path <a href="#canonical">canonical</a>(const path& p, system::error_code& ec); + path <a href="#canonical">canonical</a>(const path& p, const path& base, system::error_code& ec); + + void <a href="#copy">copy</a>(const path& from, const path& to); + void <a href="#copy">copy</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#create_directory">copy_directory</a>(const path& from, const path& to); + void <a href="#create_directory">copy_directory</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#copy_file">copy_file</a>(const path& from, const path& to); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, system::error_code& ec); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option); + void <a href="#copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option, + system::error_code& ec); + + void <a href="#copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink); + void <a href="#copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink, + system::error_code& ec); + + bool <a href="#create_directories">create_directories</a>(const path& p); + bool <a href="#create_directories">create_directories</a>(const path& p, system::error_code& ec); + + bool <a href="#create_directory">create_directory</a>(const path& p); + bool <a href="#create_directory">create_directory</a>(const path& p, system::error_code& ec); + + void <a href="#create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink); + void <a href="#create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink, + system::error_code& ec); + + void <a href="#create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link); + void <a href="#create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link, + system::error_code& ec); + + void <a href="#create_symlink">create_symlink</a>(const path& to, const path& new_symlink); + void <a href="#create_symlink">create_symlink</a>(const path& to, const path& new_symlink, + system::error_code& ec); + + path <a href="#current_path">current_path</a>(); + path <a href="#current_path">current_path</a>(system::error_code& ec); + void <a href="#current_path">current_path</a>(const path& p); + void <a href="#current_path">current_path</a>(const path& p, system::error_code& ec); + + bool <a href="#exists">exists</a>(file_status s) noexcept; + bool <a href="#exists">exists</a>(const path& p); + bool <a href="#exists">exists</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#equivalent">equivalent</a>(const path& p1, const path& p2); + bool <a href="#equivalent">equivalent</a>(const path& p1, const path& p2, system::error_code& ec); + + uintmax_t <a href="#file_size">file_size</a>(const path& p); + uintmax_t <a href="#file_size">file_size</a>(const path& p, system::error_code& ec); + + uintmax_t <a href="#hard_link_count">hard_link_count</a>(const path& p); + uintmax_t <a href="#hard_link_count">hard_link_count</a>(const path& p, system::error_code& ec); + + const path& <a href="#initial_path">initial_path</a>(); + const path& <a href="#initial_path">initial_path</a>(<code>system::error_code& ec</code>); + + bool <a href="#is_directory">is_directory</a>(file_status s) noexcept; + bool <a href="#is_directory2">is_directory</a>(const path& p); + bool <a href="#is_directory2">is_directory</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_empty">is_empty</a>(const path& p); + bool <a href="#is_empty">is_empty</a>(const path& p, system::error_code& ec); + + bool <a href="#is_other">is_other</a>(file_status s) noexcept; + bool <a href="#is_other2">is_other</a>(const path& p,); + bool <a href="#is_other2">is_other</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_regular_file">is_regular_file</a>(file_status s) noexcept; + bool i<a href="#is_regular_file2">s_regular_file</a>(const path& p); + bool i<a href="#is_regular_file2">s_regular_file</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#is_symlink">is_symlink</a>(file_status s noexcept); + bool <a href="#is_symlink2">is_symlink</a>(const path& p); + bool <a href="#is_symlink2">is_symlink</a>(const path& p, system::error_code& ec) noexcept; + + std::time_t <a href="#last_write_time">last_write_time</a>(const path& p); + std::time_t <a href="#last_write_time">last_write_time</a>(const path& p, system::error_code& ec); + void <a href="#last_write_time2">last_write_time</a>(const path& p, const std::time_t new_time); + void <a href="#last_write_time2">last_write_time</a>(const path& p, const std::time_t new_time, + system::error_code& ec); + + path <a href="#read_symlink">read_symlink</a>(const path& p); + path <a href="#read_symlink">read_symlink</a>(const path& p, system::error_code& ec); + + bool <a href="#remove">remove</a>(const path& p); + bool <a href="#remove">remove</a>(const path& p, system::error_code& ec); + + uintmax_t <a href="#remove_all">remove_all</a>(const path& p); + uintmax_t <a href="#remove_all">remove_all</a>(const path& p, system::error_code& ec); + + void <a href="#rename">rename</a>(const path& from, const path& to); + void <a href="#rename">rename</a>(const path& from, const path& to, system::error_code& ec); + + void <a href="#resize_file">resize_file</a>(const path& p, uintmax_t size); + void <a href="#resize_file2">resize_file</a>(const path& p, uintmax_t size, system::error_code& ec); + + <a href="#space_info">space_info</a> <a href="#space">space</a>(const path& p); + <a href="#space_info">space_info</a> <a href="#space">space</a>(const path& p, system::error_code& ec); + + <a href="#file_status">file_status</a> <a href="#status">status</a>(const path& p); + <a href="#file_status">file_status</a> <a href="#status">status</a>(const path& p, system::error_code& ec) noexcept; + + bool <a href="#status_known">status_known</a>(file_status s) noexcept; + + <a href="#file_status">file_status</a> <a href="#symlink_status">symlink_status</a>(const path& p); + <a href="#file_status">file_status</a> <a href="#symlink_status">symlink_status</a>(const path& p, system::error_code& ec) noexcept; + + path <a href="#system_complete">system_complete</a>(const path& p); + path <a href="#system_complete">system_complete</a>(const path& p, system::error_code& ec); + + path <a href="#temp_directory_path">temp_directory_path</a>(); + path <a href="#temp_directory_path">temp_directory_path</a>(system::error_code& ec); + + path <a href="#unique_path">unique_path</a>(const path& model="%%%%-%%%%-%%%%-%%%%"); + path <a href="#unique_path">unique_path</a>(const path& model, system::error_code& ec); + +$NAMESPACE_END;</pre> +<h2><a name="Error-reporting">Error reporting</a> [fs.err.report]</h2> +<p>Filesystem library functions often provide two overloads, one that +throws an exception to report file system errors, and another that sets an <code>error_code</code>.</p> +<blockquote> +<p>[<i>Note:</i> This supports two common use cases:</p> +<ul> + <li>Uses where file system +errors are truly exceptional and indicate a serious failure. Throwing an + exception is the most appropriate response. This is the preferred default for + most everyday programming.<br> + </li> + <li>Uses where file system system errors are routine and do not necessarily represent + failure. Returning an error code is the most appropriate response. This allows + application specific error handling, including simply ignoring the error.</li> +</ul> + <p><i>--end note</i>]</p> +</blockquote> +<p>Functions <b>not</b> having an argument of type <code>system::error_code&</code> report errors as follows, unless otherwise specified:</p> + <ul> + <li>When a call by the + implementation to an operating system or other underlying API results in an + error that prevents the function from meeting its specifications, an exception + of type +<code>filesystem_error</code> is thrown.<br> + </li> + <li>Failure to allocate storage is reported by throwing an exception as described in the C++ standard, + 17.6.4.10 [res.on.exception.handling].<br> + </li> + <li>Destructors throw nothing.</li> + </ul> + <p>Functions having an argument of type <code>system::error_code&</code> report errors as follows, unless otherwise + specified:</p> +<ul> + <li>If a call by the + implementation to an operating system or other underlying API results in an + error that prevents the function from meeting its specifications, the +<code>system::error_code&</code> argument is set as + appropriate appropriate for the specific error. Otherwise, <code>clear()</code> + is called on the +<code>system::error_code&</code> argument.<br> + </li> + <li>Failure to allocate storage is reported by + throwing an exception as described in the C++ standard, + 17.6.4.10 [res.on.exception.handling].</li> +</ul> +<h2><a name="class-path">Class <code>path</code> [class.path]</a></h2> +<p>An object of class <code>path</code> represents a <a href="#Path">path</a>, +and contains a <a href="#Pathname">pathname</a> Such an object is concerned only with the lexical and syntactic aspects +of a path. The path does not necessarily exist in external storage, and the +pathname is not necessarily valid for the current operating +system or for a particular file system.</p> +<pre>$NAMESPACE_BEGIN; + class path + { + public: + typedef <b><i><a href="#value_type">see below</a></i></b> value_type; + typedef std::basic_string<value_type> string_type; + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + constexpr value_type preferred_separator; + + // <a href="#path-constructors">constructors</a> and destructor + path(); + path(const path& p); + path(path&& p) noexcept; + + template <class <a href="#Source">Source</a>> + path(Source const& source$CODECVT_ARG2;$CODECVT_DEFAULT;); + + template <class <a href="#InputIterator">InputIterator</a>> + path(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;); + + ~path(); + + // <a href="#path-assignments">assignments</a> + path& operator=(const path& p); + path& operator=(path&& p) noexcept; + + template <class <a href="#Source">Source</a>> + path& operator=(Source const& source); + +$if $TARGET; == BOOST template <class <a href="#Source">Source</a>> + path& assign(Source const& source$CODECVT_ARG2;) + +$endif; template <class <a href="#InputIterator">InputIterator</a>> + path& assign(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;); + + // <a href="#path-appends">appends</a> + path& operator/=(const path& p); + + template <class <a href="#Source">Source</a>> + path& operator/=(Source const& source); + +$if $TARGET; == BOOST template <class <a href="#Source">Source</a>> + path& append(Source const& source$CODECVT_ARG2;); + +$endif; template <class <a href="#InputIterator">InputIterator</a>> + path& append(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;); + + // <a href="#path-concatenation">concatenation</a> + path& operator+=(const path& x); + path& operator+=(const string_type& x); + path& operator+=(const value_type* x); + path& operator+=(value_type x); + template <class Source> + path& operator+=(Source const& x); + template <class CharT> + path& operator+=(CharT x); +$if $TARGET; == BOOST template <class Source> + path& concat(Source const& x$CODECVT_ARG2;); +$endif; template <class InputIterator> + path& concat(InputIterator begin, InputIterator end); + template <class InputIterator> + path& concat(InputIterator begin, InputIterator end$CODECVT_ARG2;); + + // <a href="#path-modifiers">modifiers</a> + void <a href="#path-clear">clear</a>(); + path& <a href="#absolute">make_absolute</a>(const path& base); + path& <a href="#path-make_preferred">make_preferred</a>(); + path& <a href="#path-remove_filename">remove_filename</a>(); + path& <a href="#path-replace_extension">replace_extension</a>(const path& new_extension = path()); + void <a href="#path-swap">swap</a>(path& rhs); + + // <a href="#path-native-format-observers">native format observers</a> + const string_type& <a href="#native">native</a>() const noexcept; // native format, encoding + const value_type* <a href="#c_str">c_str</a>() const noexcept; // native().c_str() + + template <class String> + String <a href="#string-template">string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; // native format + + string <a href="#string">string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; // native format + wstring <a href="#wstring">wstring</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; // native format + u16string <a href="#u16string">u16string</a>() const; // native format + u32string <a href="#u32wstring">u32string</a>() const; // native format + + // <a href="#path-generic-format-observers">generic format observers</a> + template <class String> + String <a href="#generic_string-template">generic_string</a>() const; + + string <a href="#generic_string">generic_string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; // generic format + wstring <a href="#generic_wstring">generic_wstring</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; // generic format + u16string <a href="#generic_u16string">generic_u16string</a>() const; // generic format + u32string <a href="#generic_u32wstring">generic_u32string</a>() const; // generic format + + // <a href="#path-compare">compare</a> + int <a href="#path-compare">compare</a>(const path& p) const noexcept; + int <a href="#path-compare">compare</a>(const std::string& s) const; + int <a href="#path-compare">compare</a>(const value_type* s) const; + + // <a href="#path-decomposition">decomposition</a> + path <a href="#path-root_name">root_name</a>() const; + path <a href="#path-root_directory">root_directory</a>() const; + path <a href="#path-root_path">root_path</a>() const; + path <a href="#path-relative_path">relative_path</a>() const; + path <a href="#path-parent_path">parent_path</a>() const; + path <a href="#path-filename">filename</a>() const; + path <a href="#path-stem">stem</a>() const; + path <a href="#path-extension">extension</a>() const; + + // <a href="#path-query">query</a> + bool <a href="#path-query">empty</a>() const; + bool <a href="#path-has_root_name">has_root_name</a>() const; + bool <a href="#path-has_root_directory">has_root_directory</a>() const; + bool <a href="#path-has_root_path">has_root_path</a>() const; + bool <a href="#path-has_relative_path">has_relative_path</a>() const; + bool <a href="#path-has_parent_path">has_parent_path</a>() const; + bool <a href="#path-has_filename">has_filename</a>() const; + bool <a href="#path-has_stem">has_stem</a>() const; + bool <a href="#path-has_extension">has_extension</a>() const; + bool <a href="#path-is_absolute">is_absolute</a>() const; + bool <a href="#path-is_relative">is_relative</a>() const; + + // <a href="#path-iterators">iterators</a> + class iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + // <a href="#path-imbued-locale">imbued locale</a> + static std::locale <a href="#path-imbue">imbue</a>(const std::locale& loc); + static const codecvt_type & <a href="#path-codecvt">codecvt</a>(); + + private: + string_type pathname; // <b><i>exposition only</i></b> + }; + +$NAMESPACE_END;</pre> +<p><code><a name="value_type">value_type</a></code> is a <code>typedef</code> for the +character type used by the operating system to represent pathnames.</p> +<h3><a name="path-Conversions"><code>path</code> Conversions</a> [path.cvt]</h3> +<h4><code>path</code> argument conversions [<a name="path.arg.convert">path.arg.cvt</a>]</h4> +<h5><a name="path-Conversions-to-native-format"><code>path</code> argument +format conversions</a> [path.arg.fmt.cvt]</h5> +<p>Member function arguments that take character sequences representing paths +may use the <a href="#generic-pathname-format">generic pathname format</a> or +the <a href="#native-pathname-format">native pathname format</a>. Iff such arguments +are in the generic format and the generic format is not acceptable to the +operating system as a native path, conversion to native format shall be performed +during the processing of the argument. See [<a href="#Operating-system-examples">fs.os.examples</a>].</p> +<blockquote> +<p>[<i>Note:</i> Depending on the operating system, there may be no unambiguous way for an implementation to +always be able to distinguish between native format and generic format arguments. +This is by design as it simplifies use for operating systems that do not require +disambiguation. Should an implementation encounter an +operating system where disambiguation is required, an implementation can defined +an extension to distinguish between the formats. <i> +-- end note</i>]</p> +</blockquote> + +<p>If the native format requires +paths for regular files to be formatted differently from paths for directories, the +path shall be treated as a directory path if last element is a separator, +otherwise it shall be treated as a regular file path.</p> + +<h5><a name="path-Encoding-conversions"><code> +path</code> argument encoding conversions</a> +[path.arg.encoding.cvt]</h5> +<p>For member function arguments that take character sequences representing +paths, if the value type of the argument is not <code>value_type and </code>one +of the value types is <code>char</code> and the other is <code>wchar_t</code>, conversion to <code>value_type</code> +shall be performed by the <code>path::codecvt()</code> facet. ([<a href="#path-imbued-locale">path.imbued.locale</a>]).</p> +<h4><a name="path-Conversions-to-generic-format"><code>path</code> Conversions +to generic format</a> [fs.cvt.to.generic]</h4> +<p><a href="#path-generic-format-observers">Generic format observer</a> functions +shall return strings formatted according to the <a href="#generic-pathname-format">generic pathname format</a> +using <i>preferred-separator</i>. See [<a href="#Operating-system-examples">fs.os.examples</a>].</p> +<h3><a name="path-Requirements"><code>path</code> Requirements</a> [path.req]</h3> +<p>Template parameters named <code><a name="InputIterator">InputIterator</a></code> are required meet the +requirements for a C++ standard library <code>RandomIterator</code> compliant iterator. The iterator's value type is required to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</p> +<p>Template parameters named <code><a name="Source">Source</a></code> are required to be one of:</p> +<ul> + <li>A container with a value type of <code>char</code>, <code> + wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li> + <li>An iterator for a null terminated byte-string. The value type is required + to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code> + char32_t</code>.</li> + <li>A C-array. The value type is required to be <code>char</code>, <code> + wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li> + <li>A <code>$NAMESPACE;::$SUBNAMESPACE;::directory_entry</code>.</li> +</ul> + +<h3> <a name="path-constructors"> <code> +<font size="4">path</font></code> constructors</a> [path.construct]</h3> +<pre>template <class <a href="#Source">Source</a>> + path(Source const& source$CODECVT_ARG2;$CODECVT_DEFAULT;);</pre> +<pre>template <class <a href="#InputIterator">InputIterator</a>> + path(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;);</pre> +<blockquote> + <p><i>Effects:</i> Stores the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> in <code>pathname</code>, converting format and + encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]).</p> +</blockquote> +<h3> <a name="path-assignments"> <code> +<font size="4">path</font></code> assignments</a> [path.assign]</h3> +<pre>template <class <a href="#Source">Source</a>> + path& operator=(Source const& source); +$if $TARGET; == BOOST template <class <a href="#Source">Source</a>> + path& assign(Source const& source$CODECVT_ARG2;); +$endif; template <class <a href="#InputIterator">InputIterator</a>> + path& assign(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;);</pre> +<blockquote> + <p><i>Effects:</i> Stores the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> in <code>pathname</code>, converting format and + encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]). </p> + <p> + <i>Returns: </i><code>*this</code></p> + </blockquote> +<h3><a name="path-appends"><code><font size="4"> path</font></code> appends</a> +[path.append]</h3> + <p>The append operations use <code> + operator/=</code> to denote their semantic effect of appending <i> + preferred-separator</i> when needed. </p> +<pre>path& operator/=(const path& p);</pre> +<blockquote> + <p><i>Effects:</i></p> + <blockquote> + Appends <code>path::preferred_separator</code> to <code>pathname</code>, + converting format and encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]), unless:<ul> + <li>an added separator + would be redundant, or</li> + <li>would change an relative path to an absolute path, or</li> + <li><code>p.empty()</code>, or</li> + <li><code>*p.native().cbegin()</code> is a directory separator.</li> + </ul> + <p>Then appends <code>p.native()</code> to <code>pathname</code>.</p> + </blockquote> + <p><i>Returns: </i><code>*this</code></p> +</blockquote> +<pre>template <class <a href="#Source">Source</a>> + path& operator/=(Source const & source); +$if $TARGET; == BOOST template <class <a href="#Source">Source</a>> + path& append(Source const & source$CODECVT_ARG2;); +$endif; template <class <a href="#InputIterator">InputIterator</a>> + path& append(InputIterator begin, InputIterator end$CODECVT_ARG2;$CODECVT_DEFAULT;);</pre> +<blockquote> + <p><i>Effects:</i></p> + <blockquote> + <p>Appends <code>path::preferred_separator</code> to <code>pathname</code>, converting + format and encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]), unless:</p> + <ul> + <li>an added separator + would be redundant, or</li> + <li>would change an relative path to an absolute path, or</li> + <li><code>p.empty()</code>, or</li> + <li><code>*p.native().cbegin()</code> is a separator.</li> + </ul> + <p>Appends the contents [<code>begin</code>,<code>end</code>) + or <code>source</code> to <code>pathname</code>, converting format and + encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]).</p> + </blockquote> + <p><i>Returns: </i><code>*this</code></p> + </blockquote> + +<h3><a name="path-concatenation"><code>path</code> concatenation</a> [path.concat]</h3> +<pre>path& operator+=(const path& x); +path& operator+=(const string_type& x); +path& operator+=(const value_type* x); +path& operator+=(value_type x); +template <class Source> + path& operator+=(Source const& x); +template <class CharT> + path& operator+=(CharT x); +template <class InputIterator> + path& concat(InputIterator begin, InputIterator end); +template <class InputIterator> + path& concat(InputIterator begin, InputIterator end$CODECVT_ARG2;);</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&</code>, otherwise</li> + <li><code>s</code>, where <code>s</code> is + <code>std::basic_string<typename std::iterator_traits<InputIterator>::value_type><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> [path.modifiers]</h3><pre>void <a name="path-clear">clear</a>();</pre> +<blockquote> +<p><i>Postcondition:</i> <code>this->empty()</code> is true.</p> +</blockquote> +<pre>path& <a name="path-make_preferred">make_preferred</a>();</pre> +<blockquote> + <p><i>Effects:</i> <i>directory-separator</i>s are converted to <i>prefered-separator</i>s. + See [<a href="#Operating-system-examples">fs.os.examples</a>].</p> + <p><i>Returns:</i> <code>*this</code></p> +</blockquote> + +<pre>path& <a name="path-remove_filename">remove_filename</a>();</pre> +<blockquote> + <p><i>Returns: </i>As if, <code>*this = parent_path();</code></p> + <p>[<i>Note:</i> This function is needed to efficiently implement <code>directory_iterator</code>. It is exposed to allow additional uses. The actual + implementation may be much more efficient than <code>*this = parent_path()</code> <i>-- end + note</i>]</p> +</blockquote> +<pre>path& <a name="path-replace_extension">replace_extension</a>(const path& new_extension = path());</pre> +<blockquote> + <p><i>Effects:</i></p> + <ul> + <li>Any existing <code>extension()</code> is removed from the stored path, + then</li> + <li>iff + <code>new_extension</code> is not empty and does not begin with a dot + character, a dot character is appended to the stored path, then</li> + <li> + <code>new_extension</code> is appended to the stored path.</li> + </ul> + <p><i>Returns:</i> <code>*this</code></p> +</blockquote> +<pre><code>void <a name="path-swap">swap</a>(path& rhs) noexcept;</code></pre> +<blockquote> + <p><i>Effects:</i> Swaps the contents of the two paths.</p> + <p><i>Complexity: </i>constant time.</p> +</blockquote> + +<h3> <a name="path-native-format-observers"><code><font size="4">path</font></code> native format observers</a> +[path.native.obs]</h3> +<p>The string returned by all native format observers is in the <a href="#native-pathname-format">native pathname format</a>.</p> +<pre>const string_type& <a name="native">native</a>() const noexcept;</pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +</blockquote> +<pre>const value_type* <a name="c_str">c_str</a>() const noexcept;</pre> +<blockquote> +<p><i>Returns:</i> <code>pathname.c_str()</code>.</p> +</blockquote> +<pre>template <class String> +String <a name="string-template">string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const;</pre> +<blockquote> + <p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than <code>String</code>, conversion is performed by <code>cvt</code>.</p> +</blockquote> +<pre>string <a name="string">string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; +wstring <a name="wstring">wstring</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; +u16string <a name="u16string">u16string</a>() const; +u32wstring <a name="u32wstring">u32wstring</a>() const; </pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than +function's return type, conversion is performed by <code>cvt</code>.</p> +</blockquote> + +<h3> <a name="path-generic-format-observers"><code><font size="4">path</font></code> generic format observers</a> +[path.generic.obs]</h3> +<p>The string returned by all generic format observers is in the <a href="#generic-pathname-format">generic pathname format</a>.</p> +<pre>template <class String> +String <a name="generic_string-template">generic_string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const;</pre> +<blockquote> + <p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than <code>String</code>, conversion is performed by <code>cvt</code>.</p> +</blockquote> +<pre>string <a name="generic_string">generic_string</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; +wstring <a name="generic_wstring">generic_wstring</a>($CODECVT_ARG;$CODECVT_DEFAULT;) const; +u16string <a name="generic_u16string">generic_u16string</a>() const; +u32wstring <a name="generic_u32wstring">generic_u32wstring</a>() const; </pre> +<blockquote> +<p><i>Returns:</i> <code>pathname</code>.</p> +<p><i>Remarks:</i> If <code>string_type</code> is a different type than +function's return type, conversion is performed by <code>cvt</code>.</p> +</blockquote> + +<h3> <a name="path-compare"><code>path</code> compare</a> [path.compare]</h3> +<pre>int compare(const path& p) const noexcept;</pre> +<blockquote> + <p><i>Returns:</i> A value less than 0 if the elements of <code>*this</code> are lexicographically less than the elements of <code>p</code>, otherwise a + value greater than 0 if the elements of <code>*this</code> are + lexicographically greater than the elements of <code>p</code>, otherwise 0.</p> + <p>Remark: The elements are determined as if by iteration over the half-open + range [<code>begin()</code>, <code>end()</code>) for <code>*this</code> and <code>p</code>.</p> +</blockquote> +<pre>int compare(const std::string& s) const</pre> +<blockquote> + <p><i>Returns:</i> <code>compare(path(s))</code>.</p> +</blockquote> +<pre>int compare(const value_type* s) const</pre> +<blockquote> + <p><i>Returns:</i> <code>compare(path(s))</code>.</p> +</blockquote> +<h3> <a name="path-decomposition"> <code><font size="4">path</font></code> decomposition</a> +[path.decompose]</h3> +<p><span style="background-color: #E0E0E0"><i>See the <a href="#Path-decomposition-table">Path decomposition table</a> for examples +for values returned by decomposition functions. The <a href="tutorial.html#Using-path-decomposition">Tutorial</a> may also be +helpful.</i></span></p> +<pre>path <a name="path-root_name">root_name</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> <i>root-name,</i> if <code>pathname</code> includes <i>root-name</i>, otherwise <code>path()</code>. </p> +</blockquote> +<pre>path <a name="path-root_directory">root_directory</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> <i>root-directory</i>, if <code>pathname</code> includes <i>root-directory</i>, otherwise <code>path()</code>.</p> +<p>If <i>root-directory</i> is composed of <i>slash name</i>, <i>slash</i> is +excluded from the returned string.</p> +</blockquote> +<pre>path <a name="path-root_path">root_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>root_name() / root_directory()</code></p> +</blockquote> +<pre>path <a name="path-relative_path">relative_path</a>() const;</pre> +<blockquote> +<p><i>Returns:</i> A <code>path</code> composed from <code>pathname</code>, if <code>!empty()</code>, beginning +with the first <i>filename</i> after <i>root-path</i>. Otherwise, <code>path()</code>.</p> +</blockquote> +<pre>path <a name="path-parent_path">parent_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>(empty() || begin() == --end()) ? path() : <i>pp</i></code>, where <code><i>pp</i></code> is constructed as if by + starting with an empty <code>path</code> and successively applying <code>operator/=</code> for each element in the range <code>begin()</code>, <code>--end()</code>.</p> +</blockquote> +<pre>path <a name="path-filename">filename</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>empty() ? path() : *--end()</code></p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").filename();</code> // outputs "<code>bar.txt</code>"</pre> + </blockquote> + <p> <i>--end example</i>]</p> +</blockquote> +<pre>path <a name="path-stem">stem</a>(const path& p) const;</pre> +<blockquote> + <p><i>Returns:</i> if <code>p.filename()</code> contains a dot but does not + consist solely of one or to two dots, returns + the substring of <code>p.filename()</code> starting at its beginning and + ending at the last dot (the dot is not included). Otherwise, + returns <code>p.filename()</code>.</p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").stem();</code> // outputs "<code>bar</code>" +path p = "foo.bar.baz.tar"; +for (; !p.extension().empty(); p = p.stem()) + std::cout << p.extension() << '\n'; + // outputs: .tar + // .baz + // .bar</pre> + </blockquote> + <p> <i>--end example</i>]</p> +</blockquote> +<pre>path <a name="path-extension">extension</a>(const path& p) const;</pre> +<blockquote> + <p><i>Returns:</i> if <code>p.filename()</code> contains a dot but does not + consist solely of one or to two dots, returns + the substring of <code>p.filename()</code> starting at the rightmost dot + and ending at the path's end. Otherwise, returns an empty <code>path</code> object. </p> + <p><i>Remarks:</i> Implementations are permitted but not required to define additional + behavior for file systems which append additional elements to extensions, such + as alternate data streams or partitioned dataset names.</p> + <p>[<i>Example:</i></p> + <blockquote> + <pre><code>std::cout << path("/foo/bar.txt").extension(); //</code> outputs "<code>.txt</code>"</pre> + </blockquote> + <p> <i>--end example</i>]</p> + <p>[<i>Note:<b> </b></i>The dot is included in the return value so that it is + possible to distinguish between no extension and an empty extension. <span style="background-color: #FFFF00"> + See + </span> <a href="http://permalink.gmane.org/gmane.comp.lib.boost.devel/199744"> + <span style="background-color: #FFFF00">http://permalink.gmane.org/gmane.comp.lib.boost.devel/199744</span></a><span style="background-color: #FFFF00"> for more + extensive rationale. </span> <i><span style="background-color: #FFFF00">-- end note</span></i><span style="background-color: #FFFF00">]</span></p> +</blockquote> +<h3> <a name="path-query"> <code><font size="4">path</font></code> query</a> [path.query]</h3> +<pre>bool <a name="path-empty">empty</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>m_pathname.empty()</code>.</p> +</blockquote> +<pre>bool <a name="path-has_root_path">has_root_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_path">root_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_root_name">has_root_name</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_name">root_name</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_root_directory">has_root_directory</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-root_directory">root_directory</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_relative_path">has_relative_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-has_relative_path">relative_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_parent_path">has_parent_path</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-parent_path">parent_path</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_filename">has_filename</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-filename">filename</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_stem">has_stem</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-stem">stem</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-has_extension">has_extension</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!<a href="#path-has_extension">extension</a>().empty()</code></p> +</blockquote> +<pre>bool <a name="path-is_absolute">is_absolute</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>true</code> if the elements of <code>root_path()</code> uniquely identify a directory, else <code>false</code>.</p> +</blockquote> +<pre>bool <a name="path-is_relative">is_relative</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>!is_absolute()</code>.</p> +</blockquote> +<h3> <a name="path-iterators"> <code> +<font size="4">path</font></code> iterators</a> [path.itr]</h3> +<p> Path iterators iterate over the elements of the stored pathname.</p> +<p> A <code>path::iterator</code> is a constant iterator satisfying all +the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional +iterators [lib.bidirectional.iterators]). Its <code>value_type</code> is <code>path</code>.</p> + <p>Calling any non-const member function of a <code>path</code> object + invalidates all iterators referring to elements of that object.</p> +<p> The forward traversal order is as follows:</p> +<ul> + <li>The <i>root-name</i> element, if present.</li> + <li>The <i>root-directory</i> element, if present, in the generic format. <i> + [note:</i> the generic format is required to ensure lexicographical + comparison works correctly. <i>-- end note</i>]</li> + <li>Each successive <i>filename</i> element, if present.</li> + <li><i>Dot</i>, if one or more trailing non-root <i>slash</i> + characters are present.</li> +</ul> + <p>The backward traversal order is the reverse of forward traversal.</p> + <pre>iterator begin() const;</pre> +<blockquote> + <p><i>Returns:</i> An iterator for the first present element in the traversal + list above. If no elements are present, the end iterator.</p> +</blockquote> +<pre>iterator end() const;</pre> +<blockquote> + <p><i>Returns:</i> The end iterator.</p> +</blockquote> + <h3><a name="path-imbued-locale"><code><font size="4"> path</font></code> + imbued locale</a> [path.imbued.locale]</h3> + <p><code>path</code> operations sometimes require encoding conversions between + <code>pathname</code> and some other string object where one of the value types + is <code>char</code> and the other is <code>wchar_t</code>. Such conversions + shall be performed by the <code>path::codecvt()</code> facet.</p> + <blockquote> + <p><span style="background-color: #FFFF00">[</span><i><span style="background-color: #FFFF00">Example:</span></i><span style="background-color: #FFFF00"> + ... </span><i><span style="background-color: #FFFF00">--end example</span></i><span style="background-color: #FFFF00">]</span></p> + </blockquote> + <pre>static std::locale <a name="path-imbue">imbue</a>(const std::locale& loc);</pre> +<blockquote> + <p><i>Effects:</i> Stores a copy of <code>loc</code> as the imbued <code>path</code> + locale.</p> + <p><i>Returns:</i> The previous imbued <code>path</code> locale.</p> + <p><i>Remarks:</i> The initial value of the imbued <code>path</code> locale is + operating system dependent. It shall be a locale with a <code>codecvt</code> + facet for a <code>char</code> string encoding appropriate for the operating + system. See ([<a href="#Operating-system-examples">fs.os.examples</a>]). </p> +</blockquote> +<pre>static const codecvt_type& <a name="path-codecvt">codecvt</a>();</pre> +<blockquote> + <p><i>Returns:</i> The <code>codecvt</code> facet for the imbued<code> path</code> + locale .</p> +</blockquote> + +$if $TARGET; == BOOST +<h3> <a name="path-deprecated-functions"><code><font size="4"> path</font></code> deprecated functions</a></h3> +<p> Several member functions from previous versions of <code>class path</code> have been deprecated, either because they have been renamed or because the +functionality is no longer desirable or has become obsolete.</p> +<p> Deprecated functions available by default; will be suppressed if <code>BOOST_FILESYSTEM_NO_DEPRECATED</code> is defined:</p> +<blockquote> + <pre>path& remove_leaf() { return remove_filename(); } +path leaf() const { return filename(); } +path branch_path() const { return parent_path(); } +bool has_leaf() const { return !m_path.empty(); } +bool has_branch_path() const { return !parent_path().empty(); }</pre> +</blockquote> +<p> Deprecated functions not available by default; will be supplied if <code>BOOST_FILESYSTEM_DEPRECATED</code> is defined:</p> +<blockquote> +<pre>const std::string file_string() const { return native_string(); } +const std::string directory_string() const { return native_string(); } +const std::string native_file_string() const { return native_string(); } +const std::string native_directory_string() const { return native_string(); } +const string_type external_file_string() const { return native(); } +const string_type external_directory_string() const { return native(); }</pre> +</blockquote> + +$endif + +<h3> <a name="path-non-member-functions"> <code><font size="4">path</font></code> non-member functions</a> +[path.non-member]</h3> +$if $TARGET; == BOOST + <pre>bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2);</pre> +<blockquote> + <p><i>Returns:</i> <code>true</code> if the sequence of <code>native()</code> strings for the elements defined by the half-open range <code>[first1,last1)</code> is + lexicographically less than the sequence of <code>native()</code> strings for + the elements defined by the half-open range <code>[first2,last2)</code>. Returns <code>false</code> otherwise.</p> + <p><i>Remarks:</i> If two sequences have the same number of elements and their + corresponding elements are equivalent, then neither sequence is + lexicographically less than the other. If one sequence is a prefix of the + other, then the shorter sequence is lexicographically less than the longer + sequence. Otherwise, the lexicographical comparison of the sequences yields + the same result as the comparison of the first corresponding pair of elements + that are not equivalent.</p> + <p>[<i>Note:</i> A <code>path</code> aware <code>lexicographical_compare</code> algorithm is provided for historical reasons. <i>--end note</i>]</p> +</blockquote> +$endif +<pre>void swap( path& lhs, path& rhs )</pre> +<blockquote> + <p><i>Effects: </i><code>lhs.swap(rhs)</code>.</p> +</blockquote> +<pre>std::size_t <a name="hash_value">hash_value</a> (const path& p);</pre> +<blockquote> + <p><i>Returns:</i> A hash value for the path <code>p</code>. If + for two paths, <code>p1 == p2</code> then <code>hash_value(p1) == hash_value(p2)</code>.</p> + <p>This allows paths to be used with <a href="../../functional/hash/index.html">Boost.Hash</a>.</p> +</blockquote> +<pre>bool operator< (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>return lhs.compare(rhs.begin) < 0</code>.</p> +</blockquote> +<pre>bool operator<=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(rhs < lhs)</code>.</p> +</blockquote> +<pre>bool operator> (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>rhs < lhs</code>.</p> +</blockquote> +<pre>bool operator>=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs < rhs)</code>.</p> +</blockquote> +<pre>bool operator==(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs < rhs) && !(rhs < lhs)</code>.</p> + <p>[<i>Note:</i> <a name="Path-equality">Path equality</a> and path + equivalence have different semantics.</p> + <p>Equality is determined by the <code>path</code> non-member <code>operator==</code>, which considers the two path's lexical + representations only. Thus <code>path("foo") == "bar"</code> is never <code>true</code>.</p> + <p>Equivalence is determined by the <a href="#equivalent"><code>equivalent()</code></a> non-member function, which determines if two paths <a href="#Path">resolve</a> to the same file system entity. + Thus <code>equivalent("foo", "bar")</code> will be <code>true</code> when both paths resolve to the same file.</p> + <p>Programmers wishing to determine if two paths are "the same" must decide if + "the same" means "the same representation" or "resolve to the same actual + file", and choose the appropriate function accordingly. <i>-- end note</i>]</p> +</blockquote> +<pre>bool operator!=(const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>!(lhs == rhs)</code>.</p> +</blockquote> +<pre>path operator/ (const path& lhs, const path& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>path(lhs) /= rhs</code>.</p> +</blockquote> +<h3> <a name="path-non-member-operators"><code><font size="4">path</font></code></a><a name="path-inserter-extractor"> inserter + and extractor</a> [path.io]</h3> +<p> The inserter and extractor delimit the string with double-quotes (<code>"</code>) +so that paths with embedded spaces will round trip correctly. Ampersand (<code>&</code>) +is as an escape character, so the path can itself contain double quotes.</p> +<pre>template <class Char, class Traits> +std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, + const path& p) +</pre> +<blockquote> + <p><i>Effects: </i>Insert characters into <code>os</code>:</p> + <ul> + <li> + <p>A double-quote.</p> + </li> + <li> + <p>Each character in <code>p.string<std::basic_string<Char>>()</code>. + If the character to be inserted is equal to the escape character or a + double-quote, as determined by <code>operator==</code>, first insert the + escape character.</p> + </li> + <li> + <p>A double-quote.</p> + </li> + </ul> + <p><i>Returns:</i> <code>os</code></p> +</blockquote> +<pre>template <class Char, class Traits> +inline std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is, + path& p) +</pre> +<blockquote> + <p><i>Effects: </i><code> std::basic_string<Char> str;<br> + is >> <a href="../../io/doc/quoted_manip.html">boost::io::quoted</a>(str, static_cast<Char>('&'));<br> + p = str;</code></p> + <p><i>Effects: </i>Extract characters from os:</p> + <ul> + <li>If the first character that would be extracted is equal to double-quote, + as determined by <code>operator==</code>, then:<ul> + <li>Discard the initial double-quote.</li> + <li>Save the value and then turn off the <code>skipws</code> flag.</li> + <li><code>p.clear()</code></li> + <li>Until an unescaped double-quote character is reached or <code> + is.not_good()</code>, extract characters from <code>os</code> and append + them to <code>p</code>, except that if an escape character is reached, + ignore it and append the next character to <code>p</code>.</li> + <li>Discard the final double-quote character.</li> + <li>Restore the <code>skipws</code> flag to its original value.</li> + </ul> + </li> + <li>Otherwise, <code>os >> p</code>.</li> + </ul> + <p><i>Returns:</i> <code>is</code></p> + </blockquote> +<h2><a name="Class-filesystem_error">Class <code>filesystem_error</code> +[class.filesystem_error]</a></h2> +<pre>$NAMESPACE_BEGIN; + class filesystem_error : public system_error + { + public: + filesystem_error(); + filesystem_error(const filesystem_error&); + <a href="#filesystem_error-2-arg">filesystem_error</a>(const std::string& what_arg, + system::error_code ec); + <a href="#filesystem_error-3-arg">filesystem_error</a>(const std::string& what_arg, + const path& p1, system::error_code ec); + <a href="#filesystem_error-4-arg">filesystem_error</a>(const std::string& what_arg, + const path& p1, const path& p2, system::error_code ec); + + filesystem_error& filesystem_error(const filesystem_error&); + ~filesystem_error(); + + filesystem_error& operator=(const filesystem_error&); + + const path& <a href="#filesystem_error-path1">path1</a>() const; + const path& <a href="#filesystem_error-path2">path2</a>() const; + + const char * <a href="#filesystem_error-what">what</a>() const; + }; +$NAMESPACE_END;</pre> +<p>The class template <code>filesystem_error</code> defines the type of +objects thrown as exceptions to report file system errors from functions described in this +$WHAT;.</p> +<h3> <a name="filesystem_error-members"> <code>filesystem_error</code> members</a> +[filesystem_error.members]</h3> +<pre><a name="filesystem_error-2-arg">filesystem_error</a>(const std::string& what_arg, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%" bgcolor="#FFFFFF"><code> + runtime_error::what()</code></td> + <td width="82%" bgcolor="#FFFFFF"> + <code><i>what_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%"><code>path1().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + <tr> + <td width="18%"><code>path2().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + </table> +</blockquote> +<pre><a name="filesystem_error-3-arg">filesystem_error</a>(const std::string& what_arg, const path_type& p1, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%" valign="top"><code> + runtime_error::what()</code></td> + <td width="82%"> + <code><i>what_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>path1()</code></td> + <td width="82%">Reference to stored copy of <code>p1</code></td> + </tr> + <tr> + <td width="18%" valign="top"><code>path2().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + </table> +</blockquote> +<pre><a name="filesystem_error-4-arg">filesystem_error</a>(const std::string& what_arg, const path_type& p1, const path_type& p2, error_code ec);</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code> + runtime_error::what()</code></td> + <td width="82%"> + <u> + <code><i>w</i></code></u><code><i>hat_arg</i>.c_str()</code></td> + </tr> + <tr> + <td width="18%"><code>code()</code></td> + <td width="82%"><code>ec</code></td> + </tr> + <tr> + <td width="18%"><code>path1()</code></td> + <td width="82%">Reference to stored copy of <code>p1</code></td> + </tr> + <tr> + <td width="18%"><code>path2()</code></td> + <td width="82%">Reference to stored copy of <code>p2</code></td> + </tr> + </table> +</blockquote> +<pre>const path& <a name="filesystem_error-path1">path1</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> Reference to copy of <code>p1</code> stored by the + constructor, or, if none, an empty path.</p> +</blockquote> +<pre>const path& <a name="filesystem_error-path2">path2</a>() const;</pre> +<blockquote> + <p><i>Returns:</i> Reference to copy of <code>p2</code> stored by the + constructor, or, if none, an empty path.</p> +</blockquote> +<pre>const char* <a name="filesystem_error-what">what</a>() const;</pre> +<blockquote> + <p><i>Returns: </i>A string containing <code>runtime_error::what()</code>. The exact format is unspecified. + Implementations are encouraged but not required to include <code>path1.native_string()</code>if not empty, <code>path2.native_string()</code>if + not empty, and <code>system_error::what()</code> strings in the returned + string.</p> +</blockquote> +<h2><a name="Enum-file_type">Enum file_type</a> [enum.file_type]</h2> +<p>This enum specifies constants uses to identify file types.</p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>Constant Name</b></td> + <td><b>Meaning</b></td> + </tr> + <tr> + <td><code>status_error</code></td> + <td>An error occurred while trying to obtain the status of the file. The + file simply not being found is <b><u>not</u></b> considered a status error. </td> + </tr> + <tr> + <td><code>file_not_found</code></td> + <td>The file could not be found</td> + </tr> + <tr> + <td><code>regular_file</code></td> + <td>Regular file</td> + </tr> + <tr> + <td><code>directory_file</code></td> + <td>Directory file</td> + </tr> + <tr> + <td><code>symlink_file</code></td> + <td>Symbolic link file</td> + </tr> + <tr> + <td><code>block_file</code></td> + <td>Block special file</td> + </tr> + <tr> + <td><code>character_file</code></td> + <td>Character special file</td> + </tr> + <tr> + <td><code>fifo_file</code></td> + <td>FIFO or pipe file</td> + </tr> + <tr> + <td><code>socket_file</code></td> + <td>Socket file</td> + </tr> + <tr> + <td><code>type_unknown</code></td> + <td>The file exists, but it is of a system specific type not covered by any + of the above cases.</td> + </tr> +</table> +<h2><a name="Enum-perms">Enum perms</a> [enum.perms]</h2> +<p>This <code>enum</code> specifies bitmask constants uses to identify file +permissions. <i><span style="background-color: #E0E0E0">ISO/</span><span style="background-color: #E0E0E0">IEC</span><span style="background-color: #E0E0E0"> 9945 +(POSIX) specifies actual values, and those values have been adopted here because +they are very familiar and ingrained for many POSIX +users.</span></i></p> +<blockquote> +<p><span style="background-color: #FFFF00">Windows: All permissions except write are currently ignored. There is only a +single write permission; setting write permission for owner, group, or others +sets write permission for all, and removing write permission for owner, group, +or others removes write permission for all. </span> </p> +</blockquote> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>Name</b></td> + <td align="center"><b>Value<br> + (octal)</b></td> + <td align="center"><b>ISO/IEC 9945<br> + macro</b></td> + <td><b>Definition or notes</b></td> + </tr> + +<tr><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> + <td> Read permission, owner</td> +</tr> +<tr><td><code>owner_write</code></td><td><code>0200</code></td><td> <code>S_IWUSR</code></td> + <td> Write permission, owner</td> +</tr> +<tr><td><code>owner_exe</code></td><td><code>0100</code></td><td> <code>S_IXUSR</code></td> + <td> Execute/search permission, owner</td> +</tr> +<tr><td><code>owner_all</code></td><td><code>0700</code></td><td> <code>S_IRWXU</code></td> + <td> Read, write, execute/search by owner; <code>owner_read | owner_write | owner_exe</code></td> +</tr> +<tr><td><code>group_read</code></td><td><code>040</code></td><td> <code>S_IRGRP</code></td> + <td> Read permission, group</td> +</tr> +<tr><td><code>group_write</code></td><td><code>020</code></td><td> <code>S_IWGRP</code></td> + <td> Write permission, group</td> +</tr> +<tr><td><code>group_exe</code></td><td><code>010</code></td><td> <code>S_IXGRP</code></td> + <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> +</tr> +<tr><td><code>others_read</code></td><td><code>04</code></td><td> <code>S_IROTH</code></td> + <td> Read permission, others</td> +</tr> +<tr><td><code>others_write</code></td><td><code>02</code></td><td> <code>S_IWOTH</code></td> + <td> Write permission, others</td> +</tr> +<tr><td><code>others_exe</code></td><td><code>01</code></td><td> <code>S_IXOTH</code></td> + <td> Execute/search permission, others</td> +</tr> +<tr><td><code>others_all</code></td><td><code>07</code></td><td> <code>S_IRWXO</code></td> + <td>Read, write, execute/search by others; <code>others_read | others_write | others_exe</code></td> +</tr> +<tr><td><code>all_all</code></td><td><code>0777</code></td><td> </td><td><code>owner_all | group_all | others_all</code></td> +</tr> +<tr><td><code>set_uid_on_exe</code></td><td><code>04000</code></td><td> <code>S_ISUID</code></td> + <td> Set-user-ID on execution</td> +</tr> +<tr><td><code>set_gid_on_exe</code></td><td><code>02000</code></td><td> <code>S_ISGID</code></td> + <td> Set-group-ID on execution</td> +</tr> +<tr><td><code><a name="sticky_bit">sticky_bit</a> </code></td><td><code>01000</code></td><td> <code>S_ISVTX</code></td> + <td> Operating system dependent. Inherently non-portable, even between ISO/IEC 9945 + operating systems.</td> +</tr> +<tr><td><code><a name="perms_mask">perms_mask</a></code></td><td><code>07777</code></td><td> </td> + <td><code>all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit</code></td> +</tr> +<tr><td><code>perms_not_known</code></td><td><code>0xFFFF</code></td><td></td><td> + The permissions are not known, such as when a <code>file_status</code> object + is created without specifying the permissions</td> +</tr> +<tr><td> + <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> + <code>permissions()</code> removes the argument permission bits from the + file's current bits</td> +</tr> +<tr><td><code><a name="symlink_perms">symlink_perms</a></code></td><td><code>0x4000</code></td><td></td><td> + <span style="background-color: #FFFF00">On ISO/</span><span style="background-color: #FFFF00">IEC</span><span style="background-color: #FFFF00"> 9945 + </span> <code><span style="background-color: #FFFF00">permissions()</span></code><span style="background-color: #FFFF00"> resolves symlinks unless + </span> <code><span style="background-color: #FFFF00">symlink_perms</span></code><span style="background-color: #FFFF00"> is specified. + Meaningless on Windows as </span> <code> + <span style="background-color: #FFFF00">permissions()</span></code><span style="background-color: #FFFF00"> never resolves symlinks. + Meaningless on Mac OS X and some other BSD systems as </span> <code> + <span style="background-color: #FFFF00">permissions()</span></code><span style="background-color: #FFFF00"> always resolves symlinks. Get over it.</span></td> +</tr> + +</table> +<h2><a name="file_status">Class file_status</a> [class.file_status]</h2> +<pre>$NAMESPACE_BEGIN; + class file_status + { + public: + + // <a href="#file_status-constructors">constructors</a> + file_status() noexcept; + explicit file_status(<a href="#file_type">file_type</a> ft, <a href="#Enum-perms">perms</a> prms = perms_not_known) noexcept; + + // compiler generated + file_status(const file_status&) noexcept; + file_status& operator=(const file_status&) noexcept; + ~file_status() noexcept; + + // <a href="#file_status-observers">observers</a> + <a href="#file_type">file_type</a> type() const noexcept; + <a href="#Enum-perms">perms</a> permissions() const noexcept; + + // <a href="#file_status-modifiers">modifiers</a> + void type(<a href="#file_type">file_type</a> ft) noexcept; + void permissions(<a href="#Enum-perms">perms</a> prms) noexcept; + }; +$NAMESPACE_END;</pre> +<p>An object of type <code>file_status</code> stores information about the type +and permissions of a file.</p> +<h3><a name="file_status-constructors"><code>file_status</code> constructors</a> +[file_status.cons]</h3> +<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(<a href="#file_type">file_type</a> ft, <a href="#Enum-perms">perms</a> prms = perms_not_known) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>type() == ft</code>, <code>permissions() == prms</code>.</p> +</blockquote> + <h3><a name="file_status-observers"><code>file_status</code> observers</a> [file_status.obs]</h3> +<pre><a href="#file_type">file_type</a> 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> +</blockquote> +<pre><a href="#Enum-perms">perms</a> permissions() const noexcept;</pre> +<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> +<h3><a name="file_status-modifiers"><code>file_status</code> modifiers</a> [file_status.mods]</h3> +<pre>void type(<a href="#file_type">file_type</a> ft) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>type() == ft</code>.</p> +</blockquote> +<pre>void permissions(<a href="#Enum-perms">perms</a> prms) noexcept;</pre> +<blockquote> + <p><i>Postconditions:</i> <code>permissions() == prms</code>.</p> +</blockquote> +<h2><a name="Class-directory_entry">Class <code>directory_entry</code></a> [class.directory_entry]</h2> +<div> +<pre>$NAMESPACE_BEGIN; + class directory_entry + { + public: + + // <a href="#directory_entry-constructors">constructors</a> and destructor + directory_entry(); + directory_entry(const directory_entry&); + explicit directory_entry(const path_type& p, file_status st=file_status(), + file_status symlink_st=file_status()); + ~directory_entry(); + + // <a href="#directory_entry-modifiers">modifiers</a> + directory_entry& operator=(const directory_entry&); + void assign(const path_type& p, file_status st=file_status(), + file_status symlink_st=file_status()); + void replace_filename(const path& p, file_status st=file_status(), + file_status symlink_st=file_status()); + + // <a href="#directory_entry-observers">observers</a> + const path& path() const; + file_status status() const; + file_status status(system::error_code& ec) const; + file_status symlink_status() const; + file_status symlink_status(system::error_code& ec) const; + + bool operator< (const directory_entry& rhs); + bool operator==(const directory_entry& rhs); + bool operator!=(const directory_entry& rhs); + bool operator< (const directory_entry& rhs); + bool operator<=(const directory_entry& rhs); + bool operator> (const directory_entry& rhs); + bool operator>=(const directory_entry& rhs); + private: + path_type m_path; // for exposition only + mutable file_status m_status; // for exposition only; stat()-like + mutable file_status m_symlink_status; // for exposition only; lstat()-like + }; + +$NAMESPACE_END;</pre> +</div> +<p>A <code>directory_entry</code> object stores a <code>path object</code>, +a <code>file_status</code> object for non-symbolic link status, and a <code>file_status</code> object for symbolic link status. The <code>file_status</code> objects act as value caches.</p> +<blockquote> +<p>[<i>Note:</i> Because <code>status()</code>on a pathname may be a relatively expensive operation, +some operating systems provide status information as a byproduct of directory +iteration. Caching such status information can result is significant time savings. Cached and +non-cached results may differ in the presence of file system races. <i>-- end note</i>]</p> +<p><span style="background-color: #E0E0E0"><i>Actual cold-boot timing of iteration over +a directory with 15,047 entries was six seconds for non-cached status queries +versus one second for cached status queries. Windows XP, 3.0 GHz processor, with +a moderately fast hard-drive. Similar speedups are expected on Linux and BSD-derived +systems that provide status as a by-product of directory iteration.</i></span></p> +</blockquote> +<h3> <a name="directory_entry-constructors"> <code>directory_entry </code>constructors</a> +[directory_entry.cons]</h3> +<pre>directory_entry();</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path().empty()</code></td> + <td width="82%"><code>true</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>file_status()</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>file_status()</code></td> + </tr> + </table> +</blockquote> +<pre>explicit directory_entry(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>p</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<h3> <a name="directory_entry-modifiers"> <code>directory_entry </code>modifiers</a> +[directory_entry.mods]</h3> +<pre>void assign(const path_type& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>p</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<pre>void replace_filename(const path& p, file_status st=file_status(), file_status symlink_st=file_status());</pre> +<blockquote> + <p><i>Postcondition:</i></p> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%"> + <tr> + <td width="18%"><b>Expression</b></td> + <td width="82%"><b>Value</b></td> + </tr> + <tr> + <td width="18%"><code>path()</code></td> + <td width="82%"><code>path().branch() / s</code></td> + </tr> + <tr> + <td width="18%"><code>status()</code></td> + <td width="82%"><code>st</code></td> + </tr> + <tr> + <td width="18%"><code>symlink_status()</code></td> + <td width="82%"><code>symlink_st</code></td> + </tr> + </table> +</blockquote> +<h3> <a name="directory_entry-observers"> <code>directory_entry</code> observers</a> +[directory_entry.obs]</h3> +<pre>const path& path() const;</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path</code></p> +</blockquote> +<pre>file_status status() const; +file_status status(system::error_code& ec) const;</pre> +<blockquote> +<p><i>Effects:</i> As if,</p> + <blockquote> + <pre>if ( !status_known( m_status ) ) +{ + if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) ) + { m_status = m_symlink_status; } + else { m_status = status(m_path<i>[, ec]</i>); } +}</pre> + </blockquote> + <p><i>Returns:</i> <code>m_status</code></p> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>file_status symlink_status() const; +file_status symlink_status(system::error_code& ec) const;</pre> +<blockquote> +<p> + <i>Effects:</i> As if,</p> + <blockquote> + <pre>if ( !status_known( m_symlink_status ) ) +{ + m_symlink_status = symlink_status(m_path<i>[, ec]</i>); +}</pre> + </blockquote> + <p><i>Returns:</i> <code>m_symlink_status</code></p> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>bool operator==(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path == rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator!=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path != rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator< (const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path < rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator<=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path <= rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator> (const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path > rhs.m_path</code>.</p> +</blockquote> +<pre>bool operator>=(const directory_entry& rhs);</pre> +<blockquote> + <p><i>Returns:</i> <code>m_path >= rhs.m_path</code>.</p> +</blockquote> +<h2><a name="Class-directory_iterator">Class <code>directory_iterator</code> +[class.directory_iterator]</a></h2> +<p>Objects of type <code>directory_iterator</code> provide standard library +compliant iteration over the contents of a directory. Also see class <code><a href="#Class-recursive_directory_iterator">recursive_directory_iterator</a></code>.</p> +<pre>$NAMESPACE_BEGIN; + class directory_iterator + { + public: + // <a href="#directory_iterator-members">member functions</a> + + directory_iterator() noexcept; // creates the "end" iterator + directory_iterator(const directory_iterator&); + explicit directory_iterator(const path& p); + directory_iterator(const path& p, system::error_code& ec); + ~directory_iterator(); + + directory_iterator& operator=(const directory_iterator&); + + directory_iterator& operator++(); + directory_iterator& increment(system::error_code& ec); + + // other members as required by + // C++ Std, 24.1.1 Input iterators [input.iterators] + }; + +$NAMESPACE_END;</pre> +<p> <code>directory_iterator</code> satisfies the requirements of an +input iterator (C++ Std, 24.2.1, Input iterators [input.iterators]).</p> +<p>A <code>directory_iterator</code> reads successive elements from the directory for +which it was constructed, as if by calling ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/readdir_r.html">readdir_r()</a></code>. After a <code>directory_iterator</code> is constructed, and every time <code>operator++</code> is called, +it reads a directory element and stores information about it in a object of type <code><a href="#Class-directory_entry">directory_entry</a></code>. <code>operator++</code> is not equality preserving; that is, <code>i == j</code> does not imply that <code>++i == ++j</code>. </p> +<blockquote> +<p>[<i>Note:</i> The practical consequence of not preserving equality is that directory iterators +can only be used for single-pass algorithms. <i>--end note</i>]</p> +</blockquote> +<p>If the end of the directory elements is reached, the iterator shall become equal to +the end iterator value. The constructor <code>directory_iterator()</code> with no arguments always constructs an end iterator object, which +shall be the only valid iterator for the end condition. The result of <code>operator*</code> on an end iterator is not defined. For any other iterator value +a <code>const directory_entry&</code> is returned. The result of <code>operator-></code> on an end iterator is +undefined behavior. For any other iterator value a <code>const directory_entry*</code> is +returned. </p> +<p>Two end iterators are always equal. An end iterator shall not be equal to a non-end +iterator.</p> +<blockquote> +<p><i><span style="background-color: #E0E0E0">The above wording is based on the +Standard Library's istream_iterator wording.</span></i></p> +</blockquote> +<p>The result of calling the <code>path()</code> member of the <code>directory_entry</code> object obtained by dereferencing a <code>directory_iterator</code> is a reference to a <code>path</code> object composed of the directory argument from which the iterator was +constructed with filename of the directory entry appended as if by <code>operator/=</code>. </p> +<p>Directory iteration shall not yield directory entries for the current (<i>dot</i>) +and parent (<i>dot dot</i>) directories.</p> +<p>The order of directory entries obtained by dereferencing successive +increments of a <code>directory_iterator</code> is unspecified.</p> +<blockquote> +<p>[<i>Note:</i> Programs performing directory iteration may wish to test if the +path obtained by dereferencing a directory iterator actually exists. It could be +a +symbolic link to a non-existent file. Programs recursively +walking directory trees for purposes of removing and renaming entries may wish +to avoid following symbolic links.</p> +<p>If a file is removed from or added to a directory after the +construction of a <code>directory_iterator</code> for the directory, it is +unspecified whether or not subsequent incrementing of the iterator will ever +result in an iterator whose value is the removed or added directory entry. See +ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/readdir_r.html">readdir_r()</a></code>. <i>--end note</i>]</p> +</blockquote> +<h3><a name="directory_iterator-members"><code>directory_iterator</code> members</a> +[directory_iterator.members]</h3> + +<p><code><a name="directory_iterator-default-ctor">directory_iterator</a>() +noexcept;</code></p> + +<blockquote> + +<p><i>Effects:</i> Constructs the end iterator.</p> + +</blockquote> + +<pre><code>explicit <a name="directory_iterator-ctor-path">directory_iterator</a>(</code>const path& p<code>); +directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre> +<blockquote> + +<p><i>Effects:</i> Constructs a iterator representing the first +entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +<p>[<i>Note:</i> To iterate over the current directory, use <code>directory_iterator(".")</code> rather than <code>directory_iterator("")</code>. <i>-- end note</i>]</p> +</blockquote> +<pre>directory_iterator& <a name="directory_iterator-increment">operator++</a>(); +directory_iterator& increment(system::error_code& ec);</pre> +<blockquote> + +<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators]</p> + +<p><i>Returns:</i> <code>*this</code>.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<h3><a name="directory_iterator-non-member-functions"><code>directory_iterator</code> non-member functions</a></h3> +<pre>const directory_iterator& begin(const directory_iterator& iter);</pre> +<blockquote> + <p><i>Returns: </i><code>iter</code>.</p> +</blockquote> +<pre>directory_iterator end(const directory_iterator&);</pre> +<blockquote> + <p><i>Returns: </i><code>directory_iterator()</code>.</p> +</blockquote> +<h2><a name="Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code> +[class.rec.dir.itr]</a></h2> +<p>Objects of type <code>recursive_directory_iterator</code> provide standard library +compliant iteration over the contents of a directory, including recursion into +its sub-directories.</p> +<pre>$NAMESPACE_BEGIN; + class recursive_directory_iterator : + public iterator<input_iterator_tag, directory_entry> + { + public: + + // constructors and destructor + recursive_directory_iterator() noexcept; + recursive_directory_iterator(const recursive_directory_iterator&); + explicit recursive_directory_iterator(const path& p, + <a href="#symlink_option">symlink_option</a> opt = symlink_option::none); + recursive_directory_iterator(const path& p, + <a href="#symlink_option">symlink_option</a> opt, system::error_code& ec); + recursive_directory_iterator(const path& p, system::error_code& ec); + ~recursive_directory_iterator(); + + // observers + int level() const noexcept; + bool no_push<code>_pending</code>() const noexcept; + + // modifiers + recursive_directory_iterator& operator=(const recursive_directory_iterator&); + + recursive_directory_iterator& operator++(); + recursive_directory_iterator& increment(system::error_code& ec); + + void pop(); + void no_push(bool value=true); + + // other members as required by + // C++ Std, Input iterators [input.iterators] + + private: +<i><b> // actual data members will probably be stored in a shared object, + // or some similar mechanism, to achieve the required input iterator + // copy semantics +</b></i> int m_level; <b><i> // for exposition only</i></b> + bool m_no_<code>push</code>; <i><b>// for exposition only + </b></i><a href="#symlink_option">symlink_option</a> m_options; <i><b>// for exposition only</b></i> + }; + +$NAMESPACE_END;</pre> + +<p>The behavior of a <code>recursive_directory_iterator</code> is the same +as a <code>directory_iterator</code> unless otherwise specified.</p> +<ul> + <li>Incrementing a <code>recursive_directory_iterator</code> pointing to a + directory causes that directory itself to be iterated ovee, as specified by + the <code>operator++</code> and <code>increment</code> functions.<br> + </li> + <li>When a <code>recursive_directory_iterator</code> reaches the end of the directory currently being iterated + over, or when <code>pop()</code> is called, <code>m_level</code> is + decremented, and iteration of the parent directory continues.</li> +</ul> +<pre>recursive_directory_iterator() noexcept;</pre> +<blockquote> + +<p><i>Effects:</i> Constructs the end iterator.</p> + +</blockquote> + +<pre>explicit recursive_directory_iterator(const path& p, <a href="#symlink_option">symlink_option</a> opt = symlink_option::none); +recursive_directory_iterator(const path& p, <a href="#symlink_option">symlink_option</a> opt, system::error_code& ec); +recursive_<code>directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre> +<blockquote> + +<p><i>Effects:</i> Constructs a iterator representing the first +entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p> + +<p><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i><code>level() == 0 && no_push_pending() == false && 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 <a href="#Error-reporting">Error reporting</a>.</p> + +<p>[<i>Note:</i> To iterate over the current directory, use <code>recursive_directory_iterator(".")</code> rather than <code>recursive_directory_iterator("")</code>. <i>-- end note</i>]</p> + +<p>[<i>Note:</i> By default, <code>recursive_directory_iterator</code> does not +follow directory symlinks. To follow directory symlinks, specify <code>opt</code> as <code>symlink_option::recurse</code> <i>-- end note</i>]</p> +</blockquote> +<pre>int level() const noexcept;</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Returns:</i> <code>m_level</code>.</p> +</blockquote> +<pre>bool <code>no_push_pending</code>() const noexcept;</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Returns:</i> <code>m_no_push</code>.</p> +</blockquote> +<pre><code>recursive_directory_iterator</code>& <a name="recursive_directory_iterator-increment">operator++</a>(); +recursive_directory_iterator& increment(system::error_code& ec);</pre> +<blockquote> + +<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators], +except:</p> + +<ul> + <li> + +<p>if <code>!no_push_pending() && is_directory(this->status()) +&& (!is_symlink(this->symlink_status()) || (m_options & symlink_option::recurse) != 0)</code> then <code>m_level</code> is incremented and directory <code>(*this)->path()</code> is recursively iterated into.<br> + </p> + + </li> + <li>if there are no more directory entries at this level then <code>m_level</code> +is decremented and iteration of the parent directory resumes.</li> +</ul> + +<p><i>Postcondition:</i> <code>no_push_pending() == false</code>.</p> + +<p><i>Returns:</i> <code>*this</code>.</p> + +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void pop();</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> + <p><i>Effects:</i> If <code>level() == 0</code>, set <code>*this</code> to <code>recursive_directory_iterator()</code>. + Otherwise, <code>--m_level</code>, cease iteration of the directory currently being + iterated over, and continue iteration over the parent directory.</p> +</blockquote> +<pre>void no_push(bool value=true);</pre> +<blockquote> + <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p> +<p><i>Postcondition:</i> <code>no_push_pending() == value</code>.</p> + <p>[<i>Note:</i> <code>no_push()</code> is used to prevent + unwanted recursion into a directory. <i>--end note</i>]</p> +</blockquote> +<h3><a name="recursive_directory_iterator-non-member-functions"><code>recursive_directory_iterator</code> non-member functions</a></h3> +<pre>const recursive_directory_iterator& begin(const recursive_directory_iterator& iter);</pre> +<blockquote> + <p><i>Returns: </i><code>iter</code>.</p> +</blockquote> +<pre>recursive_directory_iterator end(const recursive_directory_iterator&);</pre> +<blockquote> + <p><i>Returns: </i><code>recursive_directory_iterator()</code>.</p> +</blockquote> +<h2><a name="Operational-functions">Operational functions</a> [fs.op.funcs]</h2> +<p>Operational functions query or modify files, including directories, in external +storage.</p> +<p>Operational functions access a file by resolving an +object of class <code>path</code> to a particular file in a file hierarchy. The +path is resolved as if by the ISO/IEC 9945 <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">Pathname Resolution</a> mechanism.</p> +<p>[<i>Note: </i>Because hardware failures, network failures, <a href="#Race-condition">file system races</a>, and many +other kinds of errors occur frequently in file system operations, users should be aware +that any filesystem operational function, no matter how apparently innocuous, may encounter +an error. See <a href="#Error-reporting">Error reporting</a>. <i>-- end note</i>]</p> +<pre>path <a name="absolute">absolute</a>(const path& p, const path& base=current_path());</pre> + <blockquote> + <p><i>Returns:</i> A <a href="#Absolute-path">absolute path</a> composed according to the + following table</p> + <table border="1" cellpadding="5" cellspacing="0" bordercolor="#111111" style="border-collapse: collapse"> + <tr> + <td align="center"> </td> + <td align="center"><b><code>p.has_root_directory()</code></b></td> + <td align="center"><b><code>!p.has_root_directory()</code></b></td> + </tr> + <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> + / absolute(base).relative_path() / p.relative_path()</code></td> + </tr> + <tr> + <td align="center"><b><code>!p.has_root_name()</code></b></td> + <td align="center"><code>return absolute(base).root_name()<br> + / p</code></td> + <td align="center"><code>return absolute(base) / p</code></td> + </tr> + </table> + <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> +<pre>path <a name="canonical">canonical</a>(const path& p, const path& base = current_path()); +path canonical(const path& p, system::error_code& ec); +path canonical(const path& p, const path& base, system::error_code& ec);</pre> +<blockquote> +<p><i>Overview:</i> Converts <code>p</code>, which must exist, to an absolute +path that has no symbolic link, <a href="#Dot">dot</a>, +or <a href="#Dot">dot-dot</a> elements. </p> +<p><i>Returns:</i> A <a href="#Canonical-path">canonical path</a> that refers to +the same file system object as <code>absolute(p,base)</code>. For the overload +without a <code>base</code> argument, <code>base</code> is <code>current_path()</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + + <p><i>Remarks:</i> <code>!exists(p)</code> is an error.</p> + + <p>[<i>Note:</i> Canonical pathnames allow security checking of a path (eg. + does this path live in /home/goodguy or /home/badguy?) -- end note]</p> + +</blockquote> +<pre>void <a name="copy">copy</a>(const path& from, const path& to); +void copy(const path& from, const path& to, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> As if</p> + + <blockquote> + <pre>file_status s(symlink_status(from<i>[</i><code>, ec</code><i>]</i>)); +if(is_symlink(s)) + copy_symlink(from, to<i>[</i><code>, ec</code><i>]</i>); +else if(is_directory(s)) + copy_directory(from, to<i>[</i><code>, ec</code><i>]</i>); +else if(is_regular_file(s)) + copy_file(from, to, copy_option::fail_if_exists<i>[</i><code>, ec</code><i>]</i>); +else +<i> Report error as specified in <a href="#Error-reporting">Error reporting</a>.</i></pre> + </blockquote> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void <a name="copy_directory">copy_directory</a>(const path& from, const path& to); +void copy_directory(const path& from, const path& to, system::error_code& ec);</pre> +<blockquote> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" width="90%" bgcolor="#E0E0E0"> + <tr> + <td width="100%"> + <p><i>This function is poorly named; it should probably be an overload of + <code>create_directory</code> with an additional argument.</i></td> + </tr> + </table> + + <p><i>Effects: </i>Creates directory <code>to</code>, with + attributes copied from directory <code>from</code>. The set of attributes + copied is operating system dependent.</p> + +<blockquote> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" width="90%" bgcolor="#E8FFE8"> + <tr> + <td width="100%"> + <p>[<i>Note:</i> For ISO 9945/POSIX based operating systems the + attributes are those copied by native API <code>stat(from.c_str(), &from_stat)</code> + followed by <code>mkdir(to.c_str(),from_stat.st_mode)</code>. For + Windows based operating systems the attributes are those copied by native + API <code>CreateDirectoryExW(from.c_str(), to.c_str(), 0)</code>. <i> + --end note</i>]</td> + </tr> + </table> +</blockquote> + + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> + +<pre>void copy_file(const path& from, const path& to); +void copy_file(const path& from, const path& to, system::error_code& 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>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>void <a name="copy_file">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option); +void <a name="copy_file2">copy_file</a>(const path& from, const path& to, <a href="#copy_option">copy_option</a> option, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> If <code>option == copy_option::</code><code>fail_if_exists && 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 <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink); +void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& 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>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> +<pre>bool <a name="create_directories">create_directories</a>(const path& p); +bool <a name="create_directories2">create_directories</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition by calling <code> + create_directory()</code> for any element of <code>p</code> that does not + exist.</p> + <p><i>Postcondition:</i> <code>is_directory(p)</code></p> + <p><i>Returns:</i> <code>true</code> if a new directory was created, otherwise <code> + false</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Complexity:</i> <i>O(n+1)</i> where <i>n</i> is the number of elements + of <code>p</code> that do not exist.</p> +</blockquote> +<pre>bool <a name="create_directory">create_directory</a>(const path& p); +bool <a name="create_directory2">create_directory</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition by attempting to create the + directory <code>p</code> resolves to, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/mkdir.html"> + mkdir()</a></code> with a second argument of S_IRWXU|S_IRWXG|S_IRWXO. Creation + failure because <code>p</code> resolves to an existing directory shall not be + treated as an error. </p> + <p><i>Postcondition:</i> <code>is_directory(p)</code></p> + <p><i>Returns:</i> <code>true</code> if a new directory was created, otherwise <code>false</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink); +void create_directory_symlink(const path& to, const path& new_symlink, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">symlink()</a></code>.</p> + <p><i> + 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 <a href="#Error-reporting">Error reporting</a>.</p> + <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. + Some file systems do not + support + symbolic links regardless of the operating system - the FAT file system used on + memory cards and flash drives, for example. <i>-- end note</i>]</p> + </blockquote> +<pre>void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link); +void <a name="create_hard_link2">create_hard_link</a>(const path& to, const path& new_hard_link, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">link()</a></code>.</p> + <p><i>Postcondition:</i></p> + <ul> + <li> <code>exists(to) && + exists(</code><code>new_hard_link</code><code>) && equivalent(to, + + </code><code>new_hard_link</code><code>)</code></li> + <li>The contents of the file or directory + <code>to</code> resolves to are unchanged.</li> + </ul> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> Some operating systems do not support hard links at all or support + them only for regular files. Some file systems do not support hard + links regardless of the operating system - the FAT file system used on memory + cards and flash drives, for example. Some file systems limit the number of + links per file. <i>-- end note</i>]</p> + </blockquote> +<pre>void <a name="create_symlink">create_symlink</a>(const path& to, const path& new_symlink); +void <a name="create_symlink2">create_symlink</a>(const path& to, const path& new_symlink, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">symlink()</a></code>.</p> + <p><i> + 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 <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> Some operating systems do not support symbolic links at all or support + them only for regular files. + Some file systems do not + support + symbolic links regardless of the operating system - the FAT system used on + memory cards and flash drives, for example. <i>-- end note</i>]</p> + </blockquote> +<pre>path <a name="current_path">current_path</a>(); +path <a name="current_path2">current_path</a>(system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> The current working directory path, as if by ISO/IEC + 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/getcwd.html">getcwd()</a></code>. <code>is_absolute()</code> is true for the returned path.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The <code>current_path()</code> name was chosen to emphasize that the return is a + path, not just a single directory name.</p> + <p>The current path as returned by many operating systems is a dangerous + global variable. It may be changed unexpectedly by a third-party or system + library functions, or by another thread. <i>-- end note</i>]</p> +</blockquote> +<pre>void current_path(const path& p); +void current_path(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Establishes the postcondition, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/chdir.html">chdir()</a></code>.</p> +<p><i>Postcondition:</i> <code>equivalent(p, current_path())</code>.</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The current path for many operating systems is a dangerous + global state. It may be changed unexpectedly by a third-party or system + library functions, or by another thread. <i>-- end note</i>]</p> +</blockquote> +<pre>bool <a name="exists">exists</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>status_known(s) && s.type() != file_not_found</code></p> +</blockquote> +<pre>bool <a name="exists2">exists</a>(const path& p); +bool <a name="exists3">exists</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>exists(status(p))</code> or <code>exists(status(p, ec))</code>, + respectively. If ec != 0 and an error</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre><code>bool <a name="equivalent">equivalent</a>(const path& p1, const path& p2); +bool <a name="equivalent2">equivalent</a>(const path& p1, const path& p2, system::error_code& ec);</code></pre> +<blockquote> + <p><i>Effects:</i> Determines <code>file_status s1</code> and <code>s2</code>, as if by <code>status(p1)</code> and <code>status(p2)</code>, + respectively.</p> + <p><i>Returns:</i> <code>true</code>, if <code>sf1 == + sf2</code> and <code>p1</code> and <code>p2</code> resolve to the same file + system entity, else <code>false</code>.</p> + <blockquote> + <p>Two paths are considered to resolve to the same + file system entity if two candidate entities reside on the same device at the + same location. This is determined as if by the values of the ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure<code>,</code> obtained as if by <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code> for the two paths, having equal <code>st_dev</code> values + and equal <code>st_ino</code> values.</p> + <p>[<i>Note:</i> ISO/IEC 9945 requires that <i>"st_dev</i> must be unique within a Local Area Network". Conservative + ISO/IEC 9945 implementations may also wish to check for equal <code>st_size</code> and <code>st_mtime</code> values. <i>Windows</i> implementations may use <code>GetFileInformationByHandle()</code> as a surrogate for <code>stat()</code>, + and consider "same" to be equal values for <code>dwVolumeSerialNumber</code>, <code>nFileIndexHigh</code>, <code>nFileIndexLow</code>, <code>nFileSizeHigh</code>, <code>nFileSizeLow</code>, <code>ftLastWriteTime.dwLowDateTime</code>, and <code>ftLastWriteTime.dwHighDateTime</code>. <i>-- end note</i>]</p> + </blockquote> + <p><i>Throws:</i> <code>filesystem_error</code> if <code>(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))</code>, + otherwise as specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<div> +<pre>uintmax_t <a name="file_size">file_size</a>(const path& p); +uintmax_t <a name="file_size2">file_size</a>(const path& p, system::error_code& ec);</pre> +</div> +<blockquote> + <p><i>Returns:</i> If <code>exists(p) && is_regular_file(p)</code>, the size + in bytes + of the file <code>p</code> resolves to, determined as if by the value of + the ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure member <code>st_size</code> obtained as if by + ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>. + Otherwise, <code>static_cast<uintmax_t>(-1)</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>uintmax_t <a name="hard_link_count">hard_link_count</a>(const path& p); +uintmax_t hard_link_count(const path& p, system::error_code& ec);</pre> +<blockquote> + + <p><i>Returns:</i> The number of hard links for <code>p</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + +</blockquote> + +<pre>const path& <a name="initial_path">initial_path</a>(); +const path& <a name="initial_path2">initial_path</a>(<code>system::error_code& ec</code>);</pre> +<blockquote> + <p><i>Returns:</i> <code>current_path()</code> as of the first call to <code>initial_path()</code>.</p> + <p>[<i>Note:</i> <code>initial_path()</code> is not thread safe, and may return an undesirable result + if called subsequent to a change to the current directory. These problems can + be avoided by calling <code>initial_path()</code> immediately on entry to + main(). <i>--end note</i>]</p> + <p><i>Throws:</i> For the first call, as specified in <a href="#Error-reporting">Error reporting</a>. Subsequent calls throw nothing.</p> +</blockquote> +<pre>bool <code><a name="is_directory">is_directory</a></code>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() == directory_file</code></p> +</blockquote> +<pre><code>bool <a name="is_directory2">is_directory</a>(const path& p); +bool <a name="is_directory3">is_directory</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <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&</code> throws +nothing.</p> +</blockquote> +<pre><code>bool <a name="is_empty">is_empty</a>(const path& p); +bool <a name="is_empty2">is_empty</a></a>(const path& p, system::error_code& ec);</code></pre> +<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> + ? directory_iterator(p) == directory_iterator()<br> + : 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> +<blockquote> + <p><i>Returns:</i> <code>s.type() == regular_file</code></p> +</blockquote> +<pre><code>bool <a name="is_regular_file2">is_regular_file</a>(const path& p);</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_regular_file(status(p))</code>.</p> + <p><i>Throws:</i> <code>filesystem_error</code> if <code>status(p)</code> would throw <code>filesystem_error.</code></p> + </blockquote> +<pre><code>bool <a name="is_regular_file3">is_regular_file</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Effects:</i> Sets <code>ec</code> as if by <code>status(p, ec)</code>. [<i>Note:</i> <code>status_error</code>, <code>file_not_found</code> and <code>type_unknown</code> cases set <code>ec</code> to error values. To distinguish between cases, call the <code>status</code> function directly. <i>-- end + note</i>] </p> + <p><i>Returns:</i> <code>is_regular_file(status(p, ec))</code>.</p> +</blockquote> +<pre>bool <a name="is_other">is_other</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)</code></p> +</blockquote> +<pre><code>bool <a name="is_other2">is_other</a>(const path& p); +bool <a name="is_other3">is_other</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_other(status(p))</code> or <code>is_other(status(p, ec))</code>, + respectively.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>bool <a name="is_symlink">is_symlink</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() == symlink_file</code></p> +</blockquote> +<pre><code>bool <a name="is_symlink2">is_symlink</a>(const path& p); +bool <a name="is_symlink3">is_symlink</a>(const path& p, system::error_code& ec) noexcept;</code></pre> +<blockquote> + <p><i>Returns:</i> <code>is_symlink(symlink_status(p))</code> or <code>is_symlink(symlink_status(p, ec))</code>, + respectively.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>std::time_t <a name="last_write_time">last_write_time</a>(const path& p); +std::time_t <a name="last_write_time2">last_write_time</a>(const path& p<code>, system::error_code& ec</code>);</pre> +<blockquote> + <p><i>Returns:</i> The time of last data modification of <code>p</code>, determined as if by the + value of the ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">stat</a></code> structure member <code>st_mtime</code> obtained + as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="last_write_time3">last_write_time</a>(const path& p, const std::time_t new_time); +void <a name="last_write_time4">last_write_time</a>(const path& p, const std::time_t new_time<code>, system::error_code& ec</code>);</pre> +<blockquote> + <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 ISO/IEC + 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code> followed by + ISO/IEC 9945 <a href="http://www.opengroup.org/onlinepubs/000095399/functions/utime.html"><code>utime()</code></a>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</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 + with coarse time granularity. <i>-- end note</i>]</p> +</blockquote> +<pre>void <a name="permissions">permissions</a>(const path& p, <a href="#symlink_perms">perms</a> prms); +void permissions(const path& p, <a href="#symlink_perms">perms</a> prms, system::error_code& ec);</pre> +<blockquote> + <p> + <i>Requires:</i> <code>!((prms & add_perms) && (prms & remove_perms))</code>.</p> + <p><i>Effects:</i> Applies the effective permissions bits from <code>prms</code> to the file <code>p</code> resolves to, as if by + ISO/IEC 9945 <code><a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html">fchmodat()</a></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> + <td><b>bits present in <code>prms</code></b></td> + <td><b>Effective bits applied</b></td> + </tr> + <tr> + <td>Neither <code>add_perms</code> nor <code>remove_perms</code></td> + <td><code>prms & perms_mask</code></td> + </tr> + <tr> + <td><code>add_perms</code></td> + <td> + <p><code>status(p).permissions() | (prms & <a href="#perms_mask">perms_mask</a>)</code> </td> + </tr> + <tr> + <td><code>remove_perms</code></td> + <td><code>status(p)</code><code>.permissions() & ~(prms & <a href="#perms_mask">perms_mask</a>) </code></td> + </tr> + </table> + <p>[<i>Note:</i> Conceptually permissions are viewed as bits, but the actual + implementation may use some other mechanism. -- <i>end note</i>]</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>path <a name="read_symlink">read_symlink</a>(const path& p); +path read_symlink(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> 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 <a href="#Error-reporting">Error reporting</a>. [<i>Note:</i> It is an error if <code>p</code> does not + resolve to a symbolic link. <i>-- end note</i>]</p> +</blockquote> +<pre>bool <a name="remove">remove</a>(const path& p); +bool <a name="remove2">remove</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> If <code>exists(symlink_status(p,ec))</code>, it is + removed + as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/remove.html">remove()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it + resolves to being removed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Postcondition:</i> <code>!exists(symlink_status(p))</code>.</p> + <p><i>Returns:</i> <code>false</code> if p did not exist in the first + place, otherwise <code>true</code>.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>uintmax_t <a name="remove_all">remove_all</a>(const path& p); +uintmax_t <a name="remove_all2">remove_all</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Recursively deletes the contents of p if it exists, + then deletes file <code>p</code> itself, + as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/remove.html">remove()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it + resolves to being removed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Postcondition:</i> <code>!exists(p)</code></p> + <p><i>Returns:</i> The number of files removed.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="rename">rename</a>(const path& old_p, const path& new_p); +void <a name="rename2">rename</a>(const path& old_p, const path& new_p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Renames <code>old_p</code> to <code>new_p</code>, as if by + ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/rename.html">rename()</a></code>.</p> + <blockquote> + <p>[<i>Note:</i> If <code>old_p</code> and <code>new_p</code> resolve to the + same existing file, no action is taken. Otherwise, if <code>new_p</code> resolves to an + existing non-directory file, it is removed, while if <code>new_p</code> resolves to an + existing directory, it is removed if empty on ISO/IEC 9945 but is an error on Windows. A symbolic link is itself renamed, rather than + the file it resolves to being renamed. <i>-- end note</i>]</p> + </blockquote> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre>void <a name="resize_file">resize_file</a>(const path& p, uintmax_t new_size); +void <a name="resize_file2">resize_file</a>(const path& p, uintmax_t new_size, system::error_code& ec);</pre> +<blockquote> +<p><i>Postcondition:</i> <code>file_size() == new_size</code>.</p> +<p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Remarks:</i> Achieves its postconditions as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/truncate.html">truncate()</a></code>.</p> +</blockquote> +<pre>space_info <a name="space">space</a>(const path& p); +space_info <a name="space2">space</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> An object of type <code><a href="#space_info">space_info</a></code>. The value of the <code>space_info</code> object is determined as if by + using ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/statvfs.html" + style="text-decoration: none">statvfs()</a></code> to obtain a ISO/IEC 9945 struct + <code><a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/statvfs.h.html" style="text-decoration: none">statvfs</a></code>, + and then multiplying its <code>f_blocks</code>, <code>f_bfree</code>, + and <code>f_bavail</code> members by its <code>f_frsize</code> member, + and assigning the results to the <code>capacity</code>, <code>free</code>, + and <code>available</code> members respectively. Any members for which the + value cannot be determined shall be set to -1.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> +</blockquote> +<pre><a href="#file_status">file_status</a> <a name="status">status</a>(const path& p);</pre> +<blockquote> + <p><i>Effects: </i>As if:</p> + <blockquote> + <pre>system::error_code ec; +file_status result = status(p, ec); +if (result == status_error) + throw filesystem_error(<i>implementation-supplied-message</i>, p, ec); +return result;</pre> + </blockquote> + <p><i>Returns:</i> See above.</p> + <p><i>Throws:</i> <code>filesystem_error</code>. +[<i>Note:</i> <code>result</code> values of <code>file_status(file_not_found)</code>and <code>file_status(type_unknown)</code> are not considered failures and do not + cause an exception to be +thrown.<i> -- end note</i>] </p> + </blockquote> +<pre><a href="#file_status">file_status</a> <a name="status2">status</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p><i>Effects: </i></p> + <blockquote> + <p>If possible, determines the attributes + of the file <code>p</code> resolves to, as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/stat.html">stat()</a></code>.</p> + If, during attribute determination, the underlying file system API reports + an error, sets <code>ec</code> to indicate the specific error reported. + Otherwise, <code>ec.clear()</code>.<blockquote> + <p>[<i>Note:</i> This allows users to inspect the specifics of underlying + API errors even when the value returned by <code>status()</code> is not <code>file_status(status_error)</code>. <i>--end note</i>]</p> + </blockquote> + </blockquote> + <p><i>Returns:</i></p> + <blockquote> + <p>If <code>ec != error_code()</code>:</p> + <ul> + <li>If the specific error indicates that <code>p</code> cannot be resolved + because some element of the path does not exist, return <code> + file_status(file_not_found)</code>. [<i>Note:</i> ISO/IEC 9945 errors that + indicate this are ENOENT or ENOTDIR. Windows equivalents + include ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, ERROR_INVALID_NAME, + ERROR_INVALID_PARAMETER, ERROR_BAD_PATHNAME, and ERROR_BAD_NETPATH. <i>-- + end note</i>]<br> + </li> + <li>Otherwise, if the specific error indicates that <code>p</code> can be resolved + but the attributes cannot be determined, return <code> + file_status(type_unknown)</code>. [<i>Note: </i>For example, Windows + ERROR_SHARING_VIOLATION errors. For ISO/IEC 9945, the case never arises. <i>-- end + note</i>]<br> + </li> + <li>Otherwise, return <code> + file_status(status_error)</code>.</li> + </ul> + <blockquote> + <p>[<i>Note:</i> These semantics distinguish between <code>p</code> being known not to exist, <code>p</code> existing but not being able to determine its attributes, + and there being an error that prevents even knowing if <code>p</code> exists. These + distinctions are important to some use cases. <i>--end note</i>]</p> + </blockquote> + <p>Otherwise,</p> + <ul> + <li>If the attributes indicate a regular file, as if by ISO/IEC 9945 <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISREG()</a>, + return <code> + file_status(regular_file)</code>. [<i>Note:</i> <code> +regular_file</code> implies appropriate <code><fstream></code> operations + would succeed, assuming no hardware, permission, access, or file system + race + errors. Lack of +<code>regular_file</code> does not necessarily imply <code><fstream></code> operations would +fail on a directory. +<i>-- end note</i>]<br> + </li> + <li>Otherwise, if the attributes indicate a directory, as if by ISO/IEC 9945 + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISDIR()</a>, + return <code> + file_status(directory_file)</code>. [<i>Note:</i> <code>directory_file</code> implies <code> +directory_iterator(p)</code>would succeed. +<i>-- end note</i>]<br> + </li> + <li>Otherwise, if the attributes indicate a block special file, as if by ISO/IEC 9945 + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISBLK()</a>, + return <code> + file_status(block_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a character special file, as if by ISO/IEC 9945 + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISCHR()</a>, + return <code> + file_status(character_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a fifo or pipe file, as if by + ISO/IEC 9945 + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISFIFO()</a>, + return <code> + file_status(fifo_file)</code>.<br> + </li> + <li>Otherwise, if the attributes indicate a socket, as if by ISO/IEC + 9945 + <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISSOCK()</a>, + return <code> + file_status(socket_file)</code>.<br> + </li> + <li>Otherwise, return <code> + file_status(type_unknown)</code>.</li> + </ul> + </blockquote> + <p><i>Remarks:</i> If a symbolic link is encountered during pathname + resolution, + pathname resolution continues using the contents of the symbolic link.</p> +</blockquote> +<pre>bool <a name="status_known">status_known</a>(file_status s) noexcept;</pre> +<blockquote> + <p><i>Returns:</i> <code>s.type() != status_error</code></p> +</blockquote> +<pre>file_status <a name="symlink_status">symlink_status</a>(const path& p); +file_status <a name="symlink_status2">symlink_status</a>(const path& p, system::error_code& ec) noexcept;</pre> +<blockquote> + <p><i>Effects:</i> Same as <a href="#status">status()</a>, above, + except that the attributes + of <code>p</code> are determined as if by ISO/IEC 9945 <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html">lstat()</a></code>.</p> +</blockquote> +<blockquote> + <p><i>Returns:</i> Same as <a href="#status">status()</a>, above, except + that if the attributes indicate a symbolic link, as if by ISO/IEC 9945 <a class="external" href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">S_ISLNK()</a>, return <code>file_status(symlink_file)</code>.</p> + <p><i>Remarks:</i> Pathname resolution terminates if <code>p</code> names a symbolic link.</p> + <p><i>Throws:</i> <code>filesystem_error</code>; overload with <code>error_code&</code> throws + nothing.</p> +</blockquote> +<pre>path <a name="system_complete">system_complete</a>(const path& p); +path <a name="system_complete2">system_complete</a>(const path& p, system::error_code& ec);</pre> +<blockquote> + <p><i>Effects:</i> Composes an absolute path from <code>p</code>, using the + same rules used by the operating system to resolve a path passed as the + filename argument to standard library open functions.</p> + <p><i>Returns:</i> The composed path.</p> + <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>rp.is_absolute()</code> is true.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note:</i> For ISO/IEC 9945, <code>system_complete(p)</code> has the same semantics as <code>complete(p, current_path())</code>.</p> + <p><a name="windows_effects">For <i>Windows</i></a>, <code>system_complete(p)</code> has the + same semantics as <code>complete(ph, current_path())</code> if <code>p.is_absolute() || !p.has_root_name()</code> or <code>p</code> and <code>base</code> have the same <code>root_name()</code>. + Otherwise it acts like <code>complete(p, kinky)</code>, where <code>kinky</code> is the current directory for the <code>p.root_name()</code> drive. This will + be the current directory of that drive the last time it was set, and thus may + be <b>residue left over from a prior program</b> run by the command + processor! Although these semantics are often useful, they are also very + error-prone.</p> + <p>See <a href="#complete_note"><i>complete()</i> note</a> for usage suggestions. <i>-- end note</i>]</p> +</blockquote> +<pre>path <a name="temp_directory_path">temp_directory_path</a>(); +path temp_directory_path(system::error_code& ec);</pre> +<blockquote> + <p><i>Returns:</i> A directory path suitable for temporary files under the + conventions of the operating system. The specifics of how this path is + determined are implementation defined. An error shall be reported if<code> !exists(p) + || !is_directory(p)</code>, where <code>p</code> is the path to be returned.</p> + <p>ISO/IEC 9945: The path supplied by the first environment variable found in the + list TMPDIR, TMP, TEMP, TEMPDIR. If none of these are found, <code>"/tmp"</code>.</p> + <p><i>Windows:</i> The path reported by the <i>Windows</i> <code>GetTempPath</code> API function.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p>[<i>Note: </i>The <code>temp_directory_path()</code> name was chosen to emphasize that the return is a + path, not just a single directory name. <i>-- end note</i>]</p> +</blockquote> +<pre>path <a name="unique_path">unique_path</a>(const path& model="%%%%-%%%%-%%%%-%%%%"); +path unique_path(const path& model, system::error_code& ec);</pre> +<blockquote> + <p>The <code>unique_path</code> function generates a path name suitable for + creating temporary files, including directories. The name is based + on a model that uses the percent sign character to specify replacement by a + random hexadecimal digit. [<i>Note:</i> The more bits of randomness in the + generated path name, the less likelihood of prior existence or being guessed. + Each replacement hexadecimal digit in the model adds four bits of randomness. + The default model thus provides 64 bits of randomness. This is sufficient for + most applications. <i>--end note</i>]</p> + <p><i>Returns:</i> A path identical to <code>model</code>, except that each + occurrence of a percent sign character is replaced by a random hexadecimal + digit character in the range 0-9, a-f.</p> + <p><i>Throws:</i> As specified in <a href="#Error-reporting">Error reporting</a>.</p> + <p><i>Remarks:</i> Implementations are encouraged to obtain the required + randomness via a <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">cryptographically secure pseudo-random number generator</a>, such as one + provided by the operating system. [<i>Note</i>: Such generators may block + until sufficient entropy develops. <i>--end note</i>]</p> +</blockquote> +<hr> + +<!-- generate-section-numbers=false --> + +$snippet wording_suffix "$SNIPPET_FILE;" + +<h2><a name="Path-decomposition-table">Path decomposition table</a></h2> +<p>The table is generated by a program compiled with the Boost implementation.</p> +<p>Shaded entries indicate cases where ISO/IEC 9945 (POSIX) and Windows implementations yield different results. The top value is the +ISO/IEC 9945 result and the bottom value is the Windows result. <br> +<table border="1" cellspacing="0" cellpadding="5"> +<p> +<tr><td><b>Constructor<br>argument</b></td> +<td><b>Iteration<br>over<br>Elements</b></td> +<td><b><code>string()</code></b></td> +<td><b><code>generic_<br>string()</code></b></td> +<td><b><code>root_<br>path()</code></b></td> +<td><b><code>root_<br>name()</code></b></td> +<td><b><code>root_<br>directory()</code></b></td> +<td><b><code>relative_<br>path()</code></b></td> +<td><b><code>parent_<br>path()</code></b></td> +<td><b><code>filename()</code></b></td> +</tr> +<tr> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +</tr> +<tr> +<td><code>.</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>..</code></td> +<td><code>..</code></td> +<td><code>..</code></td> +<td><code>..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><code>foo</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +</tr> +<tr> +<td><code>/foo</code></td> +<td><code>/,foo</code></td> +<td><code>/foo</code></td> +<td><code>/foo</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo</code></td> +<td><code>/</code></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>foo/</code></td> +<td><code>foo,.</code></td> +<td><code>foo/</code></td> +<td><code>foo/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/</code></td> +<td><code>foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>/foo/</code></td> +<td><code>/,foo,.</code></td> +<td><code>/foo/</code></td> +<td><code>/foo/</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo/</code></td> +<td><code>/foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/bar</code></td> +<td><code>foo,bar</code></td> +<td><code>foo/bar</code></td> +<td><code>foo/bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/bar</code></td> +<td><code>foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>/foo/bar</code></td> +<td><code>/,foo,bar</code></td> +<td><code>/foo/bar</code></td> +<td><code>/foo/bar</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo/bar</code></td> +<td><code>/foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><code>//net</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>//net</code></td> +</tr> +<tr> +<td><code>//net/foo</code></td> +<td><code>//net,/,foo</code></td> +<td><code>//net/foo</code></td> +<td><code>//net/foo</code></td> +<td><code>//net/</code></td> +<td><code>//net</code></td> +<td><code>/</code></td> +<td><code>foo</code></td> +<td><code>//net/</code></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>///foo///</code></td> +<td><code>/,foo,.</code></td> +<td><code>///foo///</code></td> +<td><code>///foo///</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo///</code></td> +<td><code>///foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>///foo///bar</code></td> +<td><code>/,foo,bar</code></td> +<td><code>///foo///bar</code></td> +<td><code>///foo///bar</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>foo///bar</code></td> +<td><code>///foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>/.</code></td> +<td><code>/,.</code></td> +<td><code>/.</code></td> +<td><code>/.</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>.</code></td> +<td><code>/</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>./</code></td> +<td><code>.,.</code></td> +<td><code>./</code></td> +<td><code>./</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>./</code></td> +<td><code>.</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>/..</code></td> +<td><code>/,..</code></td> +<td><code>/..</code></td> +<td><code>/..</code></td> +<td><code>/</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>/</code></td> +<td><code>..</code></td> +<td><code>/</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>../</code></td> +<td><code>..,.</code></td> +<td><code>../</code></td> +<td><code>../</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>../</code></td> +<td><code>..</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/.</code></td> +<td><code>foo,.</code></td> +<td><code>foo/.</code></td> +<td><code>foo/.</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/.</code></td> +<td><code>foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/..</code></td> +<td><code>foo,..</code></td> +<td><code>foo/..</code></td> +<td><code>foo/..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/..</code></td> +<td><code>foo</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo/./</code></td> +<td><code>foo,.,.</code></td> +<td><code>foo/./</code></td> +<td><code>foo/./</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/./</code></td> +<td><code>foo/.</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/./bar</code></td> +<td><code>foo,.,bar</code></td> +<td><code>foo/./bar</code></td> +<td><code>foo/./bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/./bar</code></td> +<td><code>foo/.</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>foo/..</code></td> +<td><code>foo,..</code></td> +<td><code>foo/..</code></td> +<td><code>foo/..</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/..</code></td> +<td><code>foo</code></td> +<td><code>..</code></td> +</tr> +<tr> +<td><code>foo/../</code></td> +<td><code>foo,..,.</code></td> +<td><code>foo/../</code></td> +<td><code>foo/../</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/../</code></td> +<td><code>foo/..</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>foo/../bar</code></td> +<td><code>foo,..,bar</code></td> +<td><code>foo/../bar</code></td> +<td><code>foo/../bar</code></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>foo/../bar</code></td> +<td><code>foo/..</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><code>c:</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><font size="-1"><i>empty</i></font></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>c:</code></td> +</tr> +<tr> +<td><code>c:/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,.</code><br><code>c:,/</code></span></td> +<td><code>c:/</code></td> +<td><code>c:/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/</code><br><font size="-1"><i>empty</i></font></span></td> +<td><code>c:</code></td> +<td><span style="background-color: #CCFFCC"><code>.</code><br><code>/</code></span></td> +</tr> +<tr> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>c:,foo</code></span></td> +<td><code>c:foo</code></td> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:/foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo</code><br><code>c:,/,foo</code></span></td> +<td><code>c:/foo</code></td> +<td><code>c:/foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><code>c:/</code></span></td> +<td><code>foo</code></td> +</tr> +<tr> +<td><code>c:foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo,.</code><br><code>c:,foo,.</code></span></td> +<td><code>c:foo/</code></td> +<td><code>c:foo/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo/</code><br><code>foo/</code></span></td> +<td><code>c:foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo,.</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:/foo/</code></td> +<td><code>c:/foo/</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo/</code><br><code>foo/</code></span></td> +<td><code>c:/foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo/bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo,bar</code><br><code>c:,/,foo,bar</code></span></td> +<td><code>c:/foo/bar</code></td> +<td><code>c:/foo/bar</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo/bar</code><br><code>foo/bar</code></span></td> +<td><code>c:/foo</code></td> +<td><code>bar</code></td> +</tr> +<tr> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><code>prn:</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>prn:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>prn:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>prn:</code><br><font size="-1"><i>empty</i></font></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><code>prn:</code></td> +</tr> +<tr> +<td><code>c:\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>c:,/</code></span></td> +<td><code>c:\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><font size="-1"><i>empty</i></font></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\</code><br><code>\</code></span></td> +</tr> +<tr> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>c:,foo</code></span></td> +<td><code>c:foo</code></td> +<td><code>c:foo</code></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:\foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>c:,/,foo</code></span></td> +<td><code>c:\foo</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>c:/foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>foo</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo</code><br><code>foo</code></span></td> +</tr> +<tr> +<td><code>c:foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>c:,foo,.</code></span></td> +<td><code>c:foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>c:foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><font size="-1"><i>empty</i></font></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>foo\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:foo\</code><br><code>.</code></span></td> +</tr> +<tr> +<td><code>c:\foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:\foo\</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>c:/foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>foo\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo\</code><br><code>.</code></span></td> +</tr> +<tr> +<td><code>c:\foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo,.</code><br><code>c:,/,foo,.</code></span></td> +<td><code>c:\foo/</code></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo/</code><br><code>c:/foo/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:\</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>\</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:\foo/</code><br><code>foo/</code></span></td> +<td><code>c:\foo</code></td> +<td><code>.</code></td> +</tr> +<tr> +<td><code>c:/foo\bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:,foo\bar</code><br><code>c:,/,foo,bar</code></span></td> +<td><code>c:/foo\bar</code></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo\bar</code><br><code>c:/foo/bar</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:/</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>c:</code></span></td> +<td><span style="background-color: #CCFFCC"><font size="-1"><i>empty</i></font><br><code>/</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:/foo\bar</code><br><code>foo\bar</code></span></td> +<td><span style="background-color: #CCFFCC"><code>c:</code><br><code>c:/foo</code></span></td> +<td><span style="background-color: #CCFFCC"><code>foo\bar</code><br><code>bar</code></span></td> +</tr> +</table> +<h2><a name="long-path-warning"></a>Warning: Long paths on Windows and the +extended-length <b>\\?\ </b>prefix</h2> +<p>The Microsoft Windows "Maximum Path Length Limitation" specifies:</p> +<blockquote> +<p>In the Windows API (with some exceptions ...), the maximum length for a path +is MAX_PATH, which is defined as 260 characters.</p> +<p>The Windows API has many functions that also have Unicode versions to permit +an extended-length path for a maximum total path length of 32,767 characters. +... To specify an extended-length path, use the <b>"\\?\" prefix</b>. For +example, "\\?\D:\<em>very long path</em>". <i>[C++ string literals require backslashes be doubled, of course.]</i></p> +</blockquote> +<p>Because most Boost.Filesystem operational functions just pass the contents of +a class path object to the Windows API, they do work with the extended-length +prefixes. But some won't work, because to the limitations imposed by Windows. +Read the following cautions carefully!</p> +<h3>Cautions for paths with extended-length prefixes</h3> +<ul> + <li>Individual components of a path are still are limited to whatever is + supported for the particular filesystem, commonly 255 characters.</li> + <li>Only backslashes only are acceptable as directory separators. Slashes are + not treated as separators.</li> + <li>All paths must be absolute - relative paths are not allowed.</li> + <li>Once an absolute path grows beyond 260 characters, it is essentially + poisoned and all operations must use extended-length prefixes. So even a + simple operation like <code>create_directory("a")</code> will fail if the + absolute path of the resulting directory would exceed 260 characters.</li> + <li>Certain Boost.Filesystem functions that decompose their argument path and + then work on individual relative directories or files will not work properly + with extended-length prefix paths.</li> +</ul> +<h2><a name="Acknowledgements">Acknowledgements</a></h2> +<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 +through to completion. She gave me the strength to continue after a difficult +year of cancer treatment in the middle of it all.</p> +<p>Many people contributed technical comments, ideas, and suggestions to the +Boost Filesystem Library. See <a href="http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements">http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements</a>.</p> +<p>Dietmar Kuehl contributed the original Boost Filesystem Library directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas +Witt were particularly helpful in refining the library.</p> +<p>The create_directories, extension, basename, and replace_extension functions +were developed by Vladimir Prus. The temp_directory_path function was +contributed by Jeff Flinn. David Svoboda suggested the canonical function and +provided psuedo-code.</p> +<p>Howard Hinnant and John Maddock reviewed a draft of the version 2 proposal, and +identified a number of mistakes or weaknesses, resulting in a more polished +final document.</p> +<p>Peter Dimov suggested a single class path, with member templates to adapt to +multiple string types. His idea became the basis for the version 3 path design.</p> +<h2><a name="References">References</a></h2> +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="16%" valign="top">[<a name="ISO_POSIX">ISO/IEC 9945</a>]</td> + <td width="84%">ISO/IEC 9945:2003, IEEE Std 1003.1-2001, and The Open Group + 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 + in its creation. For example, read online or download from <a href="http://www.unix.org/single_unix_specification/">www.unix.org/single_unix_specification/</a>.</font> The ISO JTC1/SC22/WG15 - + POSIX homepage is <a href="http://www.open-std.org/jtc1/sc22/WG15/">www.open-std.org/jtc1/sc22/WG15/</a></td> + </tr> + <tr> + <td width="16%" valign="top">[Abrahams]</td> + <td width="84%">Dave Abrahams, Error and Exception Handling, <a href="http://www.boost.org/more/error_handling.html">www.boost.org/more/error_handling.html</a></td> + </tr> +</table> +<hr> +$snippet backmatter "$SNIPPET_FILE;" +</body></html>
\ No newline at end of file diff --git a/libs/filesystem/doc/src/tr2_snippets.html b/libs/filesystem/doc/src/tr2_snippets.html new file mode 100644 index 0000000000..7eef9d1a37 --- /dev/null +++ b/libs/filesystem/doc/src/tr2_snippets.html @@ -0,0 +1,398 @@ +<html> +<!-- © Copyright Beman Dawes 2012 --> +<!-- Distributed under the Boost Software License, Version 1.0. --> +<!-- See http://www.boost.org/LICENSE_1_0.txt --> +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem Proposal</title> +</head> + +<body> + +$id frontmatter= + <table border="0"> + <tr> + <td>Document number: </td> + <td><span style="background-color: #FFFF00">D????=12-????</span></td> + </tr> + <tr> + <td>Date:</td> + <td> + <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2012-06-02<!--webbot bot="Timestamp" endspan i-checksum="12362" --></td> + </tr> + <tr> + <td>Project:</td> + <td>Programming Language C++</td> + </tr> + <tr> + <td valign="top">Reply-to:</td> + <td>Beman Dawes <bdawes at acm dot org></td> + </tr> + </table> + + +<h1><span style="background-color: #FFFF00">Draft</span><br> +Filesystem Library Proposal (Revision 3)</h1> + + +<p>This paper proposes a filesystem library component suitable for a <i>C++ +Standard Library Technical Specification</i> or for the <i>C++ Standard Library</i>. +The proposed library is based on Version 3 of the Boost Filesystem +Library (see <a href="http://www.boost.org/libs/filesystem"> +www.boost.org/libs/filesystem</a>). Preliminary wording is provided. A +<a href="#TODO">TODO</a> list identifies remaining work to be done.</p> + + +<p><span style="font-style: italic; background-color: #FFFF00">Material in this +document high-lighted in yellow is known to be incomplete, incorrect, or +otherwise require further refinement.</span></p> + + +<h2>Revision history</h2> + + +<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> + <li>Add section tags and section numbers, per LWG + discussion in Kona.</li> + <li>Bring use of trademarked names into ISO compliance, and minimize use of + such names by moving into a single examples section. Thanks to Stefanus Du + Toit for advice on how to do this.</li> + <li>Introduce a definition for "operating system dependent", and then use it + to replace most "implementation defined behavior".</li> + <li>Replace uses of const string return types with non-const string + return types, per LWG discussion in Kona.</li> + <li>Remove permission for implementations to return const string& in certain + cases, per LWG discussion in Kona.</li> + <li>Remove path inserter and extractor dependency on Boost quoted manip (Issue + 7).</li> +</ul> + + +<p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3365.html">N3365=12-0055</a>, Filesystem Library Proposal (Revision +2). Changes +include:</p> + + +<ul> + <li>Namespaces changed to <code>std::tbd::filesystem</code> per + <a href="#Issues-List">issue + 1</a> discussion in Kona.</li> + <li>Removed references to Boost within the proposed wording.</li> + <li>Minor fixes to the proposed wording.</li> + <li>Added Issue 7: How should class path inserter and extractor be specified?</li> + <li>Marked up all issues to reflect Kona LWG discussions.</li> +</ul> + + +<p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3335.html"> +N3335=12-0025</a>, Filesystem Library for C++11/TR2 (Revision 1). Changes +include:</p> + + + <ul> + <li>Regenerated the proposed wording from the Boost Filesystem library + reference documentation, using an automated process. This process reduces + the likelihood of inadvertent discrepancies between descriptions.</li> + <li>An <a href="#Issues-List">Issues list</a> was added, seeded with issues + raised by the LWG review of N3239 at the Bloomington meeting, and private + communications from LWG members.</li> + <li>Namespace changed to <code>files</code> as an experiment. Made this + issue number 1 so the LWG can pass judgment.</li> + <li>New functions were added, suggested by David Svoboda, to generate + canonical paths and manage permissions.</li> + <li>More C++11 functionality was applied. This process is still incomplete, + however.</li> + <li>Added proposed changes to header <fstream>. The previous paper had + inadvertently supplied the wrong wording.</li> + <li>Continued the general cleanup of wording.</li> +</ul> + + +<p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3239.html"> +N3239 = 11-0009</a>, Filesystem Library Update for TR2 (Preliminary), reflected +changes made to the Boost library version 3 since the previously accepted +committee paper:</p> + + + <ul> + <li>A single class <code>path</code> handles all aspects of + internationalization, replacing the previous template and its <code>path</code> + and <code>wpath</code> instantiations. Character types <code>char</code>, + <code>wchar_t</code>, <code>char16_t</code>, and <code>char32_t</code> are + supported. This is a major simplification of the path abstraction, + particularly for functions that take path arguments. This change was based + on a suggestion by Peter Dimov.</li> + <li>Several operational functions have been added, including much better + symlink support, the ability to resize a file, and the ability to generate a + unique path.</li> + <li>Support for error reporting via <code>error_code</code> is now uniform + throughout the operations functions.</li> + <li>Several functions have been renamed, based on feedback from users.</li> + </ul> + + +<p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html"> +N1975 = 06-0045</a>, Filesystem Library Proposal for TR2 (Revision 3), was +adopted by the committee in April, 2006, at the Berlin meeting. Shortly +afterward the Library Working Group set aside work on TR2 to concentrate on +C++0x.</p> + + +<h2>Motivation and Scope</h2> + + +<p>The motivation and scope for a filesystem library were described in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html"> +N1975</a>, and are not repeated here. A minor scope reduction is that an +addition to the current C++ runtime library is no longer needed.</p> + + +<p>Boost Filesystem Version 3 introduced a single path type that interoperates well with both <code> +basic_string</code> and user defined string types. Thus the following Design +alternatives paragraph is no long applicable:</p> + + + <blockquote> + + +<p><strike><i>Single path type which can at runtime accept narrow or wide character +pathnames.</i> Although certainly interesting, and possibly superior, such a +design would not interoperate well with the current Standard Library's +compile-time typed <code>basic_string</code>. A new runtime polymorphic string +class would be the best place to experiment with this concept, not a path class.</strike></p> + + + </blockquote> + + + <h2><a name="TODO">TODO</a></h2> + <ul> + <li>Apply more C++0X features. Boost.Filesystem needs to implement these to verify their + application is correct.</li> + <li>Ion Todirel suggests "Would be nice if path::append was variadic, to + improve usability".</li> + <li>Boost.Filesystem needs to implement <code>char16_t</code> and <code>char32_t</code> support to verify the + specification for these is correct.</li> + <li>The Boost implementation has more class path non-member relational + functions that shown in the docs, and the specific set of relational + functions varies between Windows and POSIX. Figure out what's happening and + document it.</li> + <li><code><a href="#Source">Source</a></code> is not specified as actually + implemented. Expose <code>path_traits</code>?</li> + <li><i>Effects</i> for <code>copy</code> and <code>copy_directory</code> + need to be reviewed, revised, tested, peer reviewed.</li> + <li>Dinkumware/Microsoft report slightly different results for Decomposition + table. Rerun table. Check discrepancies.</li> + <li>Apply issue resolutions from Kona. Complete except some remaining + codecvt arguments</li> + <li>Review Nick Stoughton's email for suggestions, action items.</li> + <li>Change <code>time_t</code> to <code>chrono system_clock::time_point</code>, + per LWG discussion in Kona. </li> + <li>Ed Smith-Rowland:<br> + > I found it less confusing to switch to positive logic for + recursive_directory_iterator:<br> + > bool no_push_pending() const noexcept;<br> + > to say<br> + > bool is_push_pending() const noexcept;<br> + ><br> + > and<br> + > void no_push(bool value=true);<br> + > to say<br> + > void push_pending(bool value=false);<br> + > or<br> + > void set_push_pending(bool value=false);<br> + > I found it less confusing and I think other parts of the library strive + for this.</li> + <li>recursive_directory_iterator is specified in terms of private data + members. Remove these (including the comment!) and specify in terms of + behavior only.</li> + <li>Ion Todirel: Would be nice to have a make_relative. Need to review + similar suggestions.</li> + </ul> + + $endid + +$id wording_prefix= +<h1>Proposed Wording</h1> + +<!-- generate-section-numbers=true --> + +<p><span style="font-style: italic; background-color: rgb(224, 224, 224);"> +Gray-shaded italic text is commentary on the proposal. It is not to be added to +the working paper.</span></p> +<h1>Filesystem Library [filesystem]</h1> + +<p>This clause describes components that perform operations on file systems and +their components, such as paths, regular files, and directories.</p> + +<p>ISO/IEC 9945 contains provisions which, through reference in this +text, constitute provisions of this clause. At the time of +publication, the editions indicated were valid. All standards are subject to +revision, and parties to agreements based on this clause are +encouraged to investigate the possibility of applying the most recent editions +of the standard indicated below. Members of IEC and ISO maintain registers of +currently valid International Standards.</p> +<ul> + <li>ISO/IEC 9945:2003, <i>Portable Operating System Interface (POSIX</i>®<i>), + part 1 (Base Definitions) and part 2 (System Interfaces)</i>, both as + corrected by their respective 2004 Correction 1 documents.<p><i> + <span style="background-color: #E0E0E0">ISO/</span><span style="background-color: #E0E0E0">IEC</span><span style="background-color: #E0E0E0"> 9945:2003 is also IEEE Std 1003.1-2001, and The Open Group Base + Specifications, Issue 6, and is also known as The Single Unix®</span></i><font face="Times New Roman"><i><b><span style="background-color: #E0E0E0"> + </span> + </b></i><span style="font-style: italic; background-color: #E0E0E0">Specification, Version 3. It is available from each of those + organizations, and may be read online or downloaded from + <a href="http://www.unix.org/single_unix_specification/"> + www.unix.org/single_unix_specification/</a></span></font></li> +</ul> + +$endid + +$id wording_suffix= +<p><span style="font-style: italic; background-color: #E0E0E0">End of new +Clause.</span></p> +<hr> +<h2><a name="Issues-List">Issues List</a></h2> +<hr> +<h3>Issue 1: What is the appropriate namespace? Status: +Tentatively resolved</h3> +<h4>Discussion</h4> +<p>The N3335 proposal places the library in namespace <code>std::tr2::files</code>. +Rationale for a sub-namespace is that the library uses several names that don't +seem appropriate for namespace <code>tr2</code> since full standardization would +then put the names into <code>std</code>. The function names <code>remove</code> +and <code>rename</code> are of particular concern because these functions differ +in behavior from current standard library functions with those names. It also +doesn't seem desirable to preempt names like <code>equivalent</code> and <code> +status</code>.</p> +<h4>Resolution</h4> +<p><i>Kona: Strong support for <code>filesystem</code> as the library's +namespace. Strong support for a technical specification namespace that alerts uses that +contents are likely to change if and when they later get moved into the +standard. </i></p> +<p><i>No decision yet on a TR namespace; <code>tbs</code> being used as +a placeholder. Thus the full namespace is changed to <code> +std::tbs::filesystem.</code></i></p> +<hr> +<h3>Issue 2: Excessive use of <code>const codecvt_type&</code> arguments +Status: Open</h3> +<h4>Discussion</h4> +<p>Users sometimes need to do path conversions that use something other than the +imbued codecvt facet. The need is particularly acute in multi-threaded +applications where changing the imbued facet would introduce a data race. That +said, providing an optional <code>const codecvt_type&</code> argument for every +function where the need might possibly arise is excessive because its use is so +rare and it adds considerable interface clutter.</p> +<h4>Proposed resolution</h4> +<p dir="ltr"><i>Kona:</i></p> +<p dir="ltr"><i>Remove all existing class path <code>const codecvt_type&</code> +arguments. </i></p> +<p dir="ltr"><i>Beman to pursue separate encoding conversion functionality, per +Thursday N3336 "Adapting standard library strings and IO to a Unicode World" +discussion. See Kona wiki.</i></p> +<p dir="ltr"><i>If a separate encoding conversion facility isn't possible, then +some form of minimal class path encoding conversion facility will be needed. +But..., the LWG would like to see use cases and clearer explanation of +motivation before deciding on specifics, and be very sure that there is no way +to achieve with existing std library functionality, albeit with some loss of +efficiency.</i></p> +<hr> +<h3>Issue 3: Possible "implicit cast to native type"? +Status: Open</h3> +<h4>Discussion</h4> +<p>In Bloomington there was discussion of "implicit cast to implicit cast to +native OS type to inter operate with existing iostream library and native +functions instead of modifying fstream".</p> +<h4>Proposed resolution</h4> +<p><i>Kona: The Dinkumware/Microsoft implementation has added an implicit +conversion to the string type, eliminating any need to modify fstream. +(Discussion: might be safer to make the implicit conversion protected, then make +fstream classes friends).</i></p> +<p><i>Action: Beman to investigate, test, as avoiding modification of existing +header and classes is much desired.</i></p> +<hr> +<h3>Issue 4: Given move semantics, it is best not to return const strings. +Status: Resolved</h3> +<h4>Discussion</h4> +<p>The issue title pretty much says it all.</p> +<h4>Proposed resolution</h4> +<p><i>Kona: Return plain strings. Remove the permission for implementations to +return const refs, since uses are not in performace critical code and subtle +portability bugs may occur.</i></p> +<p><i>Action: Beman to apply to proposed wording.</i></p> +<p><i>Version 3: Resolution applied.</i></p> +<hr> +<h3>Issue 5: Is there a way to handle characters that are illegal for particular +OS? Status: NAD</h3> +<h4>Discussion</h4> +<p>Question raised by Pablo in Bloomington.</p> +<h4>Proposed resolution</h4> +<p>Beman suggests NAD, Future. I've done some work on this, including looking at +systems like OpenVMS that have an escape mechanism to handle otherwise +unrepresentable characters. There was a comment to that effect in N3239. I +believe it should be deferred to some future release since (1) it is complex +enough that I'd like to see actual implementation and use experience (presumably +via Boost), and (2) I can't recall a user ever requesting such a feature.</p> +<p><i>Kona: No consensus for change, since there doesn't appear to be any +compelling use case.</i></p> +<hr> +<h3>Issue 6: Could allocator support be added to class path? +Status: Open</h3> +<h4>Discussion</h4> +<p>Question raised by a committee member in private email.</p> +<p><i>Kona: Much discussion.</i></p> +<p><i>Action: Alisdair to write paper, based on a real implementation, so that +it is possible to assess the impact on interface, performance, etc.</i></p> +<p><i>Post-Kona: Alisdair will defer paper until after TR. </i></p> +<hr> +<h3>Issue 7: How should class path inserter and extractor be specified? +Status: Resolved</h3> +<h4>Discussion</h4> +<p>Class <code>path</code> currently is specified to used the Boost detail <code> +quoted</code> stream manipulator. A path object is inserted delimited by quotes, +and extracted accordingly, ensuring that paths containing spaces are +round-tripped correctly. Quotes in the path itself are escaped, and io +state is saved and restored.</p> +<p>See +<a href="http://www.boost.org/doc/libs/1_48_0/libs/io/doc/quoted_manip.html"> +http://www.boost.org/doc/libs/1_48_0/libs/io/doc/quoted_manip.html</a></p> +<p>Since the standard can't specify behavior in terms of something in Boost, we +have to change the specification. Since the <code>quoted</code> stream +manipulator is a handy little component, the issue is raised as to whether it +should go in TR2.</p> +<h4>Resolution</h4> +<p><i>Kona: Specify the path inserter and extractor to have the desired +behavior without reference to how it is achieved. (If someone wants to propose a +quoted manipulator, that's a separate proposal for a different TR.)</i></p> +<p><i>Action: Beman to apply to proposed wording.</i></p> +<p><i>Version 3: Resolution applied.</i></p> +<hr> +<h3>Issue 8: Rename <code>rename</code> +Status: New</h3> +<h4>Discussion</h4> +<p>There are minor problems with the name of the <code>rename()</code> function:</p> +<ul> + <li>There is already a "rename" function, albeit in namespace std, and it has + different semantics as regards error handling. Thus giving the function a + different name might reduce the chance of user error.</li> + <li>The name "move" would better reflect the actual semantics, + particularly for moves between directories., and this is the name used by some + API's, console commands, and GUI file managers for that functionality.</li> +</ul> +<h4>Proposed resolution</h4> +<p>Change the name of the <code>rename()</code> function to <code>move()</code>.</p> +<hr> +<p>$endid + +$id backmatter= +$endid </p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/tutorial.html b/libs/filesystem/doc/tutorial.html new file mode 100644 index 0000000000..0dbebec097 --- /dev/null +++ b/libs/filesystem/doc/tutorial.html @@ -0,0 +1,1128 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem Tutorial</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem Tutorial</font> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> +<p> + <a href="#Introduction">Introduction</a><br> + <a href="#Preliminaries">Preliminaries</a><br> + <a href="#Reporting-size">Reporting the size of a file - (tut1.cpp)</a><br> + <a href="#Using-status-queries">Using status queries to determine file existence and type - (tut2.cpp)</a><br> + <a href="#Directory-iteration">Directory iteration plus catching + exceptions - (tut3.cpp)</a><br> + <a href="#Using-path-decomposition">Using path decomposition, plus sorting results - (tut4.cpp)</a><br> + <a href="#Class-path-Constructors">Class path: Constructors, including + Unicode - (tut5.cpp)</a><br> + <a href="#Class-path-formats">Class path: Generic format vs. Native format</a><br> + <a href="#Class path-iterators-etc">Class path: Iterators, observers, composition, decomposition, and query - (path_info.cpp)</a><br> + <a href="#Error-reporting">Error reporting</a><br> +</p> +<h2><a name="Introduction">Introduction</a></h2> + +<p>This tutorial develops a little command line program to list information +about files and directories - essentially a much simplified version of the POSIX <code>ls</code> or Windows <code>dir</code> +commands. We'll start with the simplest possible version and progress to more +complex functionality. Along the way we'll digress to cover topics you'll need +to know about to understand Boost.Filesystem.</p> + +<p>Source code for each of the tutorial programs is available, and you +are encouraged to compile, test, and experiment with it. To conserve space, we won't +always show boilerplate code here, but the provided source is complete and +ready to build.</p> + +<h2><a name="Preliminaries">Preliminaries</a></h2> + +<p>Install the Boost distribution if you haven't already done so. See the +<a href="http://www.boost.org/more/getting_started/index.html">Boost Getting +Started</a> docs.</p> + +<p>This tutorial assumes you are going to compile and test the examples using +the provided scripts. That's highly recommended.</p> + +<blockquote> + +<p><b>If you are planning to compile and test the examples but not use the +scripts, make sure your build setup knows where to +locate or build the Boost library binaries.</b></p> + +</blockquote> +<p>Fire up your command line interpreter, and type the following commands:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ cd <i><b>boost-root</b></i>/libs/filesystem/example/test +$ ./setup +$ ./bld +$ ./tut1 +Usage: tut1 path</pre> + </td> + <td style="font-size: 10pt"> + <pre>>cd <i><b>boost-root</b></i>\libs\filesystem\example\test +>setup +>bld +>tut1 +Usage: tut1 path</pre> + </td> + </tr> + </table> + +<p>If the <code>tut1</code> command outputs "<code>Usage: tut1 path</code>", all +is well. A set of tutorial programs has been copied (by <code>setup</code>) to +<i><b><code>boost-root</code></b></i><code>/libs/filesystem/example/test</code> +and then built. You are encouraged to modify and experiment with them as the +tutorial progresses. Just invoke the <code>bld</code> script again to rebuild.</p> + +<p>If something didn't work right, here are troubleshooting suggestions:</p> + + <ul> + <li>The <code>bjam</code> program executable isn't being found. + Check your path environmental variable if it should have been found, + otherwise see + <a href="http://www.boost.org/more/getting_started/windows.html">Boost + Getting Started</a>.<br> + </li> + <li>Look at <code>bjam.log</code> to try to spot an indication of the + problem.</li> + </ul> + +<h2><a name="Reporting-size">Reporting the size of a file</a> - (<a href="../example/tut1.cpp">tut1.cpp</a>)</h2> + +<p>Let's get started. One of the simplest things we can do is report the size of +a file.</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <pre><a href="../example/tut1.cpp">tut1.cpp</a></pre> + <blockquote style="font-size: 10pt"> + <pre>#include <iostream> +#include <boost/filesystem.hpp> +using namespace boost::filesystem; + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + std::cout << "Usage: tut1 path\n"; + return 1; + } + std::cout << argv[1] << " " << file_size(argv[1]) << '\n'; + return 0; +}</pre> + </blockquote> + </td> + </tr> +</table> + +<p>The Boost.Filesystem <code><a href="reference.html#file_size">file_size</a></code> +function returns a <code>uintmax_t</code> +containing the size of the file named by the argument. The declaration looks +like this:</p> + +<blockquote> + <pre><span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const path& p);</pre> +</blockquote> +<p>For now, all you need to know is that class path has constructors that take +<code>const char *</code> and many other useful types. (If you can't wait to +find out more, skip ahead to the <a href="#Class-path-Constructors">class path</a> section of +the tutorial.)</p> +<p>Please take a minute to try out <code>tut1</code> on your system, using a +file that is known to exist, such as <code>tut1.cpp</code>. Here is what the +results look like on two different operating systems:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ./tut1 tut1.cpp +tut1.cpp 569</pre> + <pre>$ ls -l tut1.cpp +-rwxrwxrwx 1 root root 569 2010-02-01 07:31 tut1.cpp</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut1 tut1.cpp +tut1.cpp 592 +>dir tut1.cpp +... +01/30/2010 10:47 AM 592 tut1.cpp +...</pre> + </td> + </tr> + </table> + +<p>So far, so good. The reported Linux and Windows sizes are different because +the Linux tests used <code>"\n"</code> line endings, while the Windows tests +used <code>"\r\n"</code> line endings.</p> + <p>Now try again, but give a path that doesn't exist:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" + style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ./tut1 foo +terminate called after throwing an instance of 'boost::exception_detail:: +clone_impl<boost::exception_detail::error_info_injector<boost:: +filesystem::filesystem_error> >' + what(): boost::filesystem::file_size: No such file or directory: "foo" +Aborted</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut1 foo</pre> + <p><b><i>An exception is thrown; the exact form of the response depends on + Windows system options.</i></b></td> + </tr> + </table> + + <p>What happens? + There's no file named <code>foo</code> in the current directory, so an +exception is thrown.</p> + <p>Try this:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./tut1 . +terminate called after throwing an instance of 'boost::exception_detail:: +clone_impl<boost::exception_detail::error_info_injector<boost:: +filesystem::filesystem_error> >' + what(): boost::filesystem::file_size: Operation not permitted "." +Aborted</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut1 .</pre> + <p><b><i>An exception is thrown; the exact form of the response depends on + Windows system options.</i></b></td> + </tr> + </table> + + <p>The current directory exists, but <code>file_size()</code> works on regular + files, not directories, so again, an exception is thrown.</p> + + <p>We'll deal with those situations in <code>tut2.cpp</code>.</p> + +<h2><a name="Using-status-queries">Using status queries to determine file existence and type</a> - (<a href="../example/tut2.cpp">tut2.cpp</a>)</h2> + +<p>Boost.Filesystem includes status query functions such as <code> +<a href="reference.html#exists-path">exists</a></code>, +<code><a href="reference.html#is_directory-path">is_directory</a></code>, and <code> +<a href="reference.html#is_regular_file-path">is_regular_file</a></code>. These return +<code>bool</code>'s, and will return <code>true</code> if the condition +described by their name is met. Otherwise they return <code>false</code>, +including when any element +of the path argument can't be found.</p> + +<p>tut2.cpp uses several of the status query functions to cope with non-existent +files and with different kinds of files:</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <pre><a href="../example/tut2.cpp">tut2.cpp</a></pre> + <blockquote style="font-size: 10pt"> + <pre>int main(int argc, char* argv[]) +{ + <a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code + + if (<a href="reference.html#exists-path">exists</a>(p)) // does p actually exist? + { + if (<a href="reference.html#is_regular_file-path">is_regular_file</a>(p)) // is p a regular file? + cout << p << " size is " << <a href="reference.html#file_size">file_size</a>(p) << '\n'; + + else if (<a href="reference.html#is_directory-path">is_directory</a>(p)) // is p a directory? + cout << p << "is a directory\n"; + + else + cout << p << "exists, but is neither a regular file nor a directory\n"; + } + else + cout << p << "does not exist\n"; + + return 0; +}</pre> + </blockquote> + </td> + </tr> +</table> + +<p>Give it a try:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ./tut2 tut2.cpp +tut2 size is cpp 1037 +$ ./tut2 foo +foo does not exist +$ ./tut2 . +. is a directory</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut2 tut2.cpp +tut2.cpp size is 1079 + +>tut2 foo +foo does not exist + +>tut2 . +. is a directory</pre> + </td> + </tr> + </table> + +<p>Although tut2 works OK in these tests, the output is less than satisfactory +for a directory. We'd typically like to see a list of the directory's contents. In <code>tut3.cpp</code> +we will see how to iterate over directories.</p> + +<p>But first, let's try one more test:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ls /home/jane/foo +ls: cannot access /home/jane/foo: Permission denied +$ ./tut2 /home/jane/foo +terminate called after throwing an instance of 'boost::exception_detail:: +clone_impl<boost::exception_detail::error_info_injector<boost:: +filesystem::filesystem_error> >' + what(): boost::filesystem::status: Permission denied: + "/home/jane/foo" +Aborted</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>dir e:\ +The device is not ready. +>tut2 e:\</pre> + <p><b><i>An exception is thrown; the exact form of the response depends on + Windows system options.</i></b></td> + </tr> + </table> + +<p>On the Linux system, the test was being run from an account that did not have +permission to access <code>/home/jane/foo</code>. On the Windows system, <code> +e:</code> was a Compact Disc reader/writer that was not ready. End users +shouldn't have to interpret cryptic exceptions reports, so as we move on to <code>tut3.cpp</code> +we will increase the robustness of the code, too.</p> + +<h2><a name="Directory-iteration">Directory iteration</a> plus catching +exceptions - (<a href="../example/tut3.cpp">tut3.cpp</a>)</h2> + +<p>Boost.Filesystem's <code><a href="reference.html#directory_iterator"> +directory_iterator</a></code> class is just what we need here. It follows the +general pattern of the standard library's <code>istream_iterator</code>. Constructed from +a path, it iterates over the contents of the directory. A default constructed <code>directory_iterator</code> +acts as the end iterator.</p> + +<p>The value type of <code>directory_iterator</code> is <code> +<a href="reference.html#directory_entry">directory_entry</a></code>. A <code> +directory_entry</code> object contains a <code>path</code> and <code><a href="reference.html#file_status">file_status</a></code> +information. A <code> +directory_entry</code> object +can be used directly, but can also be passed to <code>path</code> arguments in function calls.</p> + +<p>The other need is increased robustness in the face of the many kinds of +errors that can affect file system operations. We could do that at the level of +each call to a Boost.Filesystem function (see <a href="#Error-reporting">Error +reporting</a>), but it is easier to supply an overall try/catch block.</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <pre><a href="../example/tut3.cpp">tut3.cpp</a></pre> + <blockquote> + <pre>int main(int argc, char* argv[]) +{ + <a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code + + try + { + if (<a href="reference.html#exists-path">exists</a>(p)) // does p actually exist? + { + if (<a href="reference.html#is_regular_file-path">is_regular_file</a>(p)) // is p a regular file? + cout << p << " size is " << <a href="reference.html#file_size">file_size</a>(p) << '\n'; + + else if (<a href="reference.html#is_directory-path">is_directory</a>(p)) // is p a directory? + { + cout << p << " is a directory containing:\n"; + + copy(directory_iterator(p), directory_iterator(), // directory_iterator::value_type + ostream_iterator<directory_entry>(cout, "\n")); // is directory_entry, which is + // converted to a path by the + // path stream inserter + } + + else + cout << p << " exists, but is neither a regular file nor a directory\n"; + } + else + cout << p << " does not exist\n"; + } + + catch (const filesystem_error& ex) + { + cout << ex.what() << '\n'; + } + + return 0; +}</pre> + </blockquote> + </td> + </tr> +</table> + +<p>Give <code>tut3</code> a try, passing it a path to a directory as a command line argument. +Here is a run on a checkout of the Boost Subversion trunk, followed by a repeat +of the test cases that caused exceptions on Linux and Windows:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ./tut3 ~/boost/trunk +/home/beman/boost/trunk is a directory containing: + /home/beman/boost/trunk/tools + /home/beman/boost/trunk/boost-build.jam + /home/beman/boost/trunk/dist + /home/beman/boost/trunk/doc + /home/beman/boost/trunk/bootstrap.sh + /home/beman/boost/trunk/index.html + /home/beman/boost/trunk/bootstrap.bat + /home/beman/boost/trunk/boost.css + /home/beman/boost/trunk/INSTALL + /home/beman/boost/trunk/rst.css + /home/beman/boost/trunk/boost + /home/beman/boost/trunk/people + /home/beman/boost/trunk/wiki + /home/beman/boost/trunk/boost.png + /home/beman/boost/trunk/LICENSE_1_0.txt + /home/beman/boost/trunk/more + /home/beman/boost/trunk/Jamroot + /home/beman/boost/trunk/.svn + /home/beman/boost/trunk/libs + /home/beman/boost/trunk/index.htm + /home/beman/boost/trunk/status + /home/beman/boost/trunk/CMakeLists.txt</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut3 c:\boost\trunk +c:\boost\trunk is a directory containing: + c:\boost\trunk\.svn + c:\boost\trunk\boost + c:\boost\trunk\boost-build.jam + c:\boost\trunk\boost.css + c:\boost\trunk\boost.png + c:\boost\trunk\bootstrap.bat + c:\boost\trunk\bootstrap.sh + c:\boost\trunk\CMakeLists.txt + c:\boost\trunk\dist + c:\boost\trunk\doc + c:\boost\trunk\index.htm + c:\boost\trunk\index.html + c:\boost\trunk\INSTALL + c:\boost\trunk\Jamroot + c:\boost\trunk\libs + c:\boost\trunk\LICENSE_1_0.txt + c:\boost\trunk\more + c:\boost\trunk\people + c:\boost\trunk\rst.css + c:\boost\trunk\status + c:\boost\trunk\tools + c:\boost\trunk\wiki + +>tut3 e:\ +boost::filesystem::status: The device is not ready: "e:\"</pre> + </td> + </tr> + </table> + +<p>Not bad, but we can make further improvements:</p> + + <ul> + <li>The listing would be much easier to read if only the filename was + displayed, rather than the full path.<br> + </li> + <li>The Linux listing isn't sorted. That's because the ordering of + directory iteration is unspecified. Ordering depends on the underlying + operating system API and file system specifics. So we need to sort the + results ourselves. </li> + </ul> + +<p>Move on to <code>tut4.cpp</code> to see how those changes play out!</p> + +<h2><a name="Using-path-decomposition">Using path decomposition, plus sorting results</a> - (<a href="../example/tut4.cpp">tut4.cpp</a>)</h2> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <pre><a href="../example/tut4.cpp">tut4.cpp</a></pre> + <blockquote style="font-size: 10pt"> + <pre>int main(int argc, char* argv[]) +{ + <a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code + + try + { + if (<a href="reference.html#exists-path">exists</a>(p)) // does p actually exist? + { + if (<a href="reference.html#is_regular_file-path">is_regular_file</a>(p)) // is p a regular file? + cout << p << " size is " << <a href="reference.html#file_size">file_size</a>(p) << '\n'; + + else if (<a href="reference.html#is_directory-path">is_directory</a>(p)) // is p a directory? + { + cout << p << " is a directory containing:\n"; + + typedef vector<path> vec; // store paths, + vec v; // so we can sort them later + + copy(directory_iterator(p), directory_iterator(), back_inserter(v)); + + sort(v.begin(), v.end()); // sort, since directory iteration + // is not ordered on some file systems + + for (vec::const_iterator it (v.begin()); it != v.end(); ++it) + { + cout << " " << *it << '\n'; + } + } + + else + cout << p << " exists, but is neither a regular file nor a directory\n"; + } + else + cout << p << " does not exist\n"; + } + + catch (const filesystem_error& ex) + { + cout << ex.what() << '\n'; + } + + return 0; +}</pre> + </blockquote> + </td> + </tr> +</table> + + <p>The key difference between <code>tut3.cpp</code> and <code>tut4.cpp</code> is + what happens in the directory iteration loop. We changed:</p> + <blockquote> + <pre>cout << " " << *it << '\n'; // *it returns a <a href="reference.html#Class-directory_entry">directory_entry</a>,</pre> + </blockquote> + <p>to:</p> + <blockquote> + <pre>path fn = it->path().filename(); // extract the filename from the path +v.push_back(fn); // push into vector for later sorting</pre> + </blockquote> + <p><code><a href="reference.html#directory_entry-observers">path()</a></code> + is a <code>directory_entry</code> observer function. <code> + <a href="reference.html#path-filename">filename()</a></code> is one of + several path decomposition functions. It extracts the filename portion (<code>"index.html"</code>) + from a path (<code>"/home/beman/boost/trunk/index.html"</code>). These decomposition functions are + more fully explored in the <a href="#Class path-iterators-etc">Path iterators, observers, + composition, decomposition and query</a> portion of this tutorial.</p> + <p>The above was written as two lines of code for clarity. It could have + been written more concisely as:</p> + <blockquote> + <pre>v.push_back(it->path().filename()); // we only care about the filename</pre> + </blockquote> + <p>Here is the output from a test of <code><a href="../example/tut4.cpp">tut4.cpp</a></code>:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./tut4 ~/boost/trunk +/home/beman/boost/trunk is a directory containing: + .svn + CMakeLists.txt + INSTALL + Jamroot + LICENSE_1_0.txt + boost + boost-build.jam + boost.css + boost.png + bootstrap.bat + bootstrap.sh + doc + index.htm + index.html + libs + more + people + rst.css + status + tools + wiki</pre> + </td> + <td style="font-size: 10pt"> + <pre>C:\v3d>tut4 c:\boost\trunk +c:\boost\trunk is a directory containing: + .svn + CMakeLists.txt + INSTALL + Jamroot + LICENSE_1_0.txt + boost + boost-build.jam + boost.css + boost.png + bootstrap.bat + bootstrap.sh + doc + index.htm + index.html + libs + more + people + rst.css + status + tools + wiki</pre> + </td> + </tr> + </table> + + <p>That completes the main portion of this tutorial. If you haven't already + worked through the <a href="#Class-path-Constructors">Class path</a> sections of this tutorial, dig into them now. + The <a href="#Error-reporting">Error reporting</a> section may also be of + interest, although it can be skipped unless you are deeply concerned about + error handling issues.</p> + +<hr> + +<h2> <a name="Class-path-Constructors">Class path: Constructors</a>, +including Unicode - (<a href="../example/tut5.cpp">tut5.cpp</a>)</h2> + +<p>Traditional C interfaces pass paths as <code>const char*</code> arguments. +C++ interfaces may add <code>const std::string&</code> overloads, but adding +overloads becomes untenable if wide characters, containers, and iterator ranges +need to be supported.</p> +<p>Passing paths as <code>const path&</code> arguments is far simpler, yet far +more flexible because class <code>path</code> itself is far more flexible:</p> +<ol> + <li>Class <code>path</code> supports multiple character types and encodings, including Unicode, to + ease internationalization.</li> + <li>Class <code>path</code> supports multiple source types, such as iterators for null terminated + sequences, iterator ranges, containers (including <code>std::basic_string</code>), + and <code><a href="reference.html#Class-directory_entry">directory_entry</a></code>'s, + so functions taking paths don't need to provide several overloads.</li> + <li>Class <code>path</code> supports both native and generic pathname formats, so programs can be + portable between operating systems yet use native formats where desirable.</li> + <li>Class <code>path</code> supplies a full set of iterators, observers, composition, + decomposition, and query functions, making pathname manipulations easy, + convenient, reliable, and portable.</li> +</ol> +<p>Here is how (1) and (2) work. Class path constructors, +assignments, and appends have member templates for sources. For example, here +are the constructors that take sources:</p> + +<blockquote style="font-size: 10pt"> + <pre>template <class <a href="reference.html#Source">Source</a>> + path(Source const& source);</pre> + <pre>template <class InputIterator> + path(InputIterator begin, InputIterator end);</pre> +</blockquote> +<p>Let's look at a little program that shows how comfortable class <code>path</code> is with +both narrow and wide characters in C-style strings, C++ strings, and via C++ +iterators:</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <pre><a href="../example/tut4.cpp">tut5.cpp</a></pre> + <blockquote> + <pre>#include <boost/filesystem.hpp> +#include <string> +#include <list> +namespace fs = boost::filesystem; + +int main() +{ + // \u263A is "Unicode WHITE SMILING FACE = have a nice day!" + std::string narrow_string ("smile2"); + std::wstring wide_string (L"smile2\u263A"); + std::list<char> narrow_list; + narrow_list.push_back('s'); + narrow_list.push_back('m'); + narrow_list.push_back('i'); + narrow_list.push_back('l'); + narrow_list.push_back('e'); + narrow_list.push_back('3'); + std::list<wchar_t> wide_list; + wide_list.push_back(L's'); + wide_list.push_back(L'm'); + wide_list.push_back(L'i'); + wide_list.push_back(L'l'); + wide_list.push_back(L'e'); + wide_list.push_back(L'3'); + wide_list.push_back(L'\u263A'); + + { fs::ofstream f("smile"); } + { fs::ofstream f(L"smile\u263A"); } + { fs::ofstream f(narrow_string); } + { fs::ofstream f(wide_string); } + { fs::ofstream f(narrow_list); } + { fs::ofstream f(wide_list); } + narrow_list.pop_back(); + narrow_list.push_back('4'); + wide_list.pop_back(); + wide_list.pop_back(); + wide_list.push_back(L'4'); + wide_list.push_back(L'\u263A'); + { fs::ofstream f(fs::path(narrow_list.begin(), narrow_list.end())); } + { fs::ofstream f(fs::path(wide_list.begin(), wide_list.end())); } + + return 0; +}</pre> + </blockquote> + </td> + </tr> +</table> + +<p>Testing <code>tut5</code>:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt" valign="top"> + <pre>$ ./tut5 +$ ls smile* +smile smile☺ smile2 smile2☺ smile3 smile3☺ smile4 smile4☺</pre> + </td> + <td style="font-size: 10pt" valign="top"> + <pre>>tut5 +>dir /b smile* +smile +smile2 +smile2☺ +smile3 +smile3☺ +smile4 +smile4☺ +smile☺</pre> + </td> + </tr> + </table> + +<p>Note that the exact appearance of the smiling face will depend on the font, +font size, and other settings for your command line window. The above tests were +run with out-of-the-box Ubuntu 9.10 and Windows 7, US Edition. If you don't get +the above results, take a look at the <code><i>boost-root</i>/libs/filesystem/example/test</code> +directory with your system's GUI file browser, such as Linux Nautilus, Mac OS X +Finder, or Windows Explorer. These tend to be more comfortable with +international character sets than command line interpreters.</p> + + <p>Class <code>path</code> takes care of whatever character type or encoding + conversions are required by the particular operating system. Thus as <code> + tut5</code> demonstrates, it's no problem to pass a wide character string to a + Boost.Filesystem operational function even if the underlying operating system + uses narrow characters, and visa versa. And the same applies to user supplied + functions that take <code>const path&</code> arguments.</p> + + <p>Class <code>path</code> also provides path syntax that is portable across operating systems, + element iterators, and observer, composition, decomposition, and query + functions to manipulate the elements of a path. The next section of this + tutorial deals with path syntax.</p> + + <hr> + +<h2><a name="Class-path-formats">Class path: Generic format vs. Native format</a></h2> + +<p dir="ltr">Class <code>path</code> deals with two different pathname +formats - generic format and native format. For POSIX-like +file systems, these formats are the same. But for users of Windows and +other non-POSIX file systems, the distinction is important. Even +programmers writing for POSIX-like systems need to understand the distinction if +they want their code to be portable to non-POSIX systems.</p> + +<p dir="ltr">The <b>generic format</b> is the familiar <code>/my_directory/my_file.txt</code> format used by POSIX-like +operating systems such as the Unix variants, Linux, and Mac OS X. Windows also +recognizes the generic format, and it is the basis for the familiar Internet URL +format. The directory +separator character is always one or more slash characters.</p> + +<p dir="ltr">The <b>native format</b> is the format as defined by the particular +operating system. For Windows, either the slash or the backslash can be used as +the directory separator character, so <code>/my_directory\my_file.txt</code> +would work fine. Of course, if you write that in a C++ string literal, it +becomes <code>"/my_directory\\my_file.txt"</code>.</p> + +<p dir="ltr">If a drive specifier or a backslash appears +in a pathname on a Windows system, it is always treated as the native format.</p> + +<p dir="ltr">Class <code>path</code> has observer functions that allow you to +obtain the string representation of a path object in either the native format +or the generic format. See the <a href="#Class path-iterators-etc">next section</a> +for how that plays out.</p> + + <p>The distinction between generic format and native format is important when + communicating with native C-style API's and with users. Both tend to expect + paths in the native format and may be confused by the generic format. The generic + format is great, however, for writing portable programs that work regardless + of operating system.</p> + + <p>The next section covers class <code>path</code> observers, composition, + decomposition, query, and iteration over the elements of a path.</p> + + <hr> + +<h2><a name="Class path-iterators-etc">Class path: Iterators, observers, composition, decomposition, and query</a> +- (<a href="../example/path_info.cpp">path_info.cpp</a>)</h2> + +<p>The <code><a href="../example/path_info.cpp">path_info.cpp</a></code> program is handy for learning how class <code>path</code> +iterators, +observers, composition, decomposition, and query functions work on your system. +If it hasn't already already been built on your system, please build it now. Run +the examples below on your system, and try some different path arguments as we +go along.</p> + +<p> <code>path_info</code> produces several dozen output lines every time it's +invoked. We will only show the output lines we are interested in at each step.</p> + +<p>First we'll look at iteration over the elements of a path, and then use +iteration to illustrate the difference between generic and native format paths.</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./path_info /foo/bar/baa.txt +... +elements: + / + foo + bar + baa.txt</pre> + </td> + <td style="font-size: 10pt"> + <pre>>path_info /foo/bar/baa.txt +... +elements: + / + foo + bar + baa.txt</pre> + </td> + </tr> + </table> + +<p>Thus on both POSIX and Windows based systems the path <code>"/foo/bar/baa.txt"</code> +is seen as having four elements.</p> + +<p>Here is the code that produced the above listing:</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <blockquote style="font-size: 10pt"> + <pre>cout << "\nelements:\n"; + +for (path::iterator it = p.begin(); it != p.end(); ++it) + cout << " " << *it << '\n';</pre> + </blockquote> + </td> + </tr> +</table> +<p><code>path::iterator::value_type</code> is <code>path::string_type</code>, +and iteration treats <code>path</code> as a container of filenames.</p> + +<p dir="ltr">Let's look at some of the output from a slightly different +example:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./path_info /foo/bar/baa.txt + +composed path: + cout << -------------: /foo/bar/baa.txt + preferred()----------: /foo/bar/baa.txt +... +observers, native format: + native()-------------: /foo/bar/baa.txt + c_str()--------------: /foo/bar/baa.txt + string()-------------: /foo/bar/baa.txt + wstring()------------: /foo/bar/baa.txt + +observers, generic format: + generic_string()-----: /foo/bar/baa.txt + generic_wstring()----: /foo/bar/baa.txt</pre> + </td> + <td style="font-size: 10pt"> + <pre>>path_info /foo/bar\baa.txt + +composed path: + cout << -------------: /foo/bar/baa.txt + preferred()----------: \foo\bar\baa.txt +... +observers, native format: + native()-------------: /foo/bar\baa.txt + c_str()--------------: /foo/bar\baa.txt + string()-------------: /foo/bar\baa.txt + wstring()------------: /foo/bar\baa.txt + +observers, generic format: + generic_string()-----: /foo/bar/baa.txt + generic_wstring()----: /foo/bar/baa.txt</pre> + </td> + </tr> + </table> + +<p dir="ltr">Native format observers should be used when interacting with the +operating system or with users; that's what they expect.</p> + +<p dir="ltr">Generic format observers should be used when the results need to be +portable and uniform regardless of the operating system.</p> + +<p dir="ltr"><code>path</code> objects always hold pathnames in the native +format, but otherwise leave them unchanged from their source. The +<a href="reference.html#preferred">preferred()</a> function will convert to the +preferred form, if the native format has several forms. Thus on Windows, it will +convert slashes to backslashes.</p> + +<p dir="ltr">Let's move on to decomposition and query functions:</p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./path_info /foo/bar/baa.txt +... +decomposition: + root_name()----------: + root_directory()-----: / + root_path()----------: / + relative_path()------: foo/bar/baa.txt + parent_path()--------: /foo/bar + filename()-----------: baa.txt + stem()---------------: baa + extension()----------: .txt + +query: + empty()--------------: false + <span style="background-color: #FFFF00">is_absolute</span><span style="background-color: #FFFF00">()--------: true</span> + has_root_name()------: false + has_root_directory()-: true + has_root_path()------: true + has_relative_path()--: true + has_parent_path()----: true + has_filename()-------: true + has_stem()-----------: true + has_extension()------: true</pre> + </td> + <td style="font-size: 10pt"> + <pre>>path_info /foo/bar/baa.txt +... +decomposition: + root_name()----------: + root_directory()-----: / + root_path()----------: / + relative_path()------: foo/bar/baa.txt + parent_path()--------: /foo/bar + filename()-----------: baa.txt + stem()---------------: baa + extension()----------: .txt + +query: + empty()--------------: false + <span style="background-color: #FFFF00">is_absolute</span><span style="background-color: #FFFF00">()--------: false</span> + has_root_name()------: false + has_root_directory()-: true + has_root_path()------: true + has_relative_path()--: true + has_parent_path()----: true + has_filename()-------: true + has_stem()-----------: true + has_extension()------: true</pre> + </td> + </tr> + </table> + +<p dir="ltr">These are pretty self-evident, but do note the difference in the +result of <code>is_absolute()</code> between Linux and Windows. Because there is +no root name (i.e. drive specifier or network name), a lone slash (or backslash) +is a relative path on Windows. </p> + +<p dir="ltr">On to composition!</p> + +<p>Class <code>path</code> uses <code>/</code> and <code>/=</code> operators to +append elements. That's a reminder +that these operations append the operating system's preferred directory +separator if needed. The preferred +directory separator is a slash on POSIX-like systems, and a backslash on +Windows-like systems.</p> + +<p><a href="../example/path_info.cpp"><code>path_info.cpp</code></a> +composes a path by appending each of the command line elements to an initially +empty path:</p> + +<table align="center" border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td style="font-size: 10pt"> + <blockquote> + <pre>path p; // compose a path from the command line arguments + +for (; argc > 1; --argc, ++argv) + p /= argv[1]; + +cout << "\ncomposed path:\n"; +cout << " cout << -------------: " << p << "\n"; +cout << " preferred()----------: " << p.preferred() << "\n";</pre> + </blockquote> + </td> + </tr> +</table> + +<p>Let's give this code a try: </p> + + <table align="center" border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="90%"> + <tr> + <td align="center" width="50%" style="font-size: 10pt"><i><b>Ubuntu Linux </b></i></td> + <td align="center" style="font-size: 10pt"><i><b>Microsoft Windows</b></i></td> + </tr> + <tr> + <td width="50%" style="font-size: 10pt"> + <pre>$ ./path_info / foo/bar baa.txt + +composed path: + cout << -------------: /foo/bar/baa.txt + preferred()----------: /foo/bar/baa.txt</pre> + </td> + <td style="font-size: 10pt"> + <pre>>path_info / foo/bar baa.txt + +composed path: + cout << -------------: /foo/bar\baa.txt + preferred()----------: \foo\bar\baa.txt</pre> + </td> + </tr> + </table> + + <p> </p> + + <hr> + + <h2><a name="Error-reporting">Error reporting</a></h2> + + <p>The Boost.Filesystem <code>file_size</code> function has two overloads:</p> + + <blockquote> + <pre><span style="background-color: #FFFFFF; ">uintmax_t</span> <a name="file_size">file_size</a>(const path& p); +<span style="background-color: #FFFFFF; ">uintmax_t</span> <a name="file_size2">file_size</a>(const path& p, system::error_code& ec);</pre> +</blockquote> +<p>The only significant difference between the two is how they report errors.</p> +<p>The + first signature will throw exceptions to report errors. A <code> +<a href="reference.html#Class-filesystem_error">filesystem_error</a></code> exception will be thrown +on an + operational error. <code>filesystem_error</code> is derived from <code>std::runtime_error</code>. +It has a + member function to obtain the <code> +<a href="../../system/doc/reference.html#Class-error_code">error_code</a></code> reported by the source + of the error. It also has member functions to obtain the path or paths that caused + the error.</p> + + <blockquote> + + <p><b>Motivation for the second signature:</b> Throwing exceptions on errors was the entire error reporting story for the earliest versions of + Boost.Filesystem, and indeed throwing exceptions on errors works very well for + many applications. But user reports trickled in that some code became so + littered with try and catch blocks as to be unreadable and unmaintainable. In + some applications I/O errors aren't exceptional, and that's the use case for + the second signature.</p> + + </blockquote> + + <p>Functions with a <code>system::error_code&</code> argument set that + argument to report operational error status, and so do not throw exceptions when I/O + related errors occur. For a full explanation, see + <a href="reference.html#Error-reporting">Error reporting</a> in the reference + documentation. </p> + +<hr> +<p>© Copyright Beman Dawes 2010</p> +<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> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->20 March 2012<!--webbot bot="Timestamp" endspan i-checksum="27254" --></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/v3.html b/libs/filesystem/doc/v3.html new file mode 100644 index 0000000000..3b75140a20 --- /dev/null +++ b/libs/filesystem/doc/v3.html @@ -0,0 +1,151 @@ +<html> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem V3 Intro</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td width="277"> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> + <td align="middle"> + <font size="7">Filesystem + Version 3<br> + Introduction</font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<h1>Boost Filesystem Version 3</h1> + +<p>Version 3 is a major revision of the Boost Filesystem library. Important +changes include:</p> + +<ul> + <li>A single class <code>path</code> handles all aspects of + internationalization, replacing the previous template and its <code>path</code> + and <code>wpath</code> instantiations. Character types <code>char</code>, + <code>wchar_t</code>, <code>char16_t</code>, and <code>char32_t</code> are + supported. This is a major simplification of the path abstraction, + particularly for functions that take path arguments.<br> + </li> + <li>New <code>class path</code> members include:<br> + <ul> + <li><code><a href="reference.html#path-has_stem">has_stem</a>()</code></li> + <li><code><a href="reference.html#path-has_extension">has_extension</a>()</code></li> + <li><code><a href="reference.html#path-is_absolute">is_absolute</a>()</code>. This renames <code>is_complete()</code>, which + is now deprecated.</li> + <li><code><a href="reference.html#path-is_relative">is_relative</a>()</code></li> + <li><code><a href="reference.html#path-make_preferred">make_preferred</a>()<br> + </code></li> +</ul> + + </li> + <li>New or improved operations functions include:<br> + <ul> + <li><code><a href="reference.html#absolute">absolute</a>()</code>. This replaces the operations function <code> + complete()</code>, which is now deprecated. Semantics are now provided for a + Windows corner case where the <code>base</code> argument was not an absolute + path. Previously this resulted in an exception being thrown.</li> + <li><code><a href="reference.html#create_symlink">create_symlink</a>()</code> now supported on both POSIX and Windows.</li> + <li><code><a href="reference.html#read_symlink">read_symlink</a>()</code> function added. Supported on both POSIX and + Windows. Used to read the contents of a symlink itself.</li> + <li><code><a href="reference.html#resize_file">resize_file</a>()</code> function added. Supported on both POSIX and + Windows. Used to shrink or grow a regular file.</li> + <li><code><a href="reference.html#unique_path">unique_path</a>()</code> function added. Supported on both POSIX and + Windows. Used to generate a secure temporary pathname.<br> + </li> + </ul> + </li> + <li>Support for error reporting via <code>error_code</code> is now uniform + throughout the operations functions.<br> + </li> + <li>Documentation has been reworked, including re-writes of major portions.<br> + </li> + <li>A new <a href="tutorial.html">Tutorial</a> provides a hopefully much + gentler and more complete introduction for new users. Current users might want + to review the <a href="tutorial.html">three sections related to class path</a>.</li> +</ul> + +<h2>Deprecated names and other features</h2> + +<p>See the <a href="deprecated.html">Deprecated Features page</a> for transition +aids that allow much existing code to compile without change using Version 3.</p> + +<h2>Breaking changes</h2> + +<p>To ease the transition, Versions 2 and 3 will both be included in the next +several Boost releases. Version 2 will be the default version for one release +cycle, and then Version 3 will become the default version.</p> +<h3>Class <code>path</code></h3> +<ul> + <li>Class template <code>basic_path</code> and its specializations are + replaced by a single <code>class path</code>. Thus any code, such as + overloaded functions, that depends on <code>path</code> and <code>wpath</code> + being two distinct types will fail to compile and must be restructured. + Restructuring may be as simple as removing one of the overloads, but also + might require more complex redesign.<br> + </li> + <li>Certain functions now return <code>path</code> objects rather than <code> + string or wstring</code> objects:<ul> + <li><code>root_name()</code></li> + <li><code>root_directory()</code></li> + <li><code>filename()</code></li> + <li><code>stem()</code></li> + <li><code>extension()</code></li> + </ul> + <p>Not all uses will fail; if the function is being called in a context that + accepts a <code>path</code>, all is well. If the result is being used in a + context requiring a <code>std::string</code> or <code>std::wstring</code>, + then <code>.string()</code> or <code>.wstring()</code> respectively must be + appended to the function call.<br> + </li> + <li> <code>path::iterator::value_type</code> and <code> + path::const_iterator::value_type</code> is <code>path</code> rather than <code> + basic_string</code>.</li> +</ul> +<h3>Compiler support</h3> +<ul> + <li>Compilers and standard libraries that do not fully support wide characters + and wide character strings (<code>std::wstring</code>) are no longer + supported.<br> + </li> + <li>Cygwin versions prior to 1.7 are no longer supported because they lack + wide string support. Cygwin now compiles only for the Windows API and path + syntax.<br> + </li> + <li>MinGW versions not supporting wide strings are no longer supported.<br> + </li> + <li>Microsoft VC++ 7.1 and earlier are no longer supported.</li> +</ul> + +<hr> +<p>© Copyright Beman Dawes, 2009</p> +<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> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->20 March 2012<!--webbot bot="Timestamp" endspan i-checksum="27254" --></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/filesystem/doc/v3_design.html b/libs/filesystem/doc/v3_design.html new file mode 100644 index 0000000000..cea4f12254 --- /dev/null +++ b/libs/filesystem/doc/v3_design.html @@ -0,0 +1,192 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Filesystem V3 Design</title> +<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td> +<a href="../../../index.htm"> +<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="300" height="86"></a></td> + <td align="middle"> + <font size="7">Filesystem Version 3<br> + Design</font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><a href="index.htm">Filesystem Home</a> + <a href="release_history.html">Releases</a> + <a href="reference.html">Reference</a> + <a href="tutorial.html">Tutorial</a> + <a href="faq.htm">FAQ</a> + <a href="portability_guide.htm">Portability</a> + <a href="v3.html">V3 Intro</a> + <a href="v3_design.html">V3 Design</a> + <a href="deprecated.html">Deprecated</a> + </td> + </tr> +</table> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> + <a href="#Introduction">Introduction</a><br> + <a href="#Problem">Problem</a><br> + <a href="#Solution">Solution</a><br> + <a href="#Details">Details</a><br> + <a href="#Other-changes">Other changes</a><br> + <a href="#Acknowledgements">Acknowledgements</a></td> + </tr> + </table> + +<p><b>Caution:</b> This page documents thinking early in the V3 development +process, and is intended to serve historical purposes. It is not updated to +reflect the current state of the library.</p> + +<h2><a name="Introduction">Introduction</a></h2> + +<p>During the review of Boost.Filesystem.V2 (Internationalization), Peter Dimov +suggested that the<code> basic_path</code> class template was unwieldy, and that a single +path type that accommodated multiple character types and encodings would be more +flexible. Although I wasn't willing to stop development at that time to +explore how this idea might be implemented, or to break from the pattern for +Internationalization used the C++ standard library, I've often thought about +Peter's suggestion. With the advent of C++0x <code>char16_t</code> and <code>char32_t</code> character +types, the <code>basic_path</code> class template approach becomes even more unwieldy, so it +is time to revisit the problem in light of Peter's suggestion.</p> + +<h2><b><a name="Problem">Problem</a></b></h2> + +<p>With Filesystem.V2, a path argument to a user defined function that is to +accommodate multiple character types and encodings must be written as a +template. Do-the-right-thing overloads or template metaprogramming must be +employed to allow arguments to be written as string literals. Here's what it +looks like:</p> + +<blockquote> + <pre>template<class Path> +void foo( const Path & p );</pre> + <pre>inline void foo( const path & p ) +{ + return foo<path>( p ); +} +inline void foo( const wpath & p ) +{ + return foo<wpath>( p ); +}</pre> +</blockquote> +<p>That's really ugly for such a simple need, and there would be a combinatorial +explosion if the function took multiple Path arguments and each could be either +narrow or wide. It gets even worse if the C++0x <code>char16_t</code> and <code> +char32_t</code> types are to be supported.</p> + +<h2><a name="Solution">Solution</a></h2> + +<p>Overview:</p> + +<ul> + <li>A single, non-template, <code>class path</code>.</li> + <li>Each member function is a template accommodating the various + applicable character types, including user-defined character types.</li> + <li>Hold the path internally in a string of the type used by the operating + system API; <code>std::string</code> for POSIX, <code>std::wstring</code> for Windows.</li> +</ul> + +<p>The signatures presented in <a href="#Problem">Problem</a> collapse to +simply:</p> +<blockquote> + <pre>void foo( const path & p );</pre> +</blockquote> + +<p>That's a signification reduction in code complexity. Specification becomes +simpler, too. I believe it will be far easier to teach, and result in much more +flexible user code.</p> + +<p>Other benefits:</p> +<ul> + <li>All the polymorphism still occurs at compile time.</li> + <li>Efficiency is increased, in that conversions of the encoding, if required, + only occur once at the time of creation, not each time the path is used.</li> + <li>The size of the implementation code drops approximately in half and + becomes much more readable.</li> +</ul> + <p>Possible problems:</p> +<ul> + <li>The combination of member function templates and implicit constructors can + result in unclear error messages when the user makes simple commonplace coding + errors. This should be much less of a problem with C++ concepts, but in the + meantime work continues to restrict over aggressive templates via enable_if/disable_if.</li> +</ul> + <h2><a name="Details">Details</a></h2> + +<table border="1" cellpadding="4" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="33%" colspan="3"> + <p align="center"><b><i>Encoding </i></b><i><b>Conversions</b></i></td> + </tr> + <tr> + <td width="33%"> + <p align="center"><i><b>Host system</b></i></td> + <td width="33%"> + <p align="center"><i><b>char string path arguments</b></i></td> + <td width="34%"> + <p align="center"><i><b>wide string path arguments</b></i></td> + </tr> + <tr> + <td width="33%">Systems with <code>char</code> as the native API path character type (i.e. + POSIX-like systems)</td> + <td width="33%">No conversion.</td> + <td width="34%">Conversion occurs, performed by the current path locale's + <code>codecvt</code> facet.</td> + </tr> + <tr> + <td width="33%">Systems with <code>wchar_t</code> as the native API path character type + (i.e. Windows-like systems).</td> + <td width="33%">Conversion occurs, performed by the current path locale's + <code>codecvt</code> facet.</td> + <td width="34%">No conversion.</td> + </tr> +</table> + +<p>When a class path function argument type matches the the operating system's +API argument type for paths, no conversion is performed rather than conversion +to a specified encoding such as one of the Unicode encodings. This avoids +unintended consequences, etc.</p> + +<h2><a name="Other-changes">Other changes</a></h2> + +<p><b>Uniform hybrid error handling: </b>The hybrid error handling idiom has +been consistently applied to all applicable functions.</p> + +<h2><a name="Acknowledgements">Acknowledgements</a></h2> + +<p>Peter Dimov suggested the idea of a single path class that could cope with +multiple character types and encodings. Walter Landry contributed both the design and implementation of the copy_any, +copy_directory, copy_symlink, and read_symlink functions.</p> + +<hr> +<p>Revised +<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->20 March, 2012<!--webbot bot="Timestamp" endspan i-checksum="28814" --></p> + +<p>© Copyright Beman Dawes, 2008</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"> +www.boost.org/LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file |