|
Boost-Commit : |
From: bdawes_at_[hidden]
Date: 2007-11-07 16:54:48
Author: bemandawes
Date: 2007-11-07 16:54:48 EST (Wed, 07 Nov 2007)
New Revision: 40912
URL: http://svn.boost.org/trac/boost/changeset/40912
Log:
Initial commit. The starting point for the reference documentation is N1975, Filesystem Library Proposal for TR2 (Revision 3).
Added:
trunk/libs/filesystem/doc/reference.html (contents, props changed)
Added: trunk/libs/filesystem/doc/reference.html
==============================================================================
--- (empty file)
+++ trunk/libs/filesystem/doc/reference.html 2007-11-07 16:54:48 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,3588 @@
+<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 Library Proposal
+</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<p>Doc. no. WG21/N1975=06-0045<br>
+Date:
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2006-04-04<!--webbot bot="Timestamp" endspan i-checksum="12266" --><br>
+Project: Programming Language C++<br>
+Reply to: Beman Dawes <<a href="mailto:bdawes_at_[hidden]">bdawes_at_[hidden]</a>></p>
+
+<h1>Filesystem Library Proposal for TR2 (Revision 3)</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="26%" valign="top">Introduction<br>
+Motivation and Scope<br>
+Impact on the Standard<br>
+Important Design Decisions<br>
+Proposed Text for TR2<br>
+ Introductory chapter<br>
+ Diagnostics library chapter<br>
+ Filesystem library chapter<br>
+ Definitions<br>
+ Requirements<br>
+
+Requirements on programs<br>
+
+Requirements<br>
+
+on implementations<br>
+ <a href="#Header-filesystem-synopsis">
+ Header <filesystem> synopsis</a><br>
+ Path traits<br>
+ <a href="#Class-template-basic_path">
+ Class template basic_path</a><br>
+
+Pathname formats<br>
+
+Pathname grammar<br>
+
+Filename conversion<br>
+
+Requirements </td>
+ <td width="35%" valign="top"> Class template basic_path (continued)<br>
+
+basic_path constructors<br>
+
+basic_path assignments<br>
+
+basic_path modifiers<br>
+
+basic_path operators<br>
+
+basic_path observers<br>
+
+basic_path iterators<br>
+
+basic_path non-member functions<br>
+
+basic_path inserter and extractor<span style="background-color: #FFFFFF"><br>
+</span>
+<a href="#Class-template-basic_filesystem_error">Class template
+ basic_filesystem_error</a><br>
+
+<a href="#basic_filesystem_error-constructors">basic_filesystem_error
+ constructors</a><br>
+
+basic_filesystem_error observers<br>
+
+<a href="#Class-template-basic_directory_entry">Class template
+ basic_directory_entry</a><br>
+
+basic_directory_entry constructors<br>
+
+basic_directory_entry modifiers<br>
+
+basic_directory_entry observers<br>
+
+basic_directory_entry comparisons</td>
+ <td width="89%" valign="top">Filesystem library chapter (continued)<br>
+
+<a href="#Class-template-basic_directory_iterator">Class template
+ basic_directory_iterator</a><br>
+
+<a href="#basic_directory_iterator-constructors">basic_directory_iterator
+ constructors</a><br>
+
+<a href="#Class-template-basic_recursive_directory_iterator">Class template
+ basic_recursive_directory_iterator</a><br>
+ <a href="#file_status">Class
+ file_status</a><br>
+ <a href="#Non-member-functions">
+ Non-member operational functions</a><br>
+
+Status functions<br>
+
+Predicate functions<br>
+
+Attribute functions<br>
+
+Other operations functions<br>
+
+Convenience functions<br>
+ <a href="#header-cerrno">Additions to
+ header <cerrno></a><br>
+ <a href="#header-fstream">Additions
+ to header <fstream></a><br>
+Suggestions for <fstream>
<code><br>
+ </code>
+ implementations<br>
+Path decomposition table<br>
+Issues<br>
+Acknowledgements<br>
+References<br>
+<a href="#Revision-History"><span style="background-color: #FFFFFF">Revision
+History</span></a></td>
+ </tr>
+</table>
+
+<h2><a name="Introduction">Introduction</a></h2>
+<p>This paper proposes addition of a filesystem library component
+to the C++ Standard Library Technical Report 2. The proposal is based on the Boost Filesystem Library (see www.boost.org/libs/filesystem).</p>
+<p>The library provides portable facilities to query and
+manipulate paths, files, and directories. The Boost version of the library is widely used. It would
+be a pure addition to the C++ standard, leaving in place existing
+standard library functionality in the relatively few areas where there is overlap.</p>
+<p>Users say they prefer the Boost Filesystem Library interface to native
+operating system or
+<i>POSIX</i> API's, even in code without portability requirements, because the design
+follows modern C++ practice.</p>
+<p>The proposed text includes an example of a
+program using the library.</p>
+<h2><a name="Motivation">Motivation</a> and Scope</h2>
+<p><b><i>Why is this important? </i></b></p>
+<p>The motivation for the library is the desire to perform <i><b>safe, portable, script-like filesystem operations</b></i> from within C++ programs. Because the
+C++ Standard Library currently contains no facilities for such filesystem tasks
+as directory iteration or directory creation, programmers currently must rely on
+operating system specific interfaces, making it difficult to write
+portable programs.</p>
+<p>The intent is not to compete
+with Python, Perl, or shell scripting languages, but rather to provide
+file system operations where C++ is already the language of choice. The design
+encourages, but does not require, safe and portable usage.</p>
+<p><b><i>What kinds of problems does it address, and what kinds of programmers is
+it intended to support?</i></b></p>
+<p>The library addresses everyday needs, for both application programs and
+libraries. It is useful across every application domain that uses files. It is
+intended to be useful to all levels of programmers, from rank beginners to
+seasoned experts.</p>
+<p><b><i>Is it based on existing practice?</i></b></p>
+<p>Yes, very much so. The proposal is based on the Boost Filesystem Library,
+which has been in use since 2002 and by now is in very wide use.</p>
+<p>Note, however, that until recently all the Boost experience was with a
+narrow-character only version of the library. The internationalized version as
+described in this proposal is just starting to be used, and will not be fully
+released until Boost release 1.34.</p>
+<p>The underlying mechanisms have been in use for decades on the world's most
+wide-spread operating systems, such as <i>POSIX</i>, <i>Windows</i>, and various
+mainframe operating systems. What this proposal brings to the table is an
+approach that is C++
+Standard Library friendly and fully internationalized.</p>
+<p><b><i>Is there a reference implementation?</i></b></p>
+<p>Yes. The Boost Filesystem Library is freely and publicly available. The Boost library will track the TR2 proposed
+library as the proposal evolves.</p>
+<h2><a name="Impact">Impact</a> on the Standard</h2>
+<p><b><i>What does it depend on, and what depends on it?</i></b></p>
+<p>It depends on
+some standard library components, such as basic_string. No other proposals
+depend on it.</p>
+<p>If a revision to the Code Conversion Proposal (See
+<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1683.html">
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1683.html>) is
+accepted, it may be advantageous for the Filesystem Library
+to use that library rather than the current code conversion facilities proposed
+below.</p>
+<p><b><i>Is it a pure extension, or does it require changes to standard
+components?</i></b></p>
+<p>Most of the proposed library is a pure extension.</p>
+<p>There are additions to header <cerrno>. Since
+the critical portions that might require change to C headers (always a sore
+point) are already mandated for <i>POSIX</i> compliance, and represent
+existing practice for many non-<i>POSIX</i> operating systems such as for <i>Windows</i>, it is not expected that they will cause any problems.</p>
+<p>There are additions to header <fstream>.
+These have been carefully specified to avoid breaking existing code in common operating environments such as <i>POSIX</i>, <i>
+Windows</i>, and <i>OpenVMS</i>. See <a href="#Suggestions-for-fstream">
+Suggestions for <code><fstream></code> implementations</a> for techniques to
+avoid breaking existing code in other environments, particularly on operating
+systems allowing slashes in filenames.</p>
+<p><b><i>Can it be implemented using today's compilers, or does it require
+language features that will only be available as part of C++0x?</i></b></p>
+<p>It can
+be (and has been) implemented with today's compilers.</p>
+<p>There is one minor function that can best be implemented by an addition to
+current C++ runtime libraries, although an acceptable workaround is documented.</p>
+<p>On operating systems with built-in support for wide-character file names,
+such as <i>Windows</i>, high-quality implementation of the header <fstream>
+additions require an addition to the C++ Standard Library implementation. The
+addition is relatively small and localized, and is already supplied by the most
+recent Dinkumware implementation of the Standard Library. There is a workaround that avoids
+modifying the standard library, but it is very much a hack and depends on a <i>
+Windows</i> feature (8.3 filename support) which some users disable, thereby
+disabling the workaround. The issue doesn't affect implementations on operating
+systems which only support narrow character file names.</p>
+<h2>Important <a name="Design">Design</a> Decisions</h2>
+<h4><i>Why did you choose the specific design that you did?</i></h4>
+<p>Many of the specific design decisions were driven by the desire to provide a modern C++ interface
+that works
+well with the C++ Standard Library. The intent is that Standard Library users
+can become comfortable with the Filesystem Library in very short order.</p>
+<p>The proposed library encourages both syntactic and semantic portability, yet
+does not force implementors into heroic efforts on hopeless systems. This
+balances the benefits to users of both code and knowledge portability with the
+realities faced by implementors on some operating systems.</p>
+
+<p><span style="background-color: #FFFFFF">In some
+cases users always need portable semantics. In some cases users always need
+platform specific semantics. In some cases users need to be able to choose
+between portable and platform specific semantics. The design evolved over a
+period of years to identify and meet each of those needs. </span></p>
+
+<p>Because of the desire to support simple "script-like" usage, use cases often
+drove design choices. For example, users can write <code>if (exists("foo"))</code> rather than
+the lengthier <code>if (exists(path("foo")))</code>.</p>
+
+<p>Because filesystem operations often encounter unexpected runtime errors, the library
+by default reports runtime errors via C++ exceptions,
+and ensures enough information is provided for meaningful error messages,
+including internationalized error messages.</p>
+
+<p><b><i>What alternatives did you consider, and what are the tradeoffs?</i></b></p>
+<p><i>Additional observers and modifiers for file system attributes.</i>
+Attribute functions which cannot supply portable semantics are not provided,
+avoiding the illusion of portability in cases where it cannot in fact exist.</p>
+<p><i>A larger number of operational convenience functions.</i>
+Convenience functions (functions which can be portably created by composition
+from basic functions) were not provided unless there was widespread agreement on
+usefulness and need.</p>
+<p><i>Compile-time or run-time options for operational functions.</i>
+Numerous trial implementations were abandoned because the added complexity
+out-weighed the benefits, and because consensus could not be reached on the
+feature set.</p>
+<p><i>Automatic path name checking.</i> This feature, supplied by the Boost
+library for several years, allowed users to specify both default and per
+constructor path name checking, and thus allowed the desired degree of portability to be
+automatically enforced. This implicit name checking was abandoned because of user
+confusion and complaints of excessive nannyism..</p>
+<p><i>Separate path types for regular file and directory pathnames.</i> Pathname
+formats that use different syntax for regular pathnames versus directory
+pathnames are passing into extinction. Why prolong the agony at the cost of
+torturing those using modern systems? It is perhaps significant that one of the few web
+sites dedicated to preserving a dual pathname format operating system is named
+<i>Deathrow</i> (http://deathrow.vistech.net/).</p>
+<p><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.</p>
+<p><b><i>What are the consequences of your choices, for users and implementors?</i></b></p>
+<p>The design has evolved over a period of four years of actual experience by
+Boost users, and the most frequent causes of user complaints (such as enforced
+name-checking and several over-strict preconditions) were eliminated. The TR
+process will allow further refinement. The intent is to ensure user needs are
+met.</p>
+<p>Because the Boost implementation is tested and
+used in a wide range of <i>POSIX</i> and <i>Windows</i> environments, many implementation
+concerns have already been addressed.</p>
+<p><b><i>What decisions are left up to implementors?</i></b></p>
+<p>Because implementations of the library are dependent on facilities of the
+underlying operating system, implementors are given unusual freedom to redefine
+semantics of the library. That being said, implementors are given strong
+normative encouragement to provide the TR described semantics whenever feasible.</p>
+<p><b><i>If there are any similar libraries in use, how do their design
+decisions compare to yours?</i></b></p>
+<p>There are a number of libraries which address the problem domain. Most of the
+C/C++ libraries have C, rather than C++ interfaces. For example, see the Apache Portable Runtime
+Project (http://apr.apache.org). The ACE
+toolkit (http://www.cs.wustl.edu/~schmidt/ACE.html)
+uses a C++ approach, but doesn't mesh well with the C++ Standard Library. For
+example, the ACE directory iterator differs greatly from Standard Library
+iterator requirements.</p>
+<h2>Proposed <a name="Text">Text</a> for Technical Report 2</h2>
+<p><span style="font-style: italic; background-color: #E0E0E0">Gray-shaded
+italic text is commentary on the proposal. It is not to be added to the TR.</span></p>
+<p><span style="background-color: #FFFFFF"><i>Italic text is editorial guidance.
+It is not to be added to the TR.</i></span></p>
+<p><span style="font-style: italic; background-color: #FFFFFF">
+<a name="frontmatter">Add</a> to the
+introductory section of the TR:</span></p>
+<p>The following standard contains provisions which, through reference in this
+text, constitute provisions of this Technical Report. At the time of
+publication, the editions indicated were valid. All standards are subject to
+revision, and parties to agreements based on this Technical Report 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 (POSIX1),
+ part 1 (Base Definitions) and part 2 (System Interfaces)</i>, both as corrected by their
+ respective 2004 Correction 1 documents.<p>[<i>Note:</i> ISO/IEC 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<font face="Times New Roman"><sup>2</sup><i><b>
+ </b></i>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> <i>-- end note</i>]</font></p>
+ </li>
+ </ul>
+<p>ISO/IEC 9945:2003, with the indicated corrections, is hereinafter called <i>
+POSIX</i>.</p>
+<p>Some library behavior in this Technical Report is defined by reference to <i>
+POSIX</i>. 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. Presumably implementations will usually call native
+operating system API's. <i>--end note</i>]</p>
+</blockquote>
+<p>Implementations are encouraged, but not required, to support such behavior
+
+as it is defined by <i>POSIX</i>. Implementations shall document any
+behavior that differs from the <i>POSIX</i> defined behavior. Implementations that do not support exact <i>POSIX</i> behavior are
+encouraged to provide behavior as close to <i>POSIX</i> behavior as is reasonable given the
+limitations of actual operating 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>basic_filesystem_error</code> exception, a special
+return value, or some other manner. <i>--end note</i>]</p>
+</blockquote>
+<p><a name="Footnote-1">Footnote 1</a>: <i>POSIX</i>® is a registered trademark of The
+IEEE.</p>
+<p><a name="Footnote-2">Footnote 2</a>: <i>UNIX</i>® is a registered trademark of The
+Open Group.</p>
+<p><span style="background-color: #FFFFFF"><i>Add a new clause to the TR:</i></span></p>
+<hr>
+<h2>Chapter <span style="font-weight: 400"><i>(tbs)</i></span> -
+<a name="Diagnostics-library">Diagnostics library</a></h2>
+<hr>
+<p>This clause describes components that C++ programs may use to detect and
+report error conditions.</p>
+<h3>Header <code><system_error></code></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ typedef <i>implementation-defined</i> system_error_type;
+ typedef int errno_type; // determined by C standard
+
+ system_error_type system_code(errno_type err);
+
+ errno_type iso_code(system_error_type err);
+
+ std::string& system_message(error_code err, std::string& target);
+ std::wstring& system_message(error_code err, std::wstring& target);
+
+ enum iso_t { iso };
+
+ class error_code;
+ class system_error;
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>Type <code>system_error_type</code> is the implementation-defined type used
+by the operating system to report error codes.</p>
+<blockquote>
+<p>[<i>Note:</i> On POSIX, <code>system_error_type</code> is normally <code>int</code>.
+On Windows it is normally <code>unsigned int</code>. This type might differ if
+the implementation is built on an emulation<i> </i>layer such as Cygwin. <i>--
+end note</i>]</p>
+</blockquote>
+<pre>system_error_type system_code(errno_type err);</pre>
+<blockquote>
+<p><i>Returns:</i> An <code>system_error_type</code> value corresponding to
+<code>err</code>.</p>
+<p>[<i>Note:</i> There is no guarantee that for a value <code>err</code> of type
+<code>errno_type</code>, <code>err == iso_code( system_code(err) )</code>. <i>--
+end note</i>]</p>
+</blockquote>
+<pre>errno_type iso_code(system_error_type err);</pre>
+<blockquote>
+ <p><i>Returns:</i> An <code>errno_type</code> value corresponding to <code>err</code>.</p>
+<p>[<i>Note:</i> There is no guarantee that for a value <code>err</code> of type
+<code>system_error_type</code>, <code>err == system_code( iso_code(err) )</code>.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre>std::string& system_message(error_code err, std::string& target);
+std::wstring& system_message(error_code err, std::wstring& target);</pre>
+<blockquote>
+ <p><i>Effects: </i>Appends to <code>target</code> an operating system specific
+ and locale specific message corresponding to <code>err.system()</code>.</p>
+ <p><i>Returns:</i> <code>target</code>.</p>
+ <p><i>Remarks:</i> Implementors and users are permitted to supply additional
+ overloads in namespace <code>std::tr2::sys</code>.</p>
+</blockquote>
+<h3>Class <code>error_code</code></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ class error_code
+ {
+ public:
+ error_code();
+ error_code(system_error_type err);
+ error_code(errno_type err, iso_t);
+
+ system_error_type system() const;
+ void system(system_error_type err);
+
+ errno_type iso() const;
+ void iso(errno_type err);
+
+ bool error() const;
+
+ bool operator==(error_code rhs) const;
+ };
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>The class <code>error_code</code> defines the type of objects used to
+identify specific errors originating from the operating system.</p>
+<pre>error_code();</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>!error()&& iso()==0</code>, and <code>system()</code>
+ returns the value used by the operating system to represent not an error. </p>
+</blockquote>
+<pre>error_code(system_error_type err);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>system()==err</code>.</p>
+</blockquote>
+<pre>error_code(errno_type err, iso_t);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>iso()==err</code>.</p>
+</blockquote>
+<pre>system_error_type system() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> If the most recent non-const function called, or the
+ constructor if no non-const function has been called, had an <code>err</code>
+ argument of type <code>system_error_type</code>, then return that argument.
+ Otherwise, return <code>system_code(iso())</code>.</p>
+</blockquote>
+<pre>void system(system_error_type err);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>system()==err</code>.</p>
+</blockquote>
+<pre>errno_type iso() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> If the most recent non-const function called, or the
+ constructor if no non-const function has been called, had an <code>err</code>
+ argument of type <code>errno_type</code>, then return that argument.
+ Otherwise, return <code>iso_code(system())</code>.</p>
+</blockquote>
+<pre>void iso(errno_type err);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>iso()==err</code>.</p>
+</blockquote>
+<pre>bool error() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>system()==error_code(x),</code> where <code>x</code>
+ is the value used by the operating system to represent not an error.</p>
+</blockquote>
+<pre>bool operator==(error_code rhs) const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>system()==rhs.system()</code>.</p>
+</blockquote>
+<h3>Class <code>system_error</code></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ class system_error : public std::runtime_error
+ {
+ public:
+ system_error(const std::string & what_arg, error_code ec);
+
+ error_code code() const;</pre>
+<pre> const char * what() const;
+ };
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>The class <code>system_error</code> defines the type of objects thrown as
+exceptions to report errors originating from the operating system.</p>
+<pre>system_error(const std::string & what_arg, error_code ec);</pre>
+<blockquote>
+ <p><i>Effects:</i> Constructs an object of class <code>system_error</code>.</p>
+ <p><i>Postcondition:</i> <code>strcmp(runtime_error::what(), what_arg .c_str()) == 0 &&
+ code() == ec</code>.</p>
+</blockquote>
+<pre>error_code code() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> the <code>ec</code> constructor argument.</p>
+</blockquote>
+<pre>const char * what() const;</pre>
+<blockquote>
+ <p><i>Returns: </i>A string containing <code>runtime_error::what()</code> and
+ the result of calling <code>system_message()</code> with a first argument of
+ <code>code()</code>. The exact format is unspecified.</p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>Add a new clause to the TR:</i></span></p>
+<hr>
+<h2>Chapter <span style="font-weight: 400"><i>(tbs)</i></span> - <a name="Filesystem-library">Filesystem library</a></h2>
+<hr>
+<p>This clause describes components that C++ programs may use to interrogate and
+manipulate files (including directories), and certain of their
+attributes.</p>
+<p>This clause applies only to hosted implementations (C++ Std, 1.4,
+Implementation compliance [intro.compliance]).</p>
+<blockquote>
+<p>[<i>Note:</i> This clause applies to any hosted implementation.
+Specific operating systems such as <i>OpenMVS</i><sup>3</sup>,
+<i>UNIX</i>, and <i>Windows</i><sup>4</sup> are mentioned only for purposes of illustration or to
+give guidance to implementors. No slight to other operating systems is implied
+or intended. <i>--end note</i>.]</p>
+</blockquote>
+<p>Unless otherwise specified, all components described in this clause are
+declared in namespace <code>std::tr2::sys</code>.</p>
+<blockquote>
+<p>[<i>Note:</i> The <code>sys</code> sub-namespace prevents collisions with
+names already in the standard library and emphasizes reliance on the
+operating system dependent behavior inherent in file system operations. <i>-- end
+note</i>]</p>
+</blockquote>
+<p>The <i>Effects</i> and <i>Postconditions</i> of functions described in this clause
+may not be achieved in
+the presence of race conditions. No diagnostic is required.</p>
+<p>If the possibility of race conditions makes it unreliable for a program to
+test for a precondition before calling a function described in this clause, <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>
+<p><a name="Footnote-3">Footnote 3</a>: <i>OpenMVS</i>® is a registered
+trademark of Hewlett-Packard Development Company.</p>
+<p><a name="Footnote-4">Footnote 4</a>: <i>Windows</i>® is a registered
+trademark of Microsoft Corporation.</p>
+<h3><a name="Definitions">Definitions</a></h3>
+<p>The following definitions shall apply to this clause:</p>
+<p><i><a name="File">File</a>: </i>An object that can be written to, or read from, or both. A file
+has certain attributes, including type. File types include regular file,
+symbolic link, and directory. Other types of files may be supported by the
+implementation.</p>
+<p><i><a name="File-system">File system</a>:</i> A collection of files and certain of their attributes.</p>
+<p><i><a name="Filename">Filename</a>:</i> The name of a file. The format is as
+specified by the <i>POSIX
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_169">
+Filename</a></i> base definition.</p>
+<p><i><a name="Path">Path</a>:</i> A sequence of elements which identify
+a location within a filesystem. The elements are the <i>root-name</i>, <i>
+root-directory</i>, and each successive <i>filename</i>. See
+Pathname grammar.</p>
+<p><i><a name="Pathname">Pathname</a>: </i>A character string that represents a
+path.</p>
+<p><i><a name="Link">Link</a>: </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><i><a name="Hard-link">Hard link</a>:</i> 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">Symbolic link</a>: </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><i><a name="Slash">Slash</a>:</i> The character <tt>'/'</tt>, also known as
+solidus.</p>
+<p><i><a name="Dot">Dot</a>:</i> The character '.', also known as period.</p>
+<p><i><a name="Race-condition">Race condition</a>:</i> The condition that occurs
+when multiple threads, processes, or computers interleave access and
+modification of
+the same object within a file system.</p>
+<h3><a name="Requirements">Requirements</a></h3>
+<h4><a name="Requirements-on-programs">Requirements on programs</a></h4>
+<p>The arguments for template parameters named <code>Path</code>, <code>Path1</code>,
+or <code>Path2</code> described in this clause shall be of type <code>basic_path</code>,
+or a class derived from <code>basic_path</code>, unless otherwise
+specified.</p>
+<h4><a name="Requirements-on-implementations">Requirements on implementations</a></h4>
+<p>Some function templates described in this clause have a template parameter
+named <code>Path</code>, <code>Path1</code>, or <code>Path2</code>. When called
+with a function argument <code>s</code> of type <code>char*</code> or <code>
+std::string</code>, the implementation shall treat the argument as if it were
+coded <code>path(s)</code>. When called with a function argument <code>s</code>
+of type <code>wchar_t*</code> or <code>std::wstring</code>, the implementation
+shall treat the argument as if it were coded <code>wpath(s)</code>. For
+functions with two arguments, implementations shall not supply this treatment
+when <code>Path1</code> and <code>Path2</code> are different types.</p>
+<blockquote>
+<p>[<i>Note:</i> This "do-the-right-thing" rule allows users to write <code>exists("foo")</code>,
+taking advantage of class <code>basic_path</code>'s string conversion
+constructor, rather
+than the lengthier and more error prone <code>exists(path("foo"))</code>. This
+is particularly important for the simple, script-like, programs which are an
+important use case for the library. Calling two argument functions with
+different types is a very rare usage, and may well be a coding error, so
+automatic conversion is not supported for such cases.</p>
+<p>The implementation technique is unspecified. One possible implementation
+technique, using
+<code>exists()</code> as an example, is:</p>
+ <blockquote>
+ <pre>template <class Path>
+ typename boost::enable_if<is_basic_path<Path>,bool>::type exists(const Path& p);
+inline bool exists(const path& p) { return exists<path>(p); }
+inline bool exists(const wpath& p) { return exists<wpath>(p); }</pre>
+ </blockquote>
+ <p> The <code>enable_if</code> will fail for a C string or <code>
+ std::basic_string</code> argument, which will then be automatically converted
+ to a <code>basic_path</code> object via the appropriate <code>basic_path</code> conversion
+ constructor. <i>-- end note</i>]</p>
+ <p><span style="background-color: #E0E0E0"><i>The two overloads are not given
+ in the normative text because:</i></span></p>
+ <ul>
+ <li><span style="background-color: #E0E0E0"><i>Better techniques for
+ achieving the desired affect may be developed, perhaps enabled by core
+ language changes like Concepts.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>Implementations may prefer
+ techniques that work with legacy compilers that do not support enable_if.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>Spelling out the overloads
+ makes the text longer and harder to read without adding much benefit.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>More overloads will probably
+ be needed for char16_t and char32_t (or whatever they end up being called),
+ making it even less attractive to actually spell out each one. </i></span>
+ </li>
+ </ul>
+</blockquote>
+<p>Implementations of functions described in this clause are permitted to call the applications
+program interface (API) provided by the operating system. If such an operating
+system API call results in an error, implementations
+shall report the error by throwing exception <code>basic_filesystem_error</code>,
+unless otherwise specified.</p>
+<blockquote>
+<p>[<i>Note: </i>Such exceptions and the conditions that cause them to be thrown
+are not explicitly described in each <i>Throws</i> element within this clause.
+Because hardware failures, network failures, race conditions, and a plethora of
+other errors occur frequently in file system operations, users should be aware
+that <span style="background-color: #FFFFFF">unless otherwise specified</span> any file system operation, not matter how apparently innocuous, may throw
+an exception. <i>-- end note</i>]</p>
+</blockquote>
+<p><span style="background-color: #FFFFFF">Functions commonly used in contexts
+where errors are not exceptional have overloads taking an additional argument of
+type </span><code><span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF">. Such overloaded functions shall not throw exceptions. If an error occurs,
+<code>ec</code> shall be set to the
+error code reported by the operating system, otherwise <code>ec</code> shall be set to 0. If
+an overload without an argument of type </span><code>
+<span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF"> returns void, the other overload (with an argument of type </span><code>
+<span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF">) returns an <code>
+error_code</code> with the value of ec.</span></p>
+<h3><a name="Header-filesystem-synopsis">Header <code><filesystem></code> synopsis</a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class String, class Traits> class basic_path;
+
+ template<class String, class Traits>
+ void swap(basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs);
+
+ template<class String, class Traits> bool operator<(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator==(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator!=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator>(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator<=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator>=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator/(<i>a</i> a, <i>b</i> b);
+
+ template<class Path>
+ basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
+ operator<<(basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& os, const Path & ph);
+
+ template<class Path>
+ basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
+ operator>>(basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& is, Path & ph);
+
+ struct path_traits;
+ struct wpath_traits;
+
+ typedef basic_path<std::string, path_traits> path;
+ typedef basic_path<std::wstring, wpath_traits> wpath;
+
+ template<class Path> struct is_basic_path;
+
+ template<class Path> struct slash { static const char value = '/'; };
+ template<class Path> struct dot { static const char value = '.'; };
+<span style="background-color: #FFFFFF"> template<class Path> struct colon { static const char value = ':'; };</span><span style="background-color: #FFFF00">
+</span>
+ <span style="background-color: #FFFFFF">class filesystem_error;</span><span style="background-color: #FFFF00">
+</span>
+ template <class Path> class basic_filesystem_error;
+
+ typedef basic_filesystem_error<path> filesystem_error;
+ typedef basic_filesystem_error<wpath> wfilesystem_error;
+
+ <span style="background-color: #FFFFFF">template <class Path> class basic_directory_entry;
+
+ typedef basic_directory_entry<path> directory_entry;
+ typedef basic_directory_entry<wpath> wdirectory_entry;
+</span>
+ template <class Path> class basic_directory_iterator;
+
+ typedef basic_directory_iterator<path> directory_iterator;
+ typedef basic_directory_iterator<wpath> wdirectory_iterator;
+
+ template <class Path> class basic_recursive_directory_iterator;
+
+ typedef basic_recursive_directory_iterator<path> recursive_directory_iterator;
+ typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;
+
+ enum file_type { status_unknown, file_not_found, regular_file, directory_file,
+ symlink_file, block_file, character_file, fifo_file, socket_file,
+ type_unknown
+ };
+
+ class file_status;
+
+ <span style="background-color: #FFFFFF">struct space_info // returned by </span>space<span style="background-color: #FFFFFF"> function
+ {
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+ };
+</span>
+ // status functions
+ template <class Path> file_status status(const Path& p);
+ template <class Path> file_status status(const Path& p, error_code& ec);
+ template <class Path> file_status symlink_status(const Path& p);
+ template <class Path> file_status symlink_status(const Path& p, error_code& ec);
+
+ // predicate functions
+ bool status_known( file_status s );
+ bool exists( file_status s );
+ bool is_regular( file_status s );
+ bool is_directory( file_status s );
+ bool is_symlink( file_status s );
+ bool is_other( file_status s );
+
+ template <class Path> bool exists(const Path& p);
+ template <class Path> bool is_directory(const Path& p);
+ template <class Path> bool is_regular(const Path& p);
+ template <class Path> bool is_other(const Path& p);
+ template <class Path> bool is_symlink(const Path& p);
+ template <class Path> bool is_empty(const Path& p);
+
+ template <class Path1, class Path2>
+ bool equivalent(const Path1& p1, const Path2& p2);
+
+ // attribute functions
+ template <class Path> Path current_path();
+ template <class Path> const Path& initial_path();
+ template <class Path> <span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const Path& p);
+<span style="background-color: #FFFFFF"> template <class Path> space_info space(const Path& p);</span><span style="background-color: #FFFF00">
+</span> template <class Path> std::time_t last_write_time(const Path& p);
+ template <class Path>
+ void last_write_time(const Path& p, const std::time_t new_time);
+
+ // operations functions
+ template <class Path> bool create_directory(const Path& dp);
+ template <class Path1, class Path2>
+ void create_hard_link(const Path1& old_fp, const Path2& new_fp);
+<span style="background-color: #FFFFFF"> template <class Path1, class Path2>
+ error_code create_hard_link(const Path1& old_fp, const Path2& new_fp, error_code& ec);
+ template <class Path1, class Path2>
+ void create_symlink(const Path1& old_fp, const Path2& new_fp);
+ template <class Path1, class Path2>
+ error_code create_symlink(const Path1& old_fp, const Path2& new_fp, error_code& ec);
+</span> template <class Path> bool remove(const Path& p);
+ template <class Path1, class Path2>
+ void rename(const Path1& from_p, const Path2& to_p);
+ template <class Path1, class Path2>
+ void copy_file(const Path1& from_fp, const Path2& to_fp);
+ template <class Path> Path system_complete(const Path& p);
+ template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());
+
+ // convenience functions
+ template <class Path> bool create_directories(const Path& p);
+ template <class Path> typename Path::string_type extension(const Path& p);
+ template <class Path> typename Path::string_type basename(const Path& p);
+ template <class Path>
+ Path replace_extension(const Path& p, const typename Path::string_type& new_extension);
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<h3><a name="Path-traits">Path traits</a></h3>
+<p>This subclause defines requirements on classes representing path behavior
+traits, and defines two classes that satisfy those requirements for paths based
+on <code>string</code> and <code>wstring</code>.. It also defines several path
+additional path traits structure templates, and defines several specializations
+of them.</p>
+<p>Class template <code>basic_path</code> defined in this clause requires additional
+types, values, and behavior to complete the definition of its semantics.</p>
+<p>For purposes of exposition, Traits behaves as if it is a class with private
+members bool m_locked, initialized false, and std::locale m_locale, initialized </p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="50%" align="center" colspan="2"><b><i>
+ <a name="Path-Behavior-Traits-Requirements">Path Behavior Traits
+ Requirements</a></i></b></td>
+ </tr>
+ <tr>
+ <td width="38%" align="center"><b><i>Expression</i></b></td>
+ <td width="62%" align="center"><b><i>Requirements</i></b></td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::external_string_type</code></td>
+ <td width="62%">A typedef which is a specialization of <code>basic_string</code>.
+ The <code>value_type</code> is a character type used by the operating system
+ to represent pathnames.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::internal_string_type</code></td>
+ <td width="62%">A typedef which is a specialization of <code>basic_string</code>.
+ The <code>value_type</code> is a character type to be used by the program to
+ represent pathnames. Required be the same type as the <code>basic_path
+ String</code> template parameter. </td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::to_external( p, is )</code></td>
+ <td width="62%"><code>is</code>, converted by the <code>m_locale</code>
+ <code>codecvt</code> facet to <code>external_string_type</code>.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::to_internal( p, xs )</code></td>
+ <td width="62%"><code>xs</code>, converted by the <code>m_locale</code>
+ <code>codecvt</code> facet to to <code>internal_string_type</code>.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::imbue(loc)</code></td>
+ <td width="62%"><i>Effects:</i> if <code>m_locked</code>, throw. Otherwise,
+ <code>m_locked = true; m_locale = loc;<br>
+ </code><i>Returns:</i> <code>void</code><b><br>
+ </b><i>Throws:</i> <code>basic_filesystem_error</code></td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::imbue(loc, std::nothrow)</code></td>
+ <td width="62%"><i>Effects:</i> <code>if (!m_locked) m_locale = loc; bool
+ temp(m_locked); m_locked = true;<br>
+ </code><i>Returns:</i> <code>temp</code></td>
+ </tr>
+</table>
+<p>Type <code>is_basic_path</code> shall be a <i>UnaryTypeTrait</i> (TR1, 4.1).
+The primary template shall be derived directly or indirectly from <code>
+std::tr1::false_type</code>. Type <code>is_basic_path</code> shall be
+specialized for <code>path</code>, <code>wpath</code>, and any
+user-specialized <code>basic_path</code> types, and such specializations shall
+be derived directly or indirectly from <code>std::tr1::true_type</code>.</p>
+<p>Structure templates <code>slash</code>, <code>dot</code>, and <code>
+<span style="background-color: #FFFFFF">colon</span></code><span style="background-color: #FFFFFF">
+</span>are supplied with
+values of type <code>char</code>. If a user-specialized <code>basic_path</code>
+has a <code>
+value_type</code> type which is not convertible from <code>char</code>, the
+templates <code>slash</code> and <code>dot</code> shall be specialized to
+provide <code>value</code> with type which is convertible to <code>
+basic_path::value_type</code>.</p>
+<h3><a name="Class-template-basic_path">Class template <code>basic_path</code></a></h3>
+<p>Class template <code>basic_path</code> provides a portable mechanism for
+representing paths in C++ programs, using a portable generic
+pathname grammar. When portability is not a
+requirement, native file system specific formats can be used. Class template
+<code>basic_path</code> is concerned only with the lexical and syntactic aspects
+of a path. The path does not have to exist in the operating system's file
+system, and may contain names which are not even valid for the current operating
+system. </p>
+<blockquote>
+ <p>[<i>Note: </i>If the library's functions trafficked only in C++<i> </i>or
+ C-style strings, they would provide only the illusion of portability since
+ while the syntax of function calls would be portable, the semantics of the
+ strings they operate on would not be portable. <i>-- end note</i>]</p>
+</blockquote>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class String, class Traits> class basic_path
+ {
+ public:
+ typedef basic_path<String, Traits> path_type;
+ typedef String string_type;
+ typedef typename String::value_type value_type;
+ typedef Traits traits_type;
+ typedef typename Traits::external_string_type external_string_type;
+
+ // constructors/destructor
+ basic_path();
+ basic_path(const basic_path& p);
+ basic_path(const string_type& s);
+ basic_path(const value_type* s);
+ template <class InputIterator>
+ basic_path(InputIterator first, InputIterator last);
+
+ ~basic_path();
+
+ // assignments
+ basic_path& operator=(const basic_path& p);
+ basic_path& operator=(const string_type& s);
+ basic_path& operator=(const value_type* s);
+ template <class InputIterator>
+ basic_path& assign(InputIterator first, InputIterator last);
+
+ // modifiers
+ basic_path& operator/=(const basic_path& rhs);
+ basic_path& operator/=(const string_type& s);
+ basic_path& operator/=(const value_type* s);
+ template <class InputIterator>
+ basic_path& append(InputIterator first, InputIterator last);
+
+ <span style="background-color: #FFFFFF">void clear();
+ void swap( basic_path & rhs );</span>
+ basic_path& remove_leaf();
+
+ // observers
+ const string_type string() const;
+ const string_type file_string() const;
+ const string_type directory_string() const;
+
+ const external_string_type external_file_string() const;
+ const external_string_type external_directory_string() const;
+
+ string_type root_name() const;
+ string_type root_directory() const;
+ basic_path root_path() const;
+ basic_path relative_path() const;
+ string_type leaf() const;
+ basic_path branch_path() const;
+
+ bool empty() const;
+ bool is_complete() const;
+ bool has_root_name() const;
+ bool has_root_directory() const;
+ bool has_root_path() const;
+ bool has_relative_path() const;
+ bool has_leaf() const;
+ bool has_branch_path() const;
+
+ // iterators
+ class iterator;
+ typedef iterator const_iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ };
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>A <code>basic_path</code> object stores a possibly empty path.
+The internal form of the stored path is unspecified.</p>
+<p><a name="pathname-resolution">Functions</a> described in this clause which access files or their attributes do so by
+resolving a <code>basic_path</code> object into a particular file in a file
+hierarchy. The pathname, suitably converted to the string type, format, and
+encoding
+required by the operating system, is resolved as if by the <i>POSIX</i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a> mechanism. The encoding of the resulting pathname is determined by the <code>Traits::to_external</code> conversion function.</p>
+<blockquote>
+<p>[<i>Note:</i> There is no guarantee that the path stored in a <code>basic_path</code>
+object is valid for a particular operating system or file system. <i>-- end note</i>]</p>
+</blockquote>
+<p>Some functions in this clause return <code>basic_path</code> objects for
+paths composed partly or wholly of pathnames obtained from the operating system.
+Such pathnames are suitably converted from the actual format and string
+type supplied by the operating system. The encoding of the resulting path is determined by the <code>Traits::to_internal</code> conversion function.</p>
+<p>For member functions described as returning "<code>const string_type</code>" or
+"<code>const external_string_type</code>", implementations are permitted to return
+"<code>const string_type&</code>" or "<code>const external_string_type&</code>"
+respectively.</p>
+<blockquote>
+<p>[<i>Note:</i> This allows implementations to avoid unnecessary copies.
+Return-by-value is specified as
+<code>const</code> to ensure programs won't break if moved to a return-by-reference
+implementation. <i>--
+end note</i>]</p>
+</blockquote>
+<h4><a name="Pathname-formats">Pathname formats</a></h4>
+<p>There are two formats for string or sequence arguments that describe a
+path:</p>
+<ul>
+ <li>The portable pathname format as described in <a href="#Pathname-grammar">
+ Pathname grammar</a> and by the <i>POSIX</i> <i>Filename,
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266">
+Pathname</a> </i>and<i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a></i> definitions.<blockquote>
+<p>[<i>Note:</i> <span style="background-color: #FFFFFF">The <i>POSIX</i> format
+is the basis for the portable format because it is already an ISO standard, is
+the basis for the ubiquitous <i>URL</i> format, and is the native format or a
+subset of the native format for <i>UNIX</i>-like and <i>Windows</i>-like
+operating systems familiar to large numbers of programmers. </span></p>
+<p>Use of the portable format does not alone guarantee
+portability; filenames must also be portable.<span style="background-color: #FFFFFF">
+See Filename conversions. Each operating system
+
+follows its own rules. Use of the portable format
+does not change that. </span> <i>-- end note</i>]</p>
+ </blockquote>
+ </li>
+ <li>A native pathname format
+ as defined by the operating system.<blockquote>
+ <p>[<i>Note:</i> If an operating system supports only the <i>POSIX</i>
+ pathname format, the portable format and the native format are the same. </p>
+ <p><span style="background-color: #FFFFFF">Identifying user-provided paths
+ as native format is a common need, and ensures maximum portability, even
+ though not strictly needed except on systems where the native format
+ is not implicitly recognized.</span></p>
+ <p><span style="background-color: #FFFFFF">Programs using hard-coding native
+ formats are likely to be non-portable. --</span><i><span style="background-color: #FFFFFF"> end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+ </li>
+</ul>
+<p><span style="background-color: #FFFFFF">All <code>basic_path</code> string or sequence arguments that describe a
+path shall accept the portable pathname format, and shall accept the native
+format if explicitly identified by a native format escape sequence prefix of
+<code>slash slash colon</code>.</span></p>
+<blockquote>
+ <p><span style="background-color: #FFFFFF">[<i>Note:</i> <code>slash
+ slash colon</code> was chosen as the escape sequence because a leading <code>
+ slash slash</code> is already implementation-defined by POSIX, <code>
+ colon</code> is prohibited in a Windows filename, and on any system a single
+ <code>slash</code> can be used when a filename beginning with a <code>colon</code>
+ is desired. These factors eliminate the chance of collision with a real
+ filename. --</span><i><span style="background-color: #FFFFFF"> end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<p><span style="background-color: #FFFFFF">Implementations are encouraged to
+implicitly recognize the native pathname format if it can be lexically
+identified. An implementation </span>shall document whether or
+not the native pathname format is <span style="background-color: #FFFFFF">
+implicitly recognized</span>.</p>
+<blockquote>
+<p>[<i>Example:</i></p>
+<p><i>-- OpenVMS:</i> <code>"SYS1::DISK1:[JANE.TYLER.HARRY]</code>" is treated
+as a native pathname with a system name, drive name, and three directory
+filenames, rather than a portable pathname with one filename.</p>
+<p><i>-- Windows: </i><code>"c:\\jane\\tyler\\harry"</code> is treated as a
+native pathname with a drive letter, root-directory, and three filenames, rather
+than a portable pathname with one filename.</p>
+<p><i>-- Counter-example 1:</i> An operating system that allows slashes in
+filenames and uses dot as a directory separator. Distinguishing between portable
+and native format argument strings or sequences is not possible as there is no
+other distinguishing syntax. The implementation does not accept native format
+pathnames unless the <code>native</code> argument is present.</p>
+<p><i>-- Counter-example 2:</i> An operating system that allows slashes in
+filenames and uses some unusual character as a directory separator. The
+implementation does accept native format pathnames without the additional <code>
+native</code> argument, which only has to be used for native format arguments
+containing slashes in filenames.</p>
+<p><i>-- end example</i>]</p>
+<p>[<i>Note:</i> This <i><a name="duck-rule">duck-rule</a></i> ("if it looks
+like a duck, walks like a duck, and quacks like a duck, it must be a duck")
+eliminates format confusion as a source of programmer error and support
+requests. <i>-- end note</i>]</p>
+</blockquote>
+<p>If both the portable and native formats are accepted, implementations shall
+document what characters or character sequences are used to distinguish between
+portable and native formats.</p>
+<blockquote>
+<p>[<i>Note:</i> <i>Windows</i> implementations are encouraged to define colons
+and backslashes as the characters which distinguish native from portable
+formats. <i>--end note</i>]</p>
+</blockquote>
+<h4><a name="Pathname-grammar">Pathname grammar</a></h4>
+<p>The grammar for the portable pathname format is as follows:</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>
+<p><i>root-directory:<br>
+ slash<br>
+
+root-directory slash<br>
+
+implementation-defined</i></p>
+<p><i>relative-path:<br>
+
+filename<br>
+ relative-path
+slash<br>
+ relative-path
+slash filename</i></p>
+<p><i>filename:<br>
+ name<br>
+ dot<br>
+ dot dot</i></p>
+<p><i>slash:<br>
+ <code>
+slash<Path>::value</code></i></p>
+<p><i>dot:<br>
+ <code>
+dot<Path>::value</code></i></p>
+</blockquote>
+<p>The grammar is aligned with the <i>POSIX </i> <i>Filename,
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266">
+Pathname</a> </i>and<i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a></i> definitions. Any conflict between the grammar and <i>
+POSIX</i> is unintentional. This technical report defers to <i>POSIX</i>.</p>
+<blockquote>
+<p><span style="background-color: #E0E0E0"><i>The form of the above wording was taken
+from POSIX, which uses it in several places to defer to the C standard.</i></span></p>
+<p>[<i>Note: Windows</i> implementations are encouraged to define <i>slash slash
+name</i> as a permissible <i>root-name</i>. <i>POSIX</i> permits, but does not
+require, implementations to do the same. <i>Windows</i> implementations are
+encouraged to define an additional <i>root-directory</i> element <i>
+root_directory name.</i> It is applicable only to the <i>slash slash name</i>
+form of <i>root-name.</i></p>
+<p> <i>Windows</i> implementations are encouraged to recognize a <i>name</i>
+followed by a colon as a native format <i>root-name</i>,
+and a backslash as a format element equivalent to <i>slash</i>. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="Filename-conversion">Filename conversion</a></h4>
+<p>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.</p>
+<blockquote>
+<p>[<i>Note:</i> Filename conversion allows much wider portability of both
+programs and filenames that would otherwise be possible.</p>
+<p>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
+<i>OpenVMS</i>, 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.<i> -- end note.</i>]</p>
+<p><span style="background-color: #E0E0E0"><i>The Boost implementation for
+Windows currently does not map invalid characters. Pending feedback from the LWG,
+Boost may settle on % hex hex as the preferred escape sequence. If so, should
+there be normative encouragement?</i></span></p>
+</blockquote>
+<h4><a name="basic_path-requirements">Requirements</a></h4>
+<p>The argument for the template parameter named <code>String</code> shall be a
+class that includes members with the same names, types, values, and semantics as
+class template <code>basic_string</code>.</p>
+<p>The argument for the template parameter named <code>Traits</code> shall be a
+class that satisfies the requirements specified in the
+Path Behavior Traits Requirements
+table.</p>
+<p>The argument for template parameters named <code>InputIterator</code> shall satisfy the
+requirements of an input iterator (C++ Std, 24.1.1, Input iterators [lib.input.iterators]) and shall have a value type convertible to
+<code>basic_path::value_type</code>. </p>
+<p>Some function templates with a template
+parameter named <code>InputIterator</code> also have non-template overloads. Implementations shall
+only select the function template overload if the type named by <code>InputIterator</code>
+is not <code>path_format_t</code>.</p>
+<blockquote>
+<p>[<i>Note:</i> This "do-the-right-thing" rule ensures that the
+overload expected by the user is selected. The implementation technique is unspecified -
+implementations may use
+enable_if or
+other techniques to achieve the effect. <i>-- end note</i>]</p>
+</blockquote>
+<h4> <a name="basic_path-constructors"> <code>basic_path</code> constructors</a></h4>
+<pre>basic_path();</pre>
+<blockquote>
+ <p><i>Postconditions:</i> <code>empty()</code>.</p>
+ </blockquote>
+<pre>basic_path(const string_type& s);
+basic_path(const value_type * s);
+template <class InputIterator>
+ basic_path(InputIterator s, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+ <p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are stored.</p>
+</blockquote>
+<h4> <a name="basic_path-assignments"> <code>basic_path</code> assignments</a></h4>
+<pre>basic_path& operator=(const string_type& s);
+basic_path& operator=(const value_type* s);
+template <class InputIterator>
+ basic_path& assign(InputIterator first, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+ <p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are stored.</p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<h4> <a name="basic_path-modifiers"> <code>basic_path</code> modifiers</a></h4>
+<pre>basic_path& operator/=(const basic_path& rhs);</pre>
+<blockquote>
+ <p><i>Effects:</i> The path stored in <code>rhs</code> is appended to the
+ stored path.</p>
+ <p><i>Returns:</i> <code>*this</code></p>
+</blockquote>
+<pre>basic_path& operator/=(const string_type& s);
+basic_path& operator/=(const value_type* s);
+template <class InputIterator>
+basic_path& append(InputIterator first, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+<p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are appended to the stored path.</p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<pre>void clear();</pre>
+<blockquote>
+<p><i>Postcondition:</i> <code>this->empty()</code> is true.</p>
+</blockquote>
+<pre><code><span style="background-color: #FFFFFF">void swap( basic_path & rhs );</span></code></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ Swaps the contents of the two paths.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Throws: </span></i>
+ <span style="background-color: #FFFFFF">nothing.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i><span style="background-color: #FFFFFF">
+ </span><code><span style="background-color: #FFFFFF">this->string()</span></code><span style="background-color: #FFFFFF">
+ contains the same sequence of characters that were in </span><code><span style="background-color: #FFFFFF">
+ rhs.string()</span></code><span style="background-color: #FFFFFF">, </span><code><span style="background-color: #FFFFFF">
+ rhs.string()</span></code><span style="background-color: #FFFFFF">
+ contains the same sequence of characters that were is </span><code>
+ <span style="background-color: #FFFFFF">this->string()</span></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Complexity: </span></i>
+ <span style="background-color: #FFFFFF">constant time.</span></p>
+</blockquote>
+<pre>basic_path& remove_leaf();</pre>
+<blockquote>
+ <p><i>Effects:</i> If <code>has_branch_path()</code> then remove the last <i>filename</i> from the stored path. If that leaves
+ the stored path with one or more trailing <i>slash</i> elements not
+ representing <i>root-directory</i>, remove them.</p>
+ <p><i>Returns:</i> <code>*this</code></p>
+ <p>[<i>Note:</i> This function is needed to efficiently implement <code>
+ basic_directory_iterator</code>. It is made public to allow additional uses. <i>-- end
+ note</i>]</p>
+</blockquote>
+<h4> <a name="basic_path-observers"> <code>basic_path</code> observers</a></h4>
+<blockquote>
+<p><span style="background-color: #E0E0E0"><i>See the
+Path decomposition table for examples
+for values returned by decomposition functions.</i></span></p>
+</blockquote>
+<pre>const string_type string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+Pathname grammar rules.</p>
+</blockquote>
+<pre>const string_type file_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for regular file pathnames, with any
+Filename conversion applied.</p>
+<p>[<i>Note:</i> For some operating systems, including <i>POSIX</i> and <i>
+Windows</i>, the native format for regular file pathnames and directory
+pathnames is the same, so <code>file_string()</code> and <code>directory_string()</code>
+return the same string. On OpenMVS, however, the expression <code>path("/cats/jane").file_string()</code>
+would return the string <code>"[CATS]JANE"</code> while <code>path("/cats/jane").directory_string()</code>
+would return the string <code>"[CATS.JANE]"</code>. <i>-- end note</i>]</p>
+</blockquote>
+<pre>const string_type directory_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for directory pathnames, with any
+Filename conversion applied.</p>
+</blockquote>
+<pre>const external_string_type external_file_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for regular file pathnames, with any
+Filename conversion applied, and encoded by the <code>Traits::to_external</code>
+conversion function.</p>
+</blockquote>
+<pre>const external_string_type external_directory_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for directory pathnames, with any
+Filename conversion applied, and encoded by the <code>Traits::to_external</code>
+conversion function.</p>
+</blockquote>
+<pre>string_type root_name() const;</pre>
+<blockquote>
+<p><i>Returns:</i> <i>root-name,</i> if the stored path includes <i>
+root-name</i>, otherwise <code>string_type()</code>. </p>
+</blockquote>
+<pre>string_type root_directory() const;</pre>
+<blockquote>
+<p><i>Returns:</i> <i>root-directory</i>, if the stored path includes <i>
+root-directory</i>, otherwise <code>string_type()</code>.</p>
+<p>If <i>root-directory</i> is composed <i>slash name</i>, <i>slash</i> is
+excluded from the returned string.</p>
+</blockquote>
+<pre>basic_path root_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>root_name() / root_directory()</code></p>
+</blockquote>
+<pre>basic_path relative_path() const;</pre>
+<blockquote>
+<p><i>Returns:</i> A <code>basic_path</code> composed from the the stored path, if any, beginning
+with the first <i>filename</i> after <i>root-path</i>.
+Otherwise, an empty <code>basic_path</code>.</p>
+</blockquote>
+<pre>string_type leaf() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>empty() ? string_type() : *--end()</code></p>
+</blockquote>
+<pre>basic_path branch_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>(string().empty() || begin() == --end()) ? path_type("") :
+ <i>br</i></code>, where <code><i>br</i></code> is constructed as if by
+ starting with an empty <code>basic_path</code> and successively applying <code>
+ operator/=</code> for each element in the range <code>begin()</code>, <code>
+ --end()</code>.</p>
+</blockquote>
+<pre>bool empty() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>string().empty()</code>.</p>
+</blockquote>
+<pre>bool is_complete() const;</pre>
+<blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>true</code>,
+ if the elements of root_path() uniquely identify a directory, else <code>false</code>.</span></p>
+</blockquote>
+<pre>bool has_root_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_path().empty()</code></p>
+</blockquote>
+<pre>bool has_root_name() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_name().empty()</code></p>
+</blockquote>
+<pre>bool has_root_directory() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_directory().empty()</code></p>
+</blockquote>
+<pre>bool has_relative_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!relative_path().empty()</code></p>
+</blockquote>
+<pre>bool has_leaf() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!leaf().empty()</code></p>
+</blockquote>
+<pre>bool has_branch_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!branch_path().empty()</code></p>
+</blockquote>
+<h4> <a name="basic_path-iterators"> <code>basic_path</code> iterators</a></h4>
+<p> A <code>basic_path::iterator</code> is a constant iterator satisfying all
+the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional
+iterators [lib.bidirectional.iterators]). Its <code>value_type</code> is
+<code>string_type</code>.</p>
+ <p>Calling any non-const member function of a <code>basic_path</code> object
+ invalidates all iterators referring to elements of the 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.</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>
+<h4> <a name="basic_path-non-member-functions">
+<span style="background-color: #FFFFFF">basic_path non-member functions</span></a></h4>
+<pre><span style="background-color: #FFFFFF">template<class String, class Traits>
+void swap( basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs )</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects: </span></i><code>
+ <span style="background-color: #FFFFFF">lhs.swap(
+ rhs )</span></code></p>
+</blockquote>
+ <h4><span style="background-color: #FFFFFF">basic_path non-member operators</span></h4>
+ <p><span style="background-color: #FFFFFF">There are seven basic_path non-member operators (/,
+ </span> <code><span style="background-color: #FFFFFF">==</span></code><span style="background-color: #FFFFFF">,
+ </span> <code>
+ <span style="background-color: #FFFFFF">!=</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF"><</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF">></span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF"><=</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF">>=</span></code><span style="background-color: #FFFFFF">),
+ each with five overloads. For brevity, the specifications are given in tabular
+ form. Each of the resulting thirty-five signatures is a template, with
+ template parameter list template</span><code><span style="background-color: #FFFFFF"><class
+ String, class Traits></span></code><span style="background-color: #FFFFFF">.
+ The format of such arguments is described in </span> <a href="#Pathname-formats">
+ <span style="background-color: #FFFFFF">Pathname formats</span></a><span style="background-color: #FFFFFF">.</span></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="100%">
+ <p align="center"><i><b><span style="background-color: #FFFFFF">Argument type overloads</span></b></i></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>
+ basic_path<String, Traits>& a, basic_path<String, Traits>&
+ b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ typename basic_path<String, Traits>::string_type& a,
+ basic_path<String, Traits>& b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ typename basic_path<String, Traits>::string_type::value_type* a,
+ basic_path<String, Traits>& b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ basic_path<String, Traits>& a, typename basic_path<String, Traits>::string_type&
+ b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ basic_path<String, Traits>& a, typename
+ basic_path<String, Traits>::string_type::value_type* b</code></span></td>
+ </tr>
+ </table>
+ <p><span style="background-color: #FFFFFF">In the </span><b><i>
+ <span style="background-color: #FFFFFF">basic_path non-member operators </span>
+ </i></b><span style="background-color: #FFFFFF">table, </span><code>
+ <span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ and </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ are of the types given in the </span><i><b>
+ <span style="background-color: #FFFFFF">Argument type overloads</span></b></i><span style="background-color: #FFFFFF">
+ table. If </span><code><span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ or </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ is of type </span><code><span style="background-color: #FFFFFF">const
+ basic_path<String, Traits>&</span></code><span style="background-color: #FFFFFF">,
+ then </span><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i></code><span style="background-color: #FFFFFF">
+ or </span><i><b><span style="background-color: #FFFFFF">b'</span></b></i><span style="background-color: #FFFFFF">
+ respectively is </span><code><span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ or </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ respectively. Otherwise </span><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i></code><span style="background-color: #FFFFFF">
+ or </span><i><b><span style="background-color: #FFFFFF">b'</span></b></i><span style="background-color: #FFFFFF">
+ respectively represent named or unnamed temporary </span><code>
+ <span style="background-color: #FFFFFF">basic_path<String, Traits></span></code><span style="background-color: #FFFFFF">
+ objects constructed from </span><code><span style="background-color: #FFFFFF">
+ a</span></code><span style="background-color: #FFFFFF"> or </span><code>
+ <span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ respectively.</span></p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" height="280">
+ <tr>
+ <td width="100%" colspan="3" align="center" height="19"><b><i>
+ <span style="background-color: #FFFFFF">basic_path non-member operators</span></i></b></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Expression</span></b></i></td>
+ <td width="25%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Return type</span></b></i></td>
+ <td width="55%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Semantics</span></b></i></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="30" valign="top"><code>
+ <span style="background-color: #FFFFFF">a / b</span></code></td>
+ <td width="25%" align="center" height="30" valign="top"><code>
+ <span style="background-color: #FFFFFF">basic_path<String, Traits></span></code></td>
+ <td width="55%" height="30"><code><span style="background-color: #FFFFFF">
+ basic_path<String, Traits> tmp(a);<br>
+ return a /= </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">;</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a < b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return lexicographical_compare(</span></code><span style="background-color: #FFFFFF"><i><b>a</b></i></span><code><span style="background-color: #FFFFFF"><i><b>'</b></i>.begin(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">a</span></b></i><code><span style="background-color: #FFFFFF"><i><b>'</b></i>.end(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">.begin(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">.end());</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a == b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">)
+ && !(</span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a != b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ == </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a > b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">;</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a <= b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a >= b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+</table>
+ <blockquote>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ </span> <a name="Path-equality"><span style="background-color: #FFFFFF">Path equality</span></a><span style="background-color: #FFFFFF"> and path
+ equivalence have different semantics.</span></p>
+ <p><span style="background-color: #FFFFFF">Equality is determined by </span> <i>
+ <span style="background-color: #FFFFFF">basic_path</span></i><span style="background-color: #FFFFFF">'s
+ non-member </span> <code><a href="#operator-eq">
+ <span style="background-color: #FFFFFF">operator==</span></a></code><span style="background-color: #FFFFFF">, which considers the two path's lexical representations
+ only. Paths "abc" and "ABC" are never equal.</span></p>
+ <p><span style="background-color: #FFFFFF">Equivalence is determined by the
+ </span> equivalent()<span style="background-color: #FFFFFF">
+ non-member function, which determines if two paths </span>
+ resolve<span style="background-color: #FFFFFF"> to the same file system entity.
+ Paths "abc"
+ and "ABC" may or may not resolve to the same file, depending on the file
+ system.</span></p>
+ <p><span style="background-color: #FFFFFF">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. </span> <i>
+ <span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+</blockquote>
+ <h4><a name="basic_path-inserter-extractor"> <code>
+ <span style="background-color: #FFFFFF">basic_path</span></code><span style="background-color: #FFFFFF"> inserter
+ and extractor</span></a></h4>
+<pre><span style="background-color: #FFFFFF">template<class Path>
+ basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
+ operator>>(basic_istream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& is,
+ Path& ph );</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects: </span></i>
+ <code><span style="background-color: #FFFFFF">typename Path::string_type str;<br>
+
+ is >> str;<br>
+
+ ph = str;</span></code></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">is</span></code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">template<class Path>
+ basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
+ operator<<(basic_ostream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& os,
+ const Path& ph );</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">os << ph.string()</span></code></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">os</span></code></p>
+</blockquote>
+<h3><a name="Class-template-basic_filesystem_error">Class template <code>basic_filesystem_error</code></a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class Path> class basic_filesystem_error : public <span style="background-color: #FFFFFF">system</span>_error
+ {
+ public:
+ typedef Path path_type;
+
+ explicit basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, error_code ec);
+ basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, error_code ec);
+ basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, const path_type& p2, error_code ec);
+
+ const path_type& path1() const;
+ const path_type& path2() const;
+
+ const char * what() const;
+ };
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>The class template <code>basic_filesystem_error</code> defines the type of
+objects thrown as exceptions to report file system errors from functions described in this
+clause.</p>
+<h4> <a name="basic_filesystem_error-constructors"> <code>basic_filesystem_error</code> constructors</a></h4>
+<pre>explicit basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</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>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%" bgcolor="#FFFFFF"><span style="background-color: #FFFFFF">
+ <code><i>what_arg</i>.c_str()</code></span></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>basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</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>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">
+ <code><i>what_arg</i>.c_str()</code></span></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%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <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>basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, const path_type& p2, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</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>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">
+ <u>
+ <code><i>w</i></code></u><code><i>hat_arg</i>.c_str()</code></span></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%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <code>p1</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path2()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <code>p2</code></td>
+ </tr>
+ </table>
+</blockquote>
+<h4> <a name="basic_filesystem_error-observers"> <code>basic_filesystem_error</code> observers</a></h4>
+<pre>const path_type& path1() 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_type& path2() 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 * what() const;</pre>
+<blockquote>
+ <p><i>Returns: </i>A string containing <code>runtime_error::what()</code> and
+ the result of calling <code>system_message()</code> with a first argument of
+ <code>code()</code>. The exact format is unspecified.</p>
+<p>The implementation shall supply a specialization <code>template<> const char
+* basic_filesystem_error<path>::what() const</code> that returns a string
+containing <code>runtime_error::what(),</code> the result of calling <code>
+system_message()</code> with a first argument of <code>code()</code>, and if
+non-empty, <code>path1().file_string()</code> and <code>path2.file_string()</code>.
+The exact format is unspecified.</p>
+<p>Implementations and users are permitted to provide other specializations of
+the <code>what</code> member function.</p>
+</blockquote>
+<h3><a name="Class-template-basic_directory_entry">Class template <code>basic_directory_entry</code></a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class Path> class basic_directory_entry
+ {
+ public:
+ typedef Path path_type;
+ typedef typename Path::string_type string_type;
+
+ // constructors
+ basic_directory_entry();
+ explicit basic_directory_entry(const path_type& p,
+ <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+
+ // modifiers
+ void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+ void replace_leaf(const string_type& s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+
+ // observers
+ const Path& path() const;
+ operator const Path&() const;
+<span style="background-color: #FFFFFF">
+ file_status status() const;
+ file_status status(error_code& ec) const;
+ file_status symlink_status() const;
+ file_status symlink_status(error_code& ec) const;
+</span><span style="background-color: #FFFF00">
+</span> // comparisons
+ bool operator<(const basic_directory_entry<Path>& rhs);
+ bool operator==(const basic_directory_entry<Path>& rhs);
+ bool operator!=(const basic_directory_entry<Path>& rhs);
+ bool operator>(const basic_directory_entry<Path>& rhs);
+ bool operator<=(const basic_directory_entry<Path>& rhs);
+ bool operator>=(const basic_directory_entry<Path>& rhs);
+
+ private:
+ path_type m_path; // for exposition only
+ mutable <span style="background-color: #FFFFFF">file_status</span> m_status; // for exposition only; stat()-like
+ mutable <span style="background-color: #FFFFFF">file_status</span> m_symlink_status; // for exposition only; lstat()-like
+ };
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>A <code>basic_directory_entry</code> object stores a <code>basic_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 race conditions. <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 speedup expected on Linux and BSD-derived
+Unix variants that provide status during directory iteration.</i></span></p>
+</blockquote>
+<h4> <a name="basic_directory_entry-constructors"> <code>basic_directory_entry </code>constructors</a></h4>
+<pre>basic_directory_entry();</pre>
+<blockquote>
+ <p><i>Postconditions:</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 basic_directory_entry(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</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="basic_directory_entry-modifiers"> <code>basic_directory_entry </code>modifiers</a></h4>
+<pre>void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</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_leaf(const string_type& s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</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="basic_directory_entry-observers"> <code>basic_directory_entry</code> observers</a></h4>
+<pre>const Path& path() const;
+operator const Path&() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>m_path</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status status() const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">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); }
+}</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Throws:</i> See <code>status</code>
+ function.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status status(error_code& ec) const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">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, ec); }
+}
+else ec = 0;</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status symlink_status() const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_symlink_status ) )
+{
+ m_symlink_status = symlink_status(m_path);
+}</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Throws:</i> See <code>symlink_status</code>
+ function.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>
+ m_symlink_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status symlink_status(error_code& ec) const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_symlink_status ) )
+{
+ m_symlink_status = symlink_status(m_path, ec);
+}
+else ec = 0;</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_symlink_status</code></span></p>
+</blockquote>
+<h3><a name="Class-template-basic_directory_iterator">Class template <code>basic_directory_iterator</code></a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class Path>
+ class basic_directory_iterator :
+ public iterator<input_iterator_tag, basic_directory_entry<Path> >
+ {
+ public:
+ typedef Path path_type;
+
+ // constructors
+ basic_directory_iterator();
+ explicit basic_directory_iterator(const Path& dp);
+ basic_directory_iterator(const Path& dp, error_code& ec);
+ basic_directory_iterator(const basic_directory_iterator& bdi);
+ basic_directory_iterator& operator=(const basic_directory_iterator& bdi);
+ ~basic_directory_iterator();
+
+ // other members as required by
+ // C++ Std, 24.1.1 Input iterators [lib.input.iterators]
+ };
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p> <code>basic_directory_iterator</code> satisfies the requirements of an
+input iterator (C++ Std, 24.1.1, Input iterators [lib.input.iterators]).</p>
+<p>A <code>basic_directory_iterator</code> reads successive elements from the directory for
+which it was constructed, as if by calling <i>POSIX</i>
+<code>
+readdir_r()</code>. After a <code>basic_directory_iterator</code> is constructed, and every time
+<code>operator++</code> is called,
+it reads and stores a value of <code>basic_directory_entry<Path></code>
+and possibly stores associated status values.
+<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 be used only 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>basic_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 basic_directory_entry<Path>&</code> is returned. The result of
+<code>operator-></code> on an end iterator is not defined. For any other
+iterator value a <code>const basic_directory_entry<Path>*</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. Commentary was shortened and
+moved into a note.</span></i></p>
+</blockquote>
+<p>The result of calling the <code>path()</code> member of the <code>
+basic_directory_entry</code> object obtained by dereferencing a <code>
+basic_directory_iterator</code> is a reference to a <code>basic_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>
+<blockquote>
+<p>[<i><a name="Example-program">Example</a>: </i>This program accepts an
+optional command line argument, and if that argument is a directory pathname,
+iterates over the contents of the directory. For each directory entry, the name
+is output, and if the entry is for a regular file, the size of the file is
+output.</p>
+ <blockquote>
+ <pre>#include <iostream>
+#include <filesystem>
+
+using std::tr2::sys;
+using std::cout;
+
+int main(int argc, char* argv[])
+{
+ std::string p(argc <= 1 ? "." : argv[1]);
+
+ if (is_directory(p))
+ {
+ for (directory_iterator itr(p); itr!=directory_iterator(); ++itr)
+ {
+ cout << itr->path().leaf() << ' '; // display filename only
+ if (is_regular(itr->status())) cout << " [" << file_size(itr->path()) << ']';
+ cout << '\n';
+ }
+ }
+ else cout << (exists(p) : "Found: " : "Not found: ") << p << '\n';
+
+ return 0;
+}</pre>
+ </blockquote>
+ <p><i>-- end example</i>]</p>
+</blockquote>
+<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>basic_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>basic_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>POSIX</i>
+<code>
+readdir_r()</code>. <i>
+--end note</i>]</p>
+</blockquote>
+<h4><a name="basic_directory_iterator-constructors"><code>basic_directory_iterator</code> constructors</a></h4>
+
+<p><code>basic_directory_iterator();</code></p>
+
+<blockquote>
+
+<p><i>Effects:</i> Constructs the end iterator.</p>
+
+</blockquote>
+
+<p><code>explicit basic_directory_iterator(const Path& dp);</code></p>
+
+<blockquote>
+
+<p><i>Effects:</i> Constructs a iterator representing the first
+entry in the directory resolved to by <code>dp</code>, otherwise, the end iterator.</p>
+
+<p>[<i>Note:</i> To iterate over the current directory, write <code>
+directory_iterator(".")</code> rather than <code>directory_iterator("")</code>.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre><code>basic_directory_iterator(const Path& dp, error_code& ec );</code></pre>
+<blockquote>
+
+<p><i>Effects:</i> Constructs a iterator representing the first
+entry in the directory resolved to by <code>dp</code>, otherwise, the end iterator.
+If an error occurs while establishing the results, the iterator constructed
+represents the end iterator and <code>ec</code> is set to the error code
+reported by the operating system, otherwise to 0.</p>
+
+</blockquote>
+<h3><a name="Class-template-basic_recursive_directory_iterator">Class template <code>basic_recursive_directory_iterator</code></a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ template <class Path>
+ class basic_recursive_directory_iterator :
+ public iterator<input_iterator_tag, basic_directory_entry<Path> >
+ {
+ public:
+ typedef Path path_type;
+
+ // constructors
+ basic_recursive_directory_iterator();
+ explicit basic_recursive_directory_iterator(const Path& dp);
+ basic_recursive_directory_iterator(const basic_recursive_directory_iterator& brdi);
+ basic_recursive_directory_iterator& operator=(const basic_recursive_directory_iterator& brdi);
+ ~basic_recursive_directory_iterator();
+
+ // observers
+ int level() const;
+
+ // modifiers
+ void pop();
+ void no_push();
+
+ // other members as required by
+ // C++ Std, 24.1.1 Input iterators [lib.input.iterators]
+
+ private:
+ int m_level; // for exposition only
+ };
+
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>The behavior of a <code>basic_recursive_directory_iterator</code> is the same
+as a <code>basic_directory_iterator</code> unless otherwise specified.</p>
+<ul>
+ <li>When an iterator is constructed, <code>m_level</code> is set to 0;</li>
+ <li>When an iterator <code>it</code> is incremented, if <code>it->is_directory()</code>
+ is true and <code>no_push()</code> had not been called subsequent to
+ the most recent increment operation (or construction, if no increment has
+ occurred), then <code>m_level</code> is incremented, the
+ directory is visited, and its contents recursively iterated over.</li>
+ <li>When an iterator 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 continues with the parent directory, until the
+ directory specified in the constructor argument is reached.</li>
+ <li><code>level()</code> returns <code>m_level</code>.</li>
+ <li><code>level()</code>, <code>pop()</code>, and <code>no_push()</code> all
+ require that the iterator not be the end iterator.</li>
+</ul>
+<blockquote>
+ <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent
+ unwanted recursion into symlinked directories. This may be necessary to
+ prevent loops on some operating systems. <i>--end note</i>]</p>
+</blockquote>
+<h3><a name="file_status">Class file_status</a></h3>
+<pre>namespace std
+{
+ namespace tr2
+ {
+ namespace sys
+ {
+ class file_status
+ {
+ public:
+ explicit file_status( file_type v = status_unknown );
+
+ file_type type() const;
+ void type( file_type v );
+ };
+ } // namespace sys
+ } // namespace tr2
+} // namespace std</pre>
+<p>A <code>file_status</code> object stores information about the status of a
+file. The internal form of the stored information is unspecified.</p>
+<blockquote>
+ <p><i>[Note: </i>The class may be extended in the future to store
+ additional status information. <i>--end note]</i></p>
+</blockquote>
+<h4>Members</h4>
+<pre>explicit file_status( file_type v = status_unknown );</pre>
+<blockquote>
+ <p><i>Effects:</i> Stores <code>v</code>.</p>
+</blockquote>
+<pre>file_type type() const;</pre>
+<blockquote>
+ <p><i>Returns: </i>The stored <code>file_type</code>.</p>
+</blockquote>
+<pre>void type( file_type v );</pre>
+<blockquote>
+ <p><i>Effects:</i> Stores <code>v</code>, replacing the previously stored
+ value.</p>
+</blockquote>
+<h3><a name="Non-member-functions">Non-member operational functions</a></h3>
+<h4><a name="Status-functions">Status functions</a></h4>
+<pre>template <class Path> file_status status(const Path& p, error_code& ec);
+template <class Path> file_status symlink_status(const Path& p, error_code& ec);</pre>
+<blockquote>
+ <p><i>Returns:</i></p>
+ <blockquote>
+ For <code>status,</code> determine the attributes
+ of
+ <code>p</code> as if by<i> POSIX </i> <code>
+ stat()</code>,
+ for <code>symlink_status</code> determine the attributes as if by <i>POSIX </i> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html">
+ lstat()</a></code>.<blockquote>
+ <p>[<i>Note:</i> For symbolic links, <code>stat()</code> continues
+ pathname resolution using the contents of the symbolic link, <code>lstat()</code>
+ does not. <i>--
+ end note</i>]</p>
+ </blockquote>
+ <p>If the operating system reports an error during attribute determination:</p>
+ <ul>
+ <li>If the error indicating that <code>p</code> could not
+ be resolved, as if by POSIX error codes ENOENT or ENOTDIR, set ec to 0 and return <code>
+ file_status(not_found_flag)</code>.</li>
+ </ul>
+ <ul>
+ <li>Otherwise, set ec to the error code reported by the operating system
+ and return <code>
+ file_status(status_unknown)</code>.</li>
+ </ul>
+ Otherwise:<ul>
+ <li>If the attributes indicate a regular file, as if by <i>POSIX</i> S_ISREG(),
+ return <code>
+ file_status(regular_file)</code>.</li>
+ <li>Else if the attributes indicate a directory, as if by <i>POSIX</i> S_ISDIR(),
+ return <code>
+ file_status(directory_file)</code>.</li>
+ <li>Else if the attributes indicate a symbolic link, as if by <i>POSIX</i> S_ISLNK(),
+ return <code>
+ file_status(symlink_file)</code>. <i>[Note: </i>Only possible for <code>
+ symlink_status</code>. <i>--end note]</i></li>
+ <li>Else if the attributes indicate a block special file, as if by <i>POSIX</i> S_ISBLK(),
+ return <code>
+ file_status(block_file)</code>.</li>
+ <li>Else if the attributes indicate a character special file, as if by <i>POSIX</i> S_ISCHR(),
+ return <code>
+ file_status(character_file)</code>.</li>
+ <li>Else if the attributes indicate a fifo or pipe file, as if by <i>POSIX</i> S_ISFIFO(),
+ return <code>
+ file_status(fifo_file)</code>.</li>
+ <li>Else if the attributes indicate a socket, as if by <i>POSIX</i> S_ISSOCK(),
+ return <code>
+ file_status(socket_file)</code>.</li>
+ <li>Else return <code>
+ file_status(type_unknown)</code>.</li>
+ </ul>
+ </blockquote>
+<p>[<i>Note:</i> <code>directory_file</code> implies <code>
+basic_directory_iterator</code> on the file would succeed, and <code>
+regular_file</code> implies appropriate <code><fstream></code> operations would succeed,
+assuming no hardware, permission, access, or race
+condition errors. For <code>regular_file,</code> the converse is not true; lack of
+<code>regular_file</code> does not necessarily imply <code><fstream></code> operations would
+fail on a directory.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path> file_status status(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> <code>system_error_code ec;</code><br>
+
+ <code>file_status stat(status(p, ec));</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>ec
+ != 0</code></p>
+ <p><i>Returns:</i> <code>stat</code></p>
+</blockquote>
+<pre>template <class Path> file_status symlink_status(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> <code>system_error_code ec;</code><br>
+
+ <code>file_status stat(symlink_status(p, ec));</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>ec
+ != 0</code></p>
+ <p><i>Returns: </i><code>stat</code></p>
+</blockquote>
+<h4><a name="Predicate-functions">Predicate functions</a></h4>
+<pre><span style="background-color: #FFFFFF">bool status_known(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>s.type() != status_unknown</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><a name="exists"><span style="background-color: #FFFFFF">exists</span></a><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>status_known(s) && s.type() != file_not_found</code></span></p>
+</blockquote>
+<pre>template <class Path> bool <a name="exists">exists</a>(const Path& p);</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>exists( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><code><span style="background-color: #FFFFFF">is_regular</span></code><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>s.type() == regular_file</code></span></p>
+</blockquote>
+<pre><code>template <class Path> bool is_regular(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_regular( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><code><span style="background-color: #FFFFFF">is_directory</span></code><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> </span>
+ <code><span style="background-color: #FFFFFF">s.type() == directory_file</span></code></p>
+</blockquote>
+<pre><code>template <class Path> bool is_directory(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_directory( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool <a name="exists">is_symlink</a>(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> </span>
+ <code><span style="background-color: #FFFFFF">s.type() == symlink_file</span></code></p>
+</blockquote>
+<pre><code>template <class Path> bool is_symlink(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_symlink( symlink_status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool <a name="exists">is_other</a>(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>return exists(s) && !is_regular(s) && !is_directory(s) && !is_symlink(s)</code></span></p>
+ <p><span style="background-color: #FFFFFF">[<i>Note: </i>The specification of
+ <code>is_other()</code> will remain unchanged even if additional <code>is_xxx()</code>
+ functions are added in the future. <i>-- end note</i>]</span></p>
+</blockquote>
+<pre><code>template <class Path> bool is_other(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_other( status(p) )</code></p>
+</blockquote>
+<pre><code>template <class Path> bool <span style="background-color: #FFFFFF; text-decoration:underline">is_</span>empty(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Effects:</i> Determines <code>file_status s</code>, as if by <code>
+ status(p)</code>.</p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>!exist(s) ||
+ is_other(s)</code>.</p>
+ <p><i>Returns:</i> <code>is_directory(s)<br>
+ ?
+ basic_directory_iterator<Path>(p) == basic_directory_iterator<Path>()<br>
+ : file_size(p) == 0;</code></p>
+</blockquote>
+<pre><code>template <class Path1, class Path2> bool <a name="equivalent">equivalent</a>(const Path1& p1, const Path2& p2);</code></pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <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>Throws:</i> <code>basic_filesystem_error<Path1></code><span style="background-color: #FFFFFF"> </span>
+ if <code>(!exists(s1) && !exists(s2)) || (is_other(s1) &&
+ is_other(s2))</code>.</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>
+ <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>POSIX</i> <code>
+ stat</code>
+ structure<code>,</code> obtained as if by <code>
+ stat()</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>POSIX</i> requires that <i>"st_dev</i> must be unique
+ within a Local Area Network". Conservative <i>POSIX</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>
+<h4><a name="Attribute-functions">Attribute functions</a></h4>
+<p>[<i>Note:</i> A strictly limited number of attribute functions are provided
+because few file system attributes are portable. Even the functions provided will be impossible to implement on some file
+systems. <i>--end note</i>.]</p>
+<pre>template <class Path> const Path& <a name="initial_path">initial_path</a>();</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>current_path()</code> at the time of entry to <code>
+ main()</code>.</p>
+ <p>[<i>Note:</i> These semantics turn a dangerous global variable into a safer
+ global constant. <i>--end note</i>]</p>
+ <p>[<i>Note:</i> Full implementation requires runtime library support.
+ Implementations which cannot provide runtime library support are encouraged to
+ instead store the value of <code>current_path()</code> at the first call of
+ <a name="initial_path"><code>initial_path</code></a><code>()</code>, and
+ return this value for all subsequent calls. Programs using
+ <a name="initial_path"><code>initial_path</code></a><code>()</code> are
+ encouraged to call it immediately on entrance to <code>main()</code> so that
+ they will work correctly with such partial implementations. <i>--end note</i>]</p>
+</blockquote>
+<pre>template <class Path> Path current_path();</pre>
+<blockquote>
+ <p><i>Returns:</i> The current path, as if by <i>POSIX</i>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/getcwd.html">
+ <code>getcwd()</code></a>.</p>
+ <p><i>Postcondition:</i> <code>current_path().is_complete()</code></p>
+ <p>[<i>Note:</i> 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. Although dangerous, the
+ function is useful in dealing with other libraries.. For a safer alternative,
+ see <code>initial_path()</code>. The <code>
+ current_path()</code> name was chosen to emphasize that the return is a
+ complete path, not just a single directory name. <i>-- </i><i>end note</i>]</p>
+</blockquote>
+<pre>template <class Path> <span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const Path& p);</pre>
+<blockquote>
+ <p><i>Returns:</i> The size
+ <span style="background-color: #FFFFFF; ">in bytes</span>
+ of the file <code>p</code> resolves to, determined as if by the value of
+ the <i>POSIX</i> <code>
+ stat</code> structure member <code>st_size</code>
+ obtained as if by <i>POSIX</i> <code>
+ stat()</code>.</p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF"><a name="space">template</a> <class Path> space_info space(const Path& p);</span></pre>
+<blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> A <code>space_info</code>
+ object. The value of the <code>space_info</code> object is determined as if by
+ using </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF"> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/statvfs.html" style="text-decoration: none">
+ statvfs()</a></code> to obtain a <i>POSIX</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.</span></p>
+</blockquote>
+<pre>template <class Path> std::time_t last_write_time(const Path& p);</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>POSIX</i> <code>
+ stat</code> structure member <code>st_mtime</code> obtained
+ as if by <i>POSIX</i> <code>
+ stat()</code>.</p>
+</blockquote>
+<pre>template <class Path> void last_write_time(const Path& p, const std::time_t new_time);</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>POSIX</i> <code>
+ stat()</code>
+ followed by <i>POSIX</i>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/utime.html">
+ <code>utime()</code></a>.</p>
+ <p>[<i>Note:</i> The apparent postcondition <code>last_write_time(p) ==
+ new_time</code> is not specified since it would not hold for many file systems
+ due to coarse time mechanism granularity. <i>-- end note</i>]</p>
+</blockquote>
+<h4>Other o<a name="Operations-functions">perations functions</a></h4>
+<pre>template <class Path> bool create_directory(const Path& dp);</pre>
+<blockquote>
+ <p><i>Effects:</i> Attempts to create the directory <code>dp</code> resolves to,
+ as if by<i> POSIX </i><code>
+ mkdir()</code> with a second argument of S_IRWXU|S_IRWXG|S_IRWXO. </p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <i>
+ Effects</i> fails for any reason other than because the directory already exists.</p>
+ <p><i>Returns:</i> True if a new directory was created, otherwise false.</p>
+ <p><i>Postcondition:</i> <code>is_directory(dp)</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ error_code create_hard_link(const Path1& to_p, const Path2& from_p, error_code& ec);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
+ </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
+ </span> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">
+ <span style="background-color: #FFFFFF">link()</span></a></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> If the
+ postcondition cannot be established, a system error code
+ indicating the reason for the failure, otherwise 0.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i></p>
+ <ul>
+ <li><span style="background-color: #FFFFFF"> </span><code><span style="background-color: #FFFFFF">exists(to_p) && exists(from_p) && equivalent(to_p,
+ from_p)</span></code></li>
+ <li><span style="background-color: #FFFFFF">The contents of the file or directory
+ </span> <code><span style="background-color: #FFFFFF">to_p</span></code><span style="background-color: #FFFFFF"> resolves to are unchanged.</span></li>
+ </ul>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some operating systems do not support hard links or support
+ them only for regular files. Some operating systems limit the number of links per
+ file.
+ Some file systems that do not
+ support
+ hard links - the FAT system used on floppy discs, memory cards and flash
+ drives,
+ for example. Thus hard links should be avoided if wide portability is
+ a concern. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ void create_hard_link(const Path1& to_p, const Path2& from_p);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ As if <code>system_error_code ec( create_hard_link( to_p, from_p ) );</code></span></p>
+ <p><span style="font-style: italic; background-color: #FFFFFF">Throws:</span><span style="background-color: #FFFFFF">
+ </span> <code>basic_filesystem_error<Path1, Path2></code><span style="background-color: #FFFFFF">
+ if <code>ec</code> is not zero.</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ error_code create_symlink(const Path1& to_p, const Path2& from_p, error_code& ec);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
+ </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
+ </span> <code>
+ <span style="background-color: #FFFFFF">
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">
+ symlink()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> If the
+ postcondition cannot be established, a system error code
+ indicating the reason for the failure, otherwise 0.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Postcondition:</i> <code>from_p</code>
+ resolves to a symbolic link file that contains an unspecified representation
+ of <code>to_p</code>.</span></p>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some operating systems do not support symbolic links at all or support
+ them only for regular files. Thus symbolic links should be avoided if code portability is
+ a concern. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ void create_symlink(const Path1& to_p, const Path2& from_p);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ As if <code>system_error_code ec( create_symlink( to_p, from_p ) );</code></span></p>
+ <p><span style="font-style: italic; background-color: #FFFFFF">Throws:</span><span style="background-color: #FFFFFF">
+ </span> <code>basic_filesystem_error<Path1, Path2></code><span style="background-color: #FFFFFF">
+ if <code>ec</code> is not zero.</span></p>
+ </blockquote>
+<pre>template <class Path> bool remove(const Path& p);</pre>
+<blockquote>
+ <p><i>Precondition:</i> <code>!p.empty()</code></p>
+ <p><i>Effects:</i> Attempts to delete the file <code>p</code> resolves
+ to,
+ as if by<i> POSIX </i><code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">
+ remove()</a></code>.</p>
+ <p><i>Returns:</i> The value of <code>exists(p)</code> prior to the
+ establishment of the postcondition.</p>
+ <p><i>Postcondition:</i> <code>!exists(p)</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if:</p>
+ <ul>
+ <li><code>p.empty() || (exists(p) && is_directory(p) && !empty(p))</code>.</li>
+ <li><i>Effects</i> fails for any reason other than because <code>p</code>
+ does not resolve to an existing file.</li>
+ </ul>
+ <p>[<i>Note:</i> A symbolic link is itself removed, rather than what it
+ resolves to being removed. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path1, class Path2> void rename(const Path1& from_p, const Path2& to_p);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <p><i>Effects:</i> Renames <code>from_p</code> to <code>to_p</code>, as if by
+ <i>POSIX</i> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/rename.html">
+ rename()</a></code>.</p>
+ <p><i>Postconditions:</i> <code>!exists(from_p) && exists(to_p)</code>, and
+ the contents and attributes of the file originally named <code>from_p</code>
+ are otherwise unchanged.</p>
+ <p>[<i>Note:</i> If <code>from_p</code> and <code>to_p</code> resolve to the
+ same file, no action is taken. Otherwise, if <code>to_p</code> resolves to an
+ existing file, it is removed. A symbolic link is itself renamed, rather than
+ the file it resolves to being renamed. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path1, class Path2> void copy_file(const Path1& from_fp, const Path2& to_fp);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <p><i>Effects:</i> The contents and attributes of the file <code>from_fp</code>
+ resolves to are copied to the file <code>to_fp</code> resolves to.</p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>
+ from_fp.empty() || to_fp.empty() ||!exists(from_fp) || !is_regular(from_fp)
+ || exists(to_fp)</code></p>
+</blockquote>
+<pre>template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());</pre>
+<blockquote>
+ <p><i>Effects:</i> Composes a complete path from <code>p</code> and <code>base</code>,
+ using the following rules:</p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <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>p</code></td>
+ <td align="center">precondition failure</td>
+ </tr>
+ <tr>
+ <td align="center"><b><code>!p.has_root_name()</code></b></td>
+ <td align="center"><code>base.root_name()<br>
+ / p</code></td>
+ <td align="center"><code>base / p</code></td>
+ </tr>
+ </table>
+ <p><i>Returns:</i> The composed path.</p>
+ <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>
+ rp.is_complete()</code> is true.</p>
+ <p><i>Throws:</i>
+ <span style="background-color: #FFFFFF">If </span> <code>
+ <span style="background-color: #FFFFFF">!(base.is_complete() && (p.is_complete() || !p.has_root_name()))</span></code></p>
+ <p>[<i><a name="complete_note">Note</a>:</i> When portable behavior is
+ required, use <i>complete()</i>. When operating system dependent behavior is
+ required, use <i>system_complete()</i>.</p>
+ <p>Portable behavior is useful when dealing with paths created
+ internally within a program, particularly if the program should exhibit the
+ same behavior on all operating systems.</p>
+ <p>Operating system dependent behavior is useful when dealing with
+ paths supplied by user input, reported to program users, or when such behavior
+ is expected by program users. <i>--
+ end note</i>]</p>
+</blockquote>
+<pre>template <class Path> Path system_complete(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> Composes a complete 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_complete()</code> is true.</p>
+ <p><i>Throws:</i> <span style="background-color: #FFFFFF">If <code>p.empty()</code>.</span></p>
+ <p>[<i>Note:</i> For <i>POSIX</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_complete() || !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="file:///C|/boost/site/libs/filesystem/doc/operations.htm#complete_note">
+ <i>complete()</i> note</a> for usage suggestions. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="Convenience-functions">Convenience functions</a></h4>
+<pre>template <class Path> bool create_directories(const Path & p);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>p.empty() || <br>
+ forall px: px == p || is_parent(px, p): is_directory(px) || !exists( px )</code>
+ </p>
+ <p><i>Returns:</i> The value of <code>!exists(p)</code> prior to the
+ establishment of the postcondition.</p>
+ <p><i>Postcondition:</i> <code>is_directory(p)</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if<code>
+ exists(p) && !is_directory(p)</code></p>
+</blockquote>
+<pre>template <class Path> typename Path::string_type extension(const Path & p);</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.leaf()</code> contains a <i>dot</i>, returns the
+ substring of <code>p.leaf()</code> starting at the rightmost <i>dot</i> and
+ ending at the string's end. Otherwise, returns an empty string. </p>
+ <p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that
+ it is possible to distinguish between no extension and an empty extension. </p>
+ <p>Implementations are permitted but not required to define additional
+ behavior for file systems which append additional elements to extensions, such
+ as alternate data stream or partitioned dataset names. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path> typename Path::string_type basename(const Path & p);</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.leaf()</code> contains a <i>dot</i>, returns the
+ substring of <code>p.leaf()</code> starting at its beginning and ending at the
+ last <i>dot</i> (the <i>dot</i> is not included). Otherwise, returns <code>
+ p.leaf()</code>.</p>
+</blockquote>
+<pre>template <class Path>
+ Path replace_extension(const Path & p, const typename Path::string_type & new_extension);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>basename(<i>return_value</i>) == basename(p) &&
+ extension(<i>return_value</i>) == new_extension</code> </p>
+ <p>[<i>Note:</i> It follows from the semantics of <code>extension()</code>
+ that <code>new_extension</code> should include <i>dot</i> to achieve
+ reasonable results. <i>-- end note</i>]</p>
+</blockquote>
+<h3><a name="header-cerrno">Additions</a> to header <code><cerrno></code></h3>
+<p>The header <cerrno> shall include an additional symbolic constant macro for
+each of the values returned by the to_errno
+function. The macro names shall be as defined in <i>POSIX</i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/errno.h.html">
+errno.h</a>, with the additions below.</p>
+<blockquote>
+<p><i><span style="background-color: #E0E0E0">This codifies existing practice.
+The required names are only a sub-set of those defined by POSIX, and are usually already
+supplied in <errno.h> (as wrapped by <cerrno>) as shipped with POSIX and Windows compilers.
+These implementations require no changes to their underlying C headers to conform with the above
+requirement.</span></i></p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="33%">
+ <tr>
+ <td width="18%" align="center"><i><b>Name</b></i></td>
+ <td width="82%" align="center"><i><b>Meaning</b></i></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>EBADHANDLE</code></td>
+ <td width="82%">Bad operating system handle.</td>
+ </tr>
+ <tr>
+ <td width="18%"><code>EOTHER</code></td>
+ <td width="82%">Other error.</td>
+ </tr>
+</table>
+</blockquote>
+<h3><a name="header-fstream">Additions</a> to header <code><fstream></code></h3>
+<blockquote>
+<p><span style="background-color: #E0E0E0; font-style:italic">These additions have been carefully
+specified to avoid breaking existing code in common operating environments such as
+</span> <i><span style="background-color: #E0E0E0">POSIX</span></i><span style="background-color: #E0E0E0; font-style:italic">,
+</span> <i>
+<span style="background-color: #E0E0E0">Windows</span></i><span style="background-color: #E0E0E0; font-style:italic">, and
+</span> <i><span style="background-color: #E0E0E0">OpenVMS.
+See </span><a href="#Suggestions-for-fstream">
+<span style="background-color: #E0E0E0">Suggestions for <code><fstream></code>
+implementations</span></a><span style="background-color: #E0E0E0"> for
+techniques to avoid breaking existing code in other environments, particularly
+on operating systems allowing slashes in filenames.</span></i></p>
+<p><span style="background-color: #FFFFFF">[<i>Note:</i> The
+"do-the-right-thing" rule from <a href="#Requirements-on-implementations">
+Requirements on implementations</a> does apply to header <code><fstream></code>.</span></p>
+<p><span style="background-color: #FFFFFF">The overloads
+below are specified as additions rather than replacements for existing
+functions. This preserves existing code (perhaps
+using a <a name="home-grown-path">home-grown path</a> class) that relies on an
+automatic conversion to <code>const char*</code>.<i> -- end note</i>]</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.1 Class template
+basic_filebuf [lib.filebuf] synopsis preceding paragraph 1, add the function:</i></span></p>
+<blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path> </span><span style="background-color: #FFFFFF">basic_filebuf</span><span style="background-color: #FFFFFF"><charT,traits>* </span><span style="background-color: #FFFFFF">open(const</span><span style="background-color: #FFFFFF"> Path& p, </span><span style="background-color: #FFFFFF">ios_base::openmode</span><span style="background-color: #FFFFFF"> mode);</span></pre>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.3 Member functions [lib.filebuf.members],
+add the above to the signature preceding paragraph 2, and replace the
+sentence:</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF">It then opens a file, if possible,
+whose name is the NTBS s (as if by calling <code>std::fopen(s ,<i>modstr</i>
+))</code>.</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with:</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF">It then opens, if possible, the file
+that
+<code>p</code> or <code>path(s)</code> resolves to, as if by calling <code>std::fopen()</code> with a
+second argument of <i>modstr</i>.</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.5 Class template
+basic_ifstream [lib.ifstream] synopsis preceding paragraph 1, add the functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_ifstream(const Path& p, ios_base::openmode mode = ios_base::in);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.6 basic_ifstream
+constructors [lib.ifstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::in)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::in)</code> or <code>rdbuf()->open(p, mode | ios_base::in)</code> as
+appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.7 Member functions [lib.ifstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::in)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::in)</code> or <code>rdbuf()->open(p, mode | ios_base::in)</code> as
+appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.8 Class template
+basic_ofstream [lib.ofstream] synopsis preceding paragraph 1, add the
+
+functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_ofstream(const Path& p, ios_base::openmode mode = ios_base::out);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::out);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.9 basic_ofstream
+constructors [lib.ofstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::out)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::out)</code> or <code>rdbuf()->open(p, mode | ios_base::out)</code> as
+appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.10 Member functions [lib.ofstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::out)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::out)</code> or <code>rdbuf()->open(p, mode | ios_base::out)</code> as
+appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.11 Class template
+basic_fstream [lib.fstream] synopsis preceding paragraph 1, add the functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_fstream(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.12 basic_fstream
+constructors [lib.fstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode)</code>
+or <code>rdbuf()->open(p, mode)</code> as appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.13 Member functions [lib.fstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode)</code>
+or <code>rdbuf()->open(p, mode)</code> as appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>End of proposed text.</i></span></p>
+<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>POSIX</i> and <i>Windows</i>
+implementations yield different results. The top value is the
+<i>POSIX</i> result and the bottom value is the <i>Windows</i> result. <br>
+ <table border="1" cellspacing="0" cellpadding="5" width="1066">
+<p>
+<tr><td width="112"><b>Constructor<br>argument</b></td>
+<td width="160"><b>Elements found<br>by iteration</b></td>
+<td width="112"><b><code>string()</code></b></td>
+<td width="112"><code><b>file_<br>string()</b></td>
+<td width="72"><b><code>root_<br>path()<br>.string()</code></b></td>
+<td width="48"><b><code>root_<br>name()</code></b></td>
+<td width="88"><b><code>root_<br>directory()</code></b></td>
+<td width="96"><b><code>relative_<br>path()<br>.string()</code></b></td>
+<td width="72"><b><code>branch_<br>path()<br>.string()</code></b></td>
+<td width="72"><b><code>leaf()</code></b></td>
+</tr>
+<tr>
+<td width="112"><code>""</code></td>
+<td width="160"><code>""</code></td>
+<td width="112"><code>""</code></td>
+<td width="112"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>""</code></td>
+</tr>
+<tr>
+<td width="112"><code>"."</code></td>
+<td width="160"><code>"."</code></td>
+<td width="112"><code>"."</code></td>
+<td width="112"><code>"."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"."</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>".."</code></td>
+<td width="160"><code>".."</code></td>
+<td width="112"><code>".."</code></td>
+<td width="112"><code>".."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>".."</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo"</code></td>
+<td width="160"><code>"foo"</code></td>
+<td width="112"><code>"foo"</code></td>
+<td width="112"><code>"foo"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo"</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/"</code></td>
+<td width="160"><code>"/"</code></td>
+<td width="112"><code>"/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/"<br>"\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo"</code></td>
+<td width="160"><code>"/","foo"</code></td>
+<td width="112"><code>"/foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo"<br>"\foo"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/"</code></td>
+<td width="160"><code>"foo","."</code></td>
+<td width="112"><code>"foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/"<br>"foo\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/"</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo/"</code></td>
+<td width="160"><code>"/","foo","."</code></td>
+<td width="112"><code>"/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo/"<br>"\foo\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo/"</code></td>
+<td width="72"><code>"/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/bar"</code></td>
+<td width="160"><code>"foo","bar"</code></td>
+<td width="112"><code>"foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/bar"<br>"foo\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/bar"</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo/bar"</code></td>
+<td width="160"><code>"/","foo","bar"</code></td>
+<td width="112"><code>"/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo/bar"<br>"\foo\bar"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo/bar"</code></td>
+<td width="72"><code>"/foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"///foo///"</code></td>
+<td width="160"><code>"/","foo","."</code></td>
+<td width="112"><code>"///foo///"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"///foo///"<br>"\foo\\\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo///"</code></td>
+<td width="72"><code>"///foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"///foo///bar"</code></td>
+<td width="160"><code>"/","foo","bar"</code></td>
+<td width="112"><code>"///foo///bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"///foo///bar"<br>"\foo\\\bar"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo///bar"</code></td>
+<td width="72"><code>"///foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/."</code></td>
+<td width="160"><code>"/","."</code></td>
+<td width="112"><code>"/."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/."<br>"\."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"./"</code></td>
+<td width="160"><code>".","."</code></td>
+<td width="112"><code>"./"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"./"<br>".\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"./"</code></td>
+<td width="72"><code>"."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/.."</code></td>
+<td width="160"><code>"/",".."</code></td>
+<td width="112"><code>"/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/.."<br>"\.."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>".."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"../"</code></td>
+<td width="160"><code>"..","."</code></td>
+<td width="112"><code>"../"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"../"<br>"..\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"../"</code></td>
+<td width="72"><code>".."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/."</code></td>
+<td width="160"><code>"foo","."</code></td>
+<td width="112"><code>"foo/."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/."<br>"foo\."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/.."</code></td>
+<td width="160"><code>"foo",".."</code></td>
+<td width="112"><code>"foo/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/.."<br>"foo\.."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/.."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/./"</code></td>
+<td width="160"><code>"foo",".","."</code></td>
+<td width="112"><code>"foo/./"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/./"<br>"foo\.\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/./"</code></td>
+<td width="72"><code>"foo/."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/./bar"</code></td>
+<td width="160"><code>"foo",".","bar"</code></td>
+<td width="112"><code>"foo/./bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/./bar"<br>"foo\.\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/./bar"</code></td>
+<td width="72"><code>"foo/."</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/.."</code></td>
+<td width="160"><code>"foo",".."</code></td>
+<td width="112"><code>"foo/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/.."<br>"foo\.."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/.."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/../"</code></td>
+<td width="160"><code>"foo","..","."</code></td>
+<td width="112"><code>"foo/../"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/../"<br>"foo\..\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/../"</code></td>
+<td width="72"><code>"foo/.."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/../bar"</code></td>
+<td width="160"><code>"foo","..","bar"</code></td>
+<td width="112"><code>"foo/../bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/../bar"<br>"foo\..\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/../bar"</code></td>
+<td width="72"><code>"foo/.."</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:"</code></td>
+<td width="160"><code>"c:"</code></td>
+<td width="112"><code>"c:"</code></td>
+<td width="112"><code>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1; border-top-style: solid; border-top-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:"<br>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"c:"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","."<br>"c:","/"</code></td>
+<td width="112"><code>"c:/"</code></td>
+<td bgcolor="#99FF66" width="112"><code><span style="background-color: #99FF66">
+"c:/"<br>"c:\"</span></code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/"<br>""</code></td>
+<td width="72"><code>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"."<br>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo"<br>"c:","foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo"<br>"c:","/","foo"</code></td>
+<td width="112"><code>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo"<br>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:"<br>"c:/"</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo","."<br>"c:","foo","."</code></td>
+<td width="112"><code>"c:foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:foo/"<br>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo/"<br>"foo/"</code></td>
+<td width="72"><code>"c:foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo","."<br>"c:","/","foo","."</code></td>
+<td width="112"><code>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo/"<br>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo/"<br>"foo/"</code></td>
+<td width="72"><code>"c:/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo","bar"<br>"c:","/","foo","bar"</code></td>
+<td width="112"><code>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo/bar"<br>"c:\foo\bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo/bar"<br>"foo/bar"</code></td>
+<td width="72"><code>"c:/foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"prn:"</code></td>
+<td width="160"><code>"prn:"</code></td>
+<td width="112"><code>"prn:"</code></td>
+<td width="112"><code>"prn:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"prn:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"prn:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"prn:"<br>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"prn:"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\"<br>"c:","/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\"<br>"c:/"</code></td>
+<td width="112"><code>"c:\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\"<br>""</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\"<br>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo"<br>"c:","foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo"<br>"c:","/","foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo"<br>"c:/foo"</code></td>
+<td width="112"><code>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo\"<br>"c:","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:foo\"<br>"c:foo/"</code></td>
+<td width="112"><code>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo\"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo\"<br>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo\"<br>"c:","/","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo\"<br>"c:/foo/"</code></td>
+<td width="112"><code>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo\"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo\"<br>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo","."<br>"c:","/","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo/"<br>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo/"<br>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo/"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo"<br>"c:/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo\bar"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo\bar"<br>"c:","/","foo","bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo\bar"<br>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo\bar"<br>"c:\foo\bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1; border-bottom-style: solid; border-bottom-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo\bar"<br>"foo/bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:"<br>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"foo\bar"<br>"bar"</code></td>
+</tr>
+</table>
+<h2><a name="Suggestions-for-fstream">Suggestions for <code><fstream></code></a>
+implementations</h2>
+<p><span style="background-color: #FFFFFF">The change in semantics to functions
+taking <code>const char*</code> arguments can break existing code, but only on
+operating systems where implementations don't
+implicitly accept native format pathnames or
+operating systems that allow slashes in filenames. Thus on <i>POSIX</i>,
+<i>Windows,</i> and <i>OpenVMS</i>, for example, there is no problem if the
+implementation follows encouraged behavior.</span></p>
+<p><span style="background-color: #FFFFFF">For most of the Filesystem Library,
+there is no existing code, so the issue preserving existing code that uses
+slashes in filenames doesn't arise. New code simply must use basic_path
+constructors with <code>path_format_t</code> arguments of <code>native</code>.
+To preserve existing fstream code that uses slashes in filenames, an
+implementation may wish to provide a mechanism such as a macro to control
+selection of the old behavior.</span></p>
+<p><span style="background-color: #FFFFFF">Implementations are already required
+by the TR front-matter to provide a mechanism such as a macro to control
+selection of the old behavior (useful to guarantee protection of existing code)
+or new behavior (useful in new code, and code being ported from other systems)
+for headers. Because use of the rest of the Filesystem Library is independent of
+use of the <code><fstream></code> additions, affected implementations are
+encouraged to allow disabling the <code><fstream></code> additions separately
+from other TR features.</span></p>
+<p><span style="background-color: #FFFFFF">An rejected alternative was to supply
+new fstream classes in namespace <code>sys</code>, inheriting from the current
+classes, overriding the constructors and opens taking pathname arguments, and
+providing the additional overloads. In Lillehammer LWG members indicated lack of
+support for this alternative, feeling that costs outweigh benefits.</span></p>
+<h2><a name="Issues">Issues</a></h2>
+<h3>1. Return type of certain basic_path members returning strings. [Howard
+Hinnant]</h3>
+<p>For member functions described as returning "<code>const string_type</code>"
+or "<code>const external_string_type</code>", implementations are permitted to
+return "<code>const string_type&</code>" or "<code>const
+external_string_type&</code>" respectively.</p>
+<p>This allows implementations to avoid unnecessary copies. Return-by-value is
+specified as
+<code>const</code> to ensure programs won't break if moved to a
+return-by-reference implementation.</p>
+<p>For example, the Boost implementation keeps the internal representation of a
+pathname in the portable format, so string() returns by reference and is inlined:</p>
+<blockquote>
+ <pre>const string_type & string() const { return m_path; }</pre>
+</blockquote>
+<p>Howard Hinnant comments: This may inhibit optimization if rvalue reference is
+accepted. Const-qualified return types can't be moved from. I'd
+rather see either the return type specified as
+<code>const string_type&</code> or <code>string_type</code>.</p>
+<p>Beman Dawes comments: I can't make up my mind. Removing the const will bite
+users, but not very often. OTOH, excessive copying is a real concern, and if
+move semantics can alleviate that, I'm all for it. What does the LWG think?</p>
+<h3>2. Basic_path canonize() and normalize() removed. [Beman Dawes]</h3>
+<p>The Boost implementation has basic_path functions canonize() and normalize()
+which return cleaned up string representations of a pathname. They have been
+removed from the proposal as messy to specify and implement, not hugely useful,
+and possible to implement by users as non-member functions without any loss of
+functionality or efficiency. There was also a concern the proposal was getting a
+bit large.</p>
+<p>These functions can be added later as convenience functions if the LWG so
+desires..</p>
+<h3>3. Filename checking functions. [Beman Dawes]</h3>
+<p>Boost has a set of predicate functions that determine if a filename is valid
+for a particular operating or system. These can be used as building blocks for
+functions that determine if an entire pathname is valid for a particular
+operating or file system.</p>
+<p>Users can use these functions to ensure that pathnames are in fact portable
+to target operating or file systems, without having to actually test on the
+target systems.</p>
+<p>These functions are not included in the proposal because of lack of time, and
+uncertainty as to their fit with the Standard Library. They can be added later
+if the LWG so desires.</p>
+<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>.</p>
+<p>Dietmar Kühl 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.</p>
+<p>Howard Hinnant and John Maddock reviewed a draft of the proposal, and
+identified a number of mistakes or weaknesses, resulting in a more polished
+final document.</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-POSIX</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>
+<h2><a name="Revision-History">Revision History</a></h2>
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="11%" valign="top">
+ <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1841.html">
+ N1841</a></td>
+ <td width="89%">
+ <ul>
+ <li>Initial version, August, 2005, pre-Tremblant mailing</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td width="11%" valign="top" bgcolor="#FFFFFF">
+ <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1889.html">
+ N1889</a><br>
+ Revision 1</td>
+ <td width="89%" bgcolor="#FFFFFF">
+ <ul>
+ <li>Missing argument name <code>fmt</code> added to several <code>
+ basic_path</code> members.</li>
+ <li> <code>is_empty()</code> name discrepancy between synopsis and
+ description corrected.</li>
+ <li><code>file_size()</code> return type changed from <code>intmax_t</code>
+ to <code>uintmax_t</code>. Wording slightly clarified.</li>
+ <li><code>struct space_info</code> and non-member function <code>space()</code>
+ added.</li>
+ <li>A paragraph was added to <b><i>Important design decisions</i></b>
+ mentioning the need for both portable and platform specific semantics.</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td width="11%" valign="top" bgcolor="#FFFFFF">
+ <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1934.html">
+ N1934</a><br>
+ Revision 2</td>
+ <td width="89%" bgcolor="#FFFFFF">
+ <ul>
+ <li>Changed native path identification from constructor argument to
+ <code>"//:"</code> escape prefix. Rationale: simplifies basic_path
+ constructor interfaces, easier use for platforms needing explicit native
+ format identification.</li>
+ <li>Introduced a new base class, filesystem_error, to<span style="background-color: #FFFFFF">
+ allow users to catch a single exception type if desired, or to deal with
+ the case where the templated type is unknown. Rename filesystem_error and
+ wfilesystem_error accordingly.</span></li>
+ <li><span style="background-color: #FFFFFF">Rewording
+ basic_filesystem_error text to more closely follow the form of clause 19
+ of the standard.</span></li>
+ <li><span style="background-color: #FFFFFF">Removed dual specification of
+ certain errors in both "Reguires" and "Throws" paragraphs. Since throwing
+ an exception is well-defined behavior, the error condition does not result
+ in undefined behavior as implied by "Requires". (Suggested by Dave
+ Abrahams)</span></li>
+ <li><span style="background-color: #FFFFFF">Added a non-throwing version
+ of create_hard_link().</span></li>
+ <li><span style="background-color: #FFFFFF">Added two create_symlink()
+ functions.</span></li>
+ <li><span style="background-color: #FFFFFF">Added basic_path inserter and
+ extractor. (Suggested by Vladimir Prus)</span></li>
+ <li><span style="background-color: #FFFFFF">Added basic_path member and
+ non-member swap() functions.</span></li>
+ <li><span style="background-color: #FFFFFF">Aligned basic_path operator
+ functions with std::basic_string practice. </span></li>
+ <li><span style="background-color: #FFFFFF">Replaced status_flags with
+ file_type enum and file_status class to improve encapsulation and allow
+ for future expansion of file_status.</span></li>
+ <li><span style="background-color: #FFFFFF">Added predicate functions
+ overloaded on file_status (Suggested by Martin Adrian). This change,
+ coupled with the introduction of file_status, clarifies the meaning of
+ file types and related predicate operations, and eliminates the need for
+ user bit manipulation, which was a source of user error.</span></li>
+ <li><span style="background-color: #FFFFFF">Predicate function
+ specification clarified accordingly.</span></li>
+ <li><span style="background-color: #FFFFFF">Revised and explicitly
+ documented policy for non-throwing versions of functions to increase
+ consistency.</span></li>
+ <li><span style="background-color: #FFFFFF">Added basic_directory_iterator
+ constructor non-throwing overload (Suggested by Martin Adrian).</span></li>
+ <li><span style="background-color: #FFFFFF">Changed symlink awareness to
+ separately name functions to cut clutter caused by addition of
+ non-throwing overloads.</span></li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td width="11%" valign="top" bgcolor="#FFFFFF">
+ N1975<br>
+ Revision 3</td>
+ <td width="89%" bgcolor="#FFFFFF">
+ <ul>
+ <li><span style="background-color: #FFFFFF">Factored non-filesystem
+ related error handling into separate <system_error> header. This
+ change grew out of a Boost developer's list discussion of error handling
+ guidelines for functions likely to use operating system API calls.</span></li>
+ <li><span style="background-color: #FFFFFF">Added <code>basic_path::clear()</code>
+ in response to user request.</span></li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+<hr>
+<p>© Copyright Beman Dawes, 2002-2006</p>
+<p>Revised
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2006-04-04<!--webbot bot="Timestamp" endspan i-checksum="12266" --></p>
+
+</body>
+
+</html>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk