[12] | 1 | <html> |
---|
| 2 | |
---|
| 3 | <head> |
---|
| 4 | <meta http-equiv="Content-Language" content="en-us"> |
---|
| 5 | <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> |
---|
| 6 | <meta name="ProgId" content="FrontPage.Editor.Document"> |
---|
| 7 | <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> |
---|
| 8 | <title>Boost Filesystem path.hpp Header</title> |
---|
| 9 | </head> |
---|
| 10 | |
---|
| 11 | <body bgcolor="#FFFFFF"> |
---|
| 12 | |
---|
| 13 | <h1> |
---|
| 14 | <img border="0" src="../../../boost.png" align="center" width="277" height="86"><a href="../../../boost/filesystem/path.hpp">boost/filesystem/path.hpp</a></h1> |
---|
| 15 | |
---|
| 16 | <p> |
---|
| 17 | <a href="#Introduction">Introduction</a><br> |
---|
| 18 | <a href="#Grammar">Grammar for generic path strings</a><br> |
---|
| 19 | <a href="#Canonical">Canonical form</a><br> |
---|
| 20 | <a href="#synopsis">Header synopsis</a><br> |
---|
| 21 | <a href="#Class_path">Class path</a><br> |
---|
| 22 | <a href="#Native_path_representation">Native path |
---|
| 23 | representation</a><br> |
---|
| 24 | <a href="#Representation_example">Representation example</a><br> |
---|
| 25 | <a href="#Caution_POSIX">Caution for POSIX and UNIX |
---|
| 26 | programmers</a><br> |
---|
| 27 | <a href="#relative_paths_good">Good programming practice: |
---|
| 28 | relative paths</a><br> |
---|
| 29 | <a href="#Path_equality">Path equality vs path equivalence</a><br> |
---|
| 30 | <a href="#Member">Member functions</a><br> |
---|
| 31 | <a href="#Non-member_functions">Non-member functions</a><br> |
---|
| 32 | <a href="#name_check_mechanism">Default name_check mechansim</a><br> |
---|
| 33 | <a href="#Rationale">Rationale</a><br> |
---|
| 34 | <a href="#decomposition">Path decomposition examples</a></p> |
---|
| 35 | <h2><a name="Introduction">Introduction</a></h2> |
---|
| 36 | |
---|
| 37 | <p>Filesystem Library functions traffic in objects of class <i>path</i>, |
---|
| 38 | provided by this header. The header also supplies non-member functions for error checking.</p> |
---|
| 39 | |
---|
| 40 | <p>For actual operations on files and directories, see <a href="operations.htm"> |
---|
| 41 | boost/filesystem/operations.hpp documentation</a>.</p> |
---|
| 42 | |
---|
| 43 | <p>For file I/O stream operations, see <a href="fstream.htm">boost/filesystem/fstream.hpp |
---|
| 44 | documentation</a>.</p> |
---|
| 45 | |
---|
| 46 | <p>The Filesystem Library's <a href="index.htm#Common_Specifications">Common |
---|
| 47 | Specifications</a> apply to all member and non-member functions supplied by this |
---|
| 48 | header.</p> |
---|
| 49 | |
---|
| 50 | <p>The <a href="portability_guide.htm">Portability Guide</a> discusses path |
---|
| 51 | naming issues which are important when portability is a concern.</p> |
---|
| 52 | <h2><a name="Class_path">Class path</a></h2> |
---|
| 53 | <p>Class <i>path</i> provides for portable mechanism for representing |
---|
| 54 | <a href="index.htm#path">paths</a> in C++ programs, using a portable generic |
---|
| 55 | path string <a href="#Grammar">grammar</a>. Class <i>path</i> |
---|
| 56 | is concerned with the lexical and syntactic aspects of a path. The path does not |
---|
| 57 | have to exist in the operating system's |
---|
| 58 | filesystem, and may contain names which are not even valid for the current |
---|
| 59 | operating system. </p> |
---|
| 60 | <p><b>Rationale:</b> If Filesystem functions trafficked in <i>std::strings</i> or C-style strings, the |
---|
| 61 | functions |
---|
| 62 | would provide only an illusion of portability since the function calls would be |
---|
| 63 | portable but the strings they operate on would not be portable.</p> |
---|
| 64 | <h2>Conceptual <a name="model">model</a> of a path</h2> |
---|
| 65 | <p>An object of class <i>path</i> can be conceptualized as containing a sequence |
---|
| 66 | of strings. Each string is said to be an element of the path. Each element |
---|
| 67 | represents the name of a directory, or, in the case |
---|
| 68 | of the string representing the element farthest from the root in the directory |
---|
| 69 | hierarchy, the name of a directory or file. The names <code>".."</code> and |
---|
| 70 | <code>"."</code> are reserved to represent the concepts of <i>parent-directory</i> |
---|
| 71 | and <i>directory-placeholder</i>.</p> |
---|
| 72 | <p>This conceptual path representation is |
---|
| 73 | |
---|
| 74 | independent of any particular representation of the path as a single |
---|
| 75 | string.</p> |
---|
| 76 | <p>There is no requirement that an implementation of class <i>path</i> actually |
---|
| 77 | contain a sequence of strings, but conceptualizing the contents as a sequence of |
---|
| 78 | strings provides |
---|
| 79 | a completely portable way to reason about paths.</p> |
---|
| 80 | <p>So that programs can portably express paths as a single string, class <i>path</i> |
---|
| 81 | defines a <a href="#Grammar">grammar</a> for a portable generic path string |
---|
| 82 | format, and supplies constructor and append operations taking such strings as |
---|
| 83 | arguments. Because user input or third-party library functions may supply path |
---|
| 84 | strings formatted according to operating system specific rules, an additional |
---|
| 85 | constructor is provided which takes a system-specific format as an argument.</p> |
---|
| 86 | <p>Access functions are provided to retrieve the contents of a object of class |
---|
| 87 | <i>path</i> formatted as a portable path string, a directory path string using |
---|
| 88 | the operating system's format, and a file path string using the operating |
---|
| 89 | system's format. Additional access functions retrieve specific portions of |
---|
| 90 | the contained path.</p> |
---|
| 91 | <h2><a name="Grammar">Grammar</a> for portable generic path strings</h2> |
---|
| 92 | <p>The grammar is specified in extended BNF, with terminal symbols in quotes: |
---|
| 93 | </p> |
---|
| 94 | <blockquote> |
---|
| 95 | <pre>path ::= [root] [relative-path] // an empty path is valid</pre> |
---|
| 96 | <pre>root ::= [root-name] [root-directory]</pre> |
---|
| 97 | <pre>root-directory ::= separator</pre> |
---|
| 98 | <pre>relative-path ::= path-element { separator path-element } [separator]</pre> |
---|
| 99 | <pre>path-element ::= name | parent-directory | directory-placeholder</pre> |
---|
| 100 | <pre>name ::= char { char }</pre> |
---|
| 101 | <pre>directory-placeholder ::= "."</pre> |
---|
| 102 | <pre>parent-directory ::= ".." |
---|
| 103 | |
---|
| 104 | separator ::= "/" // an implementation may define additional separators </pre> |
---|
| 105 | </blockquote> |
---|
| 106 | <p><i>root-name</i> grammar is implementation-defined. <i> |
---|
| 107 | root-name</i> must not be present in generic input. It may be part of the strings returned by <i>path</i> |
---|
| 108 | member functions, and may be present in the <i>src</i> argument to <i>path</i> constructors |
---|
| 109 | when the <i><a href="portability_guide.htm#native">native</a></i> name check is in effect.</p> |
---|
| 110 | <p><i>char</i> may not be slash ('/') or '\0'. In additional, many operating and |
---|
| 111 | file systems may place additional restrictions on the characters which may |
---|
| 112 | appear in names. See <a href="portability_guide.htm#recommendations">File and |
---|
| 113 | Directory Name Recommendations</a>.</p> |
---|
| 114 | <p>Although implementation-defined, it is desirable that <i> |
---|
| 115 | root-name</i> have a grammar which is distinguishable from other grammar elements, |
---|
| 116 | and follow the conventions of the operating system.</p> |
---|
| 117 | <p>The optional trailing "/" in a <i>relative-path</i> is allowed as a |
---|
| 118 | notational convenience. It has no semantic meaning and is simply discarded.</p> |
---|
| 119 | <p>Whether or not a generic path string is actually portable to a particular |
---|
| 120 | operating system will depend on the |
---|
| 121 | names used. See the <a href="portability_guide.htm">Portability Guide</a>.</p> |
---|
| 122 | <h2><a name="Canonical">Canonical</a> form</h2> |
---|
| 123 | <p>All operations modifying <i>path</i> objects leave the <i>path</i> object in |
---|
| 124 | canonical form.</p> |
---|
| 125 | <p>An empty path is in canonical form.</p> |
---|
| 126 | <p>A non-empty path is converted to canonical form as if by first converting it |
---|
| 127 | to the <a href="#model">conceptual model</a>, and then:</p> |
---|
| 128 | <ul> |
---|
| 129 | <li>Repeatedly replacing any leading <i>root-directory, parent-directory</i> |
---|
| 130 | elements with a single <i>root-directory</i> element. Rationale: Both POSIX |
---|
| 131 | and Windows specify this reduction; specifying it for canonical form ensures |
---|
| 132 | portable semantics for other operating systems.</li> |
---|
| 133 | <li>Removing each <i>directory-placeholder</i> element.</li> |
---|
| 134 | <li>If the path is now empty, add a single <i>directory-placeholder</i> |
---|
| 135 | element.</li> |
---|
| 136 | </ul> |
---|
| 137 | <h2><a name="Normalized">Normalized</a> form</h2> |
---|
| 138 | <p>Normalized form is the same as canonical form, except that adjacent <i>name, parent-directory</i> |
---|
| 139 | elements are recursively removed.</p> |
---|
| 140 | <p>Thus a non-empty path in normal form either has no <i> |
---|
| 141 | directory-placeholders</i>, or consists solely of one <i>directory-placeholder</i>. |
---|
| 142 | If it has <i>parent-directory</i> elements, they precede all <i>name</i> |
---|
| 143 | elements.</p> |
---|
| 144 | <h2>Header <a href="../../../boost/filesystem/path.hpp"> |
---|
| 145 | boost/filesystem/path.hpp</a> <a name="synopsis">synopsis</a></h2> |
---|
| 146 | <pre>namespace boost |
---|
| 147 | { |
---|
| 148 | namespace filesystem |
---|
| 149 | { |
---|
| 150 | class path |
---|
| 151 | { |
---|
| 152 | public: |
---|
| 153 | <a name="name_check_typedef">typedef</a> bool (*name_check)( const std::string & name ); |
---|
| 154 | |
---|
| 155 | // compiler generates copy constructor, |
---|
| 156 | // copy assignment, and destructor |
---|
| 157 | |
---|
| 158 | // constructors: |
---|
| 159 | <a href="#constructors">path</a>(); |
---|
| 160 | <a href="#constructors">path</a>( const std::string & src ); |
---|
| 161 | <a href="#constructors">path</a>( const char * src ); |
---|
| 162 | <a href="#constructors">path</a>( const std::string & src, name_check checker ); |
---|
| 163 | <a href="#constructors">path</a>( const char * src, name_check checker ); |
---|
| 164 | |
---|
| 165 | // append operations: |
---|
| 166 | path & <a href="#operator_slash_equal">operator /=</a> ( const path & rhs ); |
---|
| 167 | path <a href="#operator_slash">operator /</a> ( const path & rhs ) const; |
---|
| 168 | |
---|
| 169 | // conversion functions: |
---|
| 170 | const std::string & <a href="#string">string</a>() const; |
---|
| 171 | std::string <a href="#native_file_string">native_file_string</a>() const; |
---|
| 172 | std::string <a href="#native_directory_string">native_directory_string</a>() const; |
---|
| 173 | |
---|
| 174 | // modification functions: |
---|
| 175 | path & <a href="#normalize">normalize</a>(); |
---|
| 176 | |
---|
| 177 | // decomposition functions: |
---|
| 178 | path <a href="#root_path">root_path</a>() const; |
---|
| 179 | std::string <a href="#root_name">root_name</a>() const; |
---|
| 180 | std::string <a href="#root_directory">root_directory</a>() const; |
---|
| 181 | path <a href="#relative_path">relative_path</a>() const; |
---|
| 182 | std::string <a href="#leaf">leaf</a>() const; |
---|
| 183 | path <a href="#branch_path">branch_path</a>() const; |
---|
| 184 | |
---|
| 185 | // query functions: |
---|
| 186 | bool <a href="#empty">empty</a>() const; |
---|
| 187 | bool <a href="#is_complete">is_complete</a>() const; |
---|
| 188 | bool <a href="#has_root_path">has_root_path</a>() const; |
---|
| 189 | bool <a href="#has_root_name">has_root_name</a>() const; |
---|
| 190 | bool <a href="#has_root_directory">has_root_directory</a>() const; |
---|
| 191 | bool <a href="#has_relative_path">has_relative_path</a>() const; |
---|
| 192 | bool <a href="#has_leaf">has_leaf</a>() const; |
---|
| 193 | bool <a href="#has_branch_path">has_branch_path</a>() const; |
---|
| 194 | |
---|
| 195 | // iteration: |
---|
| 196 | typedef <i>implementation-defined</i> <a href="#iterator">iterator</a>; |
---|
| 197 | iterator <a href="#begin">begin</a>() const; |
---|
| 198 | iterator <a href="#end">end</a>() const; |
---|
| 199 | |
---|
| 200 | // <a href="#name_check_mechanism">default name_check</a> mechanism: |
---|
| 201 | static bool <a href="#default_name_check_writable">default_name_check_writable</a>(); |
---|
| 202 | static void <a href="#default_name_check">default_name_check</a>( name_check new_check ); |
---|
| 203 | static name_check <a href="#default_name_check">default_name_check</a>();</pre> |
---|
| 204 | <pre> // relational operators: |
---|
| 205 | bool <a href="#operator_eq">operator==</a>( const path & that ) const; |
---|
| 206 | bool <a href="#operator_ne">operator!=</a>( const path & that ) const; |
---|
| 207 | bool <a href="#operator_lt">operator<</a>( const path & that ) const; |
---|
| 208 | bool <a href="#operator_le">operator<=</a>( const path & that ) const; |
---|
| 209 | bool <a href="#operator_gt">operator></a>( const path & that ) const; |
---|
| 210 | bool <a href="#operator_ge">operator>=</a>( const path & that ) const; |
---|
| 211 | |
---|
| 212 | private: |
---|
| 213 | std::vector<std::string> m_name; // for exposition only |
---|
| 214 | }; |
---|
| 215 | |
---|
| 216 | path <a href="#non-member_operator_shift">operator /</a> ( const char * lhs, const path & rhs ); |
---|
| 217 | path <a href="#non-member_operator_shift">operator /</a> ( const std::string & lhs, const path & rhs ); |
---|
| 218 | |
---|
| 219 | // <a href="portability_guide.htm#name_check_functions">name_check functions</a> |
---|
| 220 | bool <a href="portability_guide.htm#portable_posix_name">portable_posix_name</a>( const std::string & name ); |
---|
| 221 | bool <a href="portability_guide.htm#windows_name">windows_name</a>( const std::string & name ); |
---|
| 222 | bool <a href="portability_guide.htm#portable_name">portable_name</a>( const std::string & name ); |
---|
| 223 | bool <a href="portability_guide.htm#portable_directory_name">portable_directory_name</a>( const std::string & name ); |
---|
| 224 | bool <a href="portability_guide.htm#portable_file_name">portable_file_name</a>( const std::string & name ); |
---|
| 225 | bool <a href="portability_guide.htm#no_check">no_check</a>( const std::string & name ); |
---|
| 226 | bool <a href="portability_guide.htm#native">native</a>( const std::string & name ); |
---|
| 227 | } |
---|
| 228 | }</pre> |
---|
| 229 | <p>For the sake of exposition, class <i>path</i> member functions are described |
---|
| 230 | as if the class contains a private member <i>std::vector<std::string> m_name</i>. |
---|
| 231 | Actual implementations may differ.</p> |
---|
| 232 | <p>Class path member, or non-member operator/, functions may throw a |
---|
| 233 | <a href="exception.htm">filesystem_error</a> exception if the path is not in the |
---|
| 234 | syntax specified for the <a href="#Grammar">grammar</a>.</p> |
---|
| 235 | <p><b>Note:</b> There is no guarantee that a <i>path</i> object represents a |
---|
| 236 | path which is considered valid by the current operating system. A path might be |
---|
| 237 | invalid to the operating system because it contains invalid names (too long, |
---|
| 238 | invalid characters, and so on), or because it is a partial path still as yet |
---|
| 239 | unfinished by the program. An invalid path will normally be detected at time of |
---|
| 240 | use, such as by one of the Filesystem Library's <a href="operations.htm"> |
---|
| 241 | operations</a> or <a href="fstream.htm">fstream</a> functions.</p> |
---|
| 242 | <p><b>Portability Warning:</b> There is no guarantee that a <i>path</i> object |
---|
| 243 | represents a path which would be portable to another operating system. A path |
---|
| 244 | might be non-portable because it contains names which the operating systems |
---|
| 245 | considers too long or contains invalid characters. A |
---|
| 246 | <a href="#name_check_mechanism">default name_check mechanism</a> is provided to |
---|
| 247 | aid in the detection of non-portable names, or a name_check function can be |
---|
| 248 | specified in <i>path</i> constructors. The library supplies several |
---|
| 249 | <a href="portability_guide.htm#name_check_functions">name_check |
---|
| 250 | functions</a>, or users can supply their own.</p> |
---|
| 251 | <h3><a name="Native_path_representation">Native path representation</a></h3> |
---|
| 252 | <p>Several <i>path</i> member functions return representations of <i>m_name</i> |
---|
| 253 | in formats specific to the operating system. These formats are implementation |
---|
| 254 | defined. If an <i>m_name</i> |
---|
| 255 | element contains characters which are invalid under the operating system's |
---|
| 256 | rules, and there is an unambiguous translation between the invalid character and |
---|
| 257 | a valid character, the implementation is required to perform that translation. |
---|
| 258 | For example, if an operating system does not permit lowercase letters in file or |
---|
| 259 | directory names, these letters will be translated to uppercase if unambiguous. |
---|
| 260 | Such translation does not apply to generic path string format representations.</p> |
---|
| 261 | <h3><a name="Representation_example">Representation example</a></h3> |
---|
| 262 | <p>The rule-of-thumb is to use <i>string()</i> when a generic string representation of |
---|
| 263 | the path is required, and use either |
---|
| 264 | <i>native_directory_string()</i> or |
---|
| 265 | <i>native_file_string()</i> when a string representation formatted for |
---|
| 266 | the particular operating system is required.</p> |
---|
| 267 | <p>The difference between the representations returned by <i>string()</i>, |
---|
| 268 | <i>native_directory_string()</i>, and |
---|
| 269 | <i>native_file_string()</i> are illustrated by the following |
---|
| 270 | code:</p> |
---|
| 271 | <blockquote> |
---|
| 272 | <pre>path my_path( "foo/bar/data.txt" ); |
---|
| 273 | std::cout |
---|
| 274 | << "string------------------: " << my_path.string() << '\n' |
---|
| 275 | << "native_directory_string-: " << my_path.native_directory_string() << '\n' |
---|
| 276 | << "native_file_string------: " << my_path.native_file_string() << '\n';</pre> |
---|
| 277 | </blockquote> |
---|
| 278 | <p>On POSIX systems, the output would be:</p> |
---|
| 279 | <blockquote> |
---|
| 280 | <pre>string------------------: foo/bar/data.txt |
---|
| 281 | native_directory_string-: foo/bar/data.txt |
---|
| 282 | native_file_string------: foo/bar/data.txt</pre> |
---|
| 283 | </blockquote> |
---|
| 284 | <p>On Windows, the output would be:</p> |
---|
| 285 | <blockquote> |
---|
| 286 | <pre>string------------------: foo/bar/data.txt |
---|
| 287 | native_directory_string-: foo\bar\data.txt |
---|
| 288 | native_file_string------: foo\bar\data.txt</pre> |
---|
| 289 | </blockquote> |
---|
| 290 | <p>On classic Mac OS, the output would be:</p> |
---|
| 291 | <blockquote> |
---|
| 292 | <pre>string------------------: foo/bar/data.txt |
---|
| 293 | native_directory_string-: foo:bar:data.txt |
---|
| 294 | native_file_string------: foo:bar:data.txt</pre> |
---|
| 295 | </blockquote> |
---|
| 296 | <p>On a hypothetical operating system using OpenVMS format representations, it would be:</p> |
---|
| 297 | <blockquote> |
---|
| 298 | <pre>string------------------: foo/bar/data.txt |
---|
| 299 | native_directory_string-: [foo.bar.data.txt] |
---|
| 300 | native_file_string------: [foo.bar]data.txt</pre> |
---|
| 301 | </blockquote> |
---|
| 302 | <p>Note that that because OpenVMS uses period as both a directory separator |
---|
| 303 | character and as a separator between filename and extension, <i> |
---|
| 304 | native_directory_string()</i> |
---|
| 305 | in the example produces a useless result. On this operating system, the |
---|
| 306 | programmer should only use this path as a file path. (There is a |
---|
| 307 | <a href="portability_guide.htm#recommendations">portability recommendation</a> |
---|
| 308 | to not use periods in directory names.)</p> |
---|
| 309 | <h3><a name="Caution_POSIX">Caution</a> for POSIX and UNIX programmers</h3> |
---|
| 310 | <p>POSIX and other UNIX-like operating systems have a single root, while most other |
---|
| 311 | operating systems have multiple roots. Multi-root operating systems require a |
---|
| 312 | root-name |
---|
| 313 | such as a drive, device, disk, volume, or share name for a path to be resolved |
---|
| 314 | to an actual specific file or directory. |
---|
| 315 | Because of this, the <i>root()</i> and <i>root_directory()</i> functions return |
---|
| 316 | identical results on UNIX and other single-root operating systems, but different |
---|
| 317 | results on multi-root operating systems. Thus use of the wrong function will not be |
---|
| 318 | apparent on UNIX-like systems, but will result in non-portable code which will |
---|
| 319 | fail when used on multi-root systems. UNIX programmers are cautioned to use |
---|
| 320 | particular care in choosing between <i>root()</i> and <i>root_directory()</i>. If |
---|
| 321 | undecided, use <i>root()</i>.</p> |
---|
| 322 | <p>The same warning applies to <i>has_root()</i> and <i>has_root_directory()</i>.</p> |
---|
| 323 | <h3><a name="relative_paths_good">Good programming practice: relative paths</a></h3> |
---|
| 324 | <p>It is usually bad programming practice to hard-code <a href="#is_complete"> |
---|
| 325 | complete paths</a> into programs. Such programs tend to be fragile because they |
---|
| 326 | break when directory trees get reorganized or the programs are moved to other |
---|
| 327 | machines or operating systems.</p> |
---|
| 328 | <p>The most robust way to deal with path completion is to hard-code only |
---|
| 329 | relative paths. When a complete path is required, it can be obtained in several |
---|
| 330 | ways:</p> |
---|
| 331 | <ul> |
---|
| 332 | <li><b>Implicitly</b>. Allow the operating system to complete the path |
---|
| 333 | according to the operating system's path completion algorithm. For example:<pre> create_directory( "foo" ); // operating system will complete path</pre> |
---|
| 334 | </li> |
---|
| 335 | <li><b>User input</b>. The path is often best <a href="#constructors"> |
---|
| 336 | constructed</a> with the <i>native</i> name check, so that the user input |
---|
| 337 | follows the operating system's native path format, which will usually be what |
---|
| 338 | the program user expects. For example:<pre> path foo( argv[1], native ); |
---|
| 339 | foo /= "foo";</pre> |
---|
| 340 | </li> |
---|
| 341 | <li><b><a href="operations.htm#initial_path">initial_path()</a></b>. |
---|
| 342 | Particularly for command line programs, specifying paths relative to the |
---|
| 343 | current path at the time the program is started is a common practice. For |
---|
| 344 | example:<pre> path foo( initial_path() / "foo" );</pre> |
---|
| 345 | </li> |
---|
| 346 | <li><b>Algorithmically</b>. See <a href="operations.htm#complete">complete()</a> |
---|
| 347 | and <a href="operations.htm#system_complete">system_complete()</a> functions.</li> |
---|
| 348 | </ul> |
---|
| 349 | <h3><a name="Path_equality">Path equality</a> vs path equivalence</h3> |
---|
| 350 | <p>Are paths "abc" and "ABC" equal? No, never, if you determine equality via |
---|
| 351 | class <i>path</i>'s <code>operator==</code>, which considers only the two paths |
---|
| 352 | lexical representations.</p> |
---|
| 353 | <p>Do paths "abc" and "ABC" resolve to the same file or directory? The answer is |
---|
| 354 | "yes", "no", or "maybe" depending on the external file system. The (pending) |
---|
| 355 | operations function equivalent() is the only way to determine if two paths |
---|
| 356 | resolve to the same external file system entity.</p> |
---|
| 357 | <p>Programmers wishing to determine if two paths are "the same" must decide if |
---|
| 358 | that means "the same representation" or "resolve to the same actual file or |
---|
| 359 | directory", and choose the appropriate function accordingly.</p> |
---|
| 360 | <h2><a name="Member">Member</a> functions</h2> |
---|
| 361 | <h3><a name="constructors">constructors</a></h3> |
---|
| 362 | <blockquote> |
---|
| 363 | <pre>path();</pre> |
---|
| 364 | <p><b>Effects:</b> Default constructs an object of class <i>path</i>.</p> |
---|
| 365 | <p><b>Postcondition:</b> path().empty()</p> |
---|
| 366 | <pre>path( const std::string & src, name_check checker ); |
---|
| 367 | path( const char * src, name_check checker ); |
---|
| 368 | path( const std::string & src ); |
---|
| 369 | path( const char * src );</pre> |
---|
| 370 | <p>For the single-argument forms, <code>default_name_check()</code> is used as |
---|
| 371 | <code>checker</code>. </p> |
---|
| 372 | <p><b>Precondition:</b> <code>src != 0</code>.</p> |
---|
| 373 | <p><b>Effects:</b> Select the grammar as follows:</p> |
---|
| 374 | <ul> |
---|
| 375 | <li>If <code>checker == native</code>, the operating system's implementation |
---|
| 376 | defined grammar for paths.</li> |
---|
| 377 | <li>else if <code>checker == no_check</code>, the <a href="#Grammar">generic |
---|
| 378 | path string grammar</a> with optional <i> |
---|
| 379 | root-name</i>.</li> |
---|
| 380 | <li>else the <a href="#Grammar">generic |
---|
| 381 | path string grammar</a> without <i> |
---|
| 382 | root-name</i>.</li> |
---|
| 383 | </ul> |
---|
| 384 | <p>Parse src into a sequence of names, according to the grammar, then, for each name in <code>src</code>, <code>m_name.push_back( |
---|
| 385 | name )</code>.</p> |
---|
| 386 | <p><b>Throws:</b> For each name in <code>src</code>, throw if <code>checker( |
---|
| 387 | name )</code> returns |
---|
| 388 | false.</p> |
---|
| 389 | <p><b>Postcondition:</b> <code>m_name</code> is in |
---|
| 390 | <a href="#Canonical">canonical form</a>. For the single-argument forms only, <code>!default_name_check_writable()</code>.</p> |
---|
| 391 | <p><b>Rationale:</b> The single-argument constructors are not <code>explicit</code> because an intended |
---|
| 392 | use is automatic conversion of strings to paths.</p> |
---|
| 393 | </blockquote> |
---|
| 394 | <h3><a name="operator_slash_equal">operator /=</a></h3> |
---|
| 395 | <blockquote> |
---|
| 396 | <pre>path & operator/=( const path & rhs );</pre> |
---|
| 397 | <p><b>Effects:</b> If any of the following conditions are met, then |
---|
| 398 | m_name.push_back("/").</p> |
---|
| 399 | <ul> |
---|
| 400 | <li>has_relative_path().</li> |
---|
| 401 | <li>!is_absolute() && has_root_name(), and the operating system |
---|
| 402 | requires the system-specific root be absolute</li> |
---|
| 403 | </ul> |
---|
| 404 | <p> Then append <code>rhs.m_name</code> to <code>m_name</code>.</p> |
---|
| 405 | <p>(Footnote: Thus on Windows, (path("//share") /= "foo").string() is |
---|
| 406 | "//share/foo")</p> |
---|
| 407 | <p><b>Returns:</b> <code>*this</code></p> |
---|
| 408 | <p><b>Postcondition:</b> <code>m_name</code> is in |
---|
| 409 | <a href="#Canonical">canonical form</a>.</p> |
---|
| 410 | <p><b>Rationale:</b> It is not considered an error for <code>rhs</code> to |
---|
| 411 | include a <code>root-directory</code> because <code>m_name</code> might be relative |
---|
| 412 | or empty, and |
---|
| 413 | thus it is valid for rhs to supply <code>root-directory</code>. For example, on Windows, the following must succeed:</p> |
---|
| 414 | <blockquote> |
---|
| 415 | <pre>path p( "c:", native ); |
---|
| 416 | p /= "/foo"; |
---|
| 417 | assert( p.string() == "c:/foo" );</pre> |
---|
| 418 | </blockquote> |
---|
| 419 | </blockquote> |
---|
| 420 | <h3><a name="operator_slash">operator /</a></h3> |
---|
| 421 | <blockquote> |
---|
| 422 | <pre>const path operator/ ( const path & rhs ) const;</pre> |
---|
| 423 | <p><b>Returns:</b> <code>path( *this ) /= rhs</code></p> |
---|
| 424 | <p><b>Rationale:</b> Operator / is supplied because together with operator /=, |
---|
| 425 | it provides a |
---|
| 426 | convenient way for users to supply paths with a variable number of elements. |
---|
| 427 | For example, <code>initial_path() / "src" / test_name</code>. |
---|
| 428 | Operator+ and operator+= were considered as alternatives, but deemed too |
---|
| 429 | easy to confuse with those operators for std::string. Operator<< and |
---|
| 430 | operator=<< were used originally until during public review Dave |
---|
| 431 | Abrahams pointed out that / and /= |
---|
| 432 | match the generic path syntax.</p> |
---|
| 433 | <p><b>Note:</b> Also see <a href="#non-member_operator_shift">non-member <i> |
---|
| 434 | operator/</i></a> functions.</p> |
---|
| 435 | </blockquote> |
---|
| 436 | <h3><a name="normalize">normalize</a></h3> |
---|
| 437 | <blockquote> |
---|
| 438 | <p><code>path & normalize();</code></p> |
---|
| 439 | <p><b>Postcondition:</b> m_name is in <a href="#Normalized">normalized form</a>.</p> |
---|
| 440 | <p><b>Returns:</b> <code>*this</code></p> |
---|
| 441 | </blockquote> |
---|
| 442 | <h3><a name="string">string</a></h3> |
---|
| 443 | <blockquote> |
---|
| 444 | <pre>const std::string & string() const;</pre> |
---|
| 445 | <p><b>Returns:</b> The contents of <code>m_name</code>, formatted according to |
---|
| 446 | the rules of the <a href="#Grammar">generic path string grammar</a>.</p> |
---|
| 447 | <p><b>Note:</b> The returned string must be unambiguous |
---|
| 448 | according to the grammar. That means that for an operating system with root-names indistinguishable from |
---|
| 449 | relative-path names, names containing "/", or allowing "." or ".." as |
---|
| 450 | directory or file names, escapes or other mechanisms will have to be introduced |
---|
| 451 | into the grammar to prevent ambiguities. This has not been done yet, since no |
---|
| 452 | current implementations are on operating systems with any of those problems.</p> |
---|
| 453 | <p><b>See:</b> <a href="#Representation_example">Representation example</a> |
---|
| 454 | above.</p> |
---|
| 455 | </blockquote> |
---|
| 456 | <h3><a name="native_file_string">native_file_string</a></h3> |
---|
| 457 | <blockquote> |
---|
| 458 | <pre>std::string native_file_string() const;</pre> |
---|
| 459 | <p><b>Returns:</b> The contents of <code>m_name</code>, formatted in the |
---|
| 460 | <a href="#Native_path_representation">native representation</a> of |
---|
| 461 | a file path.</p> |
---|
| 462 | <p><b>See:</b> <a href="#Representation_example">Representation example</a> |
---|
| 463 | above.</p> |
---|
| 464 | <p><b>Naming rationale</b>: The name is deliberately ugly to warn users that |
---|
| 465 | this function yields non-portable results.</p> |
---|
| 466 | </blockquote> |
---|
| 467 | <h3><a name="native_directory_string">native_directory_string</a></h3> |
---|
| 468 | <blockquote> |
---|
| 469 | <pre>const std::string native_directory_string() const;</pre> |
---|
| 470 | <p><b>Returns:</b> The contents of <code>m_name</code>, formatted in the |
---|
| 471 | <a href="#Native_path_representation">native representation</a> of |
---|
| 472 | a directory path.</p> |
---|
| 473 | <p><b>See:</b> <a href="#Representation_example">Representation example</a> |
---|
| 474 | above.</p> |
---|
| 475 | <p><b>Naming rationale</b>: The name is deliberately ugly to warn users that |
---|
| 476 | this function yields non-portable results.</p> |
---|
| 477 | </blockquote> |
---|
| 478 | <h3><a name="root_path">root_path</a></h3> |
---|
| 479 | <blockquote> |
---|
| 480 | <pre>path root_path() const;</pre> |
---|
| 481 | <p><b>Returns:</b> <code>root_name() / root_directory()</code></p> |
---|
| 482 | <p>Portably provides a copy of a path's full root path, if any. See |
---|
| 483 | <a href="#decomposition">Path decomposition examples</a>.</p> |
---|
| 484 | </blockquote> |
---|
| 485 | <h3><a name="root_name">root_name</a></h3> |
---|
| 486 | <blockquote> |
---|
| 487 | <pre>std::string root_name() const;</pre> |
---|
| 488 | <p><b>Returns:</b> If <code>!m_name.empty() && m_name[0]</code> is a |
---|
| 489 | <a href="#Grammar">root-name</a>, returns m_name[0], else returns a |
---|
| 490 | null string.</p> |
---|
| 491 | <p>Portably provides a copy of a path's <a href="#Grammar">root-name</a>, |
---|
| 492 | if any. See <a href="#decomposition">Path decomposition examples</a>.</p> |
---|
| 493 | </blockquote> |
---|
| 494 | <h3><a name="root_directory">root_directory</a></h3> |
---|
| 495 | <blockquote> |
---|
| 496 | <pre>std::string root_directory() const;</pre> |
---|
| 497 | <p><b>Returns:</b> If the path contains <a href="#Grammar">root-directory</a>, |
---|
| 498 | then <code>string("/")</code>, else <code>string()</code>.</p> |
---|
| 499 | <p>Portably provides a copy of a path's <a href="#Grammar">root-directory</a>, |
---|
| 500 | if any. The only possible results are "/" or "". See <a href="#decomposition"> |
---|
| 501 | Path decomposition examples</a>.</p> |
---|
| 502 | </blockquote> |
---|
| 503 | <h3><a name="relative_path">relative_path</a></h3> |
---|
| 504 | <blockquote> |
---|
| 505 | <pre>path relative_path() const;</pre> |
---|
| 506 | <p><b>Returns:</b> A new path containing only the <a href="#Grammar"> |
---|
| 507 | relative-path</a> portion of the source path.</p> |
---|
| 508 | <p>Portably provides a copy of a path's relative portion, if any. See |
---|
| 509 | <a href="#decomposition">Path decomposition examples</a>.</p> |
---|
| 510 | </blockquote> |
---|
| 511 | <h3><a name="leaf">leaf</a></h3> |
---|
| 512 | <blockquote> |
---|
| 513 | <pre>std::string leaf() const;</pre> |
---|
| 514 | <p><b>Returns:</b> <code>empty() ? std::string() : m_name.back()</code></p> |
---|
| 515 | <p>A typical use is to obtain a file or directory name without path information |
---|
| 516 | from a path returned by a <a href="operations.htm#directory_iterator"> |
---|
| 517 | directory_iterator</a>. See <a href="#decomposition">Path decomposition examples</a>.</p> |
---|
| 518 | </blockquote> |
---|
| 519 | <h3><a name="branch_path">branch_path</a></h3> |
---|
| 520 | <blockquote> |
---|
| 521 | <pre>path branch_path() const;</pre> |
---|
| 522 | <p><b>Returns:</b> <code>m_name.size() <= 1 ? path("") : x</code>, where <code>x</code> |
---|
| 523 | is a path constructed from all the elements of <code>m_name</code> except the |
---|
| 524 | last.</p> |
---|
| 525 | <p>A typical use is to obtain the parent path for a path supplied by the user. |
---|
| 526 | See <a href="#decomposition">Path decomposition examples</a>.</p> |
---|
| 527 | </blockquote> |
---|
| 528 | <h3><a name="empty">empty</a></h3> |
---|
| 529 | <blockquote> |
---|
| 530 | <pre>bool empty() const;</pre> |
---|
| 531 | <p><b>Returns:</b> <code>string().empty()</code>.</p> |
---|
| 532 | <p>The <i>path::empty()</i> function determines if a path string itself is |
---|
| 533 | empty. To determine if the file or directory identified by the path is empty, |
---|
| 534 | use the <a href="operations.htm#is_empty">operations.hpp is_empty()</a> |
---|
| 535 | function.</p> |
---|
| 536 | <p><b>Naming rationale:</b> C++ Standard Library containers use the <i>empty</i> |
---|
| 537 | name for the equivalent functions.</p> |
---|
| 538 | </blockquote> |
---|
| 539 | <h3><a name="is_complete">is_complete</a></h3> |
---|
| 540 | <blockquote> |
---|
| 541 | <pre>bool is_complete() const;</pre> |
---|
| 542 | <p><b>Returns:</b> For single-root operating systems, <code>has_root_directory()</code>. |
---|
| 543 | For multi-root operating systems, <code>has_root_directory() && |
---|
| 544 | has_root_name()</code>.</p> |
---|
| 545 | <p><b>Naming rationale:</b> The alternate name, is_absolute(), causes |
---|
| 546 | confusion and controversy because on multi-root operating systems some people |
---|
| 547 | believe root_name() should participate in is_absolute(), and some |
---|
| 548 | don't. See the <a href="faq.htm#absolute">FAQ</a>.</p> |
---|
| 549 | <p><b><a name="is_complete_note">Note</a>:</b> On most operating systems, a |
---|
| 550 | complete path always unambiguously identifies a specific file or directory. On a few |
---|
| 551 | systems (classic Mac OS, for example), even a complete path may be ambiguous |
---|
| 552 | in unusual cases because the OS does not require unambiguousness.</p> |
---|
| 553 | </blockquote> |
---|
| 554 | <h3><a name="has_root_path">has_root_path</a></h3> |
---|
| 555 | <blockquote> |
---|
| 556 | <pre>bool has_root_path() const;</pre> |
---|
| 557 | <p><b>Returns:</b> <code>has_root_name() || has_root_directory()</code></p> |
---|
| 558 | </blockquote> |
---|
| 559 | <h3><a name="has_root_name">has_root_name</a></h3> |
---|
| 560 | <blockquote> |
---|
| 561 | <pre>bool has_root_name() const;</pre> |
---|
| 562 | <p><b>Returns:</b> <code>!root_name().empty()</code></p> |
---|
| 563 | </blockquote> |
---|
| 564 | <h3><a name="has_root_directory">has_root_directory</a></h3> |
---|
| 565 | <blockquote> |
---|
| 566 | <pre>bool has_root_directory() const;</pre> |
---|
| 567 | <p><b>Returns:</b> <code>!root_directory().empty()</code></p> |
---|
| 568 | </blockquote> |
---|
| 569 | <h3><a name="has_relative_path">has_relative_path</a></h3> |
---|
| 570 | <blockquote> |
---|
| 571 | <pre>bool has_relative_path() const;</pre> |
---|
| 572 | <p><b>Returns:</b> <code>!relative_path().empty()</code></p> |
---|
| 573 | </blockquote> |
---|
| 574 | <h3><a name="has_leaf">has_leaf</a></h3> |
---|
| 575 | <blockquote> |
---|
| 576 | <pre>bool has_leaf() const;</pre> |
---|
| 577 | <p><b>Returns:</b> <code>!leaf().empty()</code></p> |
---|
| 578 | </blockquote> |
---|
| 579 | <h3><a name="has_branch_path">has_branch_path</a></h3> |
---|
| 580 | <blockquote> |
---|
| 581 | <pre>bool has_branch_path() const;</pre> |
---|
| 582 | <p><b>Returns:</b> <code>!branch_path().empty()</code></p> |
---|
| 583 | </blockquote> |
---|
| 584 | <h3><a name="iterator">iterator</a></h3> |
---|
| 585 | <blockquote> |
---|
| 586 | <p><code>typedef <i>implementation-defined</i> iterator;</code></p> |
---|
| 587 | <p>A const iterator meeting the C++ Standard Library requirements for bidirectional |
---|
| 588 | iterators (24.1). The iterator is a class type (so that operator++ and -- will |
---|
| 589 | work on temporaries). The value, reference, and pointer types are <i>std::string</i>, |
---|
| 590 | <i>const std::string &</i>, and <i>const std::string *</i>, respectively.</p> |
---|
| 591 | </blockquote> |
---|
| 592 | <h3><a name="begin">begin</a></h3> |
---|
| 593 | <blockquote> |
---|
| 594 | <p><code>iterator begin() const;</code></p> |
---|
| 595 | <p><b>Returns:</b> <code>m_path.begin()</code></p> |
---|
| 596 | </blockquote> |
---|
| 597 | <h3><a name="end">end</a></h3> |
---|
| 598 | <blockquote> |
---|
| 599 | <p><code>iterator end() const;</code></p> |
---|
| 600 | <p><b>Returns:</b> <code>m_path.end()</code></p> |
---|
| 601 | </blockquote> |
---|
| 602 | <h3><a name="default_name_check_writable">default_name_check_writable</a></h3> |
---|
| 603 | <blockquote> |
---|
| 604 | <p><code>static bool default_name_check_writable();</code></p> |
---|
| 605 | <p><b>Returns:</b> True, unless a <i>default_name_check</i> function has been |
---|
| 606 | previously called. </p> |
---|
| 607 | </blockquote> |
---|
| 608 | <h3><a name="default_name_check">default_name_check</a></h3> |
---|
| 609 | <blockquote> |
---|
| 610 | <p><code>static void default_name_check( name_check new_check );</code></p> |
---|
| 611 | <p><b>Precondition:</b> new_check != 0</p> |
---|
| 612 | <p><b>Postcondition:</b> <code>default_name_check(new_check) && !default_name_check_writable()</code></p> |
---|
| 613 | <p><b>Throws:</b> if <code>!default_name_check_writable()</code></p> |
---|
| 614 | <p><code>static name_check default_name_check();</code></p> |
---|
| 615 | <p><b>Returns:</b> the default name_check.</p> |
---|
| 616 | <p><b>Postcondition:</b> <code>!default_name_check_writable()</code></p> |
---|
| 617 | </blockquote> |
---|
| 618 | <h3><a name="operator_eq">operator</a> ==</h3> |
---|
| 619 | <blockquote> |
---|
| 620 | <pre>bool operator==( const path & that ) const;</pre> |
---|
| 621 | <p><b>Returns:</b> <code>!(*this < that) && !(that < *this)</code></p> |
---|
| 622 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 623 | </blockquote> |
---|
| 624 | <h3><a name="operator_ne">operator !=</a></h3> |
---|
| 625 | <blockquote> |
---|
| 626 | <pre>bool operator!=( const path & that ) const;</pre> |
---|
| 627 | <p><b>Returns:</b> <code>!(*this == that)</code></p> |
---|
| 628 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 629 | </blockquote> |
---|
| 630 | <h3><a name="operator_lt">operator</a> <</h3> |
---|
| 631 | <blockquote> |
---|
| 632 | <pre>bool operator<( const path & that ) const;</pre> |
---|
| 633 | <p><b>Returns:</b> <code>std::lexicographical_compare( begin(), end(), |
---|
| 634 | that.begin(), that.end() )</code></p> |
---|
| 635 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 636 | <p><b>Rationale:</b> Relational operators are provided to ease uses such as |
---|
| 637 | specifying paths as keys in associative containers. Lexicographical comparison |
---|
| 638 | is used because:</p> |
---|
| 639 | <ol> |
---|
| 640 | <li>Even though not a full-fledged standard container, paths are enough like |
---|
| 641 | containers to merit meeting the C++ Standard Library's container comparison |
---|
| 642 | requirements (23.1 table 65).</li> |
---|
| 643 | <li>The alternative is to return <code>this->string(), that.string()</code>. |
---|
| 644 | But path::string() as currently specified can yield non-unique results for |
---|
| 645 | differing paths. The case (from Peter Dimov) is <code>path("first/")/"second"</code> |
---|
| 646 | and <code>path("first")/"second"</code> both returning a string() of <code> |
---|
| 647 | "first//second"</code>.</li> |
---|
| 648 | </ol> |
---|
| 649 | </blockquote> |
---|
| 650 | <h3><a name="operator_le">operator</a> <=</h3> |
---|
| 651 | <blockquote> |
---|
| 652 | <pre>bool operator<=( const path & that ) const;</pre> |
---|
| 653 | <p><b>Returns:</b> <code>!(that < *this)</code></p> |
---|
| 654 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 655 | </blockquote> |
---|
| 656 | <h3><a name="operator_gt">operator</a> ></h3> |
---|
| 657 | <blockquote> |
---|
| 658 | <pre>bool operator>( const path & that ) const;</pre> |
---|
| 659 | <p><b>Returns:</b> <code>that < *this</code></p> |
---|
| 660 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 661 | </blockquote> |
---|
| 662 | <h3><a name="operator_ge">operator</a> >=</h3> |
---|
| 663 | <blockquote> |
---|
| 664 | <pre>bool operator>=( const path & that ) const;</pre> |
---|
| 665 | <p><b>Returns:</b> <code>!(*this < that)</code></p> |
---|
| 666 | <p>See <a href="#Path_equality">Path equality vs path equivalence</a>.</p> |
---|
| 667 | </blockquote> |
---|
| 668 | <h2><a name="Non-member_functions">Non-member functions</a></h2> |
---|
| 669 | <h3><a name="non-member_operator_shift">Non-member operator /</a></h3> |
---|
| 670 | <blockquote> |
---|
| 671 | <p><code>path operator / ( const char * lhs, const path & rhs );<br> |
---|
| 672 | path operator / ( const std::string & lhs, const path & rhs );</code></p> |
---|
| 673 | <p><b>Returns:</b> <code>path( lhs ) /= rhs</code></p> |
---|
| 674 | </blockquote> |
---|
| 675 | <h2>Default <a name="name_check_mechanism">name_check mechanism</a></h2> |
---|
| 676 | <p>It is difficult or impossible to write portable programs without some way to |
---|
| 677 | verify that directory and file names are portable. Without automatic name |
---|
| 678 | checking, verification is tedious, error prone, and ugly. Yet no single name |
---|
| 679 | check function can serve all applications, and within an application |
---|
| 680 | different paths or portions of paths may require different name check |
---|
| 681 | functions. Sometimes there should be no checking at all.</p> |
---|
| 682 | <p>Those needs are met by providing a default name check function to meet an |
---|
| 683 | application's most common needs, and then providing <i>path</i> constructors |
---|
| 684 | which override the default name check function to handle less common needs. |
---|
| 685 | The default name check function can be set by the application, allowing the |
---|
| 686 | most common case for the particular application to be handled by the default |
---|
| 687 | check. </p> |
---|
| 688 | <h3>Dangers</h3> |
---|
| 689 | <p>The default name check function is set and retrieved by <i>path</i> static |
---|
| 690 | member functions, and as such is similar to a global variable. Since global variables are |
---|
| 691 | considered harmful [<a href="design.htm#Wulf-Shaw-73">Wulf-Shaw-73</a>], class |
---|
| 692 | <i>path</i> allows the default name check function to be set only once, and |
---|
| 693 | only before the first use. This turns a dangerous global variable into a |
---|
| 694 | safer global constant. Even with this protection, the ability to set the default name check function is |
---|
| 695 | still a powerful feature, and is still dangerous in that it can change |
---|
| 696 | the behavior of code buried out-of-sight in libraries or elsewhere. Thus |
---|
| 697 | changing the default error check function should only be done when explicitly |
---|
| 698 | specifying the function via the two argument <i>path</i> constructors is not |
---|
| 699 | reasonable.</p> |
---|
| 700 | <h2><a name="Rationale">Rationale</a></h2> |
---|
| 701 | <p>Also see the <a href="faq.htm">FAQ</a> for additional rationale.</p> |
---|
| 702 | <p><b>Function <a name="Naming_Rationale">naming</a>:</b> Class <i>path</i> |
---|
| 703 | member function names and <a href="operations.htm">operations.hpp</a> non-member |
---|
| 704 | function names were chosen to be somewhat distinct from one another. The |
---|
| 705 | objective was to avoid cases like <i>foo.empty()</i> and <i>empty( foo )</i> both being |
---|
| 706 | valid, but with completely different semantics. At one point <i>path::empty()</i> |
---|
| 707 | was renamed <i>path::is_null()</i>, but that caused many coding typos because <i> |
---|
| 708 | std::string::empty()</i> is often used nearby.</p> |
---|
| 709 | <p><b>Decomposition functions:</b> Decomposition functions are provided because without them it is impossible to write portable path |
---|
| 710 | manipulations. Convenience is also a factor.</p> |
---|
| 711 | <p><b>Const vs non-const returns:</b> In some earlier versions of the library, |
---|
| 712 | member functions returned values as const rather than non-const. |
---|
| 713 | See Scott Myers, <i>Effective C++</i>, Item 21. The const qualifiers were |
---|
| 714 | eliminated (1) to conform with C++ Standard Library practice, (2) because |
---|
| 715 | non-const returns allow occasionally useful expressions, and (3) because the |
---|
| 716 | number of coding errors eliminated were deemed rare. A requirement that path::iterator be a class type was added to eliminate non-const |
---|
| 717 | iterator errors.</p> |
---|
| 718 | <h2>Path <a name="decomposition">decomposition</a> examples</h2> |
---|
| 719 | <p>It is often useful to extract specific elements from a path object. |
---|
| 720 | While any decomposition can be achieved by iterating over the elements of a |
---|
| 721 | path, convenience functions are provided which are easier to use, more |
---|
| 722 | efficient, and less error prone.</p> |
---|
| 723 | <p>The first column of the table gives the example path, formatted by the |
---|
| 724 | string() function. The second column shows the values which would be returned by |
---|
| 725 | dereferencing each element iterator. The remaining columns show the results of |
---|
| 726 | various expressions.</p> |
---|
| 727 | <table border="1" cellpadding="5" cellspacing="0"> |
---|
| 728 | <tr> |
---|
| 729 | <td><b>p.string()</b></td> |
---|
| 730 | <td><b>Elements</b></td> |
---|
| 731 | <td><b>p.root_<br> |
---|
| 732 | path()<br> |
---|
| 733 | </b></td> |
---|
| 734 | <td><b>p.root_<br> |
---|
| 735 | name()</b></td> |
---|
| 736 | <td><b>p.root_<br> |
---|
| 737 | directory()</b></td> |
---|
| 738 | <td><b>p.relative_<br> |
---|
| 739 | path()</b></td> |
---|
| 740 | <td><b>p.root_<br> |
---|
| 741 | directory()<br> |
---|
| 742 | / p.relative_<br> |
---|
| 743 | path()</b></td> |
---|
| 744 | <td><b>p.root_<br> |
---|
| 745 | name() /<br> |
---|
| 746 | p.relative_<br> |
---|
| 747 | path()</b></td> |
---|
| 748 | <td><b>p.branch_<br> |
---|
| 749 | path()</b></td> |
---|
| 750 | <td><b>p.leaf()</b></td> |
---|
| 751 | </tr> |
---|
| 752 | <tr> |
---|
| 753 | <td><b>All systems</b></td> |
---|
| 754 | <td> </td> |
---|
| 755 | <td> </td> |
---|
| 756 | <td> </td> |
---|
| 757 | <td> </td> |
---|
| 758 | <td> </td> |
---|
| 759 | <td> </td> |
---|
| 760 | <td> </td> |
---|
| 761 | <td> </td> |
---|
| 762 | <td> </td> |
---|
| 763 | </tr> |
---|
| 764 | <tr> |
---|
| 765 | <td><code>/</code></td> |
---|
| 766 | <td><code>/</code></td> |
---|
| 767 | <td><code>/</code></td> |
---|
| 768 | <td><code>""</code></td> |
---|
| 769 | <td><code>/</code></td> |
---|
| 770 | <td><code>""</code></td> |
---|
| 771 | <td><code>/</code></td> |
---|
| 772 | <td><code>""</code></td> |
---|
| 773 | <td><code>""</code></td> |
---|
| 774 | <td><code>/</code></td> |
---|
| 775 | </tr> |
---|
| 776 | <tr> |
---|
| 777 | <td><code>foo</code></td> |
---|
| 778 | <td><code>foo</code></td> |
---|
| 779 | <td><code>""</code></td> |
---|
| 780 | <td><code>""</code></td> |
---|
| 781 | <td><code>""</code></td> |
---|
| 782 | <td><code>foo</code></td> |
---|
| 783 | <td><code>foo</code></td> |
---|
| 784 | <td><code>foo</code></td> |
---|
| 785 | <td><code>""</code></td> |
---|
| 786 | <td><code>foo</code></td> |
---|
| 787 | </tr> |
---|
| 788 | <tr> |
---|
| 789 | <td><code>/foo</code></td> |
---|
| 790 | <td><code>/,foo</code></td> |
---|
| 791 | <td><code>/</code></td> |
---|
| 792 | <td><code>""</code></td> |
---|
| 793 | <td><code>/</code></td> |
---|
| 794 | <td><code>foo</code></td> |
---|
| 795 | <td><code>/foo</code></td> |
---|
| 796 | <td><code>foo</code></td> |
---|
| 797 | <td><code>/</code></td> |
---|
| 798 | <td><code>foo</code></td> |
---|
| 799 | </tr> |
---|
| 800 | <tr> |
---|
| 801 | <td><code>foo/bar</code></td> |
---|
| 802 | <td><code>foo,bar</code></td> |
---|
| 803 | <td><code>""</code></td> |
---|
| 804 | <td><code>""</code></td> |
---|
| 805 | <td><code>""</code></td> |
---|
| 806 | <td><code>foo/bar</code></td> |
---|
| 807 | <td><code>foo/bar</code></td> |
---|
| 808 | <td><code>foo/bar</code></td> |
---|
| 809 | <td><code>foo</code></td> |
---|
| 810 | <td><code>bar</code></td> |
---|
| 811 | </tr> |
---|
| 812 | <tr> |
---|
| 813 | <td><code>/foo/bar</code></td> |
---|
| 814 | <td><code>/,foo,bar</code></td> |
---|
| 815 | <td><code>/</code></td> |
---|
| 816 | <td><code>""</code></td> |
---|
| 817 | <td><code>/</code></td> |
---|
| 818 | <td><code>foo/bar</code></td> |
---|
| 819 | <td><code>/foo/bar</code></td> |
---|
| 820 | <td><code>foo/bar</code></td> |
---|
| 821 | <td><code>/foo</code></td> |
---|
| 822 | <td><code>bar</code></td> |
---|
| 823 | </tr> |
---|
| 824 | <tr> |
---|
| 825 | <td><b><code>.</code></b></td> |
---|
| 826 | <td><code>.</code></td> |
---|
| 827 | <td><code>""</code></td> |
---|
| 828 | <td><code>""</code></td> |
---|
| 829 | <td><code>""</code></td> |
---|
| 830 | <td><code>.</code></td> |
---|
| 831 | <td><code>.</code></td> |
---|
| 832 | <td><code>.</code></td> |
---|
| 833 | <td><code>""</code></td> |
---|
| 834 | <td><code>.</code></td> |
---|
| 835 | </tr> |
---|
| 836 | <tr> |
---|
| 837 | <td><b><code>..</code></b></td> |
---|
| 838 | <td><code>..</code></td> |
---|
| 839 | <td><code>""</code></td> |
---|
| 840 | <td><code>""</code></td> |
---|
| 841 | <td><code>""</code></td> |
---|
| 842 | <td><code>..</code></td> |
---|
| 843 | <td><code>..</code></td> |
---|
| 844 | <td><code>..</code></td> |
---|
| 845 | <td><code>""</code></td> |
---|
| 846 | <td><code>..</code></td> |
---|
| 847 | </tr> |
---|
| 848 | <tr> |
---|
| 849 | <td><code>../foo</code></td> |
---|
| 850 | <td><code>..,foo</code></td> |
---|
| 851 | <td><code>""</code></td> |
---|
| 852 | <td><code>""</code></td> |
---|
| 853 | <td><code>""</code></td> |
---|
| 854 | <td><code>../foo</code></td> |
---|
| 855 | <td><code>../foo</code></td> |
---|
| 856 | <td><code>../foo</code></td> |
---|
| 857 | <td><code>..</code></td> |
---|
| 858 | <td><code>foo</code></td> |
---|
| 859 | </tr> |
---|
| 860 | <tr> |
---|
| 861 | <td><b>Windows</b></td> |
---|
| 862 | <td> </td> |
---|
| 863 | <td> </td> |
---|
| 864 | <td> </td> |
---|
| 865 | <td> </td> |
---|
| 866 | <td> </td> |
---|
| 867 | <td> </td> |
---|
| 868 | <td> </td> |
---|
| 869 | <td> </td> |
---|
| 870 | <td> </td> |
---|
| 871 | </tr> |
---|
| 872 | <tr> |
---|
| 873 | <td><code>c:</code></td> |
---|
| 874 | <td><code>c:</code></td> |
---|
| 875 | <td><code>c:</code></td> |
---|
| 876 | <td><code>c:</code></td> |
---|
| 877 | <td><code>""</code></td> |
---|
| 878 | <td><code>""</code></td> |
---|
| 879 | <td><code>""</code></td> |
---|
| 880 | <td><code>c:</code></td> |
---|
| 881 | <td><code>""</code></td> |
---|
| 882 | <td><code>c:</code></td> |
---|
| 883 | </tr> |
---|
| 884 | <tr> |
---|
| 885 | <td><code>c:/</code></td> |
---|
| 886 | <td><code>c:,/</code></td> |
---|
| 887 | <td><code>c:/</code></td> |
---|
| 888 | <td><code>c:</code></td> |
---|
| 889 | <td><code>/</code></td> |
---|
| 890 | <td><code>""</code></td> |
---|
| 891 | <td><code>/</code></td> |
---|
| 892 | <td><code>c:</code></td> |
---|
| 893 | <td><code>c:</code></td> |
---|
| 894 | <td><code>/</code></td> |
---|
| 895 | </tr> |
---|
| 896 | <tr> |
---|
| 897 | <td><code>c:..</code></td> |
---|
| 898 | <td><code>c:,..</code></td> |
---|
| 899 | <td><code>c:</code></td> |
---|
| 900 | <td><code>c:</code></td> |
---|
| 901 | <td><code>""</code></td> |
---|
| 902 | <td><code>..</code></td> |
---|
| 903 | <td><code>c:..</code></td> |
---|
| 904 | <td><code>c:..</code></td> |
---|
| 905 | <td><code>c:</code></td> |
---|
| 906 | <td><code>..</code></td> |
---|
| 907 | </tr> |
---|
| 908 | <tr> |
---|
| 909 | <td><code>c:foo</code></td> |
---|
| 910 | <td><code>c:,foo</code></td> |
---|
| 911 | <td><code>c:</code></td> |
---|
| 912 | <td><code>c:</code></td> |
---|
| 913 | <td><code>""</code></td> |
---|
| 914 | <td><code>foo</code></td> |
---|
| 915 | <td><code>foo</code></td> |
---|
| 916 | <td><code>c:foo</code></td> |
---|
| 917 | <td><code>c:</code></td> |
---|
| 918 | <td><code>foo</code></td> |
---|
| 919 | </tr> |
---|
| 920 | <tr> |
---|
| 921 | <td><code>c:/foo</code></td> |
---|
| 922 | <td><code>c:,/,foo</code></td> |
---|
| 923 | <td><code>c:/</code></td> |
---|
| 924 | <td><code>c:</code></td> |
---|
| 925 | <td><code>/</code></td> |
---|
| 926 | <td><code>foo</code></td> |
---|
| 927 | <td><code>/foo</code></td> |
---|
| 928 | <td><code>c:foo</code></td> |
---|
| 929 | <td><code>c:/</code></td> |
---|
| 930 | <td><code>foo</code></td> |
---|
| 931 | </tr> |
---|
| 932 | <tr> |
---|
| 933 | <td><code>//shr</code></td> |
---|
| 934 | <td><code>//shr</code></td> |
---|
| 935 | <td><code>//shr</code></td> |
---|
| 936 | <td><code>//shr</code></td> |
---|
| 937 | <td><code>""</code></td> |
---|
| 938 | <td><code>""</code></td> |
---|
| 939 | <td><code>""</code></td> |
---|
| 940 | <td><code>//shr</code></td> |
---|
| 941 | <td><code>""</code></td> |
---|
| 942 | <td><code>//shr</code></td> |
---|
| 943 | </tr> |
---|
| 944 | <tr> |
---|
| 945 | <td><code>//shr/</code></td> |
---|
| 946 | <td><code>//shr,/</code></td> |
---|
| 947 | <td><code>//shr/</code></td> |
---|
| 948 | <td><code>//shr</code></td> |
---|
| 949 | <td><code>/</code></td> |
---|
| 950 | <td><code>""</code></td> |
---|
| 951 | <td><code>/</code></td> |
---|
| 952 | <td><code>//shr</code></td> |
---|
| 953 | <td><code>//shr</code></td> |
---|
| 954 | <td><code>/</code></td> |
---|
| 955 | </tr> |
---|
| 956 | <tr> |
---|
| 957 | <td><code>//shr/foo</code></td> |
---|
| 958 | <td><code>//shr,<br> |
---|
| 959 | /,foo</code></td> |
---|
| 960 | <td><code>//shr/</code></td> |
---|
| 961 | <td><code>//shr</code></td> |
---|
| 962 | <td><code>/</code></td> |
---|
| 963 | <td><code>foo</code></td> |
---|
| 964 | <td><code>/foo</code></td> |
---|
| 965 | <td><code>//shr/foo</code></td> |
---|
| 966 | <td><code>//shr/</code></td> |
---|
| 967 | <td><code>foo</code></td> |
---|
| 968 | </tr> |
---|
| 969 | <tr> |
---|
| 970 | <td><code>prn:</code></td> |
---|
| 971 | <td><code>prn:</code></td> |
---|
| 972 | <td><code>prn:</code></td> |
---|
| 973 | <td><code>prn:</code></td> |
---|
| 974 | <td><code>""</code></td> |
---|
| 975 | <td><code>""</code></td> |
---|
| 976 | <td><code>""</code></td> |
---|
| 977 | <td><code>prn:</code></td> |
---|
| 978 | <td><code>""</code></td> |
---|
| 979 | <td><code>prn:</code></td> |
---|
| 980 | </tr> |
---|
| 981 | </table> |
---|
| 982 | <hr> |
---|
| 983 | <p>Revised |
---|
| 984 | <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->02 August, 2005<!--webbot bot="Timestamp" endspan i-checksum="34600" --></p> |
---|
| 985 | |
---|
| 986 | <p>© Copyright Beman Dawes, 2002</p> |
---|
| 987 | <p> Use, modification, and distribution are subject to the Boost Software |
---|
| 988 | License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> |
---|
| 989 | LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> |
---|
| 990 | www.boost.org/LICENSE_1_0.txt</a>)</p> |
---|
| 991 | |
---|
| 992 | </body> |
---|
| 993 | |
---|
| 994 | </html> |
---|