File: operations.htm

package info (click to toggle)
boost 1.33.1-10
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 100,948 kB
  • ctags: 145,103
  • sloc: cpp: 573,492; xml: 49,055; python: 15,626; ansic: 13,588; sh: 2,099; yacc: 858; makefile: 660; perl: 427; lex: 111; csh: 6
file content (642 lines) | stat: -rw-r--r-- 33,155 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
<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 operations.hpp Header</title>
</head>

<body bgcolor="#FFFFFF">

<h1>
<img border="0" src="../../../boost.png" align="center" width="277" height="86"><a href="../../../boost/filesystem/operations.hpp">boost/filesystem/operations.hpp</a></h1>

<p><a href="#Introduction">Introduction</a><br>
<a href="#Synopsis">Header synopsis</a><br>
<a href="#directory_iterator">Class directory_iterator</a><br>
&nbsp;&nbsp;&nbsp; <a href="#constructors">Constructors</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Other_functions">Other_functions</a><br>
<a href="#Non-member_functions">Operations functions</a><br>
&nbsp;&nbsp;&nbsp; <a href="#exists">exists</a><br>
&nbsp;&nbsp;&nbsp; <a href="#symbolic_link_exists">symbolic_link_exists</a><br>
&nbsp;&nbsp;&nbsp; <a href="#is_directory">is_directory</a><br>
&nbsp;&nbsp;&nbsp; <a href="#is_empty">is_empty</a><br>
&nbsp;&nbsp;&nbsp; <a href="#equivalent">equivalent</a><br>
&nbsp;&nbsp;&nbsp; <a href="#file_size">file_size</a><br>
&nbsp;&nbsp;&nbsp; <a href="#last_write_time">last_write_time</a><br>
&nbsp;&nbsp;&nbsp; <a href="#create_directory">create_directory</a><br>
&nbsp;&nbsp;&nbsp; <a href="#remove">remove</a><br>
&nbsp;&nbsp;&nbsp; <a href="#remove_all">remove_all</a><br>
&nbsp;&nbsp;&nbsp; <a href="#rename">rename</a><br>
&nbsp;&nbsp;&nbsp; <a href="#copy_file">copy_file</a><br>
&nbsp;&nbsp;&nbsp; <a href="#initial_path">initial_path</a><br>
&nbsp;&nbsp;&nbsp; <a href="#complete">complete</a><br>
&nbsp;&nbsp;&nbsp; <a href="#system_complete">system_complete</a></p>

<h2><a name="Introduction">Introduction</a></h2>

<p>The <a href="../../../boost/filesystem/operations.hpp">
boost/filesystem/operations.hpp</a> header provides operations on files and 
directories.</p>

<p>These operations traffic in paths; see <a href="path.htm">
boost/filesystem/path.hpp documentation</a>.</p>

<p>For file I/O streams, 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>

<h2>Header <a href="../../../boost/filesystem/operations.hpp">boost/filesystem/operations.hpp</a>
<a name="Synopsis">synopsis</a></h2>
<pre>namespace boost
{
  namespace filesystem
  {

    class <a href="#directory_iterator">directory_iterator</a>
    {
    public:
      typedef <a href="path.htm">path</a>                     value_type;
      typedef std::ptrdiff_t           difference_type;
      typedef const path *             pointer;
      typedef const path &amp;             reference;
      typedef std::input_iterator_tag  iterator_category;

      <a href="#constructors">directory_iterator</a>();
      explicit <a href="#constructors">directory_iterator</a>( const path &amp; directory_ph );

      // <a href="#Other_functions">Other_functions</a>
      // ...
    };

    bool <a href="#exists">exists</a>( const path &amp; ph );
    bool <a href="#symbolic_link_exists">symbolic_link_exists</a>( const path &amp; ph );
    bool <a href="#is_directory">is_directory</a>( const path &amp; ph );
    bool <a href="#is_empty">is_empty</a>( const path &amp; ph );
    bool <a href="#equivalent">equivalent</a>( const path &amp; ph1, const path &amp; ph2 );

    boost::intmax_t <a href="#file_size">file_size</a>( const path &amp; ph );

    std::time_t <a href="#last_write_time">last_write_time</a>( const path &amp; ph );
    void <a href="#last_write_time">last_write_time</a>( const path &amp; ph, std::time_t new_time );

    bool <a href="#create_directory">create_directory</a>( const path &amp; directory_ph );
    bool <a href="#remove">remove</a>( const path &amp; ph );
    unsigned long <a href="#remove_all">remove_all</a>( const path &amp; ph );
    void <a href="#rename">rename</a>( const path &amp; from_path,
                 const path &amp; to_path );
    void <a href="#copy_file">copy_file</a>( const path &amp; source_file,
                    const path &amp; target_file );

    const path &amp; <a href="#initial_path">initial_path</a>();
    path <a href="#current_path">current_path</a>();
    path <a href="#complete">complete</a>( const path &amp; ph,
                   const path &amp; base = initial_path() );
    path <a href="#system_complete">system_complete</a>( const path &amp; ph );

  } // namespace filesystem
} // namespace boost
</pre>

<h2><a name="directory_iterator">Class directory_iterator</a></h2>

<p>Class <i>directory_iterator</i> provides a C++ standard conforming input 
iterator which accesses the contents of a <a href="index.htm#directory">
directory</a>. </p>

<p>The value type is <i><a href="path.htm">boost::filesystem::path</a></i>, so 
dereferencing a <i>directory_iterator</i> yields a <a href="index.htm#path">
path</a> to a file or sub-directory contained within the directory represented by 
the directory-path argument supplied at construction. The path returned by 
dereferencing a <i>directory_iterator</i> is composed by appending the name of 
the directory entry to the directory path supplied at construction.</p>

<p>The order of the path entries returned by dereferencing successive increments 
of a <i>directory_iterator</i> is unspecified. Thus depending on the ordering 
provided by a particular implementation will result in non-portable code.</p>

<p>A path returned by dereferencing a <i>directory_iterator</i> is, if 
representing a directory, suitable for use as an argument to Filesystem Library 
functions specified as accepting paths or directory paths. If not representing a 
directory, the dereferenced path is suitable for use as an argument to 
Filesystem Library functions specified as accepting paths or file paths, or C++ 
Standard Library functions specified as taking file names. The leaf of a path 
returned by dereferencing a <i>directory_iterator</i> will never be <code>&quot;..&quot;</code> 
or <code>&quot;.&quot;</code>.</p>

<p><b>Note:</b> The implication of the above requirement is that if an operating 
system's directories can contain entries which are not usable by Filesystem 
Library or Standard Library functions, these entries will be skipped during 
directory iteration. Such entries are by definition non-portable, but can always 
be accessed via the native operating system API if required.</p>

<p><b><a name="symbolic-link-warning">Warning</a>:</b> Programs performing 
directory iteration may wish to test, via <a href="#exists">exists()</a>, if the 
path returned by dereferencing an iterator actually exists. It could be a
<a href="index.htm#symbolic-link">symbolic link</a> to a non-existent file or 
directory. Programs recursively walking directory trees for purposes of removing 
and renaming entries may wish to avoid following symbolic links, which can be 
detected with <a href="#symbolic_link_exists">symbolic_link_exists()</a>.</p>

<p><b>Warning:</b> If a file or sub-directory is removed from or added to a 
directory after the construction of a <i>directory_iterator</i> for the 
directory, it is unspecified whether or not subsequent incrementing of the 
iterator will ever result in an iterator whose value is the removed or added 
directory entry.</p>

<h3><a name="constructors">Constructors</a></h3>
<blockquote>

<p><code>directory_iterator();</code></p>

<p><b>Effects:</b> Constructs a <i>directory_iterator</i> having the <i>
past-the-end</i> value as described in the C++ standard, section 24.1.</p>

<p><code>explicit directory_iterator( const path &amp; directory_ph );</code></p>

<p><b>Effects:</b> Constructs a <i>directory_iterator</i> with a value 
representing the first path in <i>directory_ph</i>, or if <code>
empty(directory_ph)</code>, the <i>past-the-end</i> value.</p>

<p><b>Throws:</b> if <code>!exists( directory_ph )</code></p>

<p><b>Note:</b> To iterate over the current directory, write <code>
directory_iterator(current_path())</code> rather than <code>directory_iterator(&quot;&quot;)</code>.</p>
</blockquote>

<h3><a name="Other_functions">Other functions</a></h3>

<p>Class <i>directory_iterator</i> also supplies all the other functions 
required by the C++ standard clause 24 for input iterators, such as <i>operator==</i>, 
<i>operator++</i>, and <i>operator*</i>.</p>

<h2><a name="Non-member_functions">Non-member functions</a></h2>

<p>
The non-member functions provide common operations on files and directories. 
They follow traditional practice of the C and C++ standard libraries, except 
that 
they:</p>

<ul>
  <li>Traffic in <i><a href="path.htm">paths</a></i> rather than <code>char*</code>'s, for much 
  enhanced portability.</li>
  <li>Report errors by throwing exceptions, for safer and better error handling.</li>
  <li>Tighten specifications slightly, for improved portability.</li>
</ul>

<p>
<b>Rationale:</b> Functions which already exist in the C++ Standard Library, 
such as <i><a href="#remove">remove()</a></i> and <i><a href="#rename">rename()</a></i>, 
retain the same names and general behavior in the Filesystem Library, to 
minimize surprises.</p>

<p>
<b><a name="not-precondition-rationale">Rationale</a>:</b> Some errors which might 
at first glance appear to be preconditions are not 
specified as such, but instead will throw exceptions. This is 
because the possibility of <a href="index.htm#Race-condition">race-conditions</a> 
makes it unreliable to test for preconditions before calling the function. As a 
design practice, preconditions are not specified when it is not reasonable for a 
program to test for them before calling the function. </p>

<p><b>Empty path r<a name="empty_rationale">ationale</a>:</b> Some errors, 
particularly function arguments of empty paths, are specified both in <i>
Precondition</i> and in <i>Throws</i> paragraphs. A non-empty path is specified 
as a precondition because an empty path is almost certainly an error, the error 
meets the usual criteria for <i>Preconditions</i> as specified in the C++ 
Standard clause 17, and user pre-detection of the error does not suffer from the
<a href="#not-precondition-rationale">precondition race</a> problem described 
above. The error condition is also specified in the <i>Throws</i> paragraph to 
ensure that the error results in well-defined rather than implementation-defined 
behavior, and because existing practice for the equivalent operating system 
function is usually to treat an empty path as an error. The intended use of the 
Filesystem Library in script-like programs makes undefined behavior particularly 
unattractive.</p>

<p>
<b>Naming Rationale:</b> See class <i>path</i>
<a href="path.htm#Naming_Rationale">Naming Rationale</a>.</p>

<h3><a name="exists">exists</a></h3>
<blockquote>
<p><code>bool exists( const path &amp; ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path 
represented by <i>ph</i> exists, else false.</p>
<p><b>Note: </b>Even if <code>exists( ph ) == true</code>, there is no guarantee that it 
will be possible to perform other operations on the file or directory. Access 
rights or other security concerns, for example, may cause other operations to 
fail.</p>
<p><b>Note:</b> <code>exists(&quot;&quot;)</code> is valid and returns false;</p>
</blockquote>
<h3><a name="symbolic_link_exists">symbolic_link_exists</a></h3>
<blockquote>
<p><code>bool symbolic_link_exists( const path &amp; ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by&nbsp;
<i>ph</i> is present and is a <a href="index.htm#symbolic-link">symbolic link</a>, else false.</p>
<p><b>Note:</b> See the <a href="#symbolic-link-warning">directory iterator 
warning</a> for one use of <code>symbolic_link_exists()</code>.</p>
<p><b>Note:</b> The Microsoft Windows operating system does not currently 
support symbolic links, so <code>symbolic_link_exists()</code> always returns 
false on that platform. (Short-cut files (.lnk) are a Windows application 
feature, not an O/S feature.) Programmers should still test for symbolic links 
where applicable in case Windows adds the feature, and also so that programs 
will be portable to systems like POSIX, where symbolic links may be present.</p>
<p><b>Rationale:</b> The function does not throw if <i>ph</i> is not present, 
and is accordingly named <code>symbolic_link_exists</code> rather than <code>
is_symbolic_link</code>. Non-throwing behavior permits testing for all four 
possible conditions:</p>
  <ul>
    <li><i>ph</i> not present: <code>!exists(ph) &amp;&amp; !symbolic_link_exists(ph)</code></li>
    <li><i>ph</i> present and is not a symbolic link: <code>exists(ph) &amp;&amp; !symbolic_link_exists(ph)</code></li>
    <li><i>ph</i> present and is a symbolic link to a non-existent file or 
    directory: <code>!exists(ph) &amp;&amp; symbolic_link_exists(ph)</code></li>
    <li><i>ph</i> present and is a symbolic link to an existing file or 
    directory: <code>exists(ph) &amp;&amp; symbolic_link_exists(ph)</code></li>
  </ul>
</blockquote>
<h3><a name="is_directory">is_directory</a></h3>
<blockquote>
<p><code>bool is_directory( const path &amp; ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by&nbsp;
<i>ph</i> is a directory, else false.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><b>Rationale:</b> Treating <code>!exists(ph)</code> as an exception rather 
than just returning false came about because in real code <code>!exists(ph)</code> 
has 
often been the first indicate of a programming error.&nbsp; A compound function returning <code>
exists(ph) &amp;&amp; is_directory(ph)</code> can always be added later.</p>
</blockquote>
<h3><a name="is_empty">is_empty</a></h3>
<blockquote>
<p><code>bool is_empty( const path &amp; ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by&nbsp;
<i>ph</i> is an empty file or empty directory, else false.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
  <p>This function determines if the file or directory identified by the 
  contents of <i>ph</i> is empty. To determine if a path string itself is empty, 
  use the <i><a href="path.htm#empty">path::empty()</a></i> function.</p>
</blockquote>
  <h3><a name="equivalent">equivalent</a></h3>
<blockquote>
  <pre>bool equivalent( const path &amp; ph1, const path &amp; ph2 );</pre>
  <p><b>Returns:</b> <code>false</code> if <code>!exists(ph1) || !exists(ph2)</code>. 
  Otherwise, returns <code>true</code> if ph1 and ph2 resolve to the same file 
  or directory, else <code>false</code>. The criteria used to determine sameness 
  are implementation defined:</p>
  <blockquote>
    <ul>
      <li>POSIX: stat() reports identical st_dev, st_ino, st_size, and st_mtime 
      values. The POSIX implementation does not protect against
      <a href="index.htm#Race-condition">race conditions</a>.<br>
&nbsp;</li>
      <li>Windows: GetFileInformationByHandle() reports identical dwVolumeSerialNumber, 
      nFileIndexHigh, nFileIndexLow, nFileSizeHigh, nFileSizeLow values, 
      ftLastWriteTime.dwLowDateTime, and ftLastWriteTime.dwHighDateTime. 
      Note that for identical media (particularly bit-for-bit duplicate CD's, 
      Floppies, or memory cards)  equivalent() will return <code>true</code> even though the 
      media are physically different. The Windows implementation does protect 
      against <a href="index.htm#Race-condition">race conditions</a>.</li>
    </ul>
  </blockquote>
  <p><b>Throws:</b> if <code>!exists(ph1) &amp;&amp; !exists(ph2)</code></p>
  <p><b>Warning:</b> This function may be impossible to implement on some 
  operating systems; users may wish to avoid use for code which may be ported to 
  operating systems with limited filesystem support.</p>
</blockquote>
  <h3><a name="file_size">file_size</a></h3>
<blockquote>
  <p><code>boost::intmax_t file_size( const path &amp; ph );</code></p>
  <p><b>Returns:</b> The size of the file in bytes as reported by the operating 
  system.</p>
  <p><b>Throws:</b> if <code>!exists(ph) || is_directory(ph) || </code>the file 
  size cannot be determined (such as for an input stream).</p>
<p><b>Warming:</b> If a compiler does not support <code>maxint_t</code> large 
enough to represent the operating system's maximum file size, or if the 
implementation does not know how to query the operating system for large file 
sizes, the returned value could be incorrect. This is not a problem with modern 
compilers on modern versions of Linux or Windows. Users on other platforms 
should build and run the <a href="../example/file_size.cpp">file_size.cpp</a> 
sample program against a large file to verify correct operation.</p>
<p><b>Rationale:</b> Directories are excluded because the complexity of finding 
the size of a file is typically constant, while finding the size of a directory 
is typically linear. It was felt this would be surprising. The function is named 
accordingly. Users needing the size of a directory can trivially provide a user 
function which iterates over a directory returning a count.</p>
</blockquote>
<h3><a name="last_write_time">last_write_time</a></h3>
<blockquote>
<p><b>Warning:</b> The times associated with files are subject to many 
vicissitudes. Each type of filesystem differs slightly in the details and 
resolution of how times are recorded. The resolution is as low as one hour on 
some filesystems. It is not uncommon for a program to 
simultaneously have access to files maintained by FAT, ISO9660, NTFS, and POSIX 
filesystems, and so experience different last_write_time behavior for different 
files. During program execution, the system clock may be set to a new 
value by some other, possibly automatic, process. Another thread or process may 
write to a file, causing the last write time to change unexpectedly.</p>
<p><code>std::time_t last_write_time( const path &amp; ph );</code></p>
<p><b>Returns:</b> The time the file was last modified, as reported by the 
operating system. If the time cannot be determined, returns (std::time_t)(-1).</p>
<p>To convert the returned value to UTC or local time, use <code>std::gmtime()</code> 
or <code>std::localtime()</code> respectively.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><code>void last_write_time( const path &amp; ph, std::time_t new_time );</code></p>
<p><b>Effects:</b> Asks the operating system to set the last write time to <code>
new_time</code>, or to the current time if <code>new_time==std::time_t()</code>.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><b>Rationale:</b> <code>last_write_time(ph)==new_time</code> is not specified 
as a postcondition because the times may differ somewhat on some operating 
systems.</p>
</blockquote>
<h3><a name="create_directory">create_directory</a></h3>
<blockquote>
<p><code>bool create_directory( const path &amp; directory_ph );</code></p>
<p><b>Precondition:</b> <code>!directory_ph.empty()</code></p>
<p><b>Returns:</b> The value of <code>!exists( directory_ph )</code> prior to the 
establishment of the postcondition.</p>
<p><b>Postcondition:</b> <code>exists(directory_ph) &amp;&amp; 
is_directory(directory_ph)</code></p>
<p><b>Throws: </b>if <code>directory_ph.empty() || (exists(directory_ph) &amp;&amp; !is_directory(directory_ph)) || !exists(directory_ph/&quot;..&quot;)</code>. 
See <a href="#empty_rationale">empty path rationale</a>.</p>
</blockquote>
<h3><a name="remove">remove</a></h3>
<blockquote>
<p><code>bool remove( const path &amp; ph );</code></p>
<p><b>Precondition:</b> <code>!ph.empty()</code></p>
<p><b>Returns:</b> The value of <code>exists( ph )</code> prior to the 
establishment of the postcondition. </p>
<p><b>Postcondition:</b> <code>!exists( ph )</code></p>
<p><b>Throws:</b> if<code> ph.empty() || (exists(ph) &amp;&amp; is_directory(ph) &amp;&amp; !is_empty(ph))</code>. 
See <a href="#empty_rationale">empty path rationale</a>.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are 
themselves deleted, rather than what they point to being deleted.</p>
<p><b>Rationale:</b> Does not throw when <code>!exists( ph )</code> because not 
throwing:</p>
<ul>
  <li>Works correctly if <code>ph</code> is a dangling symbolic link. </li>
  <li>Is slightly easier-to-use for many common use cases.</li>
  <li>Is slightly higher-level because it implies use of postcondition semantics 
  rather than effects semantics, which would be specified in the somewhat 
  lower-level terms of interactions with the operating system.</li>
</ul>
<p>There is, however, a slight decrease in safety because some errors will slip 
by which otherwise would have been detected. For example, a misspelled path name 
could go undetected for a long time.</p>
<p>The initial version of the library threw an exception when the path did not exist; it 
was changed to reflect user complaints.</p>
</blockquote>
<h3><a name="remove_all">remove_all</a></h3>
<blockquote>
<p><code>unsigned long remove_all( const path &amp; ph );</code></p>
<p><b>Precondition:</b> <code>!ph.empty()</code></p>
<p><b>Postcondition:</b> <code>!exists( ph ) &amp;&amp; !symbolic_link_exists( ph )</code></p>
<p><b>Returns:</b> The number of files and directories removed.</p>
<p><b>Throws:</b> if<code> ph.empty()</code>. See <a href="#empty_rationale">
empty path rationale</a>.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are 
themselves deleted, rather than what they point to being deleted.</p>
</blockquote>
<h3><a name="rename">rename</a></h3>
<blockquote>
<p><code>void rename( const path &amp; source, const path &amp; target 
);</code></p>
<p><b>Precondition:</b> <code>!source.empty() &amp;&amp; !target.empty()</code></p>
<p><b>Effects:</b> Changes the name of&nbsp; file or directory <i>source</i> 
to <i>target</i>. Specifically:</p>
<table border="1" cellpadding="5">
  <tr>
    <td><b>Source</b></td>
    <td><b>Target</b></td>
    <td><b>Result is &quot;as if&quot; these actions occur</b></td>
  </tr>
  <tr>
    <td>!exists()</td>
    <td>&nbsp;</td>
    <td>Throw <a href="exception.htm">filesystem_error</a>. Note that !exists() 
    covers the source.empty() case. [case 1] </td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>target.empty()</td>
    <td>Throw <a href="exception.htm">filesystem_error</a>. See
    <a href="#empty_rationale">create_directory() rationale</a>. [case 2] </td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td>exists()</td>
    <td>Throw <a href="exception.htm">filesystem_error</a>. [case 3] </td>
  </tr>
  <tr>
    <td>!is_directory()</td>
    <td>&nbsp;</td>
    <td>If !exists( target / &quot;..&quot; ) throw <a href="exception.htm">
    filesystem_error</a>. [case 4A] <br>
    The source.leaf() name is changed to 
    target.leaf(). [case 4B] <br>
    If source / &quot;..&quot; resolves to a different directory than 
    target / &quot;..&quot;, the renamed source file is moved there. [case 4C] </td>
  </tr>
  <tr>
    <td>is_directory()</td>
    <td>&nbsp;</td>
    <td>If !exists( target / &quot;..&quot; ) throw <a href="exception.htm">
    filesystem_error</a>. [case 5A]<br>
    The source.leaf() name is changed to 
    target.leaf(). [case 5B] <br>
    If system_complete(source.banch_path()) resolves to a 
    different directory than system_complete(target.branch_path()),&nbsp; the 
    renamed source directory is moved there. [case 5C] </td>
  </tr>
  </table>
<p><b>Postconditions:</b> <code>!exists(source) &amp;&amp; exists(target)</code>, 
and the <i>source</i> file or directory contents and attributes are otherwise unchanged.</p>
<p><b>Throws:</b> See Effects table above. See <a href="#empty_rationale">empty 
path rationale</a>.</p>
<p><b>Rationale:</b> Because <i>rename</i> is logically the same operation as <i>move</i>, 
there is no need for a separate <i>move</i> function. The choice of the name is 
based on existing practice in the C, C++, and POSIX libraries, and because the 
name <i>move</i> implies physical file movement, which does not in fact occur.</p>
<p><b>Note:</b> Some operating systems with
<a href="index.htm#multi-root_filesystem">multiple roots</a> do not allow <i>rename</i> 
operations between roots, and such an attempted <i>rename</i> with throw a <i>
<a href="exception.htm">filesystem_error</a></i> exception.. Implementations should not take heroic efforts, such 
as switching to a copy mode, to make an otherwise failing <i>rename </i>succeed 
across roots.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are 
themselves renamed, rather than what they point to being renamed.</p>
</blockquote>
<h3><a name="copy_file">copy_file</a></h3>
<blockquote>
<p><code>void copy_file( const path &amp; source_file, const path &amp; 
target_file );</code></p>
<p><b>Precondition:</b> <code>!source.empty() &amp;&amp; !target.empty()</code></p>
<p><b>Effects:</b> Copies the file represented by <i>source_file</i> to <i>
target_file</i>.</p>
<p><b>Throws:</b> if <code>!exists(source_file) || is_directory(source_file) 
|| exists(target_file) || target_file.empty() || !exists(to_file_path/&quot;..&quot;))</code>. 
See <a href="#empty_rationale">empty path rationale</a>.</p>
<p><b>Note:</b> File attributes are also copied. Specifically, POSIX <i>
stat::st_mode</i>, and Windows <i>BY_HANDLE_FILE_INFORMATION::dwFileAttributes</i>. </p>
</blockquote>
<h3><a name="initial_path">initial_path</a></h3>
<blockquote>
<p><code>const path &amp; initial_path();</code></p>
<p><b>Effects:</b> The first time called, stores the path returned by
<a href="#current_path">current_path()</a>.</p>
<p>The preferred implementation would be to call <i>initial_path()</i> during program 
initialization, before the call to <i>main()</i>. This is, however, not possible 
with changing the C++ runtime library.</p>
<p><b>Returns:</b> A reference to the stored path.</p>
<p><b>Rationale:</b>&nbsp; The semantics, in effect, turn a dangerous global variable into 
a safer global constant. The preferred implementation requires runtime library 
support, so alternate semantics are supplied for those implementations which 
cannot change an existing the runtime library.</p>
<p><b>Note:</b> It is good practice for a program dependent on <i>
initial_path()</i> to call it immediately upon entering<i> main()</i>. That 
protects against another function altering the current working 
directory (using a native platform function) before the first call to <i>
initial_path()</i>.</p>

</blockquote>
<h3><a name="current_path">current_path</a></h3>
<blockquote>
  <pre>path current_path();</pre>
  <p><b>Returns:</b> The current path as maintained by the operating system.</p>
  <p><b>Postcondition:</b> <code>current_path().is_complete()</code></p>
  <p><b>Note:</b> The equivalent POSIX function is <i>getcwd()</i>. The 
  equivalent Windows function is <i>GetCurrentDirectoryA()</i>.</p>
  <p><b>Warning:</b> The current path maintained by the operating system is 
  in-effect a dangerous global variable. It may be changed unexpectedly by a 
  third-party or system library function, or by another thread. For a safer 
  alternative, see <a href="#initial_path">initial_path()</a>.</p>
  <p><b>Rationale:</b> Although dangerous, the function is useful in dealing 
  with other libraries. The <i>current_path()</i> name was chosen to emphasize 
  that the function returns a complete path, not just a single directory name.</p>
</blockquote>
<h3><a name="complete">complete</a></h3>

<blockquote>
<p><code>path complete( const path &amp; ph, const path &amp; base = initial_path() );</code></p>

<p><b>Precondition:</b> <code>!ph.empty() &amp;&amp; base.is_complete() &amp;&amp; (ph.is_complete() || !ph.has_root_name())</code></p>

<p><b>Effects:</b> Composes a complete path from <code>ph</code> and <code>base</code>, 
using the following rules:</p>

<p>For single-root operating systems (POSIX-like systems, for example), if <code>ph.empty()</code> 
or <code>ph.is_complete()</code>, the composed path is <code>ph</code>, 
otherwise the composed path is <code>base/ph</code>.</p>

  <p>For <a href="index.htm#multi-root_filesystem">multi-root</a> operating systems (Windows, Classic Mac, many others), the rules are 
  give by this table:</p>
  <table border="1" cellpadding="5">
    <tr>
      <td align="center">&nbsp;</td>
      <td align="center"><code>ph.has_root_directory()</code></td>
      <td align="center"><code>!ph.has_root_directory()</code></td>
    </tr>
    <tr>
      <td align="center"><code>ph.has_root_name()</code></td>
      <td align="center"><code>ph</code></td>
      <td align="center"><code>(precondition failure)</code></td>
    </tr>
    <tr>
      <td align="center"><code>!ph.has_root_name()</code></td>
      <td align="center"><code>base.root_name()<br>
      / ph</code></td>
      <td align="center"><code>base / ph</code></td>
    </tr>
  </table>
<p><b>Returns:</b> The composed path.</p>

<p><b>Postcondition:</b> For the returned path, <code>p,</code> <code>p.is_complete()</code> 
is true.</p>

<p><b>Throws:</b> On precondition failure. See <a href="#empty_rationale">empty 
path rationale</a>.</p>

<p><b><a name="complete_note">Note</a>:</b> When portable behavior is required, 
use <i>complete()</i>. When operating system dependent behavior is required, use
<i>system_complete()</i>.</p>

<p>Portable behavior is preferred when dealing with paths created internally 
within a program, particularly where the program should exhibit the same 
behavior on all operating systems.</p>

<p>Operating system dependent behavior is preferred when dealing with paths 
supplied by user input, reported to program users, or which should result in 
program behavior familiar to and expected by program users. The
<a href="../example/simple_ls.cpp">simple_ls.cpp</a> program, for example, 
operates on a path supplied in the native operating system format, so uses&nbsp;
<i>system_complete()</i> to ensure that the path behaves as expected for the 
particular operating system.</p>

<p><b>Rationale:</b> The <code>!ph.has_root_name()</code> portion of the 
precondition disallows the error condition of <code>ph.root_name()</code> 
being not equivalent to <code>base.root_name()</code>. The restriction is 
broader that would appear necessary, in that is also prohibits the case where 
they are equivalent. There is, however,&nbsp; no portable way to express the 
root_name() equivalence requirement.</p>

</blockquote>
<h3><a name="system_complete">system_complete</a></h3>

<blockquote>
<p><code>path system_complete( const path &amp; ph );</code></p>

<p><b>Precondition:</b> <code>!ph.empty()</code></p>

<p><b>Effects:</b> Composes a complete path from <code>ph</code>, using the same 
rules used by the operating system to resolve a path passed as the filename 
argument to standard library open functions.</p>

<p>For POSIX-like systems, system_complete( ph ) has the same semantics as <code>
complete( ph, current_path() )</code>.</p>

<p><a name="windows_effects">For Widows</a>, system_complete( ph ) has the same 
semantics as <code>complete( ph, current_path() )</code> if ph.is_complete() || 
!ph.has_root_name() or ph and base have the same root_name(). 
Otherwise it acts like <code>complete( ph, kinky )</code>, where <code>kinky</code> 
is the current directory for the <code>ph.root_name()</code> drive. This 
will be the current directory of that drive the last time it was set, and thus 
may well be <b>residue left over from some prior program</b> run by the command 
processor! Although these semantics are often useful, they are also very 
error-prone, and certainly deserve to be called &quot;kinky&quot;.</p>

<p><b>Returns:</b> The composed path.</p>

<p><b>Postcondition:</b> For the returned path, <code>p,</code> <code>p.is_complete()</code> 
is true.</p>

<p><b>Throws:</b> If <code>ph.empty()</code>. See <a href="#empty_rationale">
empty path rationale</a>.</p>

<p><b>Note:</b> See <a href="#complete_note"><i>complete()</i> note</a> for 
usage suggestions.</p>

<p><b>Warning:</b> This function relies on a global variable (current_path()), 
and so tends to be more error-prone than the similar function
<a href="#complete">complete()</a>. This function is doubly dangerous on 
Windows, where under cross-drive conditions it may be relying on a directory set 
by a prior program run by the command processor.</p>

</blockquote>

<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->02 August, 2005<!--webbot bot="Timestamp" endspan i-checksum="34600" --></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>