From Jason Turner

[fs.op.funcs]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpksulby87/{from.md → to.md} +139 -143
tmp/tmpksulby87/{from.md → to.md} RENAMED
@@ -2,11 +2,11 @@
2
 
3
  Filesystem operation functions query or modify files, including
4
  directories, in external storage.
5
 
6
  [*Note 1*: Because hardware failures, network failures, file system
7
- races ([[fs.def.race]]), and many other kinds of errors occur
8
  frequently in file system operations, users should be aware that any
9
  filesystem operation function, no matter how apparently innocuous, may
10
  encounter an error; see  [[fs.err.report]]. — *end note*]
11
 
12
  #### Absolute <a id="fs.op.absolute">[[fs.op.absolute]]</a>
@@ -15,11 +15,11 @@ encounter an error; see  [[fs.err.report]]. — *end note*]
15
  path absolute(const path& p);
16
  path absolute(const path& p, error_code& ec);
17
  ```
18
 
19
  *Effects:* Composes an absolute path referencing the same file system
20
- location as `p` according to the operating system ([[fs.conform.os]]).
21
 
22
  *Returns:* The composed path. The signature with argument `ec` returns
23
  `path()` if an error occurs.
24
 
25
  [*Note 1*: For the returned path, `rp`, `rp.is_absolute()` is `true`
@@ -27,11 +27,11 @@ unless an error occurs. — *end note*]
27
 
28
  *Throws:* As specified in  [[fs.err.report]].
29
 
30
  [*Note 2*: To resolve symlinks, or perform other sanitization which
31
  might require queries to secondary storage, such as hard disks, consider
32
- `canonical` ([[fs.op.canonical]]). — *end note*]
33
 
34
  [*Note 3*: Implementations are strongly encouraged to not query
35
  secondary storage, and not consider `!exists(p)` an
36
  error. — *end note*]
37
 
@@ -41,22 +41,19 @@ simply `current_path()/p`. For Windows-based operating systems,
41
  `GetFullPathNameW`. — *end example*]
42
 
43
  #### Canonical <a id="fs.op.canonical">[[fs.op.canonical]]</a>
44
 
45
  ``` cpp
46
- path canonical(const path& p, const path& base = current_path());
47
  path canonical(const path& p, error_code& ec);
48
- path canonical(const path& p, const path& base, error_code& ec);
49
  ```
50
 
51
- *Effects:* Converts `p`, which must exist, to an absolute path that has
52
- no symbolic link, *dot*, or *dot-dot* elements in its pathname in the
53
- generic format.
54
 
55
  *Returns:* A path that refers to the same file system object as
56
- `absolute(p, base)`. For the overload without a `base` argument, `base`
57
- is `current_path()`. Signatures with argument `ec` return `path()` if an
58
  error occurs.
59
 
60
  *Throws:* As specified in  [[fs.err.report]].
61
 
62
  *Remarks:* `!exists(p)` is an error.
@@ -68,23 +65,23 @@ void copy(const path& from, const path& to);
68
  ```
69
 
70
  *Effects:* Equivalent to `copy(from, to, copy_options::none)`.
71
 
72
  ``` cpp
73
- void copy(const path& from, const path& to, error_code& ec) noexcept;
74
  ```
75
 
76
  *Effects:* Equivalent to `copy(from, to, copy_options::none, ec)`.
77
 
78
  ``` cpp
79
  void copy(const path& from, const path& to, copy_options options);
80
  void copy(const path& from, const path& to, copy_options options,
81
- error_code& ec) noexcept;
82
  ```
83
 
84
- *Requires:* At most one element from each option group
85
- ([[fs.enum.copy.opts]]) is set in `options`.
86
 
87
  *Effects:* Before the first use of `f` and `t`:
88
 
89
  - If
90
  ``` cpp
@@ -105,17 +102,17 @@ void copy(const path& from, const path& to, copy_options options,
105
  `auto t = status(to)`.
106
 
107
  Effects are then as follows:
108
 
109
  - If `f.type()` or `t.type()` is an implementation-defined file
110
- type ([[fs.enum.file_type]]), then the effects are
111
  *implementation-defined*.
112
  - Otherwise, an error is reported as specified in  [[fs.err.report]] if:
113
- - `!exists(f)`, or
114
- - `equivalent(from, to)`, or
115
- - `is_other(f) || is_other(t)`, or
116
- - `is_directory(f) && is_regular_file(t)`.
117
  - Otherwise, if `is_symlink(f)`, then:
118
  - If `(options & copy_options::skip_symlinks) != copy_options::none`
119
  then return.
120
  - Otherwise if
121
  ``` cpp
@@ -135,24 +132,36 @@ Effects are then as follows:
135
  `(options & copy_options::create_hard_links) != copy_options::none`,
136
  then create a hard link to the source file.
137
  - Otherwise, if `is_directory(t)`, then
138
  `copy_file(from, to/from.filename(), options)`.
139
  - Otherwise, `copy_file(from, to, options)`.
 
 
 
 
 
 
 
 
140
  - Otherwise, if
141
  ``` cpp
142
  is_directory(f) &&
143
  ((options & copy_options::recursive) != copy_options::none ||
144
  options == copy_options::none)
145
  ```
146
 
147
  then:
148
- - If `!exists(t)`, then `create_directory(to, from)`.
149
  - Then, iterate over the files in `from`, as if by
150
  ``` cpp
151
  for (const directory_entry& x : directory_iterator(from))
152
- copy(x.path(), to/x.path().filename(), options | copy_options::unspecified)
 
153
  ```
 
 
 
154
  - Otherwise, for the signature with argument `ec`, `ec.clear()`.
155
  - Otherwise, no effects.
156
 
157
  *Throws:* As specified in  [[fs.err.report]].
158
 
@@ -201,62 +210,61 @@ would result in:
201
  file3
202
  ```
203
 
204
  — *end example*]
205
 
206
- #### Copy file <a id="fs.op.copy_file">[[fs.op.copy_file]]</a>
207
 
208
  ``` cpp
209
  bool copy_file(const path& from, const path& to);
210
- bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
211
  ```
212
 
213
  *Returns:* `copy_file(from, to, copy_options::none)` or
214
  `copy_file(from, to, copy_options::none, ec)`, respectively.
215
 
216
  *Throws:* As specified in  [[fs.err.report]].
217
 
218
  ``` cpp
219
  bool copy_file(const path& from, const path& to, copy_options options);
220
  bool copy_file(const path& from, const path& to, copy_options options,
221
- error_code& ec) noexcept;
222
  ```
223
 
224
- *Requires:* At most one element from each option group
225
- ([[fs.enum.copy.opts]]) is set in `options`.
226
 
227
  *Effects:* As follows:
228
 
229
- - Report a file already exists error as specified in  [[fs.err.report]]
230
- if:
231
- - `!is_regular_file(from)`, or
232
- - `exists(to)` and `!is_regular_file(to)`, or
233
- - `exists(to)` and `equivalent(from, to)`, or
234
- - `exists(to)` and
235
  ``` cpp
236
  (options & (copy_options::skip_existing |
237
  copy_options::overwrite_existing |
238
  copy_options::update_existing)) == copy_options::none
239
  ```
240
  - Otherwise, copy the contents and attributes of the file `from`
241
  resolves to, to the file `to` resolves to, if:
242
- - `!exists(to)`, or
243
  - `(options & copy_options::overwrite_existing) != copy_options::none`,
244
  or
245
  - `(options & copy_options::update_existing) `` `` != copy_options::none`
246
  and `from` is more recent than `to`, determined as if by use of the
247
- `last_write_time` function ([[fs.op.last_write_time]]).
248
  - Otherwise, no effects.
249
 
250
  *Returns:* `true` if the `from` file was copied, otherwise `false`. The
251
  signature with argument `ec` returns `false` if an error occurs.
252
 
253
  *Throws:* As specified in  [[fs.err.report]].
254
 
255
  *Complexity:* At most one direct or indirect invocation of `status(to)`.
256
 
257
- #### Copy symlink <a id="fs.op.copy_symlink">[[fs.op.copy_symlink]]</a>
258
 
259
  ``` cpp
260
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
261
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
262
  error_code& ec) noexcept;
@@ -268,86 +276,78 @@ void copy_symlink(const path& existing_symlink, const path& new_symlink,
268
  respectively, where in each case *`function`* is `create_symlink` or
269
  `create_directory_symlink` as appropriate.
270
 
271
  *Throws:* As specified in  [[fs.err.report]].
272
 
273
- #### Create directories <a id="fs.op.create_directories">[[fs.op.create_directories]]</a>
274
 
275
  ``` cpp
276
  bool create_directories(const path& p);
277
- bool create_directories(const path& p, error_code& ec) noexcept;
278
  ```
279
 
280
- *Effects:* Establishes the postcondition by calling `create_directory()`
281
- for any element of `p` that does not exist.
282
-
283
- *Postconditions:* `is_directory(p)`.
284
-
285
- *Returns:* `true` if a new directory was created, otherwise `false`. The
286
- signature with argument `ec` returns `false` if an error occurs.
287
-
288
- *Throws:* As specified in  [[fs.err.report]].
289
-
290
- *Complexity:* 𝑂(n) where *n* is the number of elements of `p` that do
291
  not exist.
292
 
293
- #### Create directory <a id="fs.op.create_directory">[[fs.op.create_directory]]</a>
 
 
 
 
 
 
 
294
 
295
  ``` cpp
296
  bool create_directory(const path& p);
297
  bool create_directory(const path& p, error_code& ec) noexcept;
298
  ```
299
 
300
- *Effects:* Establishes the postcondition by attempting to create the
301
- directory `p` resolves to, as if by POSIX `mkdir()` with a second
302
- argument of `static_cast<int>(perms::all)`. Creation failure because `p`
303
- resolves to an existing directory shall not be treated as an error.
304
 
305
- *Postconditions:* `is_directory(p)`.
306
-
307
- *Returns:* `true` if a new directory was created, otherwise `false`. The
308
- signature with argument `ec` returns `false` if an error occurs.
309
 
310
  *Throws:* As specified in  [[fs.err.report]].
311
 
312
  ``` cpp
313
  bool create_directory(const path& p, const path& existing_p);
314
  bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
315
  ```
316
 
317
- *Effects:* Establishes the postcondition by attempting to create the
318
- directory `p` resolves to, with attributes copied from directory
319
- `existing_p`. The set of attributes copied is operating system
320
- dependent. Creation failure because `p` resolves to an existing
321
- directory shall not be treated as an error.
322
 
323
  [*Note 1*: For POSIX-based operating systems, the attributes are those
324
  copied by native API `stat(existing_p.c_str(), &attributes_stat)`
325
  followed by `mkdir(p.c_str(), attributes_stat.st_mode)`. For
326
  Windows-based operating systems, the attributes are those copied by
327
  native API
328
  `CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)`. — *end note*]
329
 
330
- *Postconditions:* `is_directory(p)`.
331
-
332
- *Returns:* `true` if a new directory was created, otherwise `false`. The
333
- signature with argument `ec` returns `false` if an error occurs.
334
 
335
  *Throws:* As specified in  [[fs.err.report]].
336
 
337
- #### Create directory symlink <a id="fs.op.create_dir_symlk">[[fs.op.create_dir_symlk]]</a>
338
 
339
  ``` cpp
340
  void create_directory_symlink(const path& to, const path& new_symlink);
341
  void create_directory_symlink(const path& to, const path& new_symlink,
342
  error_code& ec) noexcept;
343
  ```
344
 
345
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
346
 
347
- *Postconditions:* `new_symlink` resolves to a symbolic link file that
348
- contains an unspecified representation of `to`.
349
 
350
  *Throws:* As specified in  [[fs.err.report]].
351
 
352
  [*Note 1*: Some operating systems require symlink creation to identify
353
  that the link is to a directory. Portable code should use
@@ -357,21 +357,21 @@ that the link is to a directory. Portable code should use
357
  [*Note 2*: Some operating systems do not support symbolic links at all
358
  or support them only for regular files. Some file systems (such as the
359
  FAT file system) do not support symbolic links regardless of the
360
  operating system. — *end note*]
361
 
362
- #### Create hard link <a id="fs.op.create_hard_lk">[[fs.op.create_hard_lk]]</a>
363
 
364
  ``` cpp
365
  void create_hard_link(const path& to, const path& new_hard_link);
366
  void create_hard_link(const path& to, const path& new_hard_link,
367
  error_code& ec) noexcept;
368
  ```
369
 
370
  *Effects:* Establishes the postcondition, as if by POSIX `link()`.
371
 
372
- *Postconditions:*
373
 
374
  - `exists(to) && exists(new_hard_link) && equivalent(to, new_hard_link)`
375
  - The contents of the file or directory `to` resolves to are unchanged.
376
 
377
  *Throws:* As specified in  [[fs.err.report]].
@@ -380,31 +380,31 @@ void create_hard_link(const path& to, const path& new_hard_link,
380
  support them only for regular files. Some file systems (such as the FAT
381
  file system) do not support hard links regardless of the operating
382
  system. Some file systems limit the number of links per
383
  file. — *end note*]
384
 
385
- #### Create symlink <a id="fs.op.create_symlink">[[fs.op.create_symlink]]</a>
386
 
387
  ``` cpp
388
  void create_symlink(const path& to, const path& new_symlink);
389
  void create_symlink(const path& to, const path& new_symlink,
390
  error_code& ec) noexcept;
391
  ```
392
 
393
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
394
 
395
- *Postconditions:* `new_symlink` resolves to a symbolic link file that
396
- contains an unspecified representation of `to`.
397
 
398
  *Throws:* As specified in  [[fs.err.report]].
399
 
400
  [*Note 1*: Some operating systems do not support symbolic links at all
401
  or support them only for regular files. Some file systems (such as the
402
  FAT file system) do not support symbolic links regardless of the
403
  operating system. — *end note*]
404
 
405
- #### Current path <a id="fs.op.current_path">[[fs.op.current_path]]</a>
406
 
407
  ``` cpp
408
  path current_path();
409
  path current_path(error_code& ec);
410
  ```
@@ -422,22 +422,21 @@ resolution for relative paths.
422
  [*Note 1*: The `current_path()` name was chosen to emphasize that the
423
  returned value is a path, not just a single directory
424
  name. — *end note*]
425
 
426
  [*Note 2*: The current path as returned by many operating systems is a
427
- dangerous global variable. It may be changed unexpectedly by a
428
- third-party or system library functions, or by another
429
- thread. — *end note*]
430
 
431
  ``` cpp
432
  void current_path(const path& p);
433
  void current_path(const path& p, error_code& ec) noexcept;
434
  ```
435
 
436
  *Effects:* Establishes the postcondition, as if by POSIX `chdir()`.
437
 
438
- *Postconditions:* `equivalent(p, current_path())`.
439
 
440
  *Throws:* As specified in  [[fs.err.report]].
441
 
442
  [*Note 3*: The current path for many operating systems is a dangerous
443
  global state. It may be changed unexpectedly by a third-party or system
@@ -448,26 +447,22 @@ library functions, or by another thread. — *end note*]
448
  ``` cpp
449
  bool equivalent(const path& p1, const path& p2);
450
  bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
451
  ```
452
 
453
- Let `s1` and `s2` be `file_status`s, determined as if by `status(p1)`
454
- and `status(p2)`, respectively.
455
-
456
- *Effects:* Determines `s1` and `s2`. If
457
- `(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))` an
458
- error is reported ([[fs.err.report]]).
459
-
460
- *Returns:* `true`, if `s1 == s2` and `p1` and `p2` resolve to the same
461
- file system entity, else `false`. The signature with argument `ec`
462
- returns `false` if an error occurs.
463
 
464
  Two paths are considered to resolve to the same file system entity if
465
  two candidate entities reside on the same device at the same location.
466
- This is determined as if by the values of the POSIX `stat` structure,
467
- obtained as if by `stat()` for the two paths, having equal `st_dev`
468
- values and equal `st_ino` values.
 
 
 
469
 
470
  *Throws:* As specified in  [[fs.err.report]].
471
 
472
  #### Exists <a id="fs.op.exists">[[fs.op.exists]]</a>
473
 
@@ -490,31 +485,33 @@ Let `s` be a `file_status`, determined as if by `status(p)` or
490
 
491
  *Returns:* `exists(s)`.
492
 
493
  *Throws:* As specified in  [[fs.err.report]].
494
 
495
- #### File size <a id="fs.op.file_size">[[fs.op.file_size]]</a>
496
 
497
  ``` cpp
498
  uintmax_t file_size(const path& p);
499
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
500
  ```
501
 
 
 
 
502
  *Returns:*
503
 
504
- - If `!exists(p)` an error is reported ([[fs.err.report]]).
505
- - Otherwise, if `is_regular_file(p)`, the size in bytes of the file `p`
506
- resolves to, determined as if by the value of the POSIX `stat`
507
- structure member `st_size` obtained as if by POSIX `stat()`.
508
  - Otherwise, the result is *implementation-defined*.
509
 
510
  The signature with argument `ec` returns `static_cast<uintmax_t>(-1)` if
511
  an error occurs.
512
 
513
  *Throws:* As specified in  [[fs.err.report]].
514
 
515
- #### Hard link count <a id="fs.op.hard_lk_ct">[[fs.op.hard_lk_ct]]</a>
516
 
517
  ``` cpp
518
  uintmax_t hard_link_count(const path& p);
519
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
520
  ```
@@ -522,11 +519,11 @@ uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
522
  *Returns:* The number of hard links for `p`. The signature with argument
523
  `ec` returns `static_cast<uintmax_t>(-1)` if an error occurs.
524
 
525
  *Throws:* As specified in  [[fs.err.report]].
526
 
527
- #### Is block file <a id="fs.op.is_block_file">[[fs.op.is_block_file]]</a>
528
 
529
  ``` cpp
530
  bool is_block_file(file_status s) noexcept;
531
  ```
532
 
@@ -541,11 +538,11 @@ bool is_block_file(const path& p, error_code& ec) noexcept;
541
  respectively. The signature with argument `ec` returns `false` if an
542
  error occurs.
543
 
544
  *Throws:* As specified in  [[fs.err.report]].
545
 
546
- #### Is character file <a id="fs.op.is_char_file">[[fs.op.is_char_file]]</a>
547
 
548
  ``` cpp
549
  bool is_character_file(file_status s) noexcept;
550
  ```
551
 
@@ -560,11 +557,11 @@ bool is_character_file(const path& p, error_code& ec) noexcept;
560
  `is_character_file(status(p, ec))`, respectively.
561
  The signature with argument `ec` returns `false` if an error occurs.
562
 
563
  *Throws:* As specified in  [[fs.err.report]].
564
 
565
- #### Is directory <a id="fs.op.is_directory">[[fs.op.is_directory]]</a>
566
 
567
  ``` cpp
568
  bool is_directory(file_status s) noexcept;
569
  ```
570
 
@@ -579,15 +576,15 @@ bool is_directory(const path& p, error_code& ec) noexcept;
579
  respectively. The signature with argument `ec` returns `false` if an
580
  error occurs.
581
 
582
  *Throws:* As specified in  [[fs.err.report]].
583
 
584
- #### Is empty <a id="fs.op.is_empty">[[fs.op.is_empty]]</a>
585
 
586
  ``` cpp
587
  bool is_empty(const path& p);
588
- bool is_empty(const path& p, error_code& ec) noexcept;
589
  ```
590
 
591
  *Effects:*
592
 
593
  - Determine `file_status s`, as if by `status(p)` or `status(p, ec)`,
@@ -607,11 +604,11 @@ bool is_empty(const path& p, error_code& ec) noexcept;
607
  occurred.
608
  - Otherwise, return `sz == 0`.
609
 
610
  *Throws:* As specified in  [[fs.err.report]].
611
 
612
- #### Is fifo <a id="fs.op.is_fifo">[[fs.op.is_fifo]]</a>
613
 
614
  ``` cpp
615
  bool is_fifo(file_status s) noexcept;
616
  ```
617
 
@@ -626,11 +623,11 @@ bool is_fifo(const path& p, error_code& ec) noexcept;
626
  respectively. The signature with argument `ec` returns `false` if an
627
  error occurs.
628
 
629
  *Throws:* As specified in  [[fs.err.report]].
630
 
631
- #### Is other <a id="fs.op.is_other">[[fs.op.is_other]]</a>
632
 
633
  ``` cpp
634
  bool is_other(file_status s) noexcept;
635
  ```
636
 
@@ -646,11 +643,11 @@ bool is_other(const path& p, error_code& ec) noexcept;
646
  respectively. The signature with argument `ec` returns `false` if an
647
  error occurs.
648
 
649
  *Throws:* As specified in  [[fs.err.report]].
650
 
651
- #### Is regular file <a id="fs.op.is_regular_file">[[fs.op.is_regular_file]]</a>
652
 
653
  ``` cpp
654
  bool is_regular_file(file_status s) noexcept;
655
  ```
656
 
@@ -661,11 +658,11 @@ bool is_regular_file(const path& p);
661
  ```
662
 
663
  *Returns:* `is_regular_file(status(p))`.
664
 
665
  *Throws:* `filesystem_error` if `status(p)` would throw
666
- `filesystem_error.`
667
 
668
  ``` cpp
669
  bool is_regular_file(const path& p, error_code& ec) noexcept;
670
  ```
671
 
@@ -676,11 +673,11 @@ bool is_regular_file(const path& p, error_code& ec) noexcept;
676
  between cases, call the `status` function directly. — *end note*]
677
 
678
  *Returns:* `is_regular_file(status(p, ec))`. Returns `false` if an error
679
  occurs.
680
 
681
- #### Is socket <a id="fs.op.is_socket">[[fs.op.is_socket]]</a>
682
 
683
  ``` cpp
684
  bool is_socket(file_status s) noexcept;
685
  ```
686
 
@@ -695,11 +692,11 @@ bool is_socket(const path& p, error_code& ec) noexcept;
695
  respectively. The signature with argument `ec` returns `false` if an
696
  error occurs.
697
 
698
  *Throws:* As specified in  [[fs.err.report]].
699
 
700
- #### Is symlink <a id="fs.op.is_symlink">[[fs.op.is_symlink]]</a>
701
 
702
  ``` cpp
703
  bool is_symlink(file_status s) noexcept;
704
  ```
705
 
@@ -714,20 +711,20 @@ bool is_symlink(const path& p, error_code& ec) noexcept;
714
  `is_symlink(symlink_status(p, ec))`, respectively. The signature with
715
  argument `ec` returns `false` if an error occurs.
716
 
717
  *Throws:* As specified in  [[fs.err.report]].
718
 
719
- #### Last write time <a id="fs.op.last_write_time">[[fs.op.last_write_time]]</a>
720
 
721
  ``` cpp
722
  file_time_type last_write_time(const path& p);
723
  file_time_type last_write_time(const path& p, error_code& ec) noexcept;
724
  ```
725
 
726
  *Returns:* The time of last data modification of `p`, determined as if
727
- by the value of the POSIX `stat` structure member `st_mtime` obtained as
728
- if by POSIX `stat()`. The signature with argument `ec` returns
729
  `file_time_type::min()` if an error occurs.
730
 
731
  *Throws:* As specified in  [[fs.err.report]].
732
 
733
  ``` cpp
@@ -751,11 +748,11 @@ granularity. — *end note*]
751
  void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
752
  void permissions(const path& p, perms prms, error_code& ec) noexcept;
753
  void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
754
  ```
755
 
756
- *Requires:* Exactly one of the `perm_options` constants `replace`,
757
  `add`, or `remove` is present in `opts`.
758
 
759
  *Remarks:* The second signature behaves as if it had an additional
760
  parameter `perm_options` `opts` with an argument of
761
  `perm_options::replace`.
@@ -799,11 +796,11 @@ weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec));
799
 
800
  or `path()` at the first error occurrence, if any.
801
 
802
  *Throws:* As specified in  [[fs.err.report]].
803
 
804
- #### Read symlink <a id="fs.op.read_symlink">[[fs.op.read_symlink]]</a>
805
 
806
  ``` cpp
807
  path read_symlink(const path& p);
808
  path read_symlink(const path& p, error_code& ec);
809
  ```
@@ -859,31 +856,31 @@ bool remove(const path& p, error_code& ec) noexcept;
859
  as if by POSIX `remove()`.
860
 
861
  [*Note 1*: A symbolic link is itself removed, rather than the file it
862
  resolves to. — *end note*]
863
 
864
- *Postconditions:* `!exists(symlink_status(p))`.
865
 
866
  *Returns:* `false` if `p` did not exist, otherwise `true`. The signature
867
  with argument `ec` returns `false` if an error occurs.
868
 
869
  *Throws:* As specified in  [[fs.err.report]].
870
 
871
- #### Remove all <a id="fs.op.remove_all">[[fs.op.remove_all]]</a>
872
 
873
  ``` cpp
874
  uintmax_t remove_all(const path& p);
875
- uintmax_t remove_all(const path& p, error_code& ec) noexcept;
876
  ```
877
 
878
  *Effects:* Recursively deletes the contents of `p` if it exists, then
879
  deletes file `p` itself, as if by POSIX `remove()`.
880
 
881
  [*Note 1*: A symbolic link is itself removed, rather than the file it
882
  resolves to. — *end note*]
883
 
884
- *Postconditions:* `!exists(symlink_status(p))`.
885
 
886
  *Returns:* The number of files removed. The signature with argument `ec`
887
  returns `static_cast< uintmax_t>(-1)` if an error occurs.
888
 
889
  *Throws:* As specified in  [[fs.err.report]].
@@ -912,23 +909,22 @@ A symbolic link is itself renamed, rather than the file it resolves to.
912
 
913
  — *end note*]
914
 
915
  *Throws:* As specified in  [[fs.err.report]].
916
 
917
- #### Resize file <a id="fs.op.resize_file">[[fs.op.resize_file]]</a>
918
 
919
  ``` cpp
920
  void resize_file(const path& p, uintmax_t new_size);
921
  void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
922
  ```
923
 
924
- *Postconditions:* `file_size(p) == new_size`.
 
925
 
926
  *Throws:* As specified in  [[fs.err.report]].
927
 
928
- *Remarks:* Achieves its postconditions as if by POSIX `truncate()`.
929
-
930
  #### Space <a id="fs.op.space">[[fs.op.space]]</a>
931
 
932
  ``` cpp
933
  space_info space(const path& p);
934
  space_info space(const path& p, error_code& ec) noexcept;
@@ -1027,27 +1023,27 @@ determined as if by converting the `st_mode` member of the obtained
1027
  - Otherwise, if the attributes indicate a fifo or pipe file, as if by
1028
  POSIX `S_ISFIFO`, returns `file_status(file_type::fifo, prms)`.
1029
  - Otherwise, if the attributes indicate a socket, as if by POSIX
1030
  `S_ISSOCK`, returns `file_status(file_type::socket, prms)`.
1031
  - Otherwise, if the attributes indicate an implementation-defined file
1032
- type ([[fs.enum.file_type]]), returns
1033
  `file_status(file_type::`*`A`*`, prms)`, where *A* is the constant
1034
  for the *implementation-defined* file type.
1035
  - Otherwise, returns `file_status(file_type::unknown, prms)`.
1036
 
1037
  *Remarks:* If a symbolic link is encountered during pathname resolution,
1038
  pathname resolution continues using the contents of the symbolic link.
1039
 
1040
- #### Status known <a id="fs.op.status_known">[[fs.op.status_known]]</a>
1041
 
1042
  ``` cpp
1043
  bool status_known(file_status s) noexcept;
1044
  ```
1045
 
1046
  *Returns:* `s.type() != file_type::none`.
1047
 
1048
- #### Symlink status <a id="fs.op.symlink_status">[[fs.op.symlink_status]]</a>
1049
 
1050
  ``` cpp
1051
  file_status symlink_status(const path& p);
1052
  file_status symlink_status(const path& p, error_code& ec) noexcept;
1053
  ```
@@ -1067,20 +1063,23 @@ indicate a symbolic link, as if by POSIX `S_ISLNK`, returns
1067
 
1068
  *Remarks:* Pathname resolution terminates if `p` names a symbolic link.
1069
 
1070
  *Throws:* As specified in  [[fs.err.report]].
1071
 
1072
- #### Temporary directory path <a id="fs.op.temp_dir_path">[[fs.op.temp_dir_path]]</a>
1073
 
1074
  ``` cpp
1075
  path temp_directory_path();
1076
  path temp_directory_path(error_code& ec);
1077
  ```
1078
 
1079
- *Returns:* An unspecifed directory path suitable for temporary files. An
1080
- error shall be reported if `!exists(p) || !is_directory(p)`, where `p`
1081
- is the path to be returned. The signature with argument `ec` returns
 
 
 
1082
  `path()` if an error occurs.
1083
 
1084
  *Throws:* As specified in  [[fs.err.report]].
1085
 
1086
  [*Example 1*: For POSIX-based operating systems, an implementation
@@ -1088,34 +1087,31 @@ might return the path supplied by the first environment variable found
1088
  in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found,
1089
  `"/tmp"`. For Windows-based operating systems, an implementation might
1090
  return the path reported by the Windows `GetTempPath` API
1091
  function. — *end example*]
1092
 
1093
- #### Weakly canonical <a id="fs.op.weakly_canonical">[[fs.op.weakly_canonical]]</a>
1094
 
1095
  ``` cpp
1096
  path weakly_canonical(const path& p);
1097
  path weakly_canonical(const path& p, error_code& ec);
1098
  ```
1099
 
1100
  *Returns:* `p` with symlinks resolved and the result
1101
- normalized ([[fs.def.normal.form]]).
1102
 
1103
  *Effects:* Using `status(p)` or `status(p, ec)`, respectively, to
1104
  determine existence, return a path composed by `operator/=` from the
1105
- result of calling `canonical()` without a `base` argument and with a
1106
- path argument composed of the leading elements of `p` that exist, if
1107
- any, followed by the elements of `p` that do not exist, if any. For the
1108
- first form, `canonical()` is called without an `error_code` argument.
1109
- For the second form, `canonical()` is called with `ec` as an
1110
- `error_code` argument, and `path()` is returned at the first error
1111
- occurrence, if any.
1112
 
1113
- *Postconditions:* The returned path is in normal
1114
- form ([[fs.def.normal.form]]).
1115
 
1116
- *Remarks:* Implementations are encouraged to avoid unnecessary
1117
- normalization such as when `canonical` has already been called on the
1118
- entirety of `p`.
1119
 
1120
  *Throws:* As specified in  [[fs.err.report]].
1121
 
 
2
 
3
  Filesystem operation functions query or modify files, including
4
  directories, in external storage.
5
 
6
  [*Note 1*: Because hardware failures, network failures, file system
7
+ races [[fs.race.behavior]], and many other kinds of errors occur
8
  frequently in file system operations, users should be aware that any
9
  filesystem operation function, no matter how apparently innocuous, may
10
  encounter an error; see  [[fs.err.report]]. — *end note*]
11
 
12
  #### Absolute <a id="fs.op.absolute">[[fs.op.absolute]]</a>
 
15
  path absolute(const path& p);
16
  path absolute(const path& p, error_code& ec);
17
  ```
18
 
19
  *Effects:* Composes an absolute path referencing the same file system
20
+ location as `p` according to the operating system [[fs.conform.os]].
21
 
22
  *Returns:* The composed path. The signature with argument `ec` returns
23
  `path()` if an error occurs.
24
 
25
  [*Note 1*: For the returned path, `rp`, `rp.is_absolute()` is `true`
 
27
 
28
  *Throws:* As specified in  [[fs.err.report]].
29
 
30
  [*Note 2*: To resolve symlinks, or perform other sanitization which
31
  might require queries to secondary storage, such as hard disks, consider
32
+ `canonical` [[fs.op.canonical]]. — *end note*]
33
 
34
  [*Note 3*: Implementations are strongly encouraged to not query
35
  secondary storage, and not consider `!exists(p)` an
36
  error. — *end note*]
37
 
 
41
  `GetFullPathNameW`. — *end example*]
42
 
43
  #### Canonical <a id="fs.op.canonical">[[fs.op.canonical]]</a>
44
 
45
  ``` cpp
46
+ path canonical(const path& p);
47
  path canonical(const path& p, error_code& ec);
 
48
  ```
49
 
50
+ *Effects:* Converts `p` to an absolute path that has no symbolic link,
51
+ dot, or dot-dot elements in its pathname in the generic format.
 
52
 
53
  *Returns:* A path that refers to the same file system object as
54
+ `absolute(p)`. The signature with argument `ec` returns `path()` if an
 
55
  error occurs.
56
 
57
  *Throws:* As specified in  [[fs.err.report]].
58
 
59
  *Remarks:* `!exists(p)` is an error.
 
65
  ```
66
 
67
  *Effects:* Equivalent to `copy(from, to, copy_options::none)`.
68
 
69
  ``` cpp
70
+ void copy(const path& from, const path& to, error_code& ec);
71
  ```
72
 
73
  *Effects:* Equivalent to `copy(from, to, copy_options::none, ec)`.
74
 
75
  ``` cpp
76
  void copy(const path& from, const path& to, copy_options options);
77
  void copy(const path& from, const path& to, copy_options options,
78
+ error_code& ec);
79
  ```
80
 
81
+ *Preconditions:* At most one element from each option
82
+ group [[fs.enum.copy.opts]] is set in `options`.
83
 
84
  *Effects:* Before the first use of `f` and `t`:
85
 
86
  - If
87
  ``` cpp
 
102
  `auto t = status(to)`.
103
 
104
  Effects are then as follows:
105
 
106
  - If `f.type()` or `t.type()` is an implementation-defined file
107
+ type [[fs.enum.file.type]], then the effects are
108
  *implementation-defined*.
109
  - Otherwise, an error is reported as specified in  [[fs.err.report]] if:
110
+ - `exists(f)` is `false`, or
111
+ - `equivalent(from, to)` is `true`, or
112
+ - `is_other(f) || is_other(t)` is `true`, or
113
+ - `is_directory(f) && is_regular_file(t)` is `true`.
114
  - Otherwise, if `is_symlink(f)`, then:
115
  - If `(options & copy_options::skip_symlinks) != copy_options::none`
116
  then return.
117
  - Otherwise if
118
  ``` cpp
 
132
  `(options & copy_options::create_hard_links) != copy_options::none`,
133
  then create a hard link to the source file.
134
  - Otherwise, if `is_directory(t)`, then
135
  `copy_file(from, to/from.filename(), options)`.
136
  - Otherwise, `copy_file(from, to, options)`.
137
+ - Otherwise, if
138
+ ``` cpp
139
+ is_directory(f) &&
140
+ (options & copy_options::create_symlinks) != copy_options::none
141
+ ```
142
+
143
+ then report an error with an `error_code` argument equal to
144
+ `make_error_code(errc::is_a_directory)`.
145
  - Otherwise, if
146
  ``` cpp
147
  is_directory(f) &&
148
  ((options & copy_options::recursive) != copy_options::none ||
149
  options == copy_options::none)
150
  ```
151
 
152
  then:
153
+ - If `exists(t)` is `false`, then `create_directory(to, from)`.
154
  - Then, iterate over the files in `from`, as if by
155
  ``` cpp
156
  for (const directory_entry& x : directory_iterator(from))
157
+ copy(x.path(), to/x.path().filename(),
158
+ options | copy_options::in-recursive-copy);
159
  ```
160
+
161
+ where *`in-recursive-copy`* is a bitmask element of `copy_options`
162
+ that is not one of the elements in  [[fs.enum.copy.opts]].
163
  - Otherwise, for the signature with argument `ec`, `ec.clear()`.
164
  - Otherwise, no effects.
165
 
166
  *Throws:* As specified in  [[fs.err.report]].
167
 
 
210
  file3
211
  ```
212
 
213
  — *end example*]
214
 
215
+ #### Copy file <a id="fs.op.copy.file">[[fs.op.copy.file]]</a>
216
 
217
  ``` cpp
218
  bool copy_file(const path& from, const path& to);
219
+ bool copy_file(const path& from, const path& to, error_code& ec);
220
  ```
221
 
222
  *Returns:* `copy_file(from, to, copy_options::none)` or
223
  `copy_file(from, to, copy_options::none, ec)`, respectively.
224
 
225
  *Throws:* As specified in  [[fs.err.report]].
226
 
227
  ``` cpp
228
  bool copy_file(const path& from, const path& to, copy_options options);
229
  bool copy_file(const path& from, const path& to, copy_options options,
230
+ error_code& ec);
231
  ```
232
 
233
+ *Preconditions:* At most one element from each option
234
+ group [[fs.enum.copy.opts]] is set in `options`.
235
 
236
  *Effects:* As follows:
237
 
238
+ - Report an error as specified in  [[fs.err.report]] if:
239
+ - `is_regular_file(from)` is `false`, or
240
+ - `exists(to)` is `true` and `is_regular_file(to)` is `false`, or
241
+ - `exists(to)` is `true` and `equivalent(from, to)` is `true`, or
242
+ - `exists(to)` is `true` and
 
243
  ``` cpp
244
  (options & (copy_options::skip_existing |
245
  copy_options::overwrite_existing |
246
  copy_options::update_existing)) == copy_options::none
247
  ```
248
  - Otherwise, copy the contents and attributes of the file `from`
249
  resolves to, to the file `to` resolves to, if:
250
+ - `exists(to)` is `false`, or
251
  - `(options & copy_options::overwrite_existing) != copy_options::none`,
252
  or
253
  - `(options & copy_options::update_existing) `` `` != copy_options::none`
254
  and `from` is more recent than `to`, determined as if by use of the
255
+ `last_write_time` function [[fs.op.last.write.time]].
256
  - Otherwise, no effects.
257
 
258
  *Returns:* `true` if the `from` file was copied, otherwise `false`. The
259
  signature with argument `ec` returns `false` if an error occurs.
260
 
261
  *Throws:* As specified in  [[fs.err.report]].
262
 
263
  *Complexity:* At most one direct or indirect invocation of `status(to)`.
264
 
265
+ #### Copy symlink <a id="fs.op.copy.symlink">[[fs.op.copy.symlink]]</a>
266
 
267
  ``` cpp
268
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
269
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
270
  error_code& ec) noexcept;
 
276
  respectively, where in each case *`function`* is `create_symlink` or
277
  `create_directory_symlink` as appropriate.
278
 
279
  *Throws:* As specified in  [[fs.err.report]].
280
 
281
+ #### Create directories <a id="fs.op.create.directories">[[fs.op.create.directories]]</a>
282
 
283
  ``` cpp
284
  bool create_directories(const path& p);
285
+ bool create_directories(const path& p, error_code& ec);
286
  ```
287
 
288
+ *Effects:* Calls `create_directory()` for each element of `p` that does
 
 
 
 
 
 
 
 
 
 
289
  not exist.
290
 
291
+ *Returns:* `true` if a new directory was created for the directory `p`
292
+ resolves to, otherwise `false`.
293
+
294
+ *Throws:* As specified in  [[fs.err.report]].
295
+
296
+ *Complexity:* 𝑂(n) where *n* is the number of elements of `p`.
297
+
298
+ #### Create directory <a id="fs.op.create.directory">[[fs.op.create.directory]]</a>
299
 
300
  ``` cpp
301
  bool create_directory(const path& p);
302
  bool create_directory(const path& p, error_code& ec) noexcept;
303
  ```
304
 
305
+ *Effects:* Creates the directory `p` resolves to, as if by POSIX `mkdir`
306
+ with a second argument of `static_cast<int>(perms::all)`. If `mkdir`
307
+ fails because `p` resolves to an existing directory, no error is
308
+ reported. Otherwise on failure an error is reported.
309
 
310
+ *Returns:* `true` if a new directory was created, otherwise `false`.
 
 
 
311
 
312
  *Throws:* As specified in  [[fs.err.report]].
313
 
314
  ``` cpp
315
  bool create_directory(const path& p, const path& existing_p);
316
  bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
317
  ```
318
 
319
+ *Effects:* Creates the directory `p` resolves to, with attributes copied
320
+ from directory `existing_p`. The set of attributes copied is operating
321
+ system dependent. If `mkdir` fails because `p` resolves to an existing
322
+ directory, no error is reported. Otherwise on failure an error is
323
+ reported.
324
 
325
  [*Note 1*: For POSIX-based operating systems, the attributes are those
326
  copied by native API `stat(existing_p.c_str(), &attributes_stat)`
327
  followed by `mkdir(p.c_str(), attributes_stat.st_mode)`. For
328
  Windows-based operating systems, the attributes are those copied by
329
  native API
330
  `CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)`. — *end note*]
331
 
332
+ *Returns:* `true` if a new directory was created with attributes copied
333
+ from directory `existing_p`, otherwise `false`.
 
 
334
 
335
  *Throws:* As specified in  [[fs.err.report]].
336
 
337
+ #### Create directory symlink <a id="fs.op.create.dir.symlk">[[fs.op.create.dir.symlk]]</a>
338
 
339
  ``` cpp
340
  void create_directory_symlink(const path& to, const path& new_symlink);
341
  void create_directory_symlink(const path& to, const path& new_symlink,
342
  error_code& ec) noexcept;
343
  ```
344
 
345
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
346
 
347
+ *Ensures:* `new_symlink` resolves to a symbolic link file that contains
348
+ an unspecified representation of `to`.
349
 
350
  *Throws:* As specified in  [[fs.err.report]].
351
 
352
  [*Note 1*: Some operating systems require symlink creation to identify
353
  that the link is to a directory. Portable code should use
 
357
  [*Note 2*: Some operating systems do not support symbolic links at all
358
  or support them only for regular files. Some file systems (such as the
359
  FAT file system) do not support symbolic links regardless of the
360
  operating system. — *end note*]
361
 
362
+ #### Create hard link <a id="fs.op.create.hard.lk">[[fs.op.create.hard.lk]]</a>
363
 
364
  ``` cpp
365
  void create_hard_link(const path& to, const path& new_hard_link);
366
  void create_hard_link(const path& to, const path& new_hard_link,
367
  error_code& ec) noexcept;
368
  ```
369
 
370
  *Effects:* Establishes the postcondition, as if by POSIX `link()`.
371
 
372
+ *Ensures:*
373
 
374
  - `exists(to) && exists(new_hard_link) && equivalent(to, new_hard_link)`
375
  - The contents of the file or directory `to` resolves to are unchanged.
376
 
377
  *Throws:* As specified in  [[fs.err.report]].
 
380
  support them only for regular files. Some file systems (such as the FAT
381
  file system) do not support hard links regardless of the operating
382
  system. Some file systems limit the number of links per
383
  file. — *end note*]
384
 
385
+ #### Create symlink <a id="fs.op.create.symlink">[[fs.op.create.symlink]]</a>
386
 
387
  ``` cpp
388
  void create_symlink(const path& to, const path& new_symlink);
389
  void create_symlink(const path& to, const path& new_symlink,
390
  error_code& ec) noexcept;
391
  ```
392
 
393
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
394
 
395
+ *Ensures:* `new_symlink` resolves to a symbolic link file that contains
396
+ an unspecified representation of `to`.
397
 
398
  *Throws:* As specified in  [[fs.err.report]].
399
 
400
  [*Note 1*: Some operating systems do not support symbolic links at all
401
  or support them only for regular files. Some file systems (such as the
402
  FAT file system) do not support symbolic links regardless of the
403
  operating system. — *end note*]
404
 
405
+ #### Current path <a id="fs.op.current.path">[[fs.op.current.path]]</a>
406
 
407
  ``` cpp
408
  path current_path();
409
  path current_path(error_code& ec);
410
  ```
 
422
  [*Note 1*: The `current_path()` name was chosen to emphasize that the
423
  returned value is a path, not just a single directory
424
  name. — *end note*]
425
 
426
  [*Note 2*: The current path as returned by many operating systems is a
427
+ dangerous global variable. It may be changed unexpectedly by third-party
428
+ or system library functions, or by another thread. — *end note*]
 
429
 
430
  ``` cpp
431
  void current_path(const path& p);
432
  void current_path(const path& p, error_code& ec) noexcept;
433
  ```
434
 
435
  *Effects:* Establishes the postcondition, as if by POSIX `chdir()`.
436
 
437
+ *Ensures:* `equivalent(p, current_path())`.
438
 
439
  *Throws:* As specified in  [[fs.err.report]].
440
 
441
  [*Note 3*: The current path for many operating systems is a dangerous
442
  global state. It may be changed unexpectedly by a third-party or system
 
447
  ``` cpp
448
  bool equivalent(const path& p1, const path& p2);
449
  bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
450
  ```
451
 
452
+ *Returns:* `true`, if `p1` and `p2` resolve to the same file system
453
+ entity, otherwise `false`. The signature with argument `ec` returns
454
+ `false` if an error occurs.
 
 
 
 
 
 
 
455
 
456
  Two paths are considered to resolve to the same file system entity if
457
  two candidate entities reside on the same device at the same location.
458
+
459
+ [*Note 1*: On POSIX platforms, this is determined as if by the values
460
+ of the POSIX `stat` class, obtained as if by `stat()` for the two paths,
461
+ having equal `st_dev` values and equal `st_ino` values. — *end note*]
462
+
463
+ *Remarks:* `!exists(p1) || !exists(p2)` is an error.
464
 
465
  *Throws:* As specified in  [[fs.err.report]].
466
 
467
  #### Exists <a id="fs.op.exists">[[fs.op.exists]]</a>
468
 
 
485
 
486
  *Returns:* `exists(s)`.
487
 
488
  *Throws:* As specified in  [[fs.err.report]].
489
 
490
+ #### File size <a id="fs.op.file.size">[[fs.op.file.size]]</a>
491
 
492
  ``` cpp
493
  uintmax_t file_size(const path& p);
494
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
495
  ```
496
 
497
+ *Effects:* If `exists(p)` is `false`, an error is
498
+ reported [[fs.err.report]].
499
+
500
  *Returns:*
501
 
502
+ - If `is_regular_file(p)`, the size in bytes of the file `p` resolves
503
+ to, determined as if by the value of the POSIX `stat` class member
504
+ `st_size` obtained as if by POSIX `stat()`.
 
505
  - Otherwise, the result is *implementation-defined*.
506
 
507
  The signature with argument `ec` returns `static_cast<uintmax_t>(-1)` if
508
  an error occurs.
509
 
510
  *Throws:* As specified in  [[fs.err.report]].
511
 
512
+ #### Hard link count <a id="fs.op.hard.lk.ct">[[fs.op.hard.lk.ct]]</a>
513
 
514
  ``` cpp
515
  uintmax_t hard_link_count(const path& p);
516
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
517
  ```
 
519
  *Returns:* The number of hard links for `p`. The signature with argument
520
  `ec` returns `static_cast<uintmax_t>(-1)` if an error occurs.
521
 
522
  *Throws:* As specified in  [[fs.err.report]].
523
 
524
+ #### Is block file <a id="fs.op.is.block.file">[[fs.op.is.block.file]]</a>
525
 
526
  ``` cpp
527
  bool is_block_file(file_status s) noexcept;
528
  ```
529
 
 
538
  respectively. The signature with argument `ec` returns `false` if an
539
  error occurs.
540
 
541
  *Throws:* As specified in  [[fs.err.report]].
542
 
543
+ #### Is character file <a id="fs.op.is.char.file">[[fs.op.is.char.file]]</a>
544
 
545
  ``` cpp
546
  bool is_character_file(file_status s) noexcept;
547
  ```
548
 
 
557
  `is_character_file(status(p, ec))`, respectively.
558
  The signature with argument `ec` returns `false` if an error occurs.
559
 
560
  *Throws:* As specified in  [[fs.err.report]].
561
 
562
+ #### Is directory <a id="fs.op.is.directory">[[fs.op.is.directory]]</a>
563
 
564
  ``` cpp
565
  bool is_directory(file_status s) noexcept;
566
  ```
567
 
 
576
  respectively. The signature with argument `ec` returns `false` if an
577
  error occurs.
578
 
579
  *Throws:* As specified in  [[fs.err.report]].
580
 
581
+ #### Is empty <a id="fs.op.is.empty">[[fs.op.is.empty]]</a>
582
 
583
  ``` cpp
584
  bool is_empty(const path& p);
585
+ bool is_empty(const path& p, error_code& ec);
586
  ```
587
 
588
  *Effects:*
589
 
590
  - Determine `file_status s`, as if by `status(p)` or `status(p, ec)`,
 
604
  occurred.
605
  - Otherwise, return `sz == 0`.
606
 
607
  *Throws:* As specified in  [[fs.err.report]].
608
 
609
+ #### Is fifo <a id="fs.op.is.fifo">[[fs.op.is.fifo]]</a>
610
 
611
  ``` cpp
612
  bool is_fifo(file_status s) noexcept;
613
  ```
614
 
 
623
  respectively. The signature with argument `ec` returns `false` if an
624
  error occurs.
625
 
626
  *Throws:* As specified in  [[fs.err.report]].
627
 
628
+ #### Is other <a id="fs.op.is.other">[[fs.op.is.other]]</a>
629
 
630
  ``` cpp
631
  bool is_other(file_status s) noexcept;
632
  ```
633
 
 
643
  respectively. The signature with argument `ec` returns `false` if an
644
  error occurs.
645
 
646
  *Throws:* As specified in  [[fs.err.report]].
647
 
648
+ #### Is regular file <a id="fs.op.is.regular.file">[[fs.op.is.regular.file]]</a>
649
 
650
  ``` cpp
651
  bool is_regular_file(file_status s) noexcept;
652
  ```
653
 
 
658
  ```
659
 
660
  *Returns:* `is_regular_file(status(p))`.
661
 
662
  *Throws:* `filesystem_error` if `status(p)` would throw
663
+ `filesystem_error`.
664
 
665
  ``` cpp
666
  bool is_regular_file(const path& p, error_code& ec) noexcept;
667
  ```
668
 
 
673
  between cases, call the `status` function directly. — *end note*]
674
 
675
  *Returns:* `is_regular_file(status(p, ec))`. Returns `false` if an error
676
  occurs.
677
 
678
+ #### Is socket <a id="fs.op.is.socket">[[fs.op.is.socket]]</a>
679
 
680
  ``` cpp
681
  bool is_socket(file_status s) noexcept;
682
  ```
683
 
 
692
  respectively. The signature with argument `ec` returns `false` if an
693
  error occurs.
694
 
695
  *Throws:* As specified in  [[fs.err.report]].
696
 
697
+ #### Is symlink <a id="fs.op.is.symlink">[[fs.op.is.symlink]]</a>
698
 
699
  ``` cpp
700
  bool is_symlink(file_status s) noexcept;
701
  ```
702
 
 
711
  `is_symlink(symlink_status(p, ec))`, respectively. The signature with
712
  argument `ec` returns `false` if an error occurs.
713
 
714
  *Throws:* As specified in  [[fs.err.report]].
715
 
716
+ #### Last write time <a id="fs.op.last.write.time">[[fs.op.last.write.time]]</a>
717
 
718
  ``` cpp
719
  file_time_type last_write_time(const path& p);
720
  file_time_type last_write_time(const path& p, error_code& ec) noexcept;
721
  ```
722
 
723
  *Returns:* The time of last data modification of `p`, determined as if
724
+ by the value of the POSIX `stat` class member `st_mtime` obtained as if
725
+ by POSIX `stat()`. The signature with argument `ec` returns
726
  `file_time_type::min()` if an error occurs.
727
 
728
  *Throws:* As specified in  [[fs.err.report]].
729
 
730
  ``` cpp
 
748
  void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
749
  void permissions(const path& p, perms prms, error_code& ec) noexcept;
750
  void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
751
  ```
752
 
753
+ *Preconditions:* Exactly one of the `perm_options` constants `replace`,
754
  `add`, or `remove` is present in `opts`.
755
 
756
  *Remarks:* The second signature behaves as if it had an additional
757
  parameter `perm_options` `opts` with an argument of
758
  `perm_options::replace`.
 
796
 
797
  or `path()` at the first error occurrence, if any.
798
 
799
  *Throws:* As specified in  [[fs.err.report]].
800
 
801
+ #### Read symlink <a id="fs.op.read.symlink">[[fs.op.read.symlink]]</a>
802
 
803
  ``` cpp
804
  path read_symlink(const path& p);
805
  path read_symlink(const path& p, error_code& ec);
806
  ```
 
856
  as if by POSIX `remove()`.
857
 
858
  [*Note 1*: A symbolic link is itself removed, rather than the file it
859
  resolves to. — *end note*]
860
 
861
+ *Ensures:* `exists(symlink_status(p))` is `false`.
862
 
863
  *Returns:* `false` if `p` did not exist, otherwise `true`. The signature
864
  with argument `ec` returns `false` if an error occurs.
865
 
866
  *Throws:* As specified in  [[fs.err.report]].
867
 
868
+ #### Remove all <a id="fs.op.remove.all">[[fs.op.remove.all]]</a>
869
 
870
  ``` cpp
871
  uintmax_t remove_all(const path& p);
872
+ uintmax_t remove_all(const path& p, error_code& ec);
873
  ```
874
 
875
  *Effects:* Recursively deletes the contents of `p` if it exists, then
876
  deletes file `p` itself, as if by POSIX `remove()`.
877
 
878
  [*Note 1*: A symbolic link is itself removed, rather than the file it
879
  resolves to. — *end note*]
880
 
881
+ *Ensures:* `exists(symlink_status(p))` is `false`.
882
 
883
  *Returns:* The number of files removed. The signature with argument `ec`
884
  returns `static_cast< uintmax_t>(-1)` if an error occurs.
885
 
886
  *Throws:* As specified in  [[fs.err.report]].
 
909
 
910
  — *end note*]
911
 
912
  *Throws:* As specified in  [[fs.err.report]].
913
 
914
+ #### Resize file <a id="fs.op.resize.file">[[fs.op.resize.file]]</a>
915
 
916
  ``` cpp
917
  void resize_file(const path& p, uintmax_t new_size);
918
  void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
919
  ```
920
 
921
+ *Effects:* Causes the size that would be returned by `file_size(p)` to
922
+ be equal to `new_size`, as if by POSIX `truncate()`.
923
 
924
  *Throws:* As specified in  [[fs.err.report]].
925
 
 
 
926
  #### Space <a id="fs.op.space">[[fs.op.space]]</a>
927
 
928
  ``` cpp
929
  space_info space(const path& p);
930
  space_info space(const path& p, error_code& ec) noexcept;
 
1023
  - Otherwise, if the attributes indicate a fifo or pipe file, as if by
1024
  POSIX `S_ISFIFO`, returns `file_status(file_type::fifo, prms)`.
1025
  - Otherwise, if the attributes indicate a socket, as if by POSIX
1026
  `S_ISSOCK`, returns `file_status(file_type::socket, prms)`.
1027
  - Otherwise, if the attributes indicate an implementation-defined file
1028
+ type [[fs.enum.file.type]], returns
1029
  `file_status(file_type::`*`A`*`, prms)`, where *A* is the constant
1030
  for the *implementation-defined* file type.
1031
  - Otherwise, returns `file_status(file_type::unknown, prms)`.
1032
 
1033
  *Remarks:* If a symbolic link is encountered during pathname resolution,
1034
  pathname resolution continues using the contents of the symbolic link.
1035
 
1036
+ #### Status known <a id="fs.op.status.known">[[fs.op.status.known]]</a>
1037
 
1038
  ``` cpp
1039
  bool status_known(file_status s) noexcept;
1040
  ```
1041
 
1042
  *Returns:* `s.type() != file_type::none`.
1043
 
1044
+ #### Symlink status <a id="fs.op.symlink.status">[[fs.op.symlink.status]]</a>
1045
 
1046
  ``` cpp
1047
  file_status symlink_status(const path& p);
1048
  file_status symlink_status(const path& p, error_code& ec) noexcept;
1049
  ```
 
1063
 
1064
  *Remarks:* Pathname resolution terminates if `p` names a symbolic link.
1065
 
1066
  *Throws:* As specified in  [[fs.err.report]].
1067
 
1068
+ #### Temporary directory path <a id="fs.op.temp.dir.path">[[fs.op.temp.dir.path]]</a>
1069
 
1070
  ``` cpp
1071
  path temp_directory_path();
1072
  path temp_directory_path(error_code& ec);
1073
  ```
1074
 
1075
+ Let `p` be an unspecified directory path suitable for temporary files.
1076
+
1077
+ *Effects:* If `exists(p)` is `false` or `is_directory(p)` is `false`, an
1078
+ error is reported [[fs.err.report]].
1079
+
1080
+ *Returns:* The path `p`. The signature with argument `ec` returns
1081
  `path()` if an error occurs.
1082
 
1083
  *Throws:* As specified in  [[fs.err.report]].
1084
 
1085
  [*Example 1*: For POSIX-based operating systems, an implementation
 
1087
  in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found,
1088
  `"/tmp"`. For Windows-based operating systems, an implementation might
1089
  return the path reported by the Windows `GetTempPath` API
1090
  function. — *end example*]
1091
 
1092
+ #### Weakly canonical <a id="fs.op.weakly.canonical">[[fs.op.weakly.canonical]]</a>
1093
 
1094
  ``` cpp
1095
  path weakly_canonical(const path& p);
1096
  path weakly_canonical(const path& p, error_code& ec);
1097
  ```
1098
 
1099
  *Returns:* `p` with symlinks resolved and the result
1100
+ normalized [[fs.path.generic]].
1101
 
1102
  *Effects:* Using `status(p)` or `status(p, ec)`, respectively, to
1103
  determine existence, return a path composed by `operator/=` from the
1104
+ result of calling `canonical()` with a path argument composed of the
1105
+ leading elements of `p` that exist, if any, followed by the elements of
1106
+ `p` that do not exist, if any. For the first form, `canonical()` is
1107
+ called without an `error_code` argument. For the second form,
1108
+ `canonical()` is called with `ec` as an `error_code` argument, and
1109
+ `path()` is returned at the first error occurrence, if any.
 
1110
 
1111
+ *Ensures:* The returned path is in normal form [[fs.path.generic]].
 
1112
 
1113
+ *Remarks:* Implementations should avoid unnecessary normalization such
1114
+ as when `canonical` has already been called on the entirety of `p`.
 
1115
 
1116
  *Throws:* As specified in  [[fs.err.report]].
1117