mirror of
https://github.com/boostorg/filesystem.git
synced 2026-01-30 07:52:08 +00:00
971 lines
45 KiB
HTML
971 lines
45 KiB
HTML
<html>
|
||
|
||
<head>
|
||
<meta http-equiv="Content-Language" content="en-us">
|
||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||
<title>Boost Filesystem path.hpp Header</title>
|
||
</head>
|
||
|
||
<body bgcolor="#FFFFFF">
|
||
|
||
<h1>
|
||
<img border="0" src="../../../boost.png" align="center" width="277" height="86"><a href="../../../boost/filesystem/path.hpp">boost/filesystem/basic_path.hpp</a></h1>
|
||
|
||
<p>
|
||
<a href="#Introduction">Introduction</a><br>
|
||
<a href="#Grammar">Grammar for generic path strings</a><br>
|
||
<a href="#Normalized">Normalized Form</a><br>
|
||
<a href="#synopsis">Header synopsis</a><br>
|
||
<a href="#Class_path">Class basic_path</a><br>
|
||
<a href="#System-specific-path-representation">
|
||
System-specific path representation</a><br>
|
||
<a href="#Representation_example">Representation example</a><br>
|
||
<a href="#Caution_POSIX">Caution for POSIX and UNIX
|
||
programmers</a><br>
|
||
<a href="#relative_paths_good">Good programming practice:
|
||
relative paths</a><br>
|
||
<a href="#Path_equality">Path equality vs path equivalence</a><br>
|
||
<a href="#Member">Member functions</a><br>
|
||
<a href="#Non-member_functions">Non-member functions</a><br>
|
||
<a href="#Rationale">Rationale</a><br>
|
||
<a href="#decomposition">Path decomposition examples</a></p>
|
||
<h2><a name="Introduction">Introduction</a></h2>
|
||
|
||
<p>Boost.Filesystem traffics in objects of class template <i>basic_path</i>,
|
||
provided by this header. The header also declares functions for error checking
|
||
and class template <i>basic_filesystem_error</i>.</p>
|
||
|
||
<p>For actual operations on files and directories, see <a href="operations.htm">
|
||
boost/filesystem/operations.hpp documentation</a>.</p>
|
||
|
||
<p>For file I/O stream operations, see <a href="fstream.htm">boost/filesystem/fstream.hpp
|
||
documentation</a>.</p>
|
||
|
||
<p>The Filesystem Library's <a href="index.htm#Common_Specifications">Common
|
||
Specifications</a> apply to all member and non-member functions supplied by this
|
||
header.</p>
|
||
|
||
<p>The <a href="portability_guide.htm">Portability Guide</a> discusses
|
||
basic_path
|
||
naming issues which are important when portability is a concern.</p>
|
||
<h2><a name="Class_path">Class basic_path</a></h2>
|
||
<p>Class template <i>basic_path</i> provides for portable mechanism for representing
|
||
<a href="index.htm#path">paths</a> in C++ programs, using a portable generic
|
||
path string <a href="#Grammar">grammar</a>. When portability is not a
|
||
requirement, native file system specific formats can be used. Class <i>
|
||
basic_path</i>
|
||
is concerned 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>
|
||
<p><b>Rationale:</b> If the library's functions trafficked in <i>std::string</i> or C-style strings, the
|
||
functions
|
||
would provide only an 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. A
|
||
number of supporting functions are also neatly packaged in class <i>basic_path</i>.</p>
|
||
<h2>Conceptual <a name="model">model</a> of a path</h2>
|
||
<p>An object of class <i>basic_path</i> can be conceptualized as containing a sequence
|
||
of strings. Each string is said to be an element of the path. Each element
|
||
represents the name of a directory, or, in the case
|
||
of the string representing the element farthest from the root in the directory
|
||
hierarchy, the name of a directory or file. The names <code>".."</code> and
|
||
<code>"."</code> are reserved to represent the concepts of <i>parent-directory</i>
|
||
and <i>directory-placeholder</i>.</p>
|
||
<p>This conceptual path representation is
|
||
|
||
independent of any particular operating system's representation of the path as a single
|
||
string.</p>
|
||
<p>There is no requirement that an implementation of class <i>basic_path</i> actually
|
||
contain a sequence of strings, but conceptualizing the contents as a sequence of
|
||
strings provides
|
||
a completely portable way to reason about paths.</p>
|
||
<p>So that programs can portably express paths as a single string, class <i>
|
||
basic_path</i>
|
||
defines a <a href="#Grammar">grammar</a> for a portable generic path string
|
||
format, and supplies constructor and append operations taking such strings as
|
||
arguments.</p>
|
||
<p>Access functions are provided to retrieve the contents of a object of class
|
||
<i>basic_path</i> formatted as a portable path string, a directory path string using
|
||
the operating system's format, and a file path string using the operating
|
||
system's format. Additional access functions retrieve specific portions of
|
||
the contained path.</p>
|
||
<h2><a name="Grammar">Grammar</a> for portable generic basic_path strings</h2>
|
||
<p>The grammar is specified in extended BNF, with terminal symbols in quotes:
|
||
</p>
|
||
<blockquote>
|
||
<pre>path ::= [root] [relative-path] // an empty path is valid</pre>
|
||
<pre>root ::= [root-name] [root-directory] | separator separator name</pre>
|
||
<pre>root-directory ::= separator</pre>
|
||
<pre>relative-path ::= path-element { separator path-element } [separator]</pre>
|
||
<pre>path-element ::= name | parent-directory | directory-placeholder</pre>
|
||
<pre>name ::= char { char }</pre>
|
||
<pre>directory-placeholder ::= "."</pre>
|
||
<pre>parent-directory ::= ".."
|
||
|
||
separator ::= "/" // an implementation may define additional alternate separators </pre>
|
||
</blockquote>
|
||
<p><i>root-name</i> grammar is implementation-defined for the particular
|
||
operating system. For example, it is used to represent drive specifiers for the
|
||
Window operating system. It is not used for POSIX implementations.</p>
|
||
<p><i>char</i> may not be slash ('/') or '\0'. In additional, operating and
|
||
file systems place additional restrictions on the characters which may
|
||
appear in names. See <a href="portability_guide.htm#recommendations">File and
|
||
Directory Name Recommendations</a>.</p>
|
||
<p>Although implementation-defined, it is desirable that <i>
|
||
root-name</i> have a grammar which is distinguishable from other grammar elements,
|
||
and follow the conventions of the operating system.</p>
|
||
<p>The meaning, if any, of a <i>root</i> in the form <i>separator separator name</i>
|
||
is operating system dependent.</p>
|
||
<p>An optional trailing "/" is allowed in a <i>relative-basic_path</i>. It
|
||
has no particular meaning to class <i>basic_path</i>. It may or may not have meaning
|
||
to operations functions, depending on the particular operating system. It will
|
||
be ignored by operations functions on operating systems for which a trailing "/"
|
||
is ignored or invalid.</p>
|
||
<p>Whether or not a generic path string is actually portable to a particular
|
||
operating system or file system will depend on the
|
||
names used. See the <a href="portability_guide.htm">Portability Guide</a>.</p>
|
||
<h2><a name="Normalized">Normalized</a> form</h2>
|
||
<p>In Normalized form, adjacent <i>name, parent-directory</i>
|
||
elements are recursively removed. Except in a single element path, <i>
|
||
directory-placeholders</i> are removed.</p>
|
||
<p>Thus a non-empty path in normal form either has no <i>
|
||
directory-placeholders</i>, or consists solely of one <i>directory-placeholder</i>.
|
||
If it has <i>parent-directory</i> elements, they precede all <i>name</i>
|
||
elements.</p>
|
||
<h2>Header <a href="../../../boost/filesystem/path.hpp">
|
||
boost/filesystem/basic_path.hpp</a> <a name="synopsis">synopsis</a></h2>
|
||
<pre>namespace boost
|
||
{
|
||
namespace filesystem
|
||
{
|
||
template<class String, class Traits> class basic_path;
|
||
typedef basic_path< string_type, detail::path_traits > path;
|
||
typedef basic_path< std::wstring, detail::wpath_traits > wpath;
|
||
|
||
template<class String, class Traits>
|
||
class basic_path
|
||
{
|
||
public:
|
||
typedef basic_path<String, Traits> path_type;
|
||
typedef String string_type;
|
||
typedef Traits traits_type;
|
||
typedef typename Traits::external_string_type external_string_type;
|
||
|
||
// compiler generates copy constructor and copy assignment
|
||
|
||
// constructors:
|
||
<a href="#Class_path">basic_path</a>();
|
||
<a href="#Class_path">basic_path</a>( const string_type & src );
|
||
<a href="#Class_path">basic_path</a>( const char * src );
|
||
|
||
~basic_path();
|
||
|
||
// append operations:
|
||
basic_path & <a href="#operator_slash_equal">operator /=</a> ( const basic_path & rhs );
|
||
basic_path & <a href="#operator_slash_equal">operator /=</a> ( const string_type & rhs );
|
||
basic_path & <a href="#operator_slash_equal">operator /=</a> ( const typename string_type::value_type * rhs );
|
||
basic_path <a href="#operator_slash">operator /</a> ( const basic_path & rhs ) const;
|
||
basic_path <a href="#operator_slash">operator /</a> ( const string_type & rhs ) const;
|
||
basic_path <a href="#operator_slash">operator /</a> ( const typename string_type::value_type * rhs ) const;
|
||
|
||
// modification functions:
|
||
basic_path & <a href="#normalize">normalize</a>();
|
||
basic_path & <a href="#remove_leaf">remove_leaf</a>();
|
||
|
||
// conversion functions:
|
||
const string_type & <a href="#string">string</a>() const;
|
||
const string_type <a href="#file_string">file_string</a>() const;
|
||
const string_type <a href="#directory_string">directory_string</a>() const;
|
||
const external_string_type <a href="#external_file_string">external_file_string</a>() const;
|
||
const external_string_type <a href="#external_directory_string">external_directory_string</a>() const;
|
||
|
||
// decomposition functions:
|
||
basic_path <a href="#root_path">root_path</a>() const;
|
||
string_type <a href="#root_name">root_name</a>() const;
|
||
string_type <a href="#root_directory">root_directory</a>() const;
|
||
basic_path <a href="#relative_path">relative_path</a>() const;
|
||
string_type <a href="#leaf">leaf</a>() const;
|
||
basic_path <a href="#branch_path">branch_path</a>() const;
|
||
|
||
// query functions:
|
||
bool <a href="#empty">empty</a>() const;
|
||
bool <a href="#is_complete">is_complete</a>() const;
|
||
bool <a href="#has_root_path">has_root_path</a>() const;
|
||
bool <a href="#has_root_name">has_root_name</a>() const;
|
||
bool <a href="#has_root_directory">has_root_directory</a>() const;
|
||
bool <a href="#has_relative_path">has_relative_path</a>() const;
|
||
bool <a href="#has_leaf">has_leaf</a>() const;
|
||
bool <a href="#has_branch_path">has_branch_path</a>() const;
|
||
|
||
// iteration:
|
||
typedef <i>implementation-defined</i> <a href="#iterator">iterator</a>;
|
||
iterator <a href="#begin">begin</a>() const;
|
||
iterator <a href="#end">end</a>() const;
|
||
|
||
// relational operators:
|
||
bool <a href="#operator_eq">operator==</a>( const basic_path & that ) const;
|
||
bool <a href="#operator_ne">operator!=</a>( const basic_path & that ) const;
|
||
bool <a href="#operator_lt">operator<</a>( const basic_path & that ) const;
|
||
bool <a href="#operator_le">operator<=</a>( const basic_path & that ) const;
|
||
bool <a href="#operator_gt">operator></a>( const basic_path & that ) const;
|
||
bool <a href="#operator_ge">operator>=</a>( const basic_path & that ) const;
|
||
|
||
private:
|
||
std::vector<string_type> m_name; // for exposition only
|
||
bool m_trailing_separator; // for exposition only
|
||
};
|
||
|
||
template<class String, class Traits>
|
||
basic_path<String, Traits>
|
||
operator/( const String & lhs, const basic_path<String, Traits> & rhs );
|
||
|
||
template<class String, class Traits>
|
||
basic_path<String, Traits>
|
||
operator/( const typename String::value_type * lhs, const basic_path<String, Traits> & rhs );
|
||
|
||
// <a href="portability_guide.htm#name_check_functions">name_check functions</a>
|
||
bool <a href="portability_guide.htm#portable_posix_name">portable_posix_name</a>( const std::string & name );
|
||
bool <a href="portability_guide.htm#windows_name">windows_name</a>( const std::string & name );
|
||
bool <a href="portability_guide.htm#portable_name">portable_name</a>( const std::string & name );
|
||
bool <a href="portability_guide.htm#portable_directory_name">portable_directory_name</a>( const std::string & name );
|
||
bool <a href="portability_guide.htm#portable_file_name">portable_file_name</a>( const std::string & name );
|
||
bool <a href="portability_guide.htm#native">native</a>( const std::string & name );
|
||
}
|
||
}</pre>
|
||
<p>For the sake of exposition, class <i>basic_path</i> member functions are described
|
||
as if the class contains the indicated private members.
|
||
Actual implementations may differ.</p>
|
||
<p>For functions <i>string</i>, <i>file_string</i>, <i>directory_string</i>, <i>
|
||
external_file_string</i>, and <i>external_directory_string</i>, implementations
|
||
are permitted to return either <code>const</code> or <code>const &</code>
|
||
values.</p>
|
||
<p>Class path member, or non-member operator/, functions may throw a
|
||
<a href="exception.htm">basic_filesystem_error</a> exception if the path is not in the
|
||
syntax specified for the <a href="#Grammar">grammar</a>.</p>
|
||
<p><b>Note:</b> There is no guarantee that a <i>basic_path</i> object represents a
|
||
path which is considered valid by the current operating system. A path might be
|
||
invalid to the operating system because it contains invalid names (too long,
|
||
invalid characters, and so on), or because it is a partial path still as yet
|
||
unfinished by the program. An invalid path will normally be detected at time of
|
||
use, such as by one of the library's <a href="operations.htm">
|
||
operations</a> or <a href="fstream.htm">fstream</a> functions.</p>
|
||
<p><b>Portability Warning:</b> There is no guarantee that a <i>basic_path</i> object
|
||
represents a path which would be portable to another operating system or file
|
||
system. A path
|
||
might be non-portable because it contains names which the operating system
|
||
considers too long or containing invalid characters. To detect portability
|
||
problems, the library supplies several
|
||
<a href="portability_guide.htm#name_check_functions">name_check
|
||
functions</a>.</p>
|
||
<h3><a name="System-specific-path-representation">System-specific path
|
||
representation</a></h3>
|
||
<p>Several <i>basic_path</i> member functions return representations of <i>m_name</i>
|
||
in formats specific to the operating system. For POSIX, the system specific
|
||
format is the same as the <a href="#Grammar">generic grammar</a>. For Window,
|
||
the system specific format is the same as the <a href="#Grammar">generic grammar</a>
|
||
except that the alternate separator (backslash) is always used. For other
|
||
operating systems, the system specific format is implementation
|
||
defined.</p>
|
||
<p>For operating systems other than POSIX and Windows, if an <i>m_name</i>
|
||
element contains characters which are invalid under the operating system's
|
||
rules, and there is an unambiguous and reasonable translation between the
|
||
invalid character and a valid character, the implementation is required to
|
||
perform that translation. For example, if an operating system does not permit
|
||
lowercase letters in file or directory names, these letters must be translated
|
||
to uppercase if unambiguous. Such translation does not apply to the representation
|
||
returned by <code>string()</code>.</p>
|
||
<h3><a name="Representation_example">Representation example</a></h3>
|
||
<p>The rule-of-thumb is to use <i>string()</i> when a generic string representation of
|
||
the basic_path is required, and use either
|
||
<i>directory_string()</i> or
|
||
<i>file_string()</i> when a string representation formatted for
|
||
the particular operating system is required.</p>
|
||
<p>The difference between the representations returned by <i>string()</i>,
|
||
<i>directory_string()</i>, and
|
||
<i>file_string()</i> are illustrated by the following
|
||
code:</p>
|
||
<blockquote>
|
||
<pre>path my_path( "foo/bar/data.txt" );
|
||
std::cout
|
||
<< "string------------------: " << my_path.string() << '\n'
|
||
<< "directory_string--------: " << my_path.directory_string() << '\n'
|
||
<< "file_string-------------: " << my_path.file_string() << '\n';</pre>
|
||
</blockquote>
|
||
<p>On POSIX systems, the output would be:</p>
|
||
<blockquote>
|
||
<pre>string------------------: foo/bar/data.txt
|
||
directory_string--------: foo/bar/data.txt
|
||
file_string-------------: foo/bar/data.txt</pre>
|
||
</blockquote>
|
||
<p>On Windows, the output would be:</p>
|
||
<blockquote>
|
||
<pre>string------------------: foo/bar/data.txt
|
||
directory_string--------: foo\bar\data.txt
|
||
file_string-------------: foo\bar\data.txt</pre>
|
||
</blockquote>
|
||
<p>On classic Mac OS, the output would be:</p>
|
||
<blockquote>
|
||
<pre>string------------------: foo/bar/data.txt
|
||
directory_string--------: foo:bar:data.txt
|
||
file_string-------------: foo:bar:data.txt</pre>
|
||
</blockquote>
|
||
<p>On a hypothetical operating system using OpenVMS format representations, it would be:</p>
|
||
<blockquote>
|
||
<pre>string------------------: foo/bar/data.txt
|
||
directory_string--------: [foo.bar.data.txt]
|
||
file_string-------------: [foo.bar]data.txt</pre>
|
||
</blockquote>
|
||
<p>Note that that because OpenVMS uses period as both a directory separator
|
||
character and as a separator between filename and extension, <i>
|
||
directory_string()</i>
|
||
in the example produces a useless result. On this operating system, the
|
||
programmer should only use this path as a file path. (There is also a
|
||
<a href="portability_guide.htm#recommendations">portability recommendation</a>
|
||
to not use periods in directory names.)</p>
|
||
<h3><a name="Caution_POSIX">Caution</a> for POSIX and UNIX programmers</h3>
|
||
<p>POSIX and other UNIX-like operating systems have a single root, while most other
|
||
operating systems have multiple roots. Multi-root operating systems require a
|
||
root-name
|
||
such as a drive, device, disk, volume, or share name for a basic_path to be resolved
|
||
to an actual specific file or directory.
|
||
Because of this, the <i>root()</i> and <i>root_directory()</i> functions return
|
||
identical results on UNIX and other single-root operating systems, but different
|
||
results on multi-root operating systems. Thus use of the wrong function will not be
|
||
apparent on UNIX-like systems, but will result in non-portable code which will
|
||
fail when used on multi-root systems. UNIX programmers are cautioned to use
|
||
particular care in choosing between <i>root()</i> and <i>root_directory()</i>. If
|
||
undecided, use <i>root()</i>.</p>
|
||
<p>The same warning applies to <i>has_root()</i> and <i>has_root_directory()</i>.</p>
|
||
<h3><a name="relative_paths_good">Good programming practice: relative paths</a></h3>
|
||
<p>It is usually bad programming practice to hard-code <a href="#is_complete">
|
||
complete paths</a> into programs. Such programs tend to be fragile because they
|
||
break when directory trees get reorganized or the programs are moved to other
|
||
machines or operating systems.</p>
|
||
<p>The most robust way to deal with basic_path completion is to hard-code only
|
||
relative paths. When a complete basic_path is required, it can be obtained in several
|
||
ways:</p>
|
||
<ul>
|
||
<li><b>Implicitly</b>. Allow the operating system to complete the path
|
||
according to the operating system's path completion algorithm. For example:<pre> create_directory( "foo" ); // operating system will complete path</pre>
|
||
</li>
|
||
<li><b><a href="operations.htm#initial_path">initial_path()</a></b>.
|
||
Particularly for command line programs, specifying paths relative to the
|
||
current directory's path at the time the program is started is a common practice. For
|
||
example:<pre> path foo( initial_path<path>() / "foo" );</pre>
|
||
</li>
|
||
<li><b>Algorithmically</b>. See <a href="operations.htm#complete">complete()</a>
|
||
and <a href="operations.htm#system_complete">system_complete()</a> functions.</li>
|
||
</ul>
|
||
<h3><a name="Path_equality">Path equality</a> vs path equivalence</h3>
|
||
<p>Are paths "abc" and "ABC" equal? No, never, if you determine equality via
|
||
class <i>basic_path</i>'s <code>operator==</code>, which considers only the two path's
|
||
lexical representations.</p>
|
||
<p>Do paths "abc" and "ABC" resolve to the same file or directory? The answer is
|
||
"yes", "no", or "maybe" depending on the operating
|
||
system and external file system. The operations function
|
||
<i>equivalent()</i> is the only way to determine if two paths
|
||
resolve to the same external file system entity.</p>
|
||
<p>Programmers wishing to determine if two paths are "the same" must decide if
|
||
"the same" means "the same representation" or "resolve to the same actual file or
|
||
directory", and choose the appropriate function accordingly.</p>
|
||
<h2><a name="Member">Member</a> functions</h2>
|
||
<h3><a name="constructors">constructors</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path();</pre>
|
||
<p><b>Effects:</b> Default constructs an object of class <i>basic_path</i>.</p>
|
||
<p><b>Postcondition:</b> basic_path().empty()</p>
|
||
<pre>basic_path( const string_type & src );
|
||
basic_path( const char * src );</pre>
|
||
<p><b>Precondition:</b> <code>src != 0</code>.</p>
|
||
<p><b>Throws:</b> If <code>src</code> is invalid according to the
|
||
<a href="#Grammar">grammar</a>. Note that because the grammar is extremely
|
||
permissive, the only invalid character combination is two adjacent slashes,
|
||
and even this is valid at the beginning of a path.</p>
|
||
<p><b>Effects:</b> For each element in <code>src</code>, as determined by the
|
||
<a href="#Grammar">grammar</a>, <code>m_name.push_back(element)</code>. Set
|
||
<code>m_trailing_separator</code> to true if <code>src</code> has a trailing
|
||
separator, else false.</p>
|
||
<p><b>Rationale:</b> The single-argument constructors are not <code>explicit</code> because an intended
|
||
use is automatic conversion of strings to paths.</p>
|
||
</blockquote>
|
||
<h3><a name="operator_slash_equal">operator /=</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path & operator/=( const basic_path & rhs );
|
||
basic_path & operator /=( const string_type & rhs );
|
||
basic_path & operator /=( const typename string_type::value_type * rhs );</pre>
|
||
<p><b>Effects:</b> For each element in <code>rhs</code>, as determined by the
|
||
<a href="#Grammar">grammar</a>, <code>m_name.push_back(element)</code>. Set
|
||
<code>m_trailing_separator</code> to true if <code>rhs</code> has a trailing
|
||
separator, else false.</p>
|
||
<p><b>Returns:</b> <code>*this</code></p>
|
||
</blockquote>
|
||
<h3><a name="operator_slash">operator /</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path operator/( const basic_path & rhs ) const;
|
||
basic_path operator/( const string_type & rhs ) const;
|
||
basic_path operator/( const typename string_type::value_type * rhs ) const;</pre>
|
||
<p><b>Returns:</b> <code>basic_path( *this ) /= rhs</code></p>
|
||
<p><b>Rationale:</b> Operator / is supplied because together with operator /=,
|
||
it provides a
|
||
convenient way for users to supply paths with a variable number of elements.
|
||
For example, <code>initial_path<path>() / "src" / src_name</code>.
|
||
Operator+ and operator+= were considered as alternative names, but deemed too
|
||
easy to confuse with those operators for std::basic_string. Operator<< and
|
||
operator=<< were used until Dave Abrahams pointed out that / and /=
|
||
match the generic path syntax.</p>
|
||
<p><b>Note:</b> Also see <a href="#non-member_operator_shift">non-member <i>
|
||
operator/</i></a> functions.</p>
|
||
</blockquote>
|
||
<h3><a name="normalize">normalize</a></h3>
|
||
<blockquote>
|
||
<p><code>basic_path & normalize();</code></p>
|
||
<p><b>Postcondition:</b> m_name is in <a href="#Normalized">normalized form</a>.</p>
|
||
<p><b>Returns:</b> <code>*this</code></p>
|
||
</blockquote>
|
||
<h3><a name="remove_leaf">remove_leaf</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path & remove_leaf();</pre>
|
||
<p><b>Effects:</b> If <code>has_branch_path()</code> then <code>
|
||
m_name.pop_back()</code>.</p>
|
||
<p><b>Returns:</b> <code>*this</code></p>
|
||
<p><b>Rationale:</b> This function is needed to implement directory iterators.
|
||
It is made public so other uses can benefit from the functionality.</p>
|
||
</blockquote>
|
||
<h3><a name="string">string</a></h3>
|
||
<blockquote>
|
||
<pre>const string_type & string() const;</pre>
|
||
<p><b>Returns:</b> The contents of <code>m_name</code>, formatted as a string according to
|
||
the rules of the <a href="#Grammar">grammar</a>, with a separator appended if
|
||
<code>m_trailing_separator</code> is true.</p>
|
||
<p><b>Note:</b> The returned string must be unambiguous
|
||
according to the grammar. That means that for an operating system with root-names indistinguishable from
|
||
relative-path names, names containing "/", or allowing "." or ".." as
|
||
directory or file names, escapes or other mechanisms will have to be introduced
|
||
into the grammar to prevent ambiguities. This has not been done yet, since no
|
||
current implementations are on operating systems with any of those problems.</p>
|
||
<p><b>See:</b> <a href="#Representation_example">Representation example</a>
|
||
above.</p>
|
||
</blockquote>
|
||
<h3><a name="file_string">file_string</a></h3>
|
||
<blockquote>
|
||
<pre>const string_type file_string() const;</pre>
|
||
<p><b>Returns:</b> The contents of <code>m_name</code>, formatted in the
|
||
<a href="#System-specific-path-representation">system-specific representation</a> of
|
||
a file path.</p>
|
||
<p><b>See:</b> <a href="#Representation_example">Representation example</a>
|
||
above.</p>
|
||
</blockquote>
|
||
<h3><a name="directory_string">directory_string</a></h3>
|
||
<blockquote>
|
||
<pre>const string_type directory_string() const;</pre>
|
||
<p><b>Returns:</b> The contents of <code>m_name</code>, formatted in the
|
||
<a href="#System-specific-path-representation">system-specific representation</a> of
|
||
a directory path.</p>
|
||
<p><b>See:</b> <a href="#Representation_example">Representation example</a>
|
||
above.</p>
|
||
</blockquote>
|
||
<h3><a name="external_file_string">external_file_string</a></h3>
|
||
<blockquote>
|
||
<pre>const external_string_type external_file_string() const;</pre>
|
||
<p><b>Returns:</b> <code>file_string()</code>, converted to the type and
|
||
encoding of <code>external_string_type</code>.</p>
|
||
<p>Using <i>wpath</i> as an example, on Linux the external string type will be
|
||
<i>string_type</i>, and the external encoding will normally be
|
||
<a href="design.htm#Kuhn">UTF-8</a>. On Windows the <i>wpath</i> internal and
|
||
external string types are both <i>std::wstring</i>, and the encoding of both
|
||
is <a href="design.htm#UTF-16">UTF-16</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="external_directory_string">external_directory_string</a></h3>
|
||
<blockquote>
|
||
<pre>const external_string_type external_directory_string() const;</pre>
|
||
<p><b>Returns:</b> <code>directory_string()</code>, converted to the type and
|
||
encoding of <code>external_string_type</code>.</p>
|
||
</blockquote>
|
||
<h3><a name="root_path">root_path</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path root_path() const;</pre>
|
||
<p><b>Returns:</b> <code>root_name() / root_directory()</code></p>
|
||
<p>Portably provides a copy of a path's full root path, if any. See
|
||
<a href="#decomposition">Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="root_name">root_name</a></h3>
|
||
<blockquote>
|
||
<pre>string_type root_name() const;</pre>
|
||
<p><b>Returns:</b> If <code>!m_name.empty() && m_name[0]</code> is a
|
||
<a href="#Grammar">root-name</a>, returns m_name[0], else returns a
|
||
null string.</p>
|
||
<p>Portably provides a copy of a path's <a href="#Grammar">root-name</a>,
|
||
if any. See <a href="#decomposition">Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="root_directory">root_directory</a></h3>
|
||
<blockquote>
|
||
<pre>string_type root_directory() const;</pre>
|
||
<p><b>Returns:</b> If the path contains <a href="#Grammar">root-directory</a>,
|
||
then <code>string("/")</code>, else <code>string()</code>.</p>
|
||
<p>Portably provides a copy of a path's <a href="#Grammar">root-directory</a>,
|
||
if any. The only possible results are "/" or "". See <a href="#decomposition">
|
||
Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="relative_path">relative_path</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path relative_path() const;</pre>
|
||
<p><b>Returns:</b> A new path containing only the <a href="#Grammar">
|
||
relative-path</a> portion of the source path.</p>
|
||
<p>Portably provides a copy of a path's relative portion, if any. See
|
||
<a href="#decomposition">Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="leaf">leaf</a></h3>
|
||
<blockquote>
|
||
<pre>string_type leaf() const;</pre>
|
||
<p><b>Returns:</b> <code>empty() ? string_type() : m_name.back()</code></p>
|
||
<p>A typical use is to obtain a file or directory name without path information
|
||
from a path returned by a <a href="operations.htm#directory_iterator">
|
||
directory_iterator</a>. See <a href="#decomposition">Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="branch_path">branch_path</a></h3>
|
||
<blockquote>
|
||
<pre>basic_path branch_path() const;</pre>
|
||
<p><b>Returns:</b> <code>m_name.size() <= 1 ? path_type("") : x</code>, where <code>x</code>
|
||
is a path constructed from all the elements of <code>m_name</code> except the
|
||
last.</p>
|
||
<p>A typical use is to obtain the parent path for a path supplied by the user.
|
||
See <a href="#decomposition">Path decomposition examples</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="empty">empty</a></h3>
|
||
<blockquote>
|
||
<pre>bool empty() const;</pre>
|
||
<p><b>Returns:</b> <code>string().empty()</code>.</p>
|
||
<p>Determines if a path string itself is
|
||
empty. To determine if the file or directory identified by the path is empty,
|
||
use the <a href="operations.htm#is_empty">operations.hpp is_empty()</a>
|
||
function.</p>
|
||
<p><b>Naming rationale:</b> C++ Standard Library containers use the <i>empty</i>
|
||
name for the equivalent functions.</p>
|
||
</blockquote>
|
||
<h3><a name="is_complete">is_complete</a></h3>
|
||
<blockquote>
|
||
<pre>bool is_complete() const;</pre>
|
||
<p><b>Returns:</b> For single-root operating systems, <code>has_root_directory()</code>.
|
||
For multi-root operating systems, <code>has_root_directory() &&
|
||
has_root_name()</code>.</p>
|
||
<p><b>Naming rationale:</b> The alternate name, is_absolute(), causes
|
||
confusion and controversy because on multi-root operating systems some people
|
||
believe root_name() should participate in is_absolute(), and some
|
||
don't. See the <a href="faq.htm#absolute">FAQ</a>.</p>
|
||
<p><b><a name="is_complete_note">Note</a>:</b> On most operating systems, a
|
||
complete path always unambiguously identifies a specific file or directory. On a few
|
||
systems (classic Mac OS, for example), even a complete path may be ambiguous
|
||
in unusual cases because the OS does not require unambiguousness.</p>
|
||
</blockquote>
|
||
<h3><a name="has_root_path">has_root_path</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_root_path() const;</pre>
|
||
<p><b>Returns:</b> <code>has_root_name() || has_root_directory()</code></p>
|
||
</blockquote>
|
||
<h3><a name="has_root_name">has_root_name</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_root_name() const;</pre>
|
||
<p><b>Returns:</b> <code>!root_name().empty()</code></p>
|
||
</blockquote>
|
||
<h3><a name="has_root_directory">has_root_directory</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_root_directory() const;</pre>
|
||
<p><b>Returns:</b> <code>!root_directory().empty()</code></p>
|
||
</blockquote>
|
||
<h3><a name="has_relative_path">has_relative_path</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_relative_path() const;</pre>
|
||
<p><b>Returns:</b> <code>!relative_path().empty()</code></p>
|
||
</blockquote>
|
||
<h3><a name="has_leaf">has_leaf</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_leaf() const;</pre>
|
||
<p><b>Returns:</b> <code>!leaf().empty()</code></p>
|
||
</blockquote>
|
||
<h3><a name="has_branch_path">has_branch_path</a></h3>
|
||
<blockquote>
|
||
<pre>bool has_branch_path() const;</pre>
|
||
<p><b>Returns:</b> <code>!branch_path().empty()</code></p>
|
||
</blockquote>
|
||
<h3><a name="iterator">iterator</a></h3>
|
||
<blockquote>
|
||
<p><code>typedef <i>implementation-defined</i> iterator;</code></p>
|
||
<p>A const iterator meeting the C++ Standard Library requirements for bidirectional
|
||
iterators (24.1). The iterator is a class type (so that operator++ and -- will
|
||
work on temporaries). The value, reference, and pointer types are <i>std::basic_string<></i>,
|
||
<i>const std::basic_string<> &</i>, and <i>const std::basic_string<> *</i>, respectively.</p>
|
||
</blockquote>
|
||
<h3><a name="begin">begin</a></h3>
|
||
<blockquote>
|
||
<p><code>iterator begin() const;</code></p>
|
||
<p><b>Returns:</b> <code>m_path.begin()</code></p>
|
||
</blockquote>
|
||
<h3><a name="end">end</a></h3>
|
||
<blockquote>
|
||
<p><code>iterator end() const;</code></p>
|
||
<p><b>Returns:</b> <code>m_path.end()</code></p>
|
||
</blockquote>
|
||
<h3><a name="operator_eq">operator</a> ==</h3>
|
||
<blockquote>
|
||
<pre>bool operator==( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>!(*this < that) && !(that < *this)</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="operator_ne">operator !=</a></h3>
|
||
<blockquote>
|
||
<pre>bool operator!=( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>!(*this == that)</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="operator_lt">operator</a> <</h3>
|
||
<blockquote>
|
||
<pre>bool operator<( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>std::lexicographical_compare( begin(), end(),
|
||
that.begin(), that.end() )</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
<p><b>Rationale:</b> Relational operators are provided to ease uses such as
|
||
specifying paths as keys in associative containers. Lexicographical comparison
|
||
is used because:</p>
|
||
<ol>
|
||
<li>Even though not a full-fledged standard container, paths are enough like
|
||
containers to merit meeting the C++ Standard Library's container comparison
|
||
requirements (23.1 table 65).</li>
|
||
<li>The alternative is to return <code>this->string() < that.string()</code>.
|
||
But basic_path::string() as currently specified can yield non-unique results for
|
||
differing paths. The case (from Peter Dimov) is <code>basic_path("first/")/"second"</code>
|
||
and <code>basic_path("first")/"second"</code> both returning a string() of <code>
|
||
"first/second"</code>. <b><i>[TODO: reanalyze this. It doesn't
|
||
make sense anymore Did something change?]</i></b></li>
|
||
</ol>
|
||
</blockquote>
|
||
<h3><a name="operator_le">operator</a> <=</h3>
|
||
<blockquote>
|
||
<pre>bool operator<=( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>!(that < *this)</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="operator_gt">operator</a> ></h3>
|
||
<blockquote>
|
||
<pre>bool operator>( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>that < *this</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
</blockquote>
|
||
<h3><a name="operator_ge">operator</a> >=</h3>
|
||
<blockquote>
|
||
<pre>bool operator>=( const basic_path & that ) const;</pre>
|
||
<p><b>Returns:</b> <code>!(*this < that)</code></p>
|
||
<p>See <a href="#Path_equality">Path equality vs basic_path equivalence</a>.</p>
|
||
</blockquote>
|
||
<h2><a name="Non-member_functions">Non-member functions</a></h2>
|
||
<h3><a name="non-member_operator_shift">Non-member operator /</a></h3>
|
||
<blockquote>
|
||
<p><code>template<class String, class Traits><br>
|
||
basic_path<String, Traits> operator/( <br>
|
||
const typename String::value_type * lhs, const basic_path<String, Traits>
|
||
& rhs );<br>
|
||
<br>
|
||
template<class String, class Traits><br>
|
||
basic_path<String, Traits> operator/(<br>
|
||
const String & lhs, const basic_path<String, Traits> & rhs );</code></p>
|
||
<p><b>Returns:</b> <code>basic_path( lhs ) /= rhs</code></p>
|
||
</blockquote>
|
||
<h2><a name="Rationale">Rationale</a></h2>
|
||
<p>Also see the <a href="faq.htm">FAQ</a> for additional rationale.</p>
|
||
<p><b>Function <a name="Naming_Rationale">naming</a>:</b> Class <i>basic_path</i>
|
||
member function names and <a href="operations.htm">operations.hpp</a> non-member
|
||
function names were chosen to be somewhat distinct from one another. The
|
||
objective was to avoid cases like <i>foo.empty()</i> and <i>empty( foo )</i> both being
|
||
valid, but with completely different semantics. At one point <i>basic_path::empty()</i>
|
||
was renamed <i>basic_path::is_null()</i>, but that caused many coding typos because <i>
|
||
std::string::empty()</i> is often used nearby.</p>
|
||
<p><b>Decomposition functions:</b> Decomposition functions are provided because without them it is impossible to write portable
|
||
basic_path
|
||
manipulations. Convenience is also a factor.</p>
|
||
<p><b>Const vs non-const returns:</b> In some earlier versions of the library,
|
||
member functions returned values as const rather than non-const.
|
||
See Scott Myers, <i>Effective C++</i>, Item 21. The const qualifiers were
|
||
eliminated (1) to conform with C++ Standard Library practice, (2) because
|
||
non-const returns allow occasionally useful expressions, and (3) because the
|
||
number of coding errors eliminated were deemed rare. A requirement that
|
||
basic_path::iterator be a class type was added to eliminate non-const
|
||
iterator errors. The returns from conversion functions are still const
|
||
qualified, to ensure that user programs do not break if implementations change
|
||
from return by value to return by reference, as they are permitted to do.</p>
|
||
<h2>Path <a name="decomposition">decomposition</a> examples</h2>
|
||
<p>It is often useful to extract specific elements from a <i>basic_path</i> object.
|
||
While any decomposition can be achieved by iterating over the elements of a
|
||
<i>basic_path</i>, convenience functions are provided which are easier to use, more
|
||
efficient, and less error prone.</p>
|
||
<p>The first column of the table gives the example path, formatted by the
|
||
string() function. The second column shows the values which would be returned by dereferencing each element iterator. The remaining columns show the results of
|
||
various expressions.</p>
|
||
<table border="1" cellpadding="5" cellspacing="0">
|
||
<tr>
|
||
<td><b>p.string()</b></td>
|
||
<td><b>Elements</b></td>
|
||
<td><b>p.root_<br>
|
||
_path()<br>
|
||
</b></td>
|
||
<td><b>p.root_<br>
|
||
name()</b></td>
|
||
<td><b>p.root_<br>
|
||
directory()</b></td>
|
||
<td><b>p.relative_<br>
|
||
_path()</b></td>
|
||
<td><b>p.root_<br>
|
||
directory()<br>
|
||
/ p.relative_<br>
|
||
path()</b></td>
|
||
<td><b>p.root_<br>
|
||
name() /<br>
|
||
p.relative_<br>
|
||
path()</b></td>
|
||
<td><b>p.branch_<br>
|
||
path()</b></td>
|
||
<td><b>p.leaf()</b></td>
|
||
</tr>
|
||
<tr>
|
||
<td><b>All systems</b></td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>/</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>foo</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>/foo</code></td>
|
||
<td><code>/,foo</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>/foo</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>foo,bar</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>bar</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>/foo/bar</code></td>
|
||
<td><code>/,foo,bar</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>/foo/bar</code></td>
|
||
<td><code>foo/bar</code></td>
|
||
<td><code>/foo</code></td>
|
||
<td><code>bar</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><b><code>.</code></b></td>
|
||
<td><code>.</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>.</code></td>
|
||
<td><code>.</code></td>
|
||
<td><code>.</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>.</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><b><code>..</code></b></td>
|
||
<td><code>..</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>..</code></td>
|
||
<td><code>..</code></td>
|
||
<td><code>..</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>..</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>../foo</code></td>
|
||
<td><code>..,foo</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>../foo</code></td>
|
||
<td><code>../foo</code></td>
|
||
<td><code>../foo</code></td>
|
||
<td><code>..</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><b>Windows</b></td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>c:</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>c:/</code></td>
|
||
<td><code>c:,/</code></td>
|
||
<td><code>c:/</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>/</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>c:..</code></td>
|
||
<td><code>c:,..</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>..</code></td>
|
||
<td><code>c:..</code></td>
|
||
<td><code>c:..</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>..</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>c:foo</code></td>
|
||
<td><code>c:,foo</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>c:foo</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>c:/foo</code></td>
|
||
<td><code>c:,/,foo</code></td>
|
||
<td><code>c:/</code></td>
|
||
<td><code>c:</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>/foo</code></td>
|
||
<td><code>c:foo</code></td>
|
||
<td><code>c:/</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>//net</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>//net</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>//net/</code></td>
|
||
<td><code>//net,/</code></td>
|
||
<td><code>//net/</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>/</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>//net/foo</code></td>
|
||
<td><code>//net,<br>
|
||
/,foo</code></td>
|
||
<td><code>//net/</code></td>
|
||
<td><code>//net</code></td>
|
||
<td><code>/</code></td>
|
||
<td><code>foo</code></td>
|
||
<td><code>/foo</code></td>
|
||
<td><code>//net/foo</code></td>
|
||
<td><code>//net/</code></td>
|
||
<td><code>foo</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>prn:</code></td>
|
||
<td><code>prn:</code></td>
|
||
<td><code>prn:</code></td>
|
||
<td><code>prn:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>prn:</code></td>
|
||
<td><code>""</code></td>
|
||
<td><code>prn:</code></td>
|
||
</tr>
|
||
</table>
|
||
<hr>
|
||
<p>Revised
|
||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->22 March, 2005<!--webbot bot="Timestamp" endspan i-checksum="28898" --></p>
|
||
|
||
<p>© Copyright Beman Dawes, 2002</p>
|
||
<p> Use, modification, and distribution are subject to the Boost Software
|
||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
|
||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||
|
||
</body>
|
||
|
||
</html> |