From Jason Turner

[filesystems]

Large diff (139.0 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmph3ri4pgb/{from.md → to.md} +718 -846
tmp/tmph3ri4pgb/{from.md → to.md} RENAMED
@@ -1,34 +1,69 @@
1
  ## File systems <a id="filesystems">[[filesystems]]</a>
2
 
3
  ### General <a id="fs.general">[[fs.general]]</a>
4
 
5
- This subclause describes operations on file systems and their
6
- components, such as paths, regular files, and directories.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  ### Conformance <a id="fs.conformance">[[fs.conformance]]</a>
9
 
10
  Conformance is specified in terms of behavior. Ideal behavior is not
11
  always implementable, so the conformance subclauses take that into
12
  account.
13
 
14
  #### POSIX conformance <a id="fs.conform.9945">[[fs.conform.9945]]</a>
15
 
16
- Some behavior is specified by reference to POSIX ([[fs.norm.ref]]). How
17
  such behavior is actually implemented is unspecified.
18
 
19
  [*Note 1*: This constitutes an “as if” rule allowing implementations to
20
  call native operating system or other APIs. — *end note*]
21
 
22
- Implementations are encouraged to provide such behavior as it is defined
23
- by POSIX. Implementations shall document any behavior that differs from
24
- the behavior defined by POSIX. Implementations that do not support exact
25
- POSIX behavior are encouraged to provide behavior as close to POSIX
26
- behavior as is reasonable given the limitations of actual operating
27
- systems and file systems. If an implementation cannot provide any
28
- reasonable behavior, the implementation shall report an error as
29
- specified in  [[fs.err.report]].
30
 
31
  [*Note 2*: This allows users to rely on an exception being thrown or an
32
  error code being set when an implementation cannot provide any
33
  reasonable behavior. — *end note*]
34
 
@@ -41,225 +76,88 @@ other features of more capable file systems, so implementations are not
41
  required to support those features on the FAT file system but instead
42
  are required to report an error as described above. — *end example*]
43
 
44
  #### Operating system dependent behavior conformance <a id="fs.conform.os">[[fs.conform.os]]</a>
45
 
46
- Some behavior is specified as being operating system dependent (
47
- [[fs.def.osdep]]). The operating system an implementation is dependent
48
- upon is *implementation-defined*.
 
49
 
50
  It is permissible for an implementation to be dependent upon an
51
  operating system emulator rather than the actual underlying operating
52
  system.
53
 
54
  #### File system race behavior <a id="fs.race.behavior">[[fs.race.behavior]]</a>
55
 
56
- Behavior is undefined if calls to functions provided by this subclause
57
- introduce a file system race ([[fs.def.race]]).
 
 
 
58
 
59
  If the possibility of a file system race would make it unreliable for a
60
  program to test for a precondition before calling a function described
61
- herein, *Requires:* is not specified for the function.
62
 
63
  [*Note 1*: As a design practice, preconditions are not specified when
64
  it is unreasonable for a program to detect them prior to calling the
65
  function. — *end note*]
66
 
67
  ### Normative references <a id="fs.norm.ref">[[fs.norm.ref]]</a>
68
 
69
- This subclause mentions commercially available operating systems for
70
- purposes of exposition.[^41]
71
-
72
- ### Terms and definitions <a id="fs.definitions">[[fs.definitions]]</a>
73
-
74
- A path that unambiguously identifies the location of a file without
75
- reference to an additional starting location. The elements of a path
76
- that determine if it is absolute are operating system dependent.
77
-
78
- A file within a file system that acts as a container of directory
79
- entries that contain information about other files, possibly including
80
- other directory files.
81
-
82
- An object within a file system that holds user or system data. Files can
83
- be written to, or read from, or both. A file has certain attributes,
84
- including type. File types include regular files and directories. Other
85
- types of files, such as symbolic links ([[fs.def.symlink]]), may be
86
- supported by the implementation.
87
-
88
- A collection of files and their attributes.
89
-
90
- The condition that occurs when multiple threads, processes, or computers
91
- interleave access and modification of the same object within a file
92
- system.
93
-
94
- The name of a file. Filenames *dot* and *dot-dot*, consisting solely of
95
- one and two period characters respectively, have special meaning. The
96
- following characteristics of filenames are operating system dependent:
97
-
98
- - The permitted characters. \[*Example 1*: Some operating systems
99
- prohibit the ASCII control characters (0x00 – 0x1F) in
100
- filenames. — *end example*]
101
- - The maximum permitted length.
102
- - Filenames that are not permitted.
103
- - Filenames that have special meaning.
104
- - Case awareness and sensitivity during path resolution.
105
- - Special rules that may apply to file types other than regular files,
106
- such as directories.
107
-
108
- A link ([[fs.def.link]]) to an existing file. Some file systems support
109
- multiple hard links to a file. If the last hard link to a file is
110
- removed, the file itself is removed.
111
-
112
- [*Note 1*: A hard link can be thought of as a shared-ownership smart
113
- pointer to a file. — *end note*]
114
-
115
- An object that associates a filename with a file. Several links can
116
- associate names with the same file.
117
-
118
- For narrow character strings, the operating system dependent current
119
- encoding for pathnames ([[fs.def.pathname]]). For wide character
120
- strings, the implementation-defined execution wide-character set
121
- encoding ([[lex.charset]]).
122
-
123
- The operating system dependent pathname format accepted by the host
124
- operating system.
125
-
126
- A path in normal form is said to be *normalized*. The process of
127
- obtaining a normalized path from a path that is not in normal form is
128
- called *normalization*.
129
-
130
- Normalization of a generic format pathname means:
131
-
132
- 1. If the path is empty, stop.
133
- 2. Replace each slash character in the *root-name* with a
134
- *preferred-separator*.
135
- 3. Replace each *directory-separator* with a *preferred-separator*.
136
- \[*Note 2*: The generic pathname grammar ([[fs.path.generic]])
137
- defines *directory-separator* as one or more slashes and
138
- *preferred-separator*s. — *end note*]
139
- 4. Remove each *dot* filename and any immediately following
140
- *directory-separator*.
141
- 5. As long as any appear, remove a non-*dot-dot* filename immediately
142
- followed by a *directory-separator* and a *dot-dot* filename, along
143
- with any immediately following *directory-separator*.
144
- 6. If there is a *root-directory*, remove all *dot-dot* filenames and
145
- any *directory-separator*s immediately following them.
146
- \[*Note 3*: These *dot-dot* filenames attempt to refer to
147
- nonexistent parent directories. — *end note*]
148
- 7. If the last filename is *dot-dot*, remove any trailing
149
- *directory-separator*.
150
- 8. If the path is empty, add a *dot*.
151
-
152
- Behavior that is dependent upon the behavior and characteristics of an
153
- operating system. See  [[fs.conform.os]].
154
-
155
- the directory that both contains a directory entry for the given
156
- directory and is represented by the filename *dot-dot* in the given
157
- directory.
158
-
159
- a directory containing a directory entry for the file under discussion.
160
-
161
- A sequence of elements that identify the location of a file within a
162
- filesystem. The elements are the *root-name*ₒₚₜ , *root-directory*ₒₚₜ ,
163
- and an optional sequence of filenames. The maximum number of elements in
164
- the sequence is operating system dependent.
165
-
166
- A character string that represents the name of a path. Pathnames are
167
- formatted according to the generic pathname format grammar (
168
- [[fs.path.generic]]) or an operating system dependent native pathname
169
- format.
170
-
171
- Pathname resolution is the operating system dependent mechanism for
172
- resolving a pathname to a particular file in a file hierarchy. There may
173
- be multiple pathnames that resolve to the same file.
174
-
175
- [*Example 2*: POSIX specifies the mechanism in section 4.11, Pathname
176
- resolution. — *end example*]
177
-
178
- A path that is not absolute, and as such, only unambiguously identifies
179
- the location of a file when resolved ([[fs.def.pathres]]) relative to
180
- an implied starting location. The elements of a path that determine if
181
- it is relative are operating system dependent.
182
-
183
- [*Note 4*: Pathnames “.” and “..” are relative paths. — *end note*]
184
-
185
- A type of file with the property that when the file is encountered
186
- during pathname resolution, a string stored by the file is used to
187
- modify the pathname resolution.
188
-
189
- [*Note 5*: Symbolic links are often called symlinks. A symbolic link
190
- can be thought of as a raw pointer to a file. If the file pointed to
191
- does not exist, the symbolic link is said to be a “dangling” symbolic
192
- link. — *end note*]
193
 
194
  ### Requirements <a id="fs.req">[[fs.req]]</a>
195
 
196
- Throughout this subclause, `char`, `wchar_t`, `char16_t`, and `char32_t`
197
- are collectively called *encoded character types*.
 
198
 
199
  Functions with template parameters named `EcharT` shall not participate
200
  in overload resolution unless `EcharT` is one of the encoded character
201
  types.
202
 
203
- Template parameters named `InputIterator` shall meet the input iterator
204
- requirements ([[input.iterators]]) and shall have a value type that is
205
- one of the encoded character types.
206
 
207
  [*Note 1*: Use of an encoded character type implies an associated
208
  character set and encoding. Since `signed char` and `unsigned char` have
209
  no implied character set and encoding, they are not included as
210
  permitted types. — *end note*]
211
 
212
- Template parameters named `Allocator` shall meet the Allocator
213
- requirements ([[allocator.requirements]]).
214
 
215
  #### Namespaces and headers <a id="fs.req.namespace">[[fs.req.namespace]]</a>
216
 
217
- Unless otherwise specified, references to entities described in this
218
- subclause are assumed to be qualified with `::std::filesystem::`.
 
219
 
220
  ### Header `<filesystem>` synopsis <a id="fs.filesystem.syn">[[fs.filesystem.syn]]</a>
221
 
222
  ``` cpp
 
 
223
  namespace std::filesystem {
224
  // [fs.class.path], paths
225
  class path;
226
 
227
  // [fs.path.nonmember], path non-member functions
228
  void swap(path& lhs, path& rhs) noexcept;
229
  size_t hash_value(const path& p) noexcept;
230
 
231
- bool operator==(const path& lhs, const path& rhs) noexcept;
232
- bool operator!=(const path& lhs, const path& rhs) noexcept;
233
- bool operator< (const path& lhs, const path& rhs) noexcept;
234
- bool operator<=(const path& lhs, const path& rhs) noexcept;
235
- bool operator> (const path& lhs, const path& rhs) noexcept;
236
- bool operator>=(const path& lhs, const path& rhs) noexcept;
237
-
238
- path operator/ (const path& lhs, const path& rhs);
239
-
240
- // [fs.path.io], path inserter and extractor
241
- template <class charT, class traits>
242
- basic_ostream<charT, traits>&
243
- operator<<(basic_ostream<charT, traits>& os, const path& p);
244
- template <class charT, class traits>
245
- basic_istream<charT, traits>&
246
- operator>>(basic_istream<charT, traits>& is, path& p);
247
-
248
- // [fs.path.factory], path factory functions
249
- template <class Source>
250
- path u8path(const Source& source);
251
- template <class InputIterator>
252
- path u8path(InputIterator first, InputIterator last);
253
-
254
- // [fs.class.filesystem_error], filesystem errors
255
  class filesystem_error;
256
 
257
- // [fs.class.directory_entry], directory entries
258
  class directory_entry;
259
 
260
- // [fs.class.directory_iterator], directory iterators
261
  class directory_iterator;
262
 
263
  // [fs.dir.itr.nonmembers], range access for directory iterators
264
  directory_iterator begin(directory_iterator iter) noexcept;
265
  directory_iterator end(const directory_iterator&) noexcept;
@@ -269,53 +167,55 @@ namespace std::filesystem {
269
 
270
  // [fs.rec.dir.itr.nonmembers], range access for recursive directory iterators
271
  recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
272
  recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
273
 
274
- // [fs.class.file_status], file status
275
  class file_status;
276
 
277
  struct space_info {
278
  uintmax_t capacity;
279
  uintmax_t free;
280
  uintmax_t available;
 
 
281
  };
282
 
283
  // [fs.enum], enumerations
284
  enum class file_type;
285
  enum class perms;
286
  enum class perm_options;
287
  enum class copy_options;
288
  enum class directory_options;
289
 
290
- using file_time_type = chrono::time_point<trivial-clock>;
291
 
292
  // [fs.op.funcs], filesystem operations
293
- path absolute(const path& p, const path& base = current_path());
 
294
 
295
- path canonical(const path& p, const path& base = current_path());
296
  path canonical(const path& p, error_code& ec);
297
- path canonical(const path& p, const path& base, error_code& ec);
298
 
299
  void copy(const path& from, const path& to);
300
- void copy(const path& from, const path& to, error_code& ec) noexcept;
301
  void copy(const path& from, const path& to, copy_options options);
302
  void copy(const path& from, const path& to, copy_options options,
303
- error_code& ec) noexcept;
304
 
305
  bool copy_file(const path& from, const path& to);
306
- bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
307
  bool copy_file(const path& from, const path& to, copy_options option);
308
  bool copy_file(const path& from, const path& to, copy_options option,
309
- error_code& ec) noexcept;
310
 
311
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
312
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
313
  error_code& ec) noexcept;
314
 
315
  bool create_directories(const path& p);
316
- bool create_directories(const path& p, error_code& ec) noexcept;
317
 
318
  bool create_directory(const path& p);
319
  bool create_directory(const path& p, error_code& ec) noexcept;
320
 
321
  bool create_directory(const path& p, const path& attributes);
@@ -337,17 +237,17 @@ namespace std::filesystem {
337
  path current_path();
338
  path current_path(error_code& ec);
339
  void current_path(const path& p);
340
  void current_path(const path& p, error_code& ec) noexcept;
341
 
 
 
 
342
  bool exists(file_status s) noexcept;
343
  bool exists(const path& p);
344
  bool exists(const path& p, error_code& ec) noexcept;
345
 
346
- bool equivalent(const path& p1, const path& p2);
347
- bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
348
-
349
  uintmax_t file_size(const path& p);
350
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
351
 
352
  uintmax_t hard_link_count(const path& p);
353
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
@@ -363,11 +263,11 @@ namespace std::filesystem {
363
  bool is_directory(file_status s) noexcept;
364
  bool is_directory(const path& p);
365
  bool is_directory(const path& p, error_code& ec) noexcept;
366
 
367
  bool is_empty(const path& p);
368
- bool is_empty(const path& p, error_code& ec) noexcept;
369
 
370
  bool is_fifo(file_status s) noexcept;
371
  bool is_fifo(const path& p);
372
  bool is_fifo(const path& p, error_code& ec) noexcept;
373
 
@@ -410,11 +310,11 @@ namespace std::filesystem {
410
 
411
  bool remove(const path& p);
412
  bool remove(const path& p, error_code& ec) noexcept;
413
 
414
  uintmax_t remove_all(const path& p);
415
- uintmax_t remove_all(const path& p, error_code& ec) noexcept;
416
 
417
  void rename(const path& from, const path& to);
418
  void rename(const path& from, const path& to, error_code& ec) noexcept;
419
 
420
  void resize_file(const path& p, uintmax_t size);
@@ -437,15 +337,13 @@ namespace std::filesystem {
437
  path weakly_canonical(const path& p);
438
  path weakly_canonical(const path& p, error_code& ec);
439
  }
440
  ```
441
 
442
- `trivial-clock` is an *implementation-defined* type that satisfies the
443
- `TrivialClock` requirements ([[time.clock.req]]) and that is capable of
444
- representing and measuring file time values. Implementations should
445
- ensure that the resolution and range of `file_time_type` reflect the
446
- operating system dependent resolution and range of file time values.
447
 
448
  ### Error reporting <a id="fs.err.report">[[fs.err.report]]</a>
449
 
450
  Filesystem library functions often provide two overloads, one that
451
  throws an exception to report file system errors, and another that sets
@@ -491,22 +389,49 @@ follows, unless otherwise specified:
491
  appropriate for the specific operating system dependent error.
492
  Otherwise, `clear()` is called on the `error_code&` argument.
493
 
494
  ### Class `path` <a id="fs.class.path">[[fs.class.path]]</a>
495
 
496
- An object of class `path` represents a path ([[fs.def.path]]) and
497
- contains a pathname ([[fs.def.pathname]]). Such an object is concerned
498
- only with the lexical and syntactic aspects of a path. The path does not
499
- necessarily exist in external storage, and the pathname is not
500
- necessarily valid for the current operating system or for a particular
501
- file system.
502
 
503
  [*Note 1*: Class `path` is used to support the differences between the
504
  string types used by different operating systems to represent pathnames,
505
  and to perform conversions between encodings when
506
  necessary. — *end note*]
507
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  ``` cpp
509
  namespace std::filesystem {
510
  class path {
511
  public:
512
  using value_type = see below;
@@ -537,11 +462,11 @@ namespace std::filesystem {
537
  path& operator=(string_type&& source);
538
  path& assign(string_type&& source);
539
  template<class Source>
540
  path& operator=(const Source& source);
541
  template<class Source>
542
- path& assign(const Source& source)
543
  template<class InputIterator>
544
  path& assign(InputIterator first, InputIterator last);
545
 
546
  // [fs.path.append], appends
547
  path& operator/=(const path& p);
@@ -573,10 +498,16 @@ namespace std::filesystem {
573
  path& remove_filename();
574
  path& replace_filename(const path& replacement);
575
  path& replace_extension(const path& replacement = path());
576
  void swap(path& rhs) noexcept;
577
 
 
 
 
 
 
 
578
  // [fs.path.native.obs], native format observers
579
  const string_type& native() const noexcept;
580
  const value_type* c_str() const noexcept;
581
  operator string_type() const;
582
 
@@ -584,22 +515,22 @@ namespace std::filesystem {
584
  class Allocator = allocator<EcharT>>
585
  basic_string<EcharT, traits, Allocator>
586
  string(const Allocator& a = Allocator()) const;
587
  std::string string() const;
588
  std::wstring wstring() const;
589
- std::string u8string() const;
590
  std::u16string u16string() const;
591
  std::u32string u32string() const;
592
 
593
  // [fs.path.generic.obs], generic format observers
594
  template<class EcharT, class traits = char_traits<EcharT>,
595
  class Allocator = allocator<EcharT>>
596
  basic_string<EcharT, traits, Allocator>
597
  generic_string(const Allocator& a = Allocator()) const;
598
  std::string generic_string() const;
599
  std::wstring generic_wstring() const;
600
- std::string generic_u8string() const;
601
  std::u16string generic_u16string() const;
602
  std::u32string generic_u32string() const;
603
 
604
  // [fs.path.compare], compare
605
  int compare(const path& p) const noexcept;
@@ -616,11 +547,11 @@ namespace std::filesystem {
616
  path filename() const;
617
  path stem() const;
618
  path extension() const;
619
 
620
  // [fs.path.query], query
621
- bool empty() const noexcept;
622
  bool has_root_name() const;
623
  bool has_root_directory() const;
624
  bool has_root_path() const;
625
  bool has_relative_path() const;
626
  bool has_parent_path() const;
@@ -639,21 +570,29 @@ namespace std::filesystem {
639
  class iterator;
640
  using const_iterator = iterator;
641
 
642
  iterator begin() const;
643
  iterator end() const;
 
 
 
 
 
 
 
 
644
  };
645
  }
646
  ```
647
 
648
  `value_type` is a `typedef` for the operating system dependent encoded
649
  character type used to represent pathnames.
650
 
651
  The value of the `preferred_separator` member is the operating system
652
- dependent *preferred-separator* character ([[fs.path.generic]]).
653
 
654
- [*Example 1*: For POSIX-based operating systems, `value_type` is `char`
655
  and `preferred_separator` is the slash character (`'/'`). For
656
  Windows-based operating systems, `value_type` is `wchar_t` and
657
  `preferred_separator` is the backslash character
658
  (`L'\\'`). — *end example*]
659
 
@@ -701,31 +640,42 @@ preferred-separator:
701
  ``` bnf
702
  fallback-separator:
703
  /, if *preferred-separator* is not /
704
  ```
705
 
706
- [*Note 1*: Operating systems often place restrictions on the characters
707
- that may be used in a *filename*. For wide portability, users may wish
708
- to limit *filename* characters to the POSIX Portable Filename Character
709
- Set:
 
 
 
 
 
 
710
  `A B C D E F G H I J K L M N O P Q R S T U V W X Y Z`
711
  `a b c d e f g h i j k l m n o p q r s t u v w x y z`
712
  `0 1 2 3 4 5 6 7 8 9 . _ -` — *end note*]
 
 
 
 
 
 
713
 
714
  Except in a *root-name*, multiple successive *directory-separator*
715
  characters are considered to be the same as one *directory-separator*
716
  character.
717
 
718
- The filename *dot* ([[fs.def.filename]]) is treated as a reference to
719
- the current directory. The filename *dot-dot* ([[fs.def.filename]]) is
720
- treated as a reference to the parent directory. What the filename
721
- *dot-dot* refers to relative to *root-directory* is
722
  *implementation-defined*. Specific filenames may have special meanings
723
  for a particular operating system.
724
 
725
- A *root-name* identifies the starting location for pathname resolution (
726
- [[fs.def.pathres]]). If there are no operating system dependent
727
  *root-name*s, at least one *implementation-defined* *root-name* is
728
  required.
729
 
730
  [*Note 2*: Many operating systems define a name beginning with two
731
  *directory-separator* characters as a *root-name* that identifies
@@ -738,17 +688,42 @@ longest sequence of characters is chosen.
738
 
739
  [*Note 3*: On a POSIX-like operating system, it is impossible to have a
740
  *root-name* and a *relative-path* without an intervening
741
  *root-directory* element. — *end note*]
742
 
743
- #### `path` conversions <a id="fs.path.cvt">[[fs.path.cvt]]</a>
744
 
745
- ##### `path` argument format conversions <a id="fs.path.fmt.cvt">[[fs.path.fmt.cvt]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
 
747
  [*Note 1*:
748
 
749
- The format conversions described in this section are not applied on
750
  POSIX-based operating systems because on these systems:
751
 
752
  - The generic format is acceptable as a native path.
753
  - There is no need to distinguish between native format and generic
754
  format in function arguments.
@@ -757,15 +732,15 @@ POSIX-based operating systems because on these systems:
757
 
758
  — *end note*]
759
 
760
  Several functions are defined to accept *detected-format* arguments,
761
  which are character sequences. A detected-format argument represents a
762
- path using either a pathname in the generic format (
763
- [[fs.path.generic]]) or a pathname in the native format (
764
- [[fs.def.native]]). Such an argument is taken to be in the generic
765
- format if and only if it matches the generic format and is not
766
- acceptable to the operating system as a native path.
767
 
768
  [*Note 2*: Some operating systems may have no unambiguous way to
769
  distinguish between native format and generic format arguments. This is
770
  by design as it simplifies use for operating systems that do not require
771
  disambiguation. An implementation for an operating system where
@@ -784,12 +759,12 @@ native-to-generic and generic-to-native formats respectively. If
784
  If the native format requires paths for regular files to be formatted
785
  differently from paths for directories, the path shall be treated as a
786
  directory path if its last element is a *directory-separator*, otherwise
787
  it shall be treated as a path to a regular file.
788
 
789
- [*Note 4*: A path stores a native format pathname (
790
- [[fs.path.native.obs]]) and acts as if it also stores a generic format
791
  pathname, related as given below. The implementation may generate the
792
  generic format pathname based on the native format pathname (and
793
  possibly other information) when requested. — *end note*]
794
 
795
  When a path is constructed from or is assigned a single representation
@@ -802,95 +777,101 @@ the other representation. The value *q* converts to *p* (by *G* or *N*
802
  as appropriate) if any such value does so; *q* is otherwise unspecified.
803
 
804
  [*Note 5*: If *q* is the result of converting any path at all, it is
805
  the result of converting *p*. — *end note*]
806
 
807
- ##### `path` type and encoding conversions <a id="fs.path.type.cvt">[[fs.path.type.cvt]]</a>
 
 
 
 
 
 
808
 
809
  For member function arguments that take character sequences representing
810
  paths and for member functions returning strings, value type and
811
  encoding conversion is performed if the value type of the argument or
812
  return value differs from `path::value_type`. For the argument or return
813
  value, the method of conversion and the encoding to be converted to is
814
  determined by its value type:
815
 
816
- - `char`: The encoding is the native narrow encoding (
817
- [[fs.def.native.encode]]). The method of conversion, if any, is
818
- operating system dependent. \[*Note 6*: For POSIX-based operating
819
- systems `path::value_type` is `char` so no conversion from `char`
820
- value type arguments or to `char` value type return values is
821
- performed. For Windows-based operating systems, the native narrow
822
- encoding is determined by calling a Windows API
823
  function. — *end note*] \[*Note 7*: This results in behavior
824
  identical to other C and C++ standard library functions that perform
825
- file operations using narrow character strings to identify paths.
826
  Changing this behavior would be surprising and error
827
  prone. — *end note*]
828
- - `wchar_t`: The encoding is the native wide encoding (
829
- [[fs.def.native.encode]]). The method of conversion is unspecified.
830
- \[*Note 8*: For Windows-based operating systems `path::value_type` is
831
- `wchar_t` so no conversion from `wchar_t` value type arguments or to
832
- `wchar_t` value type return values is performed. — *end note*]
 
 
833
  - `char16_t`: The encoding is UTF-16. The method of conversion is
834
  unspecified.
835
  - `char32_t`: The encoding is UTF-32. The method of conversion is
836
  unspecified.
837
 
838
  If the encoding being converted to has no representation for source
839
  characters, the resulting converted characters, if any, are unspecified.
840
  Implementations should not modify member function arguments if already
841
  of type `path::value_type`.
842
 
843
- #### `path` requirements <a id="fs.path.req">[[fs.path.req]]</a>
844
 
845
- In addition to the requirements ([[fs.req]]), function template
846
- parameters named `Source` shall be one of:
847
 
848
  - `basic_string<EcharT, traits, Allocator>`. A function argument
849
  `const Source&` `source` shall have an effective range
850
  \[`source.begin()`, `source.end()`).
851
  - `basic_string_view<EcharT, traits>`. A function argument
852
  `const Source&` `source` shall have an effective range
853
  \[`source.begin()`, `source.end()`).
854
- - A type meeting the input iterator requirements that iterates over a
855
- NTCTS. The value type shall be an encoded character type. A function
856
- argument `const Source&` `source` shall have an effective range
857
- \[`source`, `end`) where `end` is the first iterator value with an
858
- element value equal to `iterator_traits<Source>::value_type()`.
859
  - A character array that after array-to-pointer decay results in a
860
  pointer to the start of a NTCTS. The value type shall be an encoded
861
  character type. A function argument `const Source&` `source` shall
862
  have an effective range \[`source`, `end`) where `end` is the first
863
  iterator value with an element value equal to
864
  `iterator_traits<decay_t<Source>>::value_type()`.
865
 
866
  Functions taking template parameters named `Source` shall not
867
- participate in overload resolution unless either
 
868
 
869
  - `Source` is a specialization of `basic_string` or `basic_string_view`,
870
  or
871
  - the *qualified-id* `iterator_traits<decay_t<Source>>::value_type` is
872
- valid and denotes a possibly `const` encoded character type (
873
- [[temp.deduct]]).
874
 
875
- [*Note 1*: See path conversions ([[fs.path.cvt]]) for how the value
876
- types above and their encodings convert to `path::value_type` and its
877
  encoding. — *end note*]
878
 
879
  Arguments of type `Source` shall not be null pointers.
880
 
881
- #### `path` members <a id="fs.path.member">[[fs.path.member]]</a>
882
 
883
- ##### `path` constructors <a id="fs.path.construct">[[fs.path.construct]]</a>
884
 
885
  ``` cpp
886
  path() noexcept;
887
  ```
888
 
889
- *Effects:* Constructs an object of class `path`.
890
-
891
- *Postconditions:* `empty() == true`.
892
 
893
  ``` cpp
894
  path(const path& p);
895
  path(path&& p) noexcept;
896
  ```
@@ -903,49 +884,48 @@ state.
903
  ``` cpp
904
  path(string_type&& source, format fmt = auto_format);
905
  ```
906
 
907
  *Effects:* Constructs an object of class `path` for which the pathname
908
- in the detected-format of `source` has the original value of
909
- `source` ([[fs.path.fmt.cvt]]), converting format if
910
- required ([[fs.path.fmt.cvt]]). `source` is left in a valid but
911
- unspecified state.
912
 
913
  ``` cpp
914
  template<class Source>
915
  path(const Source& source, format fmt = auto_format);
916
  template<class InputIterator>
917
  path(InputIterator first, InputIterator last, format fmt = auto_format);
918
  ```
919
 
920
- *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
921
- or the range \[`first`, `last`), with the encoding converted if
922
- required ([[fs.path.cvt]]). Finds the detected-format of
923
- `s` ([[fs.path.fmt.cvt]]) and constructs an object of class `path` for
924
- which the pathname in that format is `s`.
925
 
926
  ``` cpp
927
  template<class Source>
928
  path(const Source& source, const locale& loc, format fmt = auto_format);
929
  template<class InputIterator>
930
  path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
931
  ```
932
 
933
- *Requires:* The value type of `Source` and `InputIterator` is `char`.
934
 
935
  *Effects:* Let `s` be the effective range of `source` or the range
936
  \[`first`, `last`), after converting the encoding as follows:
937
 
938
  - If `value_type` is `wchar_t`, converts to the native wide
939
- encoding ([[fs.def.native.encode]]) using the
940
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`.
941
  - Otherwise a conversion is performed using the
942
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`, and then a second
943
- conversion to the current narrow encoding.
944
 
945
- Finds the detected-format of `s` ([[fs.path.fmt.cvt]]) and constructs
946
- an object of class `path` for which the pathname in that format is `s`.
947
 
948
  [*Example 1*:
949
 
950
  A string is to be read from a database that is encoded in ISO/IEC
951
  8859-1, and used to create a directory:
@@ -959,27 +939,27 @@ fs::create_directory(fs::path(latin1_string, latin1_locale));
959
  ```
960
 
961
  For POSIX-based operating systems, the path is constructed by first
962
  using `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string`
963
  to a wide character string in the native wide
964
- encoding ([[fs.def.native.encode]]). The resulting wide string is then
965
- converted to a narrow character pathname string in the current native
966
- narrow encoding. If the native wide encoding is UTF-16 or UTF-32, and
967
- the current native narrow encoding is UTF-8, all of the characters in
968
  the ISO/IEC 8859-1 character set will be converted to their Unicode
969
- representation, but for other native narrow encodings some characters
970
  may have no representation.
971
 
972
  For Windows-based operating systems, the path is constructed by using
973
  `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string` to a
974
  UTF-16 encoded wide character pathname string. All of the characters in
975
  the ISO/IEC 8859-1 character set will be converted to their Unicode
976
  representation.
977
 
978
  — *end example*]
979
 
980
- ##### `path` assignments <a id="fs.path.assign">[[fs.path.assign]]</a>
981
 
982
  ``` cpp
983
  path& operator=(const path& p);
984
  ```
985
 
@@ -1019,18 +999,18 @@ template <class Source>
1019
  path& assign(const Source& source);
1020
  template<class InputIterator>
1021
  path& assign(InputIterator first, InputIterator last);
1022
  ```
1023
 
1024
- *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
1025
- or the range \[`first`, `last`), with the encoding converted if
1026
- required ([[fs.path.cvt]]). Finds the detected-format of
1027
- `s` ([[fs.path.fmt.cvt]]) and sets the pathname in that format to `s`.
1028
 
1029
  *Returns:* `*this`.
1030
 
1031
- ##### `path` appends <a id="fs.path.append">[[fs.path.append]]</a>
1032
 
1033
  The append operations use `operator/=` to denote their semantic effect
1034
  of appending *preferred-separator* when needed.
1035
 
1036
  ``` cpp
@@ -1053,26 +1033,28 @@ Otherwise, modifies `*this` as if by these steps:
1053
  pathname.
1054
 
1055
  [*Example 2*:
1056
 
1057
  Even if `//host` is interpreted as a *root-name*, both of the paths
1058
- `path("//host")/"foo"` and `path("//host/")/"foo"` equal `"//host/foo"`.
 
1059
 
1060
  Expression examples:
1061
 
1062
  ``` cpp
1063
  // On POSIX,
1064
- path("foo") / ""; // yields "foo/"
1065
- path("foo") / "/bar"; // yields "/bar"
1066
- // On Windows, backslashes replace slashes in the above yields
1067
 
1068
  // On Windows,
1069
- path("foo") / "c:/bar"; // yields "c:/bar"
1070
- path("foo") / "c:"; // yields "c:"
1071
- path("c:") / ""; // yields "c:"
1072
- path("c:foo") / "/bar"; // yields "c:/bar"
1073
- path("c:foo") / "c:bar"; // yields "c:foo/bar"
 
 
1074
  ```
1075
 
1076
  — *end example*]
1077
 
1078
  *Returns:* `*this`.
@@ -1091,22 +1073,19 @@ template <class InputIterator>
1091
  path& append(InputIterator first, InputIterator last);
1092
  ```
1093
 
1094
  *Effects:* Equivalent to: `return operator/=(path(first, last));`
1095
 
1096
- ##### `path` concatenation <a id="fs.path.concat">[[fs.path.concat]]</a>
1097
 
1098
  ``` cpp
1099
  path& operator+=(const path& x);
1100
  path& operator+=(const string_type& x);
1101
  path& operator+=(basic_string_view<value_type> x);
1102
  path& operator+=(const value_type* x);
1103
- path& operator+=(value_type x);
1104
  template<class Source>
1105
  path& operator+=(const Source& x);
1106
- template <class EcharT>
1107
- path& operator+=(EcharT x);
1108
  template<class Source>
1109
  path& concat(const Source& x);
1110
  ```
1111
 
1112
  *Effects:* Appends `path(x).native()` to the pathname in the native
@@ -1115,24 +1094,32 @@ format.
1115
  [*Note 2*: This directly manipulates the value of `native()` and may
1116
  not be portable between operating systems. — *end note*]
1117
 
1118
  *Returns:* `*this`.
1119
 
 
 
 
 
 
 
 
 
1120
  ``` cpp
1121
  template<class InputIterator>
1122
  path& concat(InputIterator first, InputIterator last);
1123
  ```
1124
 
1125
- *Effects:* Equivalent to `return *this += path(first, last)`.
1126
 
1127
- ##### `path` modifiers <a id="fs.path.modifiers">[[fs.path.modifiers]]</a>
1128
 
1129
  ``` cpp
1130
  void clear() noexcept;
1131
  ```
1132
 
1133
- *Postconditions:* `empty() == true`.
1134
 
1135
  ``` cpp
1136
  path& make_preferred();
1137
  ```
1138
 
@@ -1170,15 +1157,15 @@ output is:
1170
 
1171
  ``` cpp
1172
  path& remove_filename();
1173
  ```
1174
 
1175
- *Postconditions:* `!has_filename()`.
1176
-
1177
  *Effects:* Remove the generic format pathname of `filename()` from the
1178
  generic format pathname.
1179
 
 
 
1180
  *Returns:* `*this`.
1181
 
1182
  [*Example 4*:
1183
 
1184
  ``` cpp
@@ -1216,12 +1203,12 @@ path("/").replace_filename("bar"); // yields "/bar" on POSIX
1216
  path& replace_extension(const path& replacement = path());
1217
  ```
1218
 
1219
  *Effects:*
1220
 
1221
- - Any existing `extension()(` [[fs.path.decompose]]`)` is removed from
1222
- the pathname in the generic format, then
1223
  - If `replacement` is not empty and does not begin with a dot character,
1224
  a dot character is appended to the pathname in the generic format,
1225
  then
1226
  - `operator+=(replacement);`.
1227
 
@@ -1233,14 +1220,14 @@ void swap(path& rhs) noexcept;
1233
 
1234
  *Effects:* Swaps the contents (in all formats) of the two paths.
1235
 
1236
  *Complexity:* Constant time.
1237
 
1238
- ##### `path` native format observers <a id="fs.path.native.obs">[[fs.path.native.obs]]</a>
1239
 
1240
  The string returned by all native format observers is in the native
1241
- pathname format ([[fs.def.native]]).
1242
 
1243
  ``` cpp
1244
  const string_type& native() const noexcept;
1245
  ```
1246
 
@@ -1248,11 +1235,11 @@ const string_type& native() const noexcept;
1248
 
1249
  ``` cpp
1250
  const value_type* c_str() const noexcept;
1251
  ```
1252
 
1253
- *Returns:* Equivalent to `native().c_str()`.
1254
 
1255
  ``` cpp
1256
  operator string_type() const;
1257
  ```
1258
 
@@ -1276,26 +1263,25 @@ be performed by `a`. Conversion, if any, is specified by
1276
  [[fs.path.cvt]].
1277
 
1278
  ``` cpp
1279
  std::string string() const;
1280
  std::wstring wstring() const;
1281
- std::string u8string() const;
1282
  std::u16string u16string() const;
1283
  std::u32string u32string() const;
1284
  ```
1285
 
1286
- *Returns:* `pathstring`.
1287
 
1288
  *Remarks:* Conversion, if any, is performed as specified by
1289
- [[fs.path.cvt]]. The encoding of the string returned by `u8string()` is
1290
- always UTF-8.
1291
 
1292
- ##### `path` generic format observers <a id="fs.path.generic.obs">[[fs.path.generic.obs]]</a>
1293
 
1294
  Generic format observer functions return strings formatted according to
1295
- the generic pathname format ([[fs.path.generic]]). A single slash
1296
- (`'/'`) character is used as the *directory-separator*.
1297
 
1298
  [*Example 1*:
1299
 
1300
  On an operating system that uses backslash as its *preferred-separator*,
1301
 
@@ -1321,53 +1307,51 @@ be performed by `a`. Conversion, if any, is specified by
1321
  [[fs.path.cvt]].
1322
 
1323
  ``` cpp
1324
  std::string generic_string() const;
1325
  std::wstring generic_wstring() const;
1326
- std::string generic_u8string() const;
1327
  std::u16string generic_u16string() const;
1328
  std::u32string generic_u32string() const;
1329
  ```
1330
 
1331
  *Returns:* The pathname in the generic format.
1332
 
1333
- *Remarks:* Conversion, if any, is specified by  [[fs.path.cvt]]. The
1334
- encoding of the string returned by `generic_u8string()` is always UTF-8.
1335
 
1336
- ##### `path` compare <a id="fs.path.compare">[[fs.path.compare]]</a>
1337
 
1338
  ``` cpp
1339
  int compare(const path& p) const noexcept;
1340
  ```
1341
 
1342
  *Returns:*
1343
 
1344
- - A value less than `0`, if `native()` for the elements of `*this` are
1345
- lexicographically less than `native()` for the elements of `p`;
1346
- otherwise,
1347
- - a value greater than `0`, if `native()` for the elements of `*this`
1348
- are lexicographically greater than `native()` for the elements of `p`;
1349
- otherwise,
1350
- - `0`.
1351
-
1352
- *Remarks:* The elements are determined as if by iteration over the
1353
- half-open range \[`begin()`, `end()`) for `*this` and `p`.
 
 
 
 
1354
 
1355
  ``` cpp
1356
- int compare(const string_type& s) const
1357
  int compare(basic_string_view<value_type> s) const;
 
1358
  ```
1359
 
1360
- *Returns:* `compare(path(s))`.
1361
 
1362
- ``` cpp
1363
- int compare(const value_type* s) const
1364
- ```
1365
-
1366
- *Returns:* `compare(path(s))`.
1367
-
1368
- ##### `path` decomposition <a id="fs.path.decompose">[[fs.path.decompose]]</a>
1369
 
1370
  ``` cpp
1371
  path root_name() const;
1372
  ```
1373
 
@@ -1390,20 +1374,21 @@ path root_path() const;
1390
  ``` cpp
1391
  path relative_path() const;
1392
  ```
1393
 
1394
  *Returns:* A `path` composed from the pathname in the generic format, if
1395
- `!empty()`, beginning with the first *filename* after *root-path*.
1396
- Otherwise, `path()`.
1397
 
1398
  ``` cpp
1399
  path parent_path() const;
1400
  ```
1401
 
1402
- *Returns:* `*this` if `!has_relative_path()`, otherwise a path whose
1403
- generic format pathname is the longest prefix of the generic format
1404
- pathname of `*this` that produces one fewer element in its iteration.
 
1405
 
1406
  ``` cpp
1407
  path filename() const;
1408
  ```
1409
 
@@ -1450,11 +1435,11 @@ for (; !p.extension().empty(); p = p.stem())
1450
 
1451
  ``` cpp
1452
  path extension() const;
1453
  ```
1454
 
1455
- *Returns:* a path whose pathname in the generic format is the suffix of
1456
  `filename()` not included in `stem()`.
1457
 
1458
  [*Example 8*:
1459
 
1460
  ``` cpp
@@ -1473,18 +1458,18 @@ extension. — *end note*]
1473
 
1474
  [*Note 5*: On non-POSIX operating systems, for a path `p`, it may not
1475
  be the case that `p.stem() + p.extension() == p.filename()`, even though
1476
  the generic format pathnames are the same. — *end note*]
1477
 
1478
- ##### `path` query <a id="fs.path.query">[[fs.path.query]]</a>
1479
 
1480
  ``` cpp
1481
- bool empty() const noexcept;
1482
  ```
1483
 
1484
- *Returns:* `true` if the pathname in the generic format is empty, else
1485
- `false`.
1486
 
1487
  ``` cpp
1488
  bool has_root_path() const;
1489
  ```
1490
 
@@ -1535,11 +1520,11 @@ bool has_extension() const;
1535
  ``` cpp
1536
  bool is_absolute() const;
1537
  ```
1538
 
1539
  *Returns:* `true` if the pathname in the native format contains an
1540
- absolute path ([[fs.def.absolute.path]]), else `false`.
1541
 
1542
  [*Example 9*: `path("/").is_absolute()` is `true` for POSIX-based
1543
  operating systems, and `false` for Windows-based operating
1544
  systems. — *end example*]
1545
 
@@ -1547,18 +1532,18 @@ systems. — *end example*]
1547
  bool is_relative() const;
1548
  ```
1549
 
1550
  *Returns:* `!is_absolute()`.
1551
 
1552
- ##### `path` generation <a id="fs.path.gen">[[fs.path.gen]]</a>
1553
 
1554
  ``` cpp
1555
  path lexically_normal() const;
1556
  ```
1557
 
1558
  *Returns:* A path whose pathname in the generic format is the normal
1559
- form ([[fs.def.normal.form]]) of the pathname in the generic format of
1560
  `*this`.
1561
 
1562
  [*Example 10*:
1563
 
1564
  ``` cpp
@@ -1575,29 +1560,40 @@ slashes, but that does not affect `path` equality.
1575
  ``` cpp
1576
  path lexically_relative(const path& base) const;
1577
  ```
1578
 
1579
  *Returns:* `*this` made relative to `base`. Does not
1580
- resolve ([[fs.def.pathres]]) symlinks. Does not first
1581
- normalize ([[fs.def.normal.form]]) `*this` or `base`.
1582
-
1583
- *Effects:* If `root_name() != base.root_name()` is `true` or
1584
- `is_absolute() != base.is_absolute()` is `true` or
1585
- `!has_root_directory() && base.has_root_directory()` is `true`, returns
1586
- `path()`. Determines the first mismatched element of `*this` and `base`
1587
- as if by:
 
 
 
 
 
 
 
 
 
1588
 
1589
  ``` cpp
1590
  auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
1591
  ```
1592
 
1593
  Then,
1594
 
1595
  - if `a == end()` and `b == base.end()`, returns `path(".")`; otherwise
1596
  - let `n` be the number of *filename* elements in \[`b`, `base.end()`)
1597
- that are not *dot* or *dot-dot* minus the number that are *dot-dot*.
1598
- If `n<0,` returns `path()`; otherwise
 
 
1599
  - returns an object of class `path` that is default-constructed,
1600
  followed by
1601
  - application of `operator/=(path(".."))` `n` times, and then
1602
  - application of `operator/=` for each element in \[`a`, `end()`).
1603
 
@@ -1616,41 +1612,41 @@ The above assertions will succeed. On Windows, the returned path’s
1616
  *directory-separator* characters will be backslashes rather than
1617
  slashes, but that does not affect `path` equality.
1618
 
1619
  — *end example*]
1620
 
1621
- [*Note 6*: If symlink following semantics are desired, use the
1622
  operational function `relative()`. — *end note*]
1623
 
1624
- [*Note 7*: If normalization ([[fs.def.normal.form]]) is needed to
1625
- ensure consistent matching of elements, apply `lexically_normal()` to
1626
- `*this`, `base`, or both. — *end note*]
1627
 
1628
  ``` cpp
1629
  path lexically_proximate(const path& base) const;
1630
  ```
1631
 
1632
  *Returns:* If the value of `lexically_relative(base)` is not an empty
1633
  path, return it. Otherwise return `*this`.
1634
 
1635
- [*Note 8*: If symlink following semantics are desired, use the
1636
  operational function `proximate()`. — *end note*]
1637
 
1638
- [*Note 9*: If normalization ([[fs.def.normal.form]]) is needed to
1639
- ensure consistent matching of elements, apply `lexically_normal()` to
1640
- `*this`, `base`, or both. — *end note*]
1641
 
1642
- #### `path` iterators <a id="fs.path.itr">[[fs.path.itr]]</a>
1643
 
1644
  Path iterators iterate over the elements of the pathname in the generic
1645
- format ([[fs.path.generic]]).
1646
 
1647
- A `path::iterator` is a constant iterator satisfying all the
1648
- requirements of a bidirectional iterator ([[bidirectional.iterators]])
1649
- except that, for dereferenceable iterators `a` and `b` of type
1650
- `path::iterator` with `a == b`, there is no requirement that `*a` and
1651
- `*b` are bound to the same object. Its `value_type` is `path`.
1652
 
1653
  Calling any non-const member function of a `path` object invalidates all
1654
  iterators referring to elements of that object.
1655
 
1656
  For the elements of the pathname in the generic format, the forward
@@ -1677,171 +1673,94 @@ list above. If no elements are present, the end iterator.
1677
  iterator end() const;
1678
  ```
1679
 
1680
  *Returns:* The end iterator.
1681
 
1682
- #### `path` non-member functions <a id="fs.path.nonmember">[[fs.path.nonmember]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1683
 
1684
  ``` cpp
1685
  void swap(path& lhs, path& rhs) noexcept;
1686
  ```
1687
 
1688
- *Effects:* Equivalent to: `lhs.swap(rhs);`
1689
 
1690
  ``` cpp
1691
  size_t hash_value (const path& p) noexcept;
1692
  ```
1693
 
1694
  *Returns:* A hash value for the path `p`. If for two paths, `p1 == p2`
1695
  then `hash_value(p1) == hash_value(p2)`.
1696
 
1697
  ``` cpp
1698
- bool operator< (const path& lhs, const path& rhs) noexcept;
1699
  ```
1700
 
1701
- *Returns:* `lhs.compare(rhs) < 0`.
1702
-
1703
- ``` cpp
1704
- bool operator<=(const path& lhs, const path& rhs) noexcept;
1705
- ```
1706
-
1707
- *Returns:* `!(rhs < lhs)`.
1708
-
1709
- ``` cpp
1710
- bool operator> (const path& lhs, const path& rhs) noexcept;
1711
- ```
1712
-
1713
- *Returns:* `rhs < lhs`.
1714
-
1715
- ``` cpp
1716
- bool operator>=(const path& lhs, const path& rhs) noexcept;
1717
- ```
1718
-
1719
- *Returns:* `!(lhs < rhs)`.
1720
-
1721
- ``` cpp
1722
- bool operator==(const path& lhs, const path& rhs) noexcept;
1723
- ```
1724
-
1725
- *Returns:* `!(lhs < rhs) && !(rhs < lhs)`.
1726
 
1727
  [*Note 1*:
1728
 
1729
  Path equality and path equivalence have different semantics.
1730
 
1731
  - Equality is determined by the `path` non-member `operator==`, which
1732
- considers the two paths lexical representations only.
1733
  \[*Example 1*: `path("foo") == "bar"` is never
1734
  `true`. — *end example*]
1735
  - Equivalence is determined by the `equivalent()` non-member function,
1736
- which determines if two paths resolve ([[fs.def.pathres]]) to the
1737
- same file system entity. \[*Example 2*: `equivalent("foo", "bar")`
1738
- will be `true` when both paths resolve to the same
1739
- file. — *end example*]
1740
 
1741
  Programmers wishing to determine if two paths are “the same” must decide
1742
  if “the same” means “the same representation” or “resolve to the same
1743
  actual file”, and choose the appropriate function accordingly.
1744
 
1745
  — *end note*]
1746
 
1747
  ``` cpp
1748
- bool operator!=(const path& lhs, const path& rhs) noexcept;
1749
  ```
1750
 
1751
- *Returns:* `!(lhs == rhs)`.
1752
 
1753
  ``` cpp
1754
- path operator/ (const path& lhs, const path& rhs);
1755
  ```
1756
 
1757
  *Effects:* Equivalent to: `return path(lhs) /= rhs;`
1758
 
1759
- ##### `path` inserter and extractor <a id="fs.path.io">[[fs.path.io]]</a>
1760
-
1761
- ``` cpp
1762
- template <class charT, class traits>
1763
- basic_ostream<charT, traits>&
1764
- operator<<(basic_ostream<charT, traits>& os, const path& p);
1765
- ```
1766
-
1767
- *Effects:* Equivalent to: `os << quoted(p.string<charT, traits>());`
1768
-
1769
- [*Note 2*: The `quoted` function is described
1770
- in  [[quoted.manip]]. — *end note*]
1771
-
1772
- *Returns:* `os`.
1773
-
1774
- ``` cpp
1775
- template <class charT, class traits>
1776
- basic_istream<charT, traits>&
1777
- operator>>(basic_istream<charT, traits>& is, path& p);
1778
- ```
1779
-
1780
- *Effects:* Equivalent to:
1781
-
1782
- ``` cpp
1783
- basic_string<charT, traits> tmp;
1784
- is >> quoted(tmp);
1785
- p = tmp;
1786
- ```
1787
-
1788
- *Returns:* `is`.
1789
-
1790
- ##### `path` factory functions <a id="fs.path.factory">[[fs.path.factory]]</a>
1791
-
1792
- ``` cpp
1793
- template <class Source>
1794
- path u8path(const Source& source);
1795
- template <class InputIterator>
1796
- path u8path(InputIterator first, InputIterator last);
1797
- ```
1798
-
1799
- *Requires:* The `source` and \[`first`, `last`) sequences are UTF-8
1800
- encoded. The value type of `Source` and `InputIterator` is `char`.
1801
-
1802
- *Returns:*
1803
-
1804
- - If `value_type` is `char` and the current native narrow
1805
- encoding ([[fs.def.native.encode]]) is UTF-8, return `path(source)`
1806
- or `path(first, last)`; otherwise,
1807
- - if `value_type` is `wchar_t` and the native wide encoding is UTF-16,
1808
- or if `value_type` is `char16_t` or `char32_t`, convert `source` or
1809
- \[`first`, `last`) to a temporary, `tmp`, of type `string_type` and
1810
- return `path(tmp)`; otherwise,
1811
- - convert `source` or \[`first`, `last`) to a temporary, `tmp`, of type
1812
- `u32string` and return `path(tmp)`.
1813
-
1814
- *Remarks:* Argument format conversion ([[fs.path.fmt.cvt]]) applies to
1815
- the arguments for these functions. How Unicode encoding conversions are
1816
- performed is unspecified.
1817
-
1818
- [*Example 1*:
1819
-
1820
- A string is to be read from a database that is encoded in UTF-8, and
1821
- used to create a directory using the native encoding for filenames:
1822
-
1823
- ``` cpp
1824
- namespace fs = std::filesystem;
1825
- std::string utf8_string = read_utf8_data();
1826
- fs::create_directory(fs::u8path(utf8_string));
1827
- ```
1828
-
1829
- For POSIX-based operating systems with the native narrow encoding set to
1830
- UTF-8, no encoding or type conversion occurs.
1831
-
1832
- For POSIX-based operating systems with the native narrow encoding not
1833
- set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to
1834
- the current native narrow encoding. Some Unicode characters may have no
1835
- native character set representation.
1836
-
1837
- For Windows-based operating systems a conversion from UTF-8 to UTF-16
1838
- occurs.
1839
-
1840
- — *end example*]
1841
-
1842
- ### Class `filesystem_error` <a id="fs.class.filesystem_error">[[fs.class.filesystem_error]]</a>
1843
 
1844
  ``` cpp
1845
  namespace std::filesystem {
1846
  class filesystem_error : public system_error {
1847
  public:
@@ -1857,65 +1776,50 @@ namespace std::filesystem {
1857
  };
1858
  }
1859
  ```
1860
 
1861
  The class `filesystem_error` defines the type of objects thrown as
1862
- exceptions to report file system errors from functions described in this
1863
- subclause.
1864
 
1865
- #### `filesystem_error` members <a id="filesystem_error.members">[[filesystem_error.members]]</a>
1866
 
1867
  Constructors are provided that store zero, one, or two paths associated
1868
  with an error.
1869
 
1870
  ``` cpp
1871
  filesystem_error(const string& what_arg, error_code ec);
1872
  ```
1873
 
1874
- *Postconditions:* The postconditions of this function are indicated in
1875
- Table  [[tab:filesystem_error.1]].
1876
 
1877
- **Table: `filesystem_error(const string&, error_code)` effects** <a id="tab:filesystem_error.1">[tab:filesystem_error.1]</a>
1878
-
1879
- | Expression | Value |
1880
- | ----------------------- | ------------------ |
1881
- | `runtime_error::what()` | `what_arg.c_str()` |
1882
- | `code()` | `ec` |
1883
- | `path1().empty()` | `true` |
1884
- | `path2().empty()` | `true` |
1885
 
1886
  ``` cpp
1887
  filesystem_error(const string& what_arg, const path& p1, error_code ec);
1888
  ```
1889
 
1890
- *Postconditions:* The postconditions of this function are indicated in
1891
- Table  [[tab:filesystem_error.2]].
1892
 
1893
- **Table: `filesystem_error(const string&, const path&, error_code)` effects** <a id="tab:filesystem_error.2">[tab:filesystem_error.2]</a>
1894
-
1895
- | Expression | Value |
1896
- | ----------------------- | -------------------------------- |
1897
- | `runtime_error::what()` | `what_arg.c_str()` |
1898
- | `code()` | `ec` |
1899
- | `path1()` | Reference to stored copy of `p1` |
1900
- | `path2().empty()` | `true` |
1901
 
1902
  ``` cpp
1903
  filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec);
1904
  ```
1905
 
1906
- *Postconditions:* The postconditions of this function are indicated in
1907
- Table  [[tab:filesystem_error.3]].
1908
 
1909
- **Table: `filesystem_error(const string&, const path&, const path&, error_code)` effects** <a id="tab:filesystem_error.3">[tab:filesystem_error.3]</a>
1910
-
1911
- | Expression | Value |
1912
- | ----------------------- | -------------------------------- |
1913
- | `runtime_error::what()` | `what_arg.c_str()` |
1914
- | `code()` | `ec` |
1915
- | `path1()` | Reference to stored copy of `p1` |
1916
- | `path2()` | Reference to stored copy of `p2` |
1917
 
1918
  ``` cpp
1919
  const path& path1() const noexcept;
1920
  ```
1921
 
@@ -1931,45 +1835,46 @@ or, if none, an empty path.
1931
 
1932
  ``` cpp
1933
  const char* what() const noexcept override;
1934
  ```
1935
 
1936
- *Returns:* A string containing `runtime_error::what()`. The exact format
1937
- is unspecified. Implementations are encouraged but not required to
1938
- include `path1.native_string()` if not empty, `path2.native_string()` if
1939
- not empty, and `system_error::what()` strings in the returned string.
1940
 
1941
  ### Enumerations <a id="fs.enum">[[fs.enum]]</a>
1942
 
1943
  #### Enum `path::format` <a id="fs.enum.path.format">[[fs.enum.path.format]]</a>
1944
 
1945
  This enum specifies constants used to identify the format of the
1946
- character sequence, with the meanings listed in Table 
1947
- [[tab:enum.path.format]].
1948
 
1949
  [*Note 1*: For POSIX-based systems, native and generic formats are
1950
  equivalent and the character sequence should always be interpreted in
1951
  the same way. — *end note*]
1952
 
1953
- #### Enum class `file_type` <a id="fs.enum.file_type">[[fs.enum.file_type]]</a>
1954
 
1955
  This enum class specifies constants used to identify file types, with
1956
- the meanings listed in Table  [[tab:fs.enum.file_type]].
 
1957
 
1958
  [*Note 1*: The file not being found is not considered an error while
1959
  determining the type of a file. — *end note*]
1960
 
1961
  #### Enum class `copy_options` <a id="fs.enum.copy.opts">[[fs.enum.copy.opts]]</a>
1962
 
1963
- The `enum class` type `copy_options` is a bitmask type (
1964
- [[bitmask.types]]) that specifies bitmask constants used to control the
1965
- semantics of copy operations. The constants are specified in option
1966
- groups with the meanings listed in Table  [[tab:fs.enum.copy_options]].
1967
- Constant `none` is shown in each option group for purposes of
1968
  exposition; implementations shall provide only a single definition.
 
1969
 
1970
- **Table: Enum class `copy_options`** <a id="tab:fs.enum.copy_options">[tab:fs.enum.copy_options]</a>
1971
 
1972
  | Constant | Meaning |
1973
  | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
1974
  | `none` | (Default) Error; file already exists. |
1975
  | `skip_existing` | Do not overwrite existing file, do not report an error. |
@@ -1983,15 +1888,15 @@ exposition; implementations shall provide only a single definition.
1983
  | `create_hard_links` | Make hard links instead of copies of files. |
1984
 
1985
 
1986
  #### Enum class `perms` <a id="fs.enum.perms">[[fs.enum.perms]]</a>
1987
 
1988
- The `enum class` type `perms` is a bitmask type ([[bitmask.types]])
1989
- that specifies bitmask constants used to identify file permissions, with
1990
- the meanings listed in Table  [[tab:fs.enum.perms]].
1991
 
1992
- **Table: Enum class `perms`** <a id="tab:fs.enum.perms">[tab:fs.enum.perms]</a>
1993
 
1994
  | Name | Value (octal) | POSIX macro | Definition or notes |
1995
  | -------------- | ------------- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
1996
  | `none` | `0` | | There are no permissions set for the file. |
1997
  | `owner_read` | `0400` | `S_IRUSR` | Read permission, owner |
@@ -2014,81 +1919,85 @@ the meanings listed in Table  [[tab:fs.enum.perms]].
2014
  | `unknown` | `0xFFFF` | | The permissions are not known, such as when a `file_status` object is created without specifying the permissions |
2015
 
2016
 
2017
  #### Enum class `perm_options` <a id="fs.enum.perm.opts">[[fs.enum.perm.opts]]</a>
2018
 
2019
- The `enum class` type `perm_options` is a bitmask type (
2020
- [[bitmask.types]]) that specifies bitmask constants used to control the
2021
- semantics of permissions operations, with the meanings listed in Table 
2022
- [[tab:enum.perm_options]]. The bitmask constants are bitmask elements.
2023
- In Table  [[tab:enum.perm_options]] `perm` denotes a value of type
2024
- `perms` passed to `permissions`.
2025
 
2026
- **Table: Enum class `perm_options`** <a id="tab:enum.perm_options">[tab:enum.perm_options]</a>
2027
 
2028
  | Name | Meaning |
2029
- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
2030
  | `replace` | `permissions` shall replace the file's permission bits with `perm` |
2031
- | `add` | `permissions` shall replace the file's permission bits with the bitwise OR of `perm` and the file's current permission bits. |
2032
- | `remove` | `permissions` shall replace the file's permission bits with the bitwise AND of the complement of `perm` and the file's current permission bits. |
2033
  | `nofollow` | `permissions` shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. |
2034
 
2035
 
2036
  #### Enum class `directory_options` <a id="fs.enum.dir.opts">[[fs.enum.dir.opts]]</a>
2037
 
2038
- The `enum class` type `directory_options` is a bitmask type (
2039
- [[bitmask.types]]) that specifies bitmask constants used to identify
2040
- directory traversal options, with the meanings listed in Table 
2041
- [[tab:fs.enum.directory_options]].
 
2042
 
2043
- **Table: Enum class `directory_options`** <a id="tab:fs.enum.directory_options">[tab:fs.enum.directory_options]</a>
2044
 
2045
  | Name | Meaning |
2046
  | -------------------------- | ------------------------------------------------------------------ |
2047
  | `none` | (Default) Skip directory symlinks, permission denied is an error. |
2048
  | `follow_directory_symlink` | Follow rather than skip directory symlinks. |
2049
  | `skip_permission_denied` | Skip directories that would otherwise result in permission denied. |
2050
 
2051
 
2052
- ### Class `file_status` <a id="fs.class.file_status">[[fs.class.file_status]]</a>
2053
 
2054
  ``` cpp
2055
  namespace std::filesystem {
2056
  class file_status {
2057
  public:
2058
- // [fs.file_status.cons], constructors and destructor
2059
  file_status() noexcept : file_status(file_type::none) {}
2060
  explicit file_status(file_type ft,
2061
  perms prms = perms::unknown) noexcept;
2062
  file_status(const file_status&) noexcept = default;
2063
  file_status(file_status&&) noexcept = default;
2064
  ~file_status();
2065
 
2066
- // assignments:
2067
  file_status& operator=(const file_status&) noexcept = default;
2068
  file_status& operator=(file_status&&) noexcept = default;
2069
 
2070
- // [fs.file_status.mods], modifiers
2071
  void type(file_type ft) noexcept;
2072
  void permissions(perms prms) noexcept;
2073
 
2074
- // [fs.file_status.obs], observers
2075
  file_type type() const noexcept;
2076
  perms permissions() const noexcept;
 
 
 
2077
  };
2078
  }
2079
  ```
2080
 
2081
- #### `file_status` constructors <a id="fs.file_status.cons">[[fs.file_status.cons]]</a>
2082
 
2083
  ``` cpp
2084
  explicit file_status(file_type ft, perms prms = perms::unknown) noexcept;
2085
  ```
2086
 
2087
- *Postconditions:* `type() == ft` and `permissions() == prms`.
2088
 
2089
- #### `file_status` observers <a id="fs.file_status.obs">[[fs.file_status.obs]]</a>
2090
 
2091
  ``` cpp
2092
  file_type type() const noexcept;
2093
  ```
2094
 
@@ -2102,53 +2011,53 @@ perms permissions() const noexcept;
2102
 
2103
  *Returns:* The value of `permissions()` specified by the postconditions
2104
  of the most recent call to a constructor, `operator=`, or
2105
  `permissions(perms)` function.
2106
 
2107
- #### `file_status` modifiers <a id="fs.file_status.mods">[[fs.file_status.mods]]</a>
2108
 
2109
  ``` cpp
2110
  void type(file_type ft) noexcept;
2111
  ```
2112
 
2113
- *Postconditions:* `type() == ft`.
2114
 
2115
  ``` cpp
2116
  void permissions(perms prms) noexcept;
2117
  ```
2118
 
2119
- *Postconditions:* `permissions() == prms`.
2120
 
2121
- ### Class `directory_entry` <a id="fs.class.directory_entry">[[fs.class.directory_entry]]</a>
2122
 
2123
  ``` cpp
2124
  namespace std::filesystem {
2125
  class directory_entry {
2126
  public:
2127
  // [fs.dir.entry.cons], constructors and destructor
2128
  directory_entry() noexcept = default;
2129
  directory_entry(const directory_entry&) = default;
2130
  directory_entry(directory_entry&&) noexcept = default;
2131
- explicit directory_entry(const path& p);
2132
- directory_entry(const path& p, error_code& ec);
2133
  ~directory_entry();
2134
 
2135
- // assignments:
2136
  directory_entry& operator=(const directory_entry&) = default;
2137
  directory_entry& operator=(directory_entry&&) noexcept = default;
2138
 
2139
  // [fs.dir.entry.mods], modifiers
2140
- void assign(const path& p);
2141
- void assign(const path& p, error_code& ec);
2142
- void replace_filename(const path& p);
2143
- void replace_filename(const path& p, error_code& ec);
2144
  void refresh();
2145
  void refresh(error_code& ec) noexcept;
2146
 
2147
  // [fs.dir.entry.obs], observers
2148
- const path& path() const noexcept;
2149
- operator const path&() const noexcept;
2150
  bool exists() const;
2151
  bool exists(error_code& ec) const noexcept;
2152
  bool is_block_file() const;
2153
  bool is_block_file(error_code& ec) const noexcept;
2154
  bool is_character_file() const;
@@ -2174,36 +2083,32 @@ namespace std::filesystem {
2174
  file_status status() const;
2175
  file_status status(error_code& ec) const noexcept;
2176
  file_status symlink_status() const;
2177
  file_status symlink_status(error_code& ec) const noexcept;
2178
 
2179
- bool operator< (const directory_entry& rhs) const noexcept;
2180
  bool operator==(const directory_entry& rhs) const noexcept;
2181
- bool operator!=(const directory_entry& rhs) const noexcept;
2182
- bool operator<=(const directory_entry& rhs) const noexcept;
2183
- bool operator> (const directory_entry& rhs) const noexcept;
2184
- bool operator>=(const directory_entry& rhs) const noexcept;
2185
 
2186
  private:
2187
- path pathobject; // exposition only
2188
  friend class directory_iterator; // exposition only
2189
  };
2190
  }
2191
  ```
2192
 
2193
  A `directory_entry` object stores a `path` object and may store
2194
  additional objects for file attributes such as hard link count, status,
2195
  symlink status, file size, and last write time.
2196
 
2197
- Implementations are encouraged to store such additional file attributes
2198
- during directory iteration if their values are available and storing the
2199
- values would allow the implementation to eliminate file system accesses
2200
- by `directory_entry` observer functions ([[fs.op.funcs]]). Such stored
2201
- file attribute values are said to be *cached*.
2202
 
2203
- [*Note 1*: For purposes of exposition, class `directory_iterator` (
2204
- [[fs.class.directory_iterator]]) is shown above as a friend of class
2205
  `directory_entry`. Friendship allows the `directory_iterator`
2206
  implementation to cache already available attribute values directly into
2207
  a `directory_entry` object without the cost of an unneeded call to
2208
  `refresh()`. — *end note*]
2209
 
@@ -2235,41 +2140,40 @@ so will not result in a potentially expensive call to the
2235
  `std::filesystem::last_write_time` function. The code is portable to any
2236
  implementation, regardless of whether or not it employs caching.
2237
 
2238
  — *end example*]
2239
 
2240
- #### `directory_entry` constructors <a id="fs.dir.entry.cons">[[fs.dir.entry.cons]]</a>
2241
 
2242
  ``` cpp
2243
- explicit directory_entry(const path& p);
2244
- directory_entry(const path& p, error_code& ec);
2245
  ```
2246
 
2247
- *Effects:* Constructs an object of type `directory_entry`, then
2248
- `refresh()` or `refresh(ec)`, respectively.
2249
 
2250
- *Postconditions:* `path() == p` if no error occurs, otherwise
2251
- `path() == std::filesystem::path()`.
2252
 
2253
  *Throws:* As specified in  [[fs.err.report]].
2254
 
2255
- #### `directory_entry` modifiers <a id="fs.dir.entry.mods">[[fs.dir.entry.mods]]</a>
2256
 
2257
  ``` cpp
2258
- void assign(const path& p);
2259
- void assign(const path& p, error_code& ec);
2260
  ```
2261
 
2262
  *Effects:* Equivalent to `pathobject = p`, then `refresh()` or
2263
  `refresh(ec)`, respectively. If an error occurs, the values of any
2264
  cached attributes are unspecified.
2265
 
2266
  *Throws:* As specified in  [[fs.err.report]].
2267
 
2268
  ``` cpp
2269
- void replace_filename(const path& p);
2270
- void replace_filename(const path& p, error_code& ec);
2271
  ```
2272
 
2273
  *Effects:* Equivalent to `pathobject.replace_filename(p)`, then
2274
  `refresh()` or `refresh(ec)`, respectively. If an error occurs, the
2275
  values of any cached attributes are unspecified.
@@ -2281,121 +2185,121 @@ void refresh();
2281
  void refresh(error_code& ec) noexcept;
2282
  ```
2283
 
2284
  *Effects:* Stores the current values of any cached attributes of the
2285
  file `p` resolves to. If an error occurs, an error is
2286
- reported ([[fs.err.report]]) and the values of any cached attributes
2287
- are unspecified.
2288
 
2289
  *Throws:* As specified in  [[fs.err.report]].
2290
 
2291
- [*Note 1*: Implementations of
2292
- `directory_iterator` ([[fs.class.directory_iterator]]) are prohibited
2293
- from directly or indirectly calling the `refresh` function since it must
2294
- access the external file system, and the objective of caching is to
2295
- avoid unnecessary file system accesses. — *end note*]
2296
 
2297
- #### `directory_entry` observers <a id="fs.dir.entry.obs">[[fs.dir.entry.obs]]</a>
2298
 
2299
  Unqualified function names in the *Returns:* elements of the
2300
  `directory_entry` observers described below refer to members of the
2301
  `std::filesystem` namespace.
2302
 
2303
  ``` cpp
2304
- const path& path() const noexcept;
2305
- operator const path&() const noexcept;
2306
  ```
2307
 
2308
  *Returns:* `pathobject`.
2309
 
2310
  ``` cpp
2311
  bool exists() const;
2312
  bool exists(error_code& ec) const noexcept;
2313
  ```
2314
 
2315
- *Returns:* `exists(this->status())` or `exists(this->status(), ec)`,
2316
  respectively.
2317
 
2318
  *Throws:* As specified in  [[fs.err.report]].
2319
 
2320
  ``` cpp
2321
  bool is_block_file() const;
2322
  bool is_block_file(error_code& ec) const noexcept;
2323
  ```
2324
 
2325
  *Returns:* `is_block_file(this->status())` or
2326
- `is_block_file(this->status(), ec)`, respectively.
2327
 
2328
  *Throws:* As specified in  [[fs.err.report]].
2329
 
2330
  ``` cpp
2331
  bool is_character_file() const;
2332
  bool is_character_file(error_code& ec) const noexcept;
2333
  ```
2334
 
2335
  *Returns:* `is_character_file(this->status())` or
2336
- `is_character_file(this->status(), ec)`, respectively.
2337
 
2338
  *Throws:* As specified in  [[fs.err.report]].
2339
 
2340
  ``` cpp
2341
  bool is_directory() const;
2342
  bool is_directory(error_code& ec) const noexcept;
2343
  ```
2344
 
2345
  *Returns:* `is_directory(this->status())` or
2346
- `is_directory(this->status(), ec)`, respectively.
2347
 
2348
  *Throws:* As specified in  [[fs.err.report]].
2349
 
2350
  ``` cpp
2351
  bool is_fifo() const;
2352
  bool is_fifo(error_code& ec) const noexcept;
2353
  ```
2354
 
2355
- *Returns:* `is_fifo(this->status())` or `is_fifo(this->status(), ec)`,
2356
  respectively.
2357
 
2358
  *Throws:* As specified in  [[fs.err.report]].
2359
 
2360
  ``` cpp
2361
  bool is_other() const;
2362
  bool is_other(error_code& ec) const noexcept;
2363
  ```
2364
 
2365
- *Returns:* `is_other(this->status())` or `is_other(this->status(), ec)`,
2366
  respectively.
2367
 
2368
  *Throws:* As specified in  [[fs.err.report]].
2369
 
2370
  ``` cpp
2371
  bool is_regular_file() const;
2372
  bool is_regular_file(error_code& ec) const noexcept;
2373
  ```
2374
 
2375
  *Returns:* `is_regular_file(this->status())` or
2376
- `is_regular_file(this->status(), ec)`, respectively.
2377
 
2378
  *Throws:* As specified in  [[fs.err.report]].
2379
 
2380
  ``` cpp
2381
  bool is_socket() const;
2382
  bool is_socket(error_code& ec) const noexcept;
2383
  ```
2384
 
2385
- *Returns:* `is_socket(this->status())` or
2386
- `is_socket(this->status(), ec)`, respectively.
2387
 
2388
  *Throws:* As specified in  [[fs.err.report]].
2389
 
2390
  ``` cpp
2391
  bool is_symlink() const;
2392
  bool is_symlink(error_code& ec) const noexcept;
2393
  ```
2394
 
2395
  *Returns:* `is_symlink(this->symlink_status())` or
2396
- `is_symlink(this->symlink_status(), ec)`, respectively.
2397
 
2398
  *Throws:* As specified in  [[fs.err.report]].
2399
 
2400
  ``` cpp
2401
  uintmax_t file_size() const;
@@ -2454,49 +2358,24 @@ bool operator==(const directory_entry& rhs) const noexcept;
2454
  ```
2455
 
2456
  *Returns:* `pathobject == rhs.pathobject`.
2457
 
2458
  ``` cpp
2459
- bool operator!=(const directory_entry& rhs) const noexcept;
2460
  ```
2461
 
2462
- *Returns:* `pathobject != rhs.pathobject`.
2463
 
2464
- ``` cpp
2465
- bool operator< (const directory_entry& rhs) const noexcept;
2466
- ```
2467
-
2468
- *Returns:* `pathobject < rhs.pathobject`.
2469
-
2470
- ``` cpp
2471
- bool operator<=(const directory_entry& rhs) const noexcept;
2472
- ```
2473
-
2474
- *Returns:* `pathobject <= rhs.pathobject`.
2475
-
2476
- ``` cpp
2477
- bool operator> (const directory_entry& rhs) const noexcept;
2478
- ```
2479
-
2480
- *Returns:* `pathobject > rhs.pathobject`.
2481
-
2482
- ``` cpp
2483
- bool operator>=(const directory_entry& rhs) const noexcept;
2484
- ```
2485
-
2486
- *Returns:* `pathobject >= rhs.pathobject`.
2487
-
2488
- ### Class `directory_iterator` <a id="fs.class.directory_iterator">[[fs.class.directory_iterator]]</a>
2489
 
2490
  An object of type `directory_iterator` provides an iterator for a
2491
  sequence of `directory_entry` elements representing the path and any
2492
- cached attribute values ([[fs.class.directory_entry]]) for each file in
2493
- a directory or in an *implementation-defined* directory-like file type.
2494
 
2495
  [*Note 1*: For iteration into sub-directories, see class
2496
- `recursive_directory_iterator` (
2497
- [[fs.class.rec.dir.itr]]). — *end note*]
2498
 
2499
  ``` cpp
2500
  namespace std::filesystem {
2501
  class directory_iterator {
2502
  public:
@@ -2508,32 +2387,32 @@ namespace std::filesystem {
2508
 
2509
  // [fs.dir.itr.members], member functions
2510
  directory_iterator() noexcept;
2511
  explicit directory_iterator(const path& p);
2512
  directory_iterator(const path& p, directory_options options);
2513
- directory_iterator(const path& p, error_code& ec) noexcept;
2514
  directory_iterator(const path& p, directory_options options,
2515
- error_code& ec) noexcept;
2516
  directory_iterator(const directory_iterator& rhs);
2517
  directory_iterator(directory_iterator&& rhs) noexcept;
2518
  ~directory_iterator();
2519
 
2520
  directory_iterator& operator=(const directory_iterator& rhs);
2521
  directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2522
 
2523
  const directory_entry& operator*() const;
2524
  const directory_entry* operator->() const;
2525
  directory_iterator& operator++();
2526
- directory_iterator& increment(error_code& ec) noexcept;
2527
 
2528
  // other members as required by [input.iterators], input iterators
2529
  };
2530
  }
2531
  ```
2532
 
2533
- `directory_iterator` satisfies the requirements of an input iterator (
2534
- [[input.iterators]]).
2535
 
2536
  If an iterator of type `directory_iterator` reports an error or is
2537
  advanced past the last directory element, that iterator shall become
2538
  equal to the end iterator value. The `directory_iterator` default
2539
  constructor shall create an iterator equal to the end iterator value,
@@ -2549,24 +2428,24 @@ object obtained by dereferencing a `directory_iterator` is a reference
2549
  to a `path` object composed of the directory argument from which the
2550
  iterator was constructed with filename of the directory entry appended
2551
  as if by `operator/=`.
2552
 
2553
  Directory iteration shall not yield directory entries for the current
2554
- (*dot*) and parent (*dot-dot*) directories.
2555
 
2556
  The order of directory entries obtained by dereferencing successive
2557
  increments of a `directory_iterator` is unspecified.
2558
 
2559
  Constructors and non-const `directory_iterator` member functions store
2560
- the values of any cached attributes ([[fs.class.directory_entry]]) in
2561
- the `directory_entry` element returned by `operator*()`.
2562
  `directory_iterator` member functions shall not directly or indirectly
2563
  call any `directory_entry` `refresh` function.
2564
 
2565
  [*Note 2*: The exact mechanism for storing cached attribute values is
2566
  not exposed to users. For exposition, class `directory_iterator` is
2567
- shown in [[fs.class.directory_entry]] as a friend of class
2568
  `directory_entry`. — *end note*]
2569
 
2570
  [*Note 3*: Programs performing directory iteration may wish to test if
2571
  the path obtained by dereferencing a directory iterator actually exists.
2572
  It could be a symbolic link to a non-existent file. Programs recursively
@@ -2577,23 +2456,23 @@ may wish to avoid following symbolic links. — *end note*]
2577
  construction of a `directory_iterator` for the directory, it is
2578
  unspecified whether or not subsequently incrementing the iterator will
2579
  ever result in an iterator referencing the removed or added directory
2580
  entry. See POSIX `readdir_r`. — *end note*]
2581
 
2582
- #### `directory_iterator` members <a id="fs.dir.itr.members">[[fs.dir.itr.members]]</a>
2583
 
2584
  ``` cpp
2585
  directory_iterator() noexcept;
2586
  ```
2587
 
2588
  *Effects:* Constructs the end iterator.
2589
 
2590
  ``` cpp
2591
  explicit directory_iterator(const path& p);
2592
  directory_iterator(const path& p, directory_options options);
2593
- directory_iterator(const path& p, error_code& ec) noexcept;
2594
- directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
2595
  ```
2596
 
2597
  *Effects:* For the directory that `p` resolves to, constructs an
2598
  iterator for the first element in a sequence of `directory_entry`
2599
  elements representing the files in the directory, if any; otherwise the
@@ -2616,39 +2495,37 @@ error.
2616
  ``` cpp
2617
  directory_iterator(const directory_iterator& rhs);
2618
  directory_iterator(directory_iterator&& rhs) noexcept;
2619
  ```
2620
 
2621
- *Effects:* Constructs an object of class `directory_iterator`.
2622
-
2623
- *Postconditions:* `*this` has the original value of `rhs`.
2624
 
2625
  ``` cpp
2626
  directory_iterator& operator=(const directory_iterator& rhs);
2627
  directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2628
  ```
2629
 
2630
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2631
  effect.
2632
 
2633
- *Postconditions:* `*this` has the original value of `rhs`.
2634
 
2635
  *Returns:* `*this`.
2636
 
2637
  ``` cpp
2638
  directory_iterator& operator++();
2639
- directory_iterator& increment(error_code& ec) noexcept;
2640
  ```
2641
 
2642
  *Effects:* As specified for the prefix increment operation of Input
2643
- iterators ([[input.iterators]]).
2644
 
2645
  *Returns:* `*this`.
2646
 
2647
  *Throws:* As specified in  [[fs.err.report]].
2648
 
2649
- #### `directory_iterator` non-member functions <a id="fs.dir.itr.nonmembers">[[fs.dir.itr.nonmembers]]</a>
2650
 
2651
  These functions enable range access for `directory_iterator`.
2652
 
2653
  ``` cpp
2654
  directory_iterator begin(directory_iterator iter) noexcept;
@@ -2682,12 +2559,12 @@ namespace std::filesystem {
2682
  // [fs.rec.dir.itr.members], constructors and destructor
2683
  recursive_directory_iterator() noexcept;
2684
  explicit recursive_directory_iterator(const path& p);
2685
  recursive_directory_iterator(const path& p, directory_options options);
2686
  recursive_directory_iterator(const path& p, directory_options options,
2687
- error_code& ec) noexcept;
2688
- recursive_directory_iterator(const path& p, error_code& ec) noexcept;
2689
  recursive_directory_iterator(const recursive_directory_iterator& rhs);
2690
  recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2691
  ~recursive_directory_iterator();
2692
 
2693
  // [fs.rec.dir.itr.members], observers
@@ -2703,11 +2580,11 @@ namespace std::filesystem {
2703
  operator=(const recursive_directory_iterator& rhs);
2704
  recursive_directory_iterator&
2705
  operator=(recursive_directory_iterator&& rhs) noexcept;
2706
 
2707
  recursive_directory_iterator& operator++();
2708
- recursive_directory_iterator& increment(error_code& ec) noexcept;
2709
 
2710
  void pop();
2711
  void pop(error_code& ec);
2712
  void disable_recursion_pending();
2713
 
@@ -2724,38 +2601,38 @@ The behavior of a `recursive_directory_iterator` is the same as a
2724
  `directory_iterator` unless otherwise specified.
2725
 
2726
  [*Note 1*: If the directory structure being iterated over contains
2727
  cycles then the end iterator may be unreachable. — *end note*]
2728
 
2729
- #### `recursive_directory_iterator` members <a id="fs.rec.dir.itr.members">[[fs.rec.dir.itr.members]]</a>
2730
 
2731
  ``` cpp
2732
  recursive_directory_iterator() noexcept;
2733
  ```
2734
 
2735
  *Effects:* Constructs the end iterator.
2736
 
2737
  ``` cpp
2738
  explicit recursive_directory_iterator(const path& p);
2739
  recursive_directory_iterator(const path& p, directory_options options);
2740
- recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
2741
- recursive_directory_iterator(const path& p, error_code& ec) noexcept;
2742
  ```
2743
 
2744
- *Effects:* Constructs a iterator representing the first entry in the
2745
- directory `p` resolves to, if any; otherwise, the end iterator. However,
2746
- if
2747
 
2748
  ``` cpp
2749
  (options & directory_options::skip_permission_denied) != directory_options::none
2750
  ```
2751
 
2752
  and construction encounters an error indicating that permission to
2753
  access `p` is denied, constructs the end iterator and does not report an
2754
  error.
2755
 
2756
- *Postconditions:* `options() == options` for the signatures with a
2757
  `directory_options` argument, otherwise
2758
  `options() == directory_options::none`.
2759
 
2760
  *Throws:* As specified in  [[fs.err.report]].
2761
 
@@ -2763,42 +2640,38 @@ error.
2763
  `recursive_directory_iterator(".")` rather than
2764
  `recursive_directory_iterator("")`. — *end note*]
2765
 
2766
  [*Note 2*: By default, `recursive_directory_iterator` does not follow
2767
  directory symlinks. To follow directory symlinks, specify `options` as
2768
- `directory_options::follow_directory_symlink` — *end note*]
2769
 
2770
  ``` cpp
2771
  recursive_directory_iterator(const recursive_directory_iterator& rhs);
2772
  ```
2773
 
2774
- *Effects:* Constructs an object of class `recursive_directory_iterator`.
2775
-
2776
- *Postconditions:*
2777
 
2778
  - `options() == rhs.options()`
2779
  - `depth() == rhs.depth()`
2780
  - `recursion_pending() == rhs.recursion_pending()`
2781
 
2782
  ``` cpp
2783
  recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2784
  ```
2785
 
2786
- *Effects:* Constructs an object of class `recursive_directory_iterator`.
2787
-
2788
- *Postconditions:* `options()`, `depth()`, and `recursion_pending()` have
2789
- the values that `rhs.options()`, `rhs.depth()`, and
2790
  `rhs.recursion_pending()`, respectively, had before the function call.
2791
 
2792
  ``` cpp
2793
  recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);
2794
  ```
2795
 
2796
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2797
  effect.
2798
 
2799
- *Postconditions:*
2800
 
2801
  - `options() == rhs.options()`
2802
  - `depth() == rhs.depth()`
2803
  - `recursion_pending() == rhs.recursion_pending()`
2804
 
@@ -2809,12 +2682,12 @@ recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noex
2809
  ```
2810
 
2811
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2812
  effect.
2813
 
2814
- *Postconditions:* `options()`, `depth()`, and `recursion_pending()` have
2815
- the values that `rhs.options()`, `rhs.depth()`, and
2816
  `rhs.recursion_pending()`, respectively, had before the function call.
2817
 
2818
  *Returns:* `*this`.
2819
 
2820
  ``` cpp
@@ -2847,15 +2720,15 @@ subsequent to the prior construction or increment operation, otherwise
2847
 
2848
  *Throws:* Nothing.
2849
 
2850
  ``` cpp
2851
  recursive_directory_iterator& operator++();
2852
- recursive_directory_iterator& increment(error_code& ec) noexcept;
2853
  ```
2854
 
2855
  *Effects:* As specified for the prefix increment operation of Input
2856
- iterators ([[input.iterators]]), except that:
2857
 
2858
  - If there are no more entries at the current depth, then if
2859
  `depth() != 0` iteration over the parent directory resumes; otherwise
2860
  `*this = recursive_directory_iterator()`.
2861
  - Otherwise if
@@ -2889,20 +2762,23 @@ void pop(error_code& ec);
2889
  directory currently being iterated over, and continue iteration over the
2890
  parent directory.
2891
 
2892
  *Throws:* As specified in  [[fs.err.report]].
2893
 
 
 
 
2894
  ``` cpp
2895
  void disable_recursion_pending();
2896
  ```
2897
 
2898
- *Postconditions:* `recursion_pending() == false`.
2899
 
2900
  [*Note 4*: `disable_recursion_pending``()` is used to prevent unwanted
2901
  recursion into a directory. — *end note*]
2902
 
2903
- #### `recursive_directory_iterator` non-member functions <a id="fs.rec.dir.itr.nonmembers">[[fs.rec.dir.itr.nonmembers]]</a>
2904
 
2905
  These functions enable use of `recursive_directory_iterator` with
2906
  range-based for statements.
2907
 
2908
  ``` cpp
@@ -2921,11 +2797,11 @@ recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
2921
 
2922
  Filesystem operation functions query or modify files, including
2923
  directories, in external storage.
2924
 
2925
  [*Note 1*: Because hardware failures, network failures, file system
2926
- races ([[fs.def.race]]), and many other kinds of errors occur
2927
  frequently in file system operations, users should be aware that any
2928
  filesystem operation function, no matter how apparently innocuous, may
2929
  encounter an error; see  [[fs.err.report]]. — *end note*]
2930
 
2931
  #### Absolute <a id="fs.op.absolute">[[fs.op.absolute]]</a>
@@ -2934,11 +2810,11 @@ encounter an error; see  [[fs.err.report]]. — *end note*]
2934
  path absolute(const path& p);
2935
  path absolute(const path& p, error_code& ec);
2936
  ```
2937
 
2938
  *Effects:* Composes an absolute path referencing the same file system
2939
- location as `p` according to the operating system ([[fs.conform.os]]).
2940
 
2941
  *Returns:* The composed path. The signature with argument `ec` returns
2942
  `path()` if an error occurs.
2943
 
2944
  [*Note 1*: For the returned path, `rp`, `rp.is_absolute()` is `true`
@@ -2946,11 +2822,11 @@ unless an error occurs. — *end note*]
2946
 
2947
  *Throws:* As specified in  [[fs.err.report]].
2948
 
2949
  [*Note 2*: To resolve symlinks, or perform other sanitization which
2950
  might require queries to secondary storage, such as hard disks, consider
2951
- `canonical` ([[fs.op.canonical]]). — *end note*]
2952
 
2953
  [*Note 3*: Implementations are strongly encouraged to not query
2954
  secondary storage, and not consider `!exists(p)` an
2955
  error. — *end note*]
2956
 
@@ -2960,22 +2836,19 @@ simply `current_path()/p`. For Windows-based operating systems,
2960
  `GetFullPathNameW`. — *end example*]
2961
 
2962
  #### Canonical <a id="fs.op.canonical">[[fs.op.canonical]]</a>
2963
 
2964
  ``` cpp
2965
- path canonical(const path& p, const path& base = current_path());
2966
  path canonical(const path& p, error_code& ec);
2967
- path canonical(const path& p, const path& base, error_code& ec);
2968
  ```
2969
 
2970
- *Effects:* Converts `p`, which must exist, to an absolute path that has
2971
- no symbolic link, *dot*, or *dot-dot* elements in its pathname in the
2972
- generic format.
2973
 
2974
  *Returns:* A path that refers to the same file system object as
2975
- `absolute(p, base)`. For the overload without a `base` argument, `base`
2976
- is `current_path()`. Signatures with argument `ec` return `path()` if an
2977
  error occurs.
2978
 
2979
  *Throws:* As specified in  [[fs.err.report]].
2980
 
2981
  *Remarks:* `!exists(p)` is an error.
@@ -2987,23 +2860,23 @@ void copy(const path& from, const path& to);
2987
  ```
2988
 
2989
  *Effects:* Equivalent to `copy(from, to, copy_options::none)`.
2990
 
2991
  ``` cpp
2992
- void copy(const path& from, const path& to, error_code& ec) noexcept;
2993
  ```
2994
 
2995
  *Effects:* Equivalent to `copy(from, to, copy_options::none, ec)`.
2996
 
2997
  ``` cpp
2998
  void copy(const path& from, const path& to, copy_options options);
2999
  void copy(const path& from, const path& to, copy_options options,
3000
- error_code& ec) noexcept;
3001
  ```
3002
 
3003
- *Requires:* At most one element from each option group
3004
- ([[fs.enum.copy.opts]]) is set in `options`.
3005
 
3006
  *Effects:* Before the first use of `f` and `t`:
3007
 
3008
  - If
3009
  ``` cpp
@@ -3024,17 +2897,17 @@ void copy(const path& from, const path& to, copy_options options,
3024
  `auto t = status(to)`.
3025
 
3026
  Effects are then as follows:
3027
 
3028
  - If `f.type()` or `t.type()` is an implementation-defined file
3029
- type ([[fs.enum.file_type]]), then the effects are
3030
  *implementation-defined*.
3031
  - Otherwise, an error is reported as specified in  [[fs.err.report]] if:
3032
- - `!exists(f)`, or
3033
- - `equivalent(from, to)`, or
3034
- - `is_other(f) || is_other(t)`, or
3035
- - `is_directory(f) && is_regular_file(t)`.
3036
  - Otherwise, if `is_symlink(f)`, then:
3037
  - If `(options & copy_options::skip_symlinks) != copy_options::none`
3038
  then return.
3039
  - Otherwise if
3040
  ``` cpp
@@ -3054,24 +2927,36 @@ Effects are then as follows:
3054
  `(options & copy_options::create_hard_links) != copy_options::none`,
3055
  then create a hard link to the source file.
3056
  - Otherwise, if `is_directory(t)`, then
3057
  `copy_file(from, to/from.filename(), options)`.
3058
  - Otherwise, `copy_file(from, to, options)`.
 
 
 
 
 
 
 
 
3059
  - Otherwise, if
3060
  ``` cpp
3061
  is_directory(f) &&
3062
  ((options & copy_options::recursive) != copy_options::none ||
3063
  options == copy_options::none)
3064
  ```
3065
 
3066
  then:
3067
- - If `!exists(t)`, then `create_directory(to, from)`.
3068
  - Then, iterate over the files in `from`, as if by
3069
  ``` cpp
3070
  for (const directory_entry& x : directory_iterator(from))
3071
- copy(x.path(), to/x.path().filename(), options | copy_options::unspecified)
 
3072
  ```
 
 
 
3073
  - Otherwise, for the signature with argument `ec`, `ec.clear()`.
3074
  - Otherwise, no effects.
3075
 
3076
  *Throws:* As specified in  [[fs.err.report]].
3077
 
@@ -3120,62 +3005,61 @@ would result in:
3120
  file3
3121
  ```
3122
 
3123
  — *end example*]
3124
 
3125
- #### Copy file <a id="fs.op.copy_file">[[fs.op.copy_file]]</a>
3126
 
3127
  ``` cpp
3128
  bool copy_file(const path& from, const path& to);
3129
- bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
3130
  ```
3131
 
3132
  *Returns:* `copy_file(from, to, copy_options::none)` or
3133
  `copy_file(from, to, copy_options::none, ec)`, respectively.
3134
 
3135
  *Throws:* As specified in  [[fs.err.report]].
3136
 
3137
  ``` cpp
3138
  bool copy_file(const path& from, const path& to, copy_options options);
3139
  bool copy_file(const path& from, const path& to, copy_options options,
3140
- error_code& ec) noexcept;
3141
  ```
3142
 
3143
- *Requires:* At most one element from each option group
3144
- ([[fs.enum.copy.opts]]) is set in `options`.
3145
 
3146
  *Effects:* As follows:
3147
 
3148
- - Report a file already exists error as specified in  [[fs.err.report]]
3149
- if:
3150
- - `!is_regular_file(from)`, or
3151
- - `exists(to)` and `!is_regular_file(to)`, or
3152
- - `exists(to)` and `equivalent(from, to)`, or
3153
- - `exists(to)` and
3154
  ``` cpp
3155
  (options & (copy_options::skip_existing |
3156
  copy_options::overwrite_existing |
3157
  copy_options::update_existing)) == copy_options::none
3158
  ```
3159
  - Otherwise, copy the contents and attributes of the file `from`
3160
  resolves to, to the file `to` resolves to, if:
3161
- - `!exists(to)`, or
3162
  - `(options & copy_options::overwrite_existing) != copy_options::none`,
3163
  or
3164
  - `(options & copy_options::update_existing) `` `` != copy_options::none`
3165
  and `from` is more recent than `to`, determined as if by use of the
3166
- `last_write_time` function ([[fs.op.last_write_time]]).
3167
  - Otherwise, no effects.
3168
 
3169
  *Returns:* `true` if the `from` file was copied, otherwise `false`. The
3170
  signature with argument `ec` returns `false` if an error occurs.
3171
 
3172
  *Throws:* As specified in  [[fs.err.report]].
3173
 
3174
  *Complexity:* At most one direct or indirect invocation of `status(to)`.
3175
 
3176
- #### Copy symlink <a id="fs.op.copy_symlink">[[fs.op.copy_symlink]]</a>
3177
 
3178
  ``` cpp
3179
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
3180
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
3181
  error_code& ec) noexcept;
@@ -3187,86 +3071,78 @@ void copy_symlink(const path& existing_symlink, const path& new_symlink,
3187
  respectively, where in each case *`function`* is `create_symlink` or
3188
  `create_directory_symlink` as appropriate.
3189
 
3190
  *Throws:* As specified in  [[fs.err.report]].
3191
 
3192
- #### Create directories <a id="fs.op.create_directories">[[fs.op.create_directories]]</a>
3193
 
3194
  ``` cpp
3195
  bool create_directories(const path& p);
3196
- bool create_directories(const path& p, error_code& ec) noexcept;
3197
  ```
3198
 
3199
- *Effects:* Establishes the postcondition by calling `create_directory()`
3200
- for any element of `p` that does not exist.
3201
-
3202
- *Postconditions:* `is_directory(p)`.
3203
-
3204
- *Returns:* `true` if a new directory was created, otherwise `false`. The
3205
- signature with argument `ec` returns `false` if an error occurs.
3206
-
3207
- *Throws:* As specified in  [[fs.err.report]].
3208
-
3209
- *Complexity:* 𝑂(n) where *n* is the number of elements of `p` that do
3210
  not exist.
3211
 
3212
- #### Create directory <a id="fs.op.create_directory">[[fs.op.create_directory]]</a>
 
 
 
 
 
 
 
3213
 
3214
  ``` cpp
3215
  bool create_directory(const path& p);
3216
  bool create_directory(const path& p, error_code& ec) noexcept;
3217
  ```
3218
 
3219
- *Effects:* Establishes the postcondition by attempting to create the
3220
- directory `p` resolves to, as if by POSIX `mkdir()` with a second
3221
- argument of `static_cast<int>(perms::all)`. Creation failure because `p`
3222
- resolves to an existing directory shall not be treated as an error.
3223
 
3224
- *Postconditions:* `is_directory(p)`.
3225
-
3226
- *Returns:* `true` if a new directory was created, otherwise `false`. The
3227
- signature with argument `ec` returns `false` if an error occurs.
3228
 
3229
  *Throws:* As specified in  [[fs.err.report]].
3230
 
3231
  ``` cpp
3232
  bool create_directory(const path& p, const path& existing_p);
3233
  bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
3234
  ```
3235
 
3236
- *Effects:* Establishes the postcondition by attempting to create the
3237
- directory `p` resolves to, with attributes copied from directory
3238
- `existing_p`. The set of attributes copied is operating system
3239
- dependent. Creation failure because `p` resolves to an existing
3240
- directory shall not be treated as an error.
3241
 
3242
  [*Note 1*: For POSIX-based operating systems, the attributes are those
3243
  copied by native API `stat(existing_p.c_str(), &attributes_stat)`
3244
  followed by `mkdir(p.c_str(), attributes_stat.st_mode)`. For
3245
  Windows-based operating systems, the attributes are those copied by
3246
  native API
3247
  `CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)`. — *end note*]
3248
 
3249
- *Postconditions:* `is_directory(p)`.
3250
-
3251
- *Returns:* `true` if a new directory was created, otherwise `false`. The
3252
- signature with argument `ec` returns `false` if an error occurs.
3253
 
3254
  *Throws:* As specified in  [[fs.err.report]].
3255
 
3256
- #### Create directory symlink <a id="fs.op.create_dir_symlk">[[fs.op.create_dir_symlk]]</a>
3257
 
3258
  ``` cpp
3259
  void create_directory_symlink(const path& to, const path& new_symlink);
3260
  void create_directory_symlink(const path& to, const path& new_symlink,
3261
  error_code& ec) noexcept;
3262
  ```
3263
 
3264
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3265
 
3266
- *Postconditions:* `new_symlink` resolves to a symbolic link file that
3267
- contains an unspecified representation of `to`.
3268
 
3269
  *Throws:* As specified in  [[fs.err.report]].
3270
 
3271
  [*Note 1*: Some operating systems require symlink creation to identify
3272
  that the link is to a directory. Portable code should use
@@ -3276,21 +3152,21 @@ that the link is to a directory. Portable code should use
3276
  [*Note 2*: Some operating systems do not support symbolic links at all
3277
  or support them only for regular files. Some file systems (such as the
3278
  FAT file system) do not support symbolic links regardless of the
3279
  operating system. — *end note*]
3280
 
3281
- #### Create hard link <a id="fs.op.create_hard_lk">[[fs.op.create_hard_lk]]</a>
3282
 
3283
  ``` cpp
3284
  void create_hard_link(const path& to, const path& new_hard_link);
3285
  void create_hard_link(const path& to, const path& new_hard_link,
3286
  error_code& ec) noexcept;
3287
  ```
3288
 
3289
  *Effects:* Establishes the postcondition, as if by POSIX `link()`.
3290
 
3291
- *Postconditions:*
3292
 
3293
  - `exists(to) && exists(new_hard_link) && equivalent(to, new_hard_link)`
3294
  - The contents of the file or directory `to` resolves to are unchanged.
3295
 
3296
  *Throws:* As specified in  [[fs.err.report]].
@@ -3299,31 +3175,31 @@ void create_hard_link(const path& to, const path& new_hard_link,
3299
  support them only for regular files. Some file systems (such as the FAT
3300
  file system) do not support hard links regardless of the operating
3301
  system. Some file systems limit the number of links per
3302
  file. — *end note*]
3303
 
3304
- #### Create symlink <a id="fs.op.create_symlink">[[fs.op.create_symlink]]</a>
3305
 
3306
  ``` cpp
3307
  void create_symlink(const path& to, const path& new_symlink);
3308
  void create_symlink(const path& to, const path& new_symlink,
3309
  error_code& ec) noexcept;
3310
  ```
3311
 
3312
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3313
 
3314
- *Postconditions:* `new_symlink` resolves to a symbolic link file that
3315
- contains an unspecified representation of `to`.
3316
 
3317
  *Throws:* As specified in  [[fs.err.report]].
3318
 
3319
  [*Note 1*: Some operating systems do not support symbolic links at all
3320
  or support them only for regular files. Some file systems (such as the
3321
  FAT file system) do not support symbolic links regardless of the
3322
  operating system. — *end note*]
3323
 
3324
- #### Current path <a id="fs.op.current_path">[[fs.op.current_path]]</a>
3325
 
3326
  ``` cpp
3327
  path current_path();
3328
  path current_path(error_code& ec);
3329
  ```
@@ -3341,22 +3217,21 @@ resolution for relative paths.
3341
  [*Note 1*: The `current_path()` name was chosen to emphasize that the
3342
  returned value is a path, not just a single directory
3343
  name. — *end note*]
3344
 
3345
  [*Note 2*: The current path as returned by many operating systems is a
3346
- dangerous global variable. It may be changed unexpectedly by a
3347
- third-party or system library functions, or by another
3348
- thread. — *end note*]
3349
 
3350
  ``` cpp
3351
  void current_path(const path& p);
3352
  void current_path(const path& p, error_code& ec) noexcept;
3353
  ```
3354
 
3355
  *Effects:* Establishes the postcondition, as if by POSIX `chdir()`.
3356
 
3357
- *Postconditions:* `equivalent(p, current_path())`.
3358
 
3359
  *Throws:* As specified in  [[fs.err.report]].
3360
 
3361
  [*Note 3*: The current path for many operating systems is a dangerous
3362
  global state. It may be changed unexpectedly by a third-party or system
@@ -3367,26 +3242,22 @@ library functions, or by another thread. — *end note*]
3367
  ``` cpp
3368
  bool equivalent(const path& p1, const path& p2);
3369
  bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
3370
  ```
3371
 
3372
- Let `s1` and `s2` be `file_status`s, determined as if by `status(p1)`
3373
- and `status(p2)`, respectively.
3374
-
3375
- *Effects:* Determines `s1` and `s2`. If
3376
- `(!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))` an
3377
- error is reported ([[fs.err.report]]).
3378
-
3379
- *Returns:* `true`, if `s1 == s2` and `p1` and `p2` resolve to the same
3380
- file system entity, else `false`. The signature with argument `ec`
3381
- returns `false` if an error occurs.
3382
 
3383
  Two paths are considered to resolve to the same file system entity if
3384
  two candidate entities reside on the same device at the same location.
3385
- This is determined as if by the values of the POSIX `stat` structure,
3386
- obtained as if by `stat()` for the two paths, having equal `st_dev`
3387
- values and equal `st_ino` values.
 
 
 
3388
 
3389
  *Throws:* As specified in  [[fs.err.report]].
3390
 
3391
  #### Exists <a id="fs.op.exists">[[fs.op.exists]]</a>
3392
 
@@ -3409,31 +3280,33 @@ Let `s` be a `file_status`, determined as if by `status(p)` or
3409
 
3410
  *Returns:* `exists(s)`.
3411
 
3412
  *Throws:* As specified in  [[fs.err.report]].
3413
 
3414
- #### File size <a id="fs.op.file_size">[[fs.op.file_size]]</a>
3415
 
3416
  ``` cpp
3417
  uintmax_t file_size(const path& p);
3418
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
3419
  ```
3420
 
 
 
 
3421
  *Returns:*
3422
 
3423
- - If `!exists(p)` an error is reported ([[fs.err.report]]).
3424
- - Otherwise, if `is_regular_file(p)`, the size in bytes of the file `p`
3425
- resolves to, determined as if by the value of the POSIX `stat`
3426
- structure member `st_size` obtained as if by POSIX `stat()`.
3427
  - Otherwise, the result is *implementation-defined*.
3428
 
3429
  The signature with argument `ec` returns `static_cast<uintmax_t>(-1)` if
3430
  an error occurs.
3431
 
3432
  *Throws:* As specified in  [[fs.err.report]].
3433
 
3434
- #### Hard link count <a id="fs.op.hard_lk_ct">[[fs.op.hard_lk_ct]]</a>
3435
 
3436
  ``` cpp
3437
  uintmax_t hard_link_count(const path& p);
3438
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
3439
  ```
@@ -3441,11 +3314,11 @@ uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
3441
  *Returns:* The number of hard links for `p`. The signature with argument
3442
  `ec` returns `static_cast<uintmax_t>(-1)` if an error occurs.
3443
 
3444
  *Throws:* As specified in  [[fs.err.report]].
3445
 
3446
- #### Is block file <a id="fs.op.is_block_file">[[fs.op.is_block_file]]</a>
3447
 
3448
  ``` cpp
3449
  bool is_block_file(file_status s) noexcept;
3450
  ```
3451
 
@@ -3460,11 +3333,11 @@ bool is_block_file(const path& p, error_code& ec) noexcept;
3460
  respectively. The signature with argument `ec` returns `false` if an
3461
  error occurs.
3462
 
3463
  *Throws:* As specified in  [[fs.err.report]].
3464
 
3465
- #### Is character file <a id="fs.op.is_char_file">[[fs.op.is_char_file]]</a>
3466
 
3467
  ``` cpp
3468
  bool is_character_file(file_status s) noexcept;
3469
  ```
3470
 
@@ -3479,11 +3352,11 @@ bool is_character_file(const path& p, error_code& ec) noexcept;
3479
  `is_character_file(status(p, ec))`, respectively.
3480
  The signature with argument `ec` returns `false` if an error occurs.
3481
 
3482
  *Throws:* As specified in  [[fs.err.report]].
3483
 
3484
- #### Is directory <a id="fs.op.is_directory">[[fs.op.is_directory]]</a>
3485
 
3486
  ``` cpp
3487
  bool is_directory(file_status s) noexcept;
3488
  ```
3489
 
@@ -3498,15 +3371,15 @@ bool is_directory(const path& p, error_code& ec) noexcept;
3498
  respectively. The signature with argument `ec` returns `false` if an
3499
  error occurs.
3500
 
3501
  *Throws:* As specified in  [[fs.err.report]].
3502
 
3503
- #### Is empty <a id="fs.op.is_empty">[[fs.op.is_empty]]</a>
3504
 
3505
  ``` cpp
3506
  bool is_empty(const path& p);
3507
- bool is_empty(const path& p, error_code& ec) noexcept;
3508
  ```
3509
 
3510
  *Effects:*
3511
 
3512
  - Determine `file_status s`, as if by `status(p)` or `status(p, ec)`,
@@ -3526,11 +3399,11 @@ bool is_empty(const path& p, error_code& ec) noexcept;
3526
  occurred.
3527
  - Otherwise, return `sz == 0`.
3528
 
3529
  *Throws:* As specified in  [[fs.err.report]].
3530
 
3531
- #### Is fifo <a id="fs.op.is_fifo">[[fs.op.is_fifo]]</a>
3532
 
3533
  ``` cpp
3534
  bool is_fifo(file_status s) noexcept;
3535
  ```
3536
 
@@ -3545,11 +3418,11 @@ bool is_fifo(const path& p, error_code& ec) noexcept;
3545
  respectively. The signature with argument `ec` returns `false` if an
3546
  error occurs.
3547
 
3548
  *Throws:* As specified in  [[fs.err.report]].
3549
 
3550
- #### Is other <a id="fs.op.is_other">[[fs.op.is_other]]</a>
3551
 
3552
  ``` cpp
3553
  bool is_other(file_status s) noexcept;
3554
  ```
3555
 
@@ -3565,11 +3438,11 @@ bool is_other(const path& p, error_code& ec) noexcept;
3565
  respectively. The signature with argument `ec` returns `false` if an
3566
  error occurs.
3567
 
3568
  *Throws:* As specified in  [[fs.err.report]].
3569
 
3570
- #### Is regular file <a id="fs.op.is_regular_file">[[fs.op.is_regular_file]]</a>
3571
 
3572
  ``` cpp
3573
  bool is_regular_file(file_status s) noexcept;
3574
  ```
3575
 
@@ -3580,11 +3453,11 @@ bool is_regular_file(const path& p);
3580
  ```
3581
 
3582
  *Returns:* `is_regular_file(status(p))`.
3583
 
3584
  *Throws:* `filesystem_error` if `status(p)` would throw
3585
- `filesystem_error.`
3586
 
3587
  ``` cpp
3588
  bool is_regular_file(const path& p, error_code& ec) noexcept;
3589
  ```
3590
 
@@ -3595,11 +3468,11 @@ bool is_regular_file(const path& p, error_code& ec) noexcept;
3595
  between cases, call the `status` function directly. — *end note*]
3596
 
3597
  *Returns:* `is_regular_file(status(p, ec))`. Returns `false` if an error
3598
  occurs.
3599
 
3600
- #### Is socket <a id="fs.op.is_socket">[[fs.op.is_socket]]</a>
3601
 
3602
  ``` cpp
3603
  bool is_socket(file_status s) noexcept;
3604
  ```
3605
 
@@ -3614,11 +3487,11 @@ bool is_socket(const path& p, error_code& ec) noexcept;
3614
  respectively. The signature with argument `ec` returns `false` if an
3615
  error occurs.
3616
 
3617
  *Throws:* As specified in  [[fs.err.report]].
3618
 
3619
- #### Is symlink <a id="fs.op.is_symlink">[[fs.op.is_symlink]]</a>
3620
 
3621
  ``` cpp
3622
  bool is_symlink(file_status s) noexcept;
3623
  ```
3624
 
@@ -3633,20 +3506,20 @@ bool is_symlink(const path& p, error_code& ec) noexcept;
3633
  `is_symlink(symlink_status(p, ec))`, respectively. The signature with
3634
  argument `ec` returns `false` if an error occurs.
3635
 
3636
  *Throws:* As specified in  [[fs.err.report]].
3637
 
3638
- #### Last write time <a id="fs.op.last_write_time">[[fs.op.last_write_time]]</a>
3639
 
3640
  ``` cpp
3641
  file_time_type last_write_time(const path& p);
3642
  file_time_type last_write_time(const path& p, error_code& ec) noexcept;
3643
  ```
3644
 
3645
  *Returns:* The time of last data modification of `p`, determined as if
3646
- by the value of the POSIX `stat` structure member `st_mtime` obtained as
3647
- if by POSIX `stat()`. The signature with argument `ec` returns
3648
  `file_time_type::min()` if an error occurs.
3649
 
3650
  *Throws:* As specified in  [[fs.err.report]].
3651
 
3652
  ``` cpp
@@ -3670,11 +3543,11 @@ granularity. — *end note*]
3670
  void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
3671
  void permissions(const path& p, perms prms, error_code& ec) noexcept;
3672
  void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
3673
  ```
3674
 
3675
- *Requires:* Exactly one of the `perm_options` constants `replace`,
3676
  `add`, or `remove` is present in `opts`.
3677
 
3678
  *Remarks:* The second signature behaves as if it had an additional
3679
  parameter `perm_options` `opts` with an argument of
3680
  `perm_options::replace`.
@@ -3718,11 +3591,11 @@ weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec));
3718
 
3719
  or `path()` at the first error occurrence, if any.
3720
 
3721
  *Throws:* As specified in  [[fs.err.report]].
3722
 
3723
- #### Read symlink <a id="fs.op.read_symlink">[[fs.op.read_symlink]]</a>
3724
 
3725
  ``` cpp
3726
  path read_symlink(const path& p);
3727
  path read_symlink(const path& p, error_code& ec);
3728
  ```
@@ -3778,31 +3651,31 @@ bool remove(const path& p, error_code& ec) noexcept;
3778
  as if by POSIX `remove()`.
3779
 
3780
  [*Note 1*: A symbolic link is itself removed, rather than the file it
3781
  resolves to. — *end note*]
3782
 
3783
- *Postconditions:* `!exists(symlink_status(p))`.
3784
 
3785
  *Returns:* `false` if `p` did not exist, otherwise `true`. The signature
3786
  with argument `ec` returns `false` if an error occurs.
3787
 
3788
  *Throws:* As specified in  [[fs.err.report]].
3789
 
3790
- #### Remove all <a id="fs.op.remove_all">[[fs.op.remove_all]]</a>
3791
 
3792
  ``` cpp
3793
  uintmax_t remove_all(const path& p);
3794
- uintmax_t remove_all(const path& p, error_code& ec) noexcept;
3795
  ```
3796
 
3797
  *Effects:* Recursively deletes the contents of `p` if it exists, then
3798
  deletes file `p` itself, as if by POSIX `remove()`.
3799
 
3800
  [*Note 1*: A symbolic link is itself removed, rather than the file it
3801
  resolves to. — *end note*]
3802
 
3803
- *Postconditions:* `!exists(symlink_status(p))`.
3804
 
3805
  *Returns:* The number of files removed. The signature with argument `ec`
3806
  returns `static_cast< uintmax_t>(-1)` if an error occurs.
3807
 
3808
  *Throws:* As specified in  [[fs.err.report]].
@@ -3831,23 +3704,22 @@ A symbolic link is itself renamed, rather than the file it resolves to.
3831
 
3832
  — *end note*]
3833
 
3834
  *Throws:* As specified in  [[fs.err.report]].
3835
 
3836
- #### Resize file <a id="fs.op.resize_file">[[fs.op.resize_file]]</a>
3837
 
3838
  ``` cpp
3839
  void resize_file(const path& p, uintmax_t new_size);
3840
  void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
3841
  ```
3842
 
3843
- *Postconditions:* `file_size(p) == new_size`.
 
3844
 
3845
  *Throws:* As specified in  [[fs.err.report]].
3846
 
3847
- *Remarks:* Achieves its postconditions as if by POSIX `truncate()`.
3848
-
3849
  #### Space <a id="fs.op.space">[[fs.op.space]]</a>
3850
 
3851
  ``` cpp
3852
  space_info space(const path& p);
3853
  space_info space(const path& p, error_code& ec) noexcept;
@@ -3946,27 +3818,27 @@ determined as if by converting the `st_mode` member of the obtained
3946
  - Otherwise, if the attributes indicate a fifo or pipe file, as if by
3947
  POSIX `S_ISFIFO`, returns `file_status(file_type::fifo, prms)`.
3948
  - Otherwise, if the attributes indicate a socket, as if by POSIX
3949
  `S_ISSOCK`, returns `file_status(file_type::socket, prms)`.
3950
  - Otherwise, if the attributes indicate an implementation-defined file
3951
- type ([[fs.enum.file_type]]), returns
3952
  `file_status(file_type::`*`A`*`, prms)`, where *A* is the constant
3953
  for the *implementation-defined* file type.
3954
  - Otherwise, returns `file_status(file_type::unknown, prms)`.
3955
 
3956
  *Remarks:* If a symbolic link is encountered during pathname resolution,
3957
  pathname resolution continues using the contents of the symbolic link.
3958
 
3959
- #### Status known <a id="fs.op.status_known">[[fs.op.status_known]]</a>
3960
 
3961
  ``` cpp
3962
  bool status_known(file_status s) noexcept;
3963
  ```
3964
 
3965
  *Returns:* `s.type() != file_type::none`.
3966
 
3967
- #### Symlink status <a id="fs.op.symlink_status">[[fs.op.symlink_status]]</a>
3968
 
3969
  ``` cpp
3970
  file_status symlink_status(const path& p);
3971
  file_status symlink_status(const path& p, error_code& ec) noexcept;
3972
  ```
@@ -3986,20 +3858,23 @@ indicate a symbolic link, as if by POSIX `S_ISLNK`, returns
3986
 
3987
  *Remarks:* Pathname resolution terminates if `p` names a symbolic link.
3988
 
3989
  *Throws:* As specified in  [[fs.err.report]].
3990
 
3991
- #### Temporary directory path <a id="fs.op.temp_dir_path">[[fs.op.temp_dir_path]]</a>
3992
 
3993
  ``` cpp
3994
  path temp_directory_path();
3995
  path temp_directory_path(error_code& ec);
3996
  ```
3997
 
3998
- *Returns:* An unspecifed directory path suitable for temporary files. An
3999
- error shall be reported if `!exists(p) || !is_directory(p)`, where `p`
4000
- is the path to be returned. The signature with argument `ec` returns
 
 
 
4001
  `path()` if an error occurs.
4002
 
4003
  *Throws:* As specified in  [[fs.err.report]].
4004
 
4005
  [*Example 1*: For POSIX-based operating systems, an implementation
@@ -4007,34 +3882,31 @@ might return the path supplied by the first environment variable found
4007
  in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found,
4008
  `"/tmp"`. For Windows-based operating systems, an implementation might
4009
  return the path reported by the Windows `GetTempPath` API
4010
  function. — *end example*]
4011
 
4012
- #### Weakly canonical <a id="fs.op.weakly_canonical">[[fs.op.weakly_canonical]]</a>
4013
 
4014
  ``` cpp
4015
  path weakly_canonical(const path& p);
4016
  path weakly_canonical(const path& p, error_code& ec);
4017
  ```
4018
 
4019
  *Returns:* `p` with symlinks resolved and the result
4020
- normalized ([[fs.def.normal.form]]).
4021
 
4022
  *Effects:* Using `status(p)` or `status(p, ec)`, respectively, to
4023
  determine existence, return a path composed by `operator/=` from the
4024
- result of calling `canonical()` without a `base` argument and with a
4025
- path argument composed of the leading elements of `p` that exist, if
4026
- any, followed by the elements of `p` that do not exist, if any. For the
4027
- first form, `canonical()` is called without an `error_code` argument.
4028
- For the second form, `canonical()` is called with `ec` as an
4029
- `error_code` argument, and `path()` is returned at the first error
4030
- occurrence, if any.
4031
 
4032
- *Postconditions:* The returned path is in normal
4033
- form ([[fs.def.normal.form]]).
4034
 
4035
- *Remarks:* Implementations are encouraged to avoid unnecessary
4036
- normalization such as when `canonical` has already been called on the
4037
- entirety of `p`.
4038
 
4039
  *Throws:* As specified in  [[fs.err.report]].
4040
 
 
1
  ## File systems <a id="filesystems">[[filesystems]]</a>
2
 
3
  ### General <a id="fs.general">[[fs.general]]</a>
4
 
5
+ Subclause  [[filesystems]] describes operations on file systems and
6
+ their components, such as paths, regular files, and directories.
7
+
8
+ A *file system* is a collection of files and their attributes.
9
+
10
+ A *file* is an object within a file system that holds user or system
11
+ data. Files can be written to, or read from, or both. A file has certain
12
+ attributes, including type. File types include regular files and
13
+ directories. Other types of files, such as symbolic links, may be
14
+ supported by the implementation.
15
+
16
+ A *directory* is a file within a file system that acts as a container of
17
+ directory entries that contain information about other files, possibly
18
+ including other directory files. The *parent directory* of a directory
19
+ is the directory that both contains a directory entry for the given
20
+ directory and is represented by the dot-dot filename [[fs.path.generic]]
21
+ in the given directory. The *parent directory* of other types of files
22
+ is a directory containing a directory entry for the file under
23
+ discussion.
24
+
25
+ A *link* is an object that associates a filename with a file. Several
26
+ links can associate names with the same file. A *hard link* is a link to
27
+ an existing file. Some file systems support multiple hard links to a
28
+ file. If the last hard link to a file is removed, the file itself is
29
+ removed.
30
+
31
+ [*Note 1*: A hard link can be thought of as a shared-ownership smart
32
+ pointer to a file. — *end note*]
33
+
34
+ A *symbolic link* is a type of file with the property that when the file
35
+ is encountered during pathname resolution [[fs.class.path]], a string
36
+ stored by the file is used to modify the pathname resolution.
37
+
38
+ [*Note 2*: Symbolic links are often called symlinks. A symbolic link
39
+ can be thought of as a raw pointer to a file. If the file pointed to
40
+ does not exist, the symbolic link is said to be a “dangling” symbolic
41
+ link. — *end note*]
42
 
43
  ### Conformance <a id="fs.conformance">[[fs.conformance]]</a>
44
 
45
  Conformance is specified in terms of behavior. Ideal behavior is not
46
  always implementable, so the conformance subclauses take that into
47
  account.
48
 
49
  #### POSIX conformance <a id="fs.conform.9945">[[fs.conform.9945]]</a>
50
 
51
+ Some behavior is specified by reference to POSIX [[fs.norm.ref]]. How
52
  such behavior is actually implemented is unspecified.
53
 
54
  [*Note 1*: This constitutes an “as if” rule allowing implementations to
55
  call native operating system or other APIs. — *end note*]
56
 
57
+ Implementations should provide such behavior as it is defined by POSIX.
58
+ Implementations shall document any behavior that differs from the
59
+ behavior defined by POSIX. Implementations that do not support exact
60
+ POSIX behavior should provide behavior as close to POSIX behavior as is
61
+ reasonable given the limitations of actual operating systems and file
62
+ systems. If an implementation cannot provide any reasonable behavior,
63
+ the implementation shall report an error as specified in 
64
+ [[fs.err.report]].
65
 
66
  [*Note 2*: This allows users to rely on an exception being thrown or an
67
  error code being set when an implementation cannot provide any
68
  reasonable behavior. — *end note*]
69
 
 
76
  required to support those features on the FAT file system but instead
77
  are required to report an error as described above. — *end example*]
78
 
79
  #### Operating system dependent behavior conformance <a id="fs.conform.os">[[fs.conform.os]]</a>
80
 
81
+ Behavior that is specified as being *operating system dependent* is
82
+ dependent upon the behavior and characteristics of an operating system.
83
+ The operating system an implementation is dependent upon is
84
+ *implementation-defined*.
85
 
86
  It is permissible for an implementation to be dependent upon an
87
  operating system emulator rather than the actual underlying operating
88
  system.
89
 
90
  #### File system race behavior <a id="fs.race.behavior">[[fs.race.behavior]]</a>
91
 
92
+ A *file system race* is the condition that occurs when multiple threads,
93
+ processes, or computers interleave access and modification of the same
94
+ object within a file system. Behavior is undefined if calls to functions
95
+ provided by subclause  [[fs.race.behavior]] introduce a file system
96
+ race.
97
 
98
  If the possibility of a file system race would make it unreliable for a
99
  program to test for a precondition before calling a function described
100
+ herein, *Preconditions:* is not specified for the function.
101
 
102
  [*Note 1*: As a design practice, preconditions are not specified when
103
  it is unreasonable for a program to detect them prior to calling the
104
  function. — *end note*]
105
 
106
  ### Normative references <a id="fs.norm.ref">[[fs.norm.ref]]</a>
107
 
108
+ Subclause  [[filesystems]] mentions commercially available operating
109
+ systems for purposes of exposition.[^41]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  ### Requirements <a id="fs.req">[[fs.req]]</a>
112
 
113
+ Throughout subclause  [[filesystems]], `char`, `wchar_t`, `char8_t`,
114
+ `char16_t`, and `char32_t` are collectively called *encoded character
115
+ types*.
116
 
117
  Functions with template parameters named `EcharT` shall not participate
118
  in overload resolution unless `EcharT` is one of the encoded character
119
  types.
120
 
121
+ Template parameters named `InputIterator` shall meet the
122
+ *Cpp17InputIterator* requirements [[input.iterators]] and shall have a
123
+ value type that is one of the encoded character types.
124
 
125
  [*Note 1*: Use of an encoded character type implies an associated
126
  character set and encoding. Since `signed char` and `unsigned char` have
127
  no implied character set and encoding, they are not included as
128
  permitted types. — *end note*]
129
 
130
+ Template parameters named `Allocator` shall meet the *Cpp17Allocator*
131
+ requirements ([[cpp17.allocator]]).
132
 
133
  #### Namespaces and headers <a id="fs.req.namespace">[[fs.req.namespace]]</a>
134
 
135
+ Unless otherwise specified, references to entities described in
136
+ subclause  [[filesystems]] are assumed to be qualified with
137
+ `::std::filesystem::`.
138
 
139
  ### Header `<filesystem>` synopsis <a id="fs.filesystem.syn">[[fs.filesystem.syn]]</a>
140
 
141
  ``` cpp
142
+ #include <compare> // see [compare.syn]
143
+
144
  namespace std::filesystem {
145
  // [fs.class.path], paths
146
  class path;
147
 
148
  // [fs.path.nonmember], path non-member functions
149
  void swap(path& lhs, path& rhs) noexcept;
150
  size_t hash_value(const path& p) noexcept;
151
 
152
+ // [fs.class.filesystem.error], filesystem errors
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  class filesystem_error;
154
 
155
+ // [fs.class.directory.entry], directory entries
156
  class directory_entry;
157
 
158
+ // [fs.class.directory.iterator], directory iterators
159
  class directory_iterator;
160
 
161
  // [fs.dir.itr.nonmembers], range access for directory iterators
162
  directory_iterator begin(directory_iterator iter) noexcept;
163
  directory_iterator end(const directory_iterator&) noexcept;
 
167
 
168
  // [fs.rec.dir.itr.nonmembers], range access for recursive directory iterators
169
  recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
170
  recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
171
 
172
+ // [fs.class.file.status], file status
173
  class file_status;
174
 
175
  struct space_info {
176
  uintmax_t capacity;
177
  uintmax_t free;
178
  uintmax_t available;
179
+
180
+ friend bool operator==(const space_info&, const space_info&) = default;
181
  };
182
 
183
  // [fs.enum], enumerations
184
  enum class file_type;
185
  enum class perms;
186
  enum class perm_options;
187
  enum class copy_options;
188
  enum class directory_options;
189
 
190
+ using file_time_type = chrono::time_point<chrono::file_clock>;
191
 
192
  // [fs.op.funcs], filesystem operations
193
+ path absolute(const path& p);
194
+ path absolute(const path& p, error_code& ec);
195
 
196
+ path canonical(const path& p);
197
  path canonical(const path& p, error_code& ec);
 
198
 
199
  void copy(const path& from, const path& to);
200
+ void copy(const path& from, const path& to, error_code& ec);
201
  void copy(const path& from, const path& to, copy_options options);
202
  void copy(const path& from, const path& to, copy_options options,
203
+ error_code& ec);
204
 
205
  bool copy_file(const path& from, const path& to);
206
+ bool copy_file(const path& from, const path& to, error_code& ec);
207
  bool copy_file(const path& from, const path& to, copy_options option);
208
  bool copy_file(const path& from, const path& to, copy_options option,
209
+ error_code& ec);
210
 
211
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
212
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
213
  error_code& ec) noexcept;
214
 
215
  bool create_directories(const path& p);
216
+ bool create_directories(const path& p, error_code& ec);
217
 
218
  bool create_directory(const path& p);
219
  bool create_directory(const path& p, error_code& ec) noexcept;
220
 
221
  bool create_directory(const path& p, const path& attributes);
 
237
  path current_path();
238
  path current_path(error_code& ec);
239
  void current_path(const path& p);
240
  void current_path(const path& p, error_code& ec) noexcept;
241
 
242
+ bool equivalent(const path& p1, const path& p2);
243
+ bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
244
+
245
  bool exists(file_status s) noexcept;
246
  bool exists(const path& p);
247
  bool exists(const path& p, error_code& ec) noexcept;
248
 
 
 
 
249
  uintmax_t file_size(const path& p);
250
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
251
 
252
  uintmax_t hard_link_count(const path& p);
253
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
 
263
  bool is_directory(file_status s) noexcept;
264
  bool is_directory(const path& p);
265
  bool is_directory(const path& p, error_code& ec) noexcept;
266
 
267
  bool is_empty(const path& p);
268
+ bool is_empty(const path& p, error_code& ec);
269
 
270
  bool is_fifo(file_status s) noexcept;
271
  bool is_fifo(const path& p);
272
  bool is_fifo(const path& p, error_code& ec) noexcept;
273
 
 
310
 
311
  bool remove(const path& p);
312
  bool remove(const path& p, error_code& ec) noexcept;
313
 
314
  uintmax_t remove_all(const path& p);
315
+ uintmax_t remove_all(const path& p, error_code& ec);
316
 
317
  void rename(const path& from, const path& to);
318
  void rename(const path& from, const path& to, error_code& ec) noexcept;
319
 
320
  void resize_file(const path& p, uintmax_t size);
 
337
  path weakly_canonical(const path& p);
338
  path weakly_canonical(const path& p, error_code& ec);
339
  }
340
  ```
341
 
342
+ Implementations should ensure that the resolution and range of
343
+ `file_time_type` reflect the operating system dependent resolution and
344
+ range of file time values.
 
 
345
 
346
  ### Error reporting <a id="fs.err.report">[[fs.err.report]]</a>
347
 
348
  Filesystem library functions often provide two overloads, one that
349
  throws an exception to report file system errors, and another that sets
 
389
  appropriate for the specific operating system dependent error.
390
  Otherwise, `clear()` is called on the `error_code&` argument.
391
 
392
  ### Class `path` <a id="fs.class.path">[[fs.class.path]]</a>
393
 
394
+ An object of class `path` represents a path and contains a pathname.
395
+ Such an object is concerned only with the lexical and syntactic aspects
396
+ of a path. The path does not necessarily exist in external storage, and
397
+ the pathname is not necessarily valid for the current operating system
398
+ or for a particular file system.
 
399
 
400
  [*Note 1*: Class `path` is used to support the differences between the
401
  string types used by different operating systems to represent pathnames,
402
  and to perform conversions between encodings when
403
  necessary. — *end note*]
404
 
405
+ A *path* is a sequence of elements that identify the location of a file
406
+ within a filesystem. The elements are the *root-name*ₒₚₜ ,
407
+ *root-directory*ₒₚₜ , and an optional sequence of *filename*s
408
+ [[fs.path.generic]]. The maximum number of elements in the sequence is
409
+ operating system dependent [[fs.conform.os]].
410
+
411
+ An *absolute path* is a path that unambiguously identifies the location
412
+ of a file without reference to an additional starting location. The
413
+ elements of a path that determine if it is absolute are operating system
414
+ dependent. A *relative path* is a path that is not absolute, and as
415
+ such, only unambiguously identifies the location of a file when resolved
416
+ relative to an implied starting location. The elements of a path that
417
+ determine if it is relative are operating system dependent.
418
+
419
+ [*Note 2*: Pathnames “.” and “..” are relative paths. — *end note*]
420
+
421
+ A *pathname* is a character string that represents the name of a path.
422
+ Pathnames are formatted according to the generic pathname format grammar
423
+ [[fs.path.generic]] or according to an operating system dependent
424
+ *native pathname format* accepted by the host operating system.
425
+
426
+ *Pathname resolution* is the operating system dependent mechanism for
427
+ resolving a pathname to a particular file in a file hierarchy. There may
428
+ be multiple pathnames that resolve to the same file.
429
+
430
+ [*Example 1*: POSIX specifies the mechanism in section 4.11, Pathname
431
+ resolution. — *end example*]
432
+
433
  ``` cpp
434
  namespace std::filesystem {
435
  class path {
436
  public:
437
  using value_type = see below;
 
462
  path& operator=(string_type&& source);
463
  path& assign(string_type&& source);
464
  template<class Source>
465
  path& operator=(const Source& source);
466
  template<class Source>
467
+ path& assign(const Source& source);
468
  template<class InputIterator>
469
  path& assign(InputIterator first, InputIterator last);
470
 
471
  // [fs.path.append], appends
472
  path& operator/=(const path& p);
 
498
  path& remove_filename();
499
  path& replace_filename(const path& replacement);
500
  path& replace_extension(const path& replacement = path());
501
  void swap(path& rhs) noexcept;
502
 
503
+ // [fs.path.nonmember], non-member operators
504
+ friend bool operator==(const path& lhs, const path& rhs) noexcept;
505
+ friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept;
506
+
507
+ friend path operator/ (const path& lhs, const path& rhs);
508
+
509
  // [fs.path.native.obs], native format observers
510
  const string_type& native() const noexcept;
511
  const value_type* c_str() const noexcept;
512
  operator string_type() const;
513
 
 
515
  class Allocator = allocator<EcharT>>
516
  basic_string<EcharT, traits, Allocator>
517
  string(const Allocator& a = Allocator()) const;
518
  std::string string() const;
519
  std::wstring wstring() const;
520
+ std::u8string u8string() const;
521
  std::u16string u16string() const;
522
  std::u32string u32string() const;
523
 
524
  // [fs.path.generic.obs], generic format observers
525
  template<class EcharT, class traits = char_traits<EcharT>,
526
  class Allocator = allocator<EcharT>>
527
  basic_string<EcharT, traits, Allocator>
528
  generic_string(const Allocator& a = Allocator()) const;
529
  std::string generic_string() const;
530
  std::wstring generic_wstring() const;
531
+ std::u8string generic_u8string() const;
532
  std::u16string generic_u16string() const;
533
  std::u32string generic_u32string() const;
534
 
535
  // [fs.path.compare], compare
536
  int compare(const path& p) const noexcept;
 
547
  path filename() const;
548
  path stem() const;
549
  path extension() const;
550
 
551
  // [fs.path.query], query
552
+ [[nodiscard]] bool empty() const noexcept;
553
  bool has_root_name() const;
554
  bool has_root_directory() const;
555
  bool has_root_path() const;
556
  bool has_relative_path() const;
557
  bool has_parent_path() const;
 
570
  class iterator;
571
  using const_iterator = iterator;
572
 
573
  iterator begin() const;
574
  iterator end() const;
575
+
576
+ // [fs.path.io], path inserter and extractor
577
+ template<class charT, class traits>
578
+ friend basic_ostream<charT, traits>&
579
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
580
+ template<class charT, class traits>
581
+ friend basic_istream<charT, traits>&
582
+ operator>>(basic_istream<charT, traits>& is, path& p);
583
  };
584
  }
585
  ```
586
 
587
  `value_type` is a `typedef` for the operating system dependent encoded
588
  character type used to represent pathnames.
589
 
590
  The value of the `preferred_separator` member is the operating system
591
+ dependent *preferred-separator* character [[fs.path.generic]].
592
 
593
+ [*Example 2*: For POSIX-based operating systems, `value_type` is `char`
594
  and `preferred_separator` is the slash character (`'/'`). For
595
  Windows-based operating systems, `value_type` is `wchar_t` and
596
  `preferred_separator` is the backslash character
597
  (`L'\\'`). — *end example*]
598
 
 
640
  ``` bnf
641
  fallback-separator:
642
  /, if *preferred-separator* is not /
643
  ```
644
 
645
+ A *filename* is the name of a file. The *dot* and *dot-dot* filenames,
646
+ consisting solely of one and two period characters respectively, have
647
+ special meaning. The following characteristics of filenames are
648
+ operating system dependent:
649
+
650
+ - The permitted characters. \[*Example 1*: Some operating systems
651
+ prohibit the ASCII control characters (0x00 – 0x1F) in
652
+ filenames. — *end example*] \[*Note 1*: For wide portability, users
653
+ may wish to limit *filename* characters to the POSIX Portable Filename
654
+ Character Set:
655
  `A B C D E F G H I J K L M N O P Q R S T U V W X Y Z`
656
  `a b c d e f g h i j k l m n o p q r s t u v w x y z`
657
  `0 1 2 3 4 5 6 7 8 9 . _ -` — *end note*]
658
+ - The maximum permitted length.
659
+ - Filenames that are not permitted.
660
+ - Filenames that have special meaning.
661
+ - Case awareness and sensitivity during path resolution.
662
+ - Special rules that may apply to file types other than regular files,
663
+ such as directories.
664
 
665
  Except in a *root-name*, multiple successive *directory-separator*
666
  characters are considered to be the same as one *directory-separator*
667
  character.
668
 
669
+ The dot filename is treated as a reference to the current directory. The
670
+ dot-dot filename is treated as a reference to the parent directory. What
671
+ the dot-dot filename refers to relative to *root-directory* is
 
672
  *implementation-defined*. Specific filenames may have special meanings
673
  for a particular operating system.
674
 
675
+ A *root-name* identifies the starting location for pathname resolution
676
+ [[fs.class.path]]. If there are no operating system dependent
677
  *root-name*s, at least one *implementation-defined* *root-name* is
678
  required.
679
 
680
  [*Note 2*: Many operating systems define a name beginning with two
681
  *directory-separator* characters as a *root-name* that identifies
 
688
 
689
  [*Note 3*: On a POSIX-like operating system, it is impossible to have a
690
  *root-name* and a *relative-path* without an intervening
691
  *root-directory* element. — *end note*]
692
 
693
+ *Normalization* of a generic format pathname means:
694
 
695
+ 1. If the path is empty, stop.
696
+ 2. Replace each slash character in the *root-name* with a
697
+ *preferred-separator*.
698
+ 3. Replace each *directory-separator* with a *preferred-separator*.
699
+ \[*Note 4*: The generic pathname grammar [[fs.path.generic]] defines
700
+ *directory-separator* as one or more slashes and
701
+ *preferred-separator*s. — *end note*]
702
+ 4. Remove each dot filename and any immediately following
703
+ *directory-separator*.
704
+ 5. As long as any appear, remove a non-dot-dot filename immediately
705
+ followed by a *directory-separator* and a dot-dot filename, along
706
+ with any immediately following *directory-separator*.
707
+ 6. If there is a *root-directory*, remove all dot-dot filenames and any
708
+ *directory-separator*s immediately following them. \[*Note 5*: These
709
+ dot-dot filenames attempt to refer to nonexistent parent
710
+ directories. — *end note*]
711
+ 7. If the last filename is dot-dot, remove any trailing
712
+ *directory-separator*.
713
+ 8. If the path is empty, add a dot.
714
+
715
+ The result of normalization is a path in *normal form*, which is said to
716
+ be *normalized*.
717
+
718
+ #### Conversions <a id="fs.path.cvt">[[fs.path.cvt]]</a>
719
+
720
+ ##### Argument format conversions <a id="fs.path.fmt.cvt">[[fs.path.fmt.cvt]]</a>
721
 
722
  [*Note 1*:
723
 
724
+ The format conversions described in this subclause are not applied on
725
  POSIX-based operating systems because on these systems:
726
 
727
  - The generic format is acceptable as a native path.
728
  - There is no need to distinguish between native format and generic
729
  format in function arguments.
 
732
 
733
  — *end note*]
734
 
735
  Several functions are defined to accept *detected-format* arguments,
736
  which are character sequences. A detected-format argument represents a
737
+ path using either a pathname in the generic format [[fs.path.generic]]
738
+ or a pathname in the native format [[fs.class.path]]. Such an argument
739
+ is taken to be in the generic format if and only if it matches the
740
+ generic format and is not acceptable to the operating system as a native
741
+ path.
742
 
743
  [*Note 2*: Some operating systems may have no unambiguous way to
744
  distinguish between native format and generic format arguments. This is
745
  by design as it simplifies use for operating systems that do not require
746
  disambiguation. An implementation for an operating system where
 
759
  If the native format requires paths for regular files to be formatted
760
  differently from paths for directories, the path shall be treated as a
761
  directory path if its last element is a *directory-separator*, otherwise
762
  it shall be treated as a path to a regular file.
763
 
764
+ [*Note 4*: A path stores a native format pathname
765
+ [[fs.path.native.obs]] and acts as if it also stores a generic format
766
  pathname, related as given below. The implementation may generate the
767
  generic format pathname based on the native format pathname (and
768
  possibly other information) when requested. — *end note*]
769
 
770
  When a path is constructed from or is assigned a single representation
 
777
  as appropriate) if any such value does so; *q* is otherwise unspecified.
778
 
779
  [*Note 5*: If *q* is the result of converting any path at all, it is
780
  the result of converting *p*. — *end note*]
781
 
782
+ ##### Type and encoding conversions <a id="fs.path.type.cvt">[[fs.path.type.cvt]]</a>
783
+
784
+ The *native encoding* of an ordinary character string is the operating
785
+ system dependent current encoding for pathnames [[fs.class.path]]. The
786
+ *native encoding* for wide character strings is the
787
+ implementation-defined execution wide-character set encoding
788
+ [[lex.charset]].
789
 
790
  For member function arguments that take character sequences representing
791
  paths and for member functions returning strings, value type and
792
  encoding conversion is performed if the value type of the argument or
793
  return value differs from `path::value_type`. For the argument or return
794
  value, the method of conversion and the encoding to be converted to is
795
  determined by its value type:
796
 
797
+ - `char`: The encoding is the native ordinary encoding. The method of
798
+ conversion, if any, is operating system dependent. \[*Note 6*: For
799
+ POSIX-based operating systems `path::value_type` is `char` so no
800
+ conversion from `char` value type arguments or to `char` value type
801
+ return values is performed. For Windows-based operating systems, the
802
+ native ordinary encoding is determined by calling a Windows API
 
803
  function. — *end note*] \[*Note 7*: This results in behavior
804
  identical to other C and C++ standard library functions that perform
805
+ file operations using ordinary character strings to identify paths.
806
  Changing this behavior would be surprising and error
807
  prone. — *end note*]
808
+ - `wchar_t`: The encoding is the native wide encoding. The method of
809
+ conversion is unspecified. \[*Note 8*: For Windows-based operating
810
+ systems `path::value_type` is `wchar_t` so no conversion from
811
+ `wchar_t` value type arguments or to `wchar_t` value type return
812
+ values is performed. — *end note*]
813
+ - `char8_t`: The encoding is UTF-8. The method of conversion is
814
+ unspecified.
815
  - `char16_t`: The encoding is UTF-16. The method of conversion is
816
  unspecified.
817
  - `char32_t`: The encoding is UTF-32. The method of conversion is
818
  unspecified.
819
 
820
  If the encoding being converted to has no representation for source
821
  characters, the resulting converted characters, if any, are unspecified.
822
  Implementations should not modify member function arguments if already
823
  of type `path::value_type`.
824
 
825
+ #### Requirements <a id="fs.path.req">[[fs.path.req]]</a>
826
 
827
+ In addition to the requirements [[fs.req]], function template parameters
828
+ named `Source` shall be one of:
829
 
830
  - `basic_string<EcharT, traits, Allocator>`. A function argument
831
  `const Source&` `source` shall have an effective range
832
  \[`source.begin()`, `source.end()`).
833
  - `basic_string_view<EcharT, traits>`. A function argument
834
  `const Source&` `source` shall have an effective range
835
  \[`source.begin()`, `source.end()`).
836
+ - A type meeting the *Cpp17InputIterator* requirements that iterates
837
+ over a NTCTS. The value type shall be an encoded character type. A
838
+ function argument `const Source&` `source` shall have an effective
839
+ range \[`source`, `end`) where `end` is the first iterator value with
840
+ an element value equal to `iterator_traits<Source>::value_type()`.
841
  - A character array that after array-to-pointer decay results in a
842
  pointer to the start of a NTCTS. The value type shall be an encoded
843
  character type. A function argument `const Source&` `source` shall
844
  have an effective range \[`source`, `end`) where `end` is the first
845
  iterator value with an element value equal to
846
  `iterator_traits<decay_t<Source>>::value_type()`.
847
 
848
  Functions taking template parameters named `Source` shall not
849
+ participate in overload resolution unless `Source` denotes a type other
850
+ than `path`, and either
851
 
852
  - `Source` is a specialization of `basic_string` or `basic_string_view`,
853
  or
854
  - the *qualified-id* `iterator_traits<decay_t<Source>>::value_type` is
855
+ valid and denotes a possibly `const` encoded character type
856
+ [[temp.deduct]].
857
 
858
+ [*Note 1*: See path conversions [[fs.path.cvt]] for how the value types
859
+ above and their encodings convert to `path::value_type` and its
860
  encoding. — *end note*]
861
 
862
  Arguments of type `Source` shall not be null pointers.
863
 
864
+ #### Members <a id="fs.path.member">[[fs.path.member]]</a>
865
 
866
+ ##### Constructors <a id="fs.path.construct">[[fs.path.construct]]</a>
867
 
868
  ``` cpp
869
  path() noexcept;
870
  ```
871
 
872
+ *Ensures:* `empty() == true`.
 
 
873
 
874
  ``` cpp
875
  path(const path& p);
876
  path(path&& p) noexcept;
877
  ```
 
884
  ``` cpp
885
  path(string_type&& source, format fmt = auto_format);
886
  ```
887
 
888
  *Effects:* Constructs an object of class `path` for which the pathname
889
+ in the detected-format of `source` has the original value of `source`
890
+ [[fs.path.fmt.cvt]], converting format if required [[fs.path.fmt.cvt]].
891
+ `source` is left in a valid but unspecified state.
 
892
 
893
  ``` cpp
894
  template<class Source>
895
  path(const Source& source, format fmt = auto_format);
896
  template<class InputIterator>
897
  path(InputIterator first, InputIterator last, format fmt = auto_format);
898
  ```
899
 
900
+ *Effects:* Let `s` be the effective range of `source` [[fs.path.req]] or
901
+ the range \[`first`, `last`), with the encoding converted if
902
+ required [[fs.path.cvt]]. Finds the detected-format of `s`
903
+ [[fs.path.fmt.cvt]] and constructs an object of class `path` for which
904
+ the pathname in that format is `s`.
905
 
906
  ``` cpp
907
  template<class Source>
908
  path(const Source& source, const locale& loc, format fmt = auto_format);
909
  template<class InputIterator>
910
  path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
911
  ```
912
 
913
+ *Mandates:* The value type of `Source` and `InputIterator` is `char`.
914
 
915
  *Effects:* Let `s` be the effective range of `source` or the range
916
  \[`first`, `last`), after converting the encoding as follows:
917
 
918
  - If `value_type` is `wchar_t`, converts to the native wide
919
+ encoding [[fs.path.type.cvt]] using the
920
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`.
921
  - Otherwise a conversion is performed using the
922
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`, and then a second
923
+ conversion to the current ordinary encoding.
924
 
925
+ Finds the detected-format of `s` [[fs.path.fmt.cvt]] and constructs an
926
+ object of class `path` for which the pathname in that format is `s`.
927
 
928
  [*Example 1*:
929
 
930
  A string is to be read from a database that is encoded in ISO/IEC
931
  8859-1, and used to create a directory:
 
939
  ```
940
 
941
  For POSIX-based operating systems, the path is constructed by first
942
  using `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string`
943
  to a wide character string in the native wide
944
+ encoding [[fs.path.type.cvt]]. The resulting wide string is then
945
+ converted to an ordinary character pathname string in the current native
946
+ ordinary encoding. If the native wide encoding is UTF-16 or UTF-32, and
947
+ the current native ordinary encoding is UTF-8, all of the characters in
948
  the ISO/IEC 8859-1 character set will be converted to their Unicode
949
+ representation, but for other native ordinary encodings some characters
950
  may have no representation.
951
 
952
  For Windows-based operating systems, the path is constructed by using
953
  `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string` to a
954
  UTF-16 encoded wide character pathname string. All of the characters in
955
  the ISO/IEC 8859-1 character set will be converted to their Unicode
956
  representation.
957
 
958
  — *end example*]
959
 
960
+ ##### Assignments <a id="fs.path.assign">[[fs.path.assign]]</a>
961
 
962
  ``` cpp
963
  path& operator=(const path& p);
964
  ```
965
 
 
999
  path& assign(const Source& source);
1000
  template<class InputIterator>
1001
  path& assign(InputIterator first, InputIterator last);
1002
  ```
1003
 
1004
+ *Effects:* Let `s` be the effective range of `source` [[fs.path.req]] or
1005
+ the range \[`first`, `last`), with the encoding converted if
1006
+ required [[fs.path.cvt]]. Finds the detected-format of `s`
1007
+ [[fs.path.fmt.cvt]] and sets the pathname in that format to `s`.
1008
 
1009
  *Returns:* `*this`.
1010
 
1011
+ ##### Appends <a id="fs.path.append">[[fs.path.append]]</a>
1012
 
1013
  The append operations use `operator/=` to denote their semantic effect
1014
  of appending *preferred-separator* when needed.
1015
 
1016
  ``` cpp
 
1033
  pathname.
1034
 
1035
  [*Example 2*:
1036
 
1037
  Even if `//host` is interpreted as a *root-name*, both of the paths
1038
+ `path("//host")/"foo"` and `path("//host/")/"foo"` equal `"//host/foo"`
1039
+ (although the former might use backslash as the preferred separator).
1040
 
1041
  Expression examples:
1042
 
1043
  ``` cpp
1044
  // On POSIX,
1045
+ path("foo") /= path(""); // yields path("foo/")
1046
+ path("foo") /= path("/bar"); // yields path("/bar")
 
1047
 
1048
  // On Windows,
1049
+ path("foo") /= path(""); // yields path("foo\{")}
1050
+ path("foo") /= path("/bar"); // yields path("/bar")
1051
+ path("foo") /= path("c:/bar"); // yields path("c:/bar")
1052
+ path("foo") /= path("c:"); // yields path("c:")
1053
+ path("c:") /= path(""); // yields path("c:")
1054
+ path("c:foo") /= path("/bar"); // yields path("c:/bar")
1055
+ path("c:foo") /= path("c:bar"); // yields path("c:foo\{bar")}
1056
  ```
1057
 
1058
  — *end example*]
1059
 
1060
  *Returns:* `*this`.
 
1073
  path& append(InputIterator first, InputIterator last);
1074
  ```
1075
 
1076
  *Effects:* Equivalent to: `return operator/=(path(first, last));`
1077
 
1078
+ ##### Concatenation <a id="fs.path.concat">[[fs.path.concat]]</a>
1079
 
1080
  ``` cpp
1081
  path& operator+=(const path& x);
1082
  path& operator+=(const string_type& x);
1083
  path& operator+=(basic_string_view<value_type> x);
1084
  path& operator+=(const value_type* x);
 
1085
  template<class Source>
1086
  path& operator+=(const Source& x);
 
 
1087
  template<class Source>
1088
  path& concat(const Source& x);
1089
  ```
1090
 
1091
  *Effects:* Appends `path(x).native()` to the pathname in the native
 
1094
  [*Note 2*: This directly manipulates the value of `native()` and may
1095
  not be portable between operating systems. — *end note*]
1096
 
1097
  *Returns:* `*this`.
1098
 
1099
+ ``` cpp
1100
+ path& operator+=(value_type x);
1101
+ template<class EcharT>
1102
+ path& operator+=(EcharT x);
1103
+ ```
1104
+
1105
+ *Effects:* Equivalent to: `return *this += basic_string_view(&x, 1);`
1106
+
1107
  ``` cpp
1108
  template<class InputIterator>
1109
  path& concat(InputIterator first, InputIterator last);
1110
  ```
1111
 
1112
+ *Effects:* Equivalent to: `return *this += path(first, last);`
1113
 
1114
+ ##### Modifiers <a id="fs.path.modifiers">[[fs.path.modifiers]]</a>
1115
 
1116
  ``` cpp
1117
  void clear() noexcept;
1118
  ```
1119
 
1120
+ *Ensures:* `empty() == true`.
1121
 
1122
  ``` cpp
1123
  path& make_preferred();
1124
  ```
1125
 
 
1157
 
1158
  ``` cpp
1159
  path& remove_filename();
1160
  ```
1161
 
 
 
1162
  *Effects:* Remove the generic format pathname of `filename()` from the
1163
  generic format pathname.
1164
 
1165
+ *Ensures:* `!has_filename()`.
1166
+
1167
  *Returns:* `*this`.
1168
 
1169
  [*Example 4*:
1170
 
1171
  ``` cpp
 
1203
  path& replace_extension(const path& replacement = path());
1204
  ```
1205
 
1206
  *Effects:*
1207
 
1208
+ - Any existing `extension()` [[fs.path.decompose]] is removed from the
1209
+ pathname in the generic format, then
1210
  - If `replacement` is not empty and does not begin with a dot character,
1211
  a dot character is appended to the pathname in the generic format,
1212
  then
1213
  - `operator+=(replacement);`.
1214
 
 
1220
 
1221
  *Effects:* Swaps the contents (in all formats) of the two paths.
1222
 
1223
  *Complexity:* Constant time.
1224
 
1225
+ ##### Native format observers <a id="fs.path.native.obs">[[fs.path.native.obs]]</a>
1226
 
1227
  The string returned by all native format observers is in the native
1228
+ pathname format [[fs.class.path]].
1229
 
1230
  ``` cpp
1231
  const string_type& native() const noexcept;
1232
  ```
1233
 
 
1235
 
1236
  ``` cpp
1237
  const value_type* c_str() const noexcept;
1238
  ```
1239
 
1240
+ *Effects:* Equivalent to: `return native().c_str();`
1241
 
1242
  ``` cpp
1243
  operator string_type() const;
1244
  ```
1245
 
 
1263
  [[fs.path.cvt]].
1264
 
1265
  ``` cpp
1266
  std::string string() const;
1267
  std::wstring wstring() const;
1268
+ std::u8string u8string() const;
1269
  std::u16string u16string() const;
1270
  std::u32string u32string() const;
1271
  ```
1272
 
1273
+ *Returns:* `native()`.
1274
 
1275
  *Remarks:* Conversion, if any, is performed as specified by
1276
+ [[fs.path.cvt]].
 
1277
 
1278
+ ##### Generic format observers <a id="fs.path.generic.obs">[[fs.path.generic.obs]]</a>
1279
 
1280
  Generic format observer functions return strings formatted according to
1281
+ the generic pathname format [[fs.path.generic]]. A single slash (`'/'`)
1282
+ character is used as the *directory-separator*.
1283
 
1284
  [*Example 1*:
1285
 
1286
  On an operating system that uses backslash as its *preferred-separator*,
1287
 
 
1307
  [[fs.path.cvt]].
1308
 
1309
  ``` cpp
1310
  std::string generic_string() const;
1311
  std::wstring generic_wstring() const;
1312
+ std::u8string generic_u8string() const;
1313
  std::u16string generic_u16string() const;
1314
  std::u32string generic_u32string() const;
1315
  ```
1316
 
1317
  *Returns:* The pathname in the generic format.
1318
 
1319
+ *Remarks:* Conversion, if any, is specified by  [[fs.path.cvt]].
 
1320
 
1321
+ ##### Compare <a id="fs.path.compare">[[fs.path.compare]]</a>
1322
 
1323
  ``` cpp
1324
  int compare(const path& p) const noexcept;
1325
  ```
1326
 
1327
  *Returns:*
1328
 
1329
+ - Let `rootNameComparison` be the result of
1330
+ `this->root_name().native().compare(p.root_name().native())`. If
1331
+ `rootNameComparison` is not `0`, `rootNameComparison`.
1332
+ - Otherwise, if `!this->has_root_directory()` and
1333
+ `p.has_root_directory()`, a value less than `0`.
1334
+ - Otherwise, if `this->has_root_directory()` and
1335
+ `!p.has_root_directory()`, a value greater than `0`.
1336
+ - Otherwise, if `native()` for the elements of `this->relative_path()`
1337
+ are lexicographically less than `native()` for the elements of
1338
+ `p.relative_path()`, a value less than `0`.
1339
+ - Otherwise, if `native()` for the elements of `this->relative_path()`
1340
+ are lexicographically greater than `native()` for the elements of
1341
+ `p.relative_path()`, a value greater than `0`.
1342
+ - Otherwise, `0`.
1343
 
1344
  ``` cpp
1345
+ int compare(const string_type& s) const;
1346
  int compare(basic_string_view<value_type> s) const;
1347
+ int compare(const value_type* s) const;
1348
  ```
1349
 
1350
+ *Effects:* Equivalent to: `return compare(path(s));`
1351
 
1352
+ ##### Decomposition <a id="fs.path.decompose">[[fs.path.decompose]]</a>
 
 
 
 
 
 
1353
 
1354
  ``` cpp
1355
  path root_name() const;
1356
  ```
1357
 
 
1374
  ``` cpp
1375
  path relative_path() const;
1376
  ```
1377
 
1378
  *Returns:* A `path` composed from the pathname in the generic format, if
1379
+ `empty()` is `false`, beginning with the first *filename* after
1380
+ `root_path()`. Otherwise, `path()`.
1381
 
1382
  ``` cpp
1383
  path parent_path() const;
1384
  ```
1385
 
1386
+ *Returns:* `*this` if `has_relative_path()` is `false`, otherwise a path
1387
+ whose generic format pathname is the longest prefix of the generic
1388
+ format pathname of `*this` that produces one fewer element in its
1389
+ iteration.
1390
 
1391
  ``` cpp
1392
  path filename() const;
1393
  ```
1394
 
 
1435
 
1436
  ``` cpp
1437
  path extension() const;
1438
  ```
1439
 
1440
+ *Returns:* A path whose pathname in the generic format is the suffix of
1441
  `filename()` not included in `stem()`.
1442
 
1443
  [*Example 8*:
1444
 
1445
  ``` cpp
 
1458
 
1459
  [*Note 5*: On non-POSIX operating systems, for a path `p`, it may not
1460
  be the case that `p.stem() + p.extension() == p.filename()`, even though
1461
  the generic format pathnames are the same. — *end note*]
1462
 
1463
+ ##### Query <a id="fs.path.query">[[fs.path.query]]</a>
1464
 
1465
  ``` cpp
1466
+ [[nodiscard]] bool empty() const noexcept;
1467
  ```
1468
 
1469
+ *Returns:* `true` if the pathname in the generic format is empty,
1470
+ otherwise `false`.
1471
 
1472
  ``` cpp
1473
  bool has_root_path() const;
1474
  ```
1475
 
 
1520
  ``` cpp
1521
  bool is_absolute() const;
1522
  ```
1523
 
1524
  *Returns:* `true` if the pathname in the native format contains an
1525
+ absolute path [[fs.class.path]], otherwise `false`.
1526
 
1527
  [*Example 9*: `path("/").is_absolute()` is `true` for POSIX-based
1528
  operating systems, and `false` for Windows-based operating
1529
  systems. — *end example*]
1530
 
 
1532
  bool is_relative() const;
1533
  ```
1534
 
1535
  *Returns:* `!is_absolute()`.
1536
 
1537
+ ##### Generation <a id="fs.path.gen">[[fs.path.gen]]</a>
1538
 
1539
  ``` cpp
1540
  path lexically_normal() const;
1541
  ```
1542
 
1543
  *Returns:* A path whose pathname in the generic format is the normal
1544
+ form [[fs.path.generic]] of the pathname in the generic format of
1545
  `*this`.
1546
 
1547
  [*Example 10*:
1548
 
1549
  ``` cpp
 
1560
  ``` cpp
1561
  path lexically_relative(const path& base) const;
1562
  ```
1563
 
1564
  *Returns:* `*this` made relative to `base`. Does not
1565
+ resolve [[fs.class.path]] symlinks. Does not first
1566
+ normalize [[fs.path.generic]] `*this` or `base`.
1567
+
1568
+ *Effects:* If:
1569
+
1570
+ - `root_name() != base.root_name()` is `true`, or
1571
+ - `is_absolute() != base.is_absolute()` is `true`, or
1572
+ - `!has_root_directory() && base.has_root_directory()` is `true`, or
1573
+ - any *filename* in `relative_path()` or `base.relative_path()` can be
1574
+ interpreted as a *root-name*,
1575
+
1576
+ returns `path()`.
1577
+
1578
+ [*Note 6*: On a POSIX implementation, no *filename* in a
1579
+ *relative-path* is acceptable as a *root-name*. — *end note*]
1580
+
1581
+ Determines the first mismatched element of `*this` and `base` as if by:
1582
 
1583
  ``` cpp
1584
  auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
1585
  ```
1586
 
1587
  Then,
1588
 
1589
  - if `a == end()` and `b == base.end()`, returns `path(".")`; otherwise
1590
  - let `n` be the number of *filename* elements in \[`b`, `base.end()`)
1591
+ that are not dot or dot-dot or empty, minus the number that are
1592
+ dot-dot. If `n<0,` returns `path()`; otherwise
1593
+ - if `n == 0` and `(a == end() || a->empty())`, returns `path(".")`;
1594
+ otherwise
1595
  - returns an object of class `path` that is default-constructed,
1596
  followed by
1597
  - application of `operator/=(path(".."))` `n` times, and then
1598
  - application of `operator/=` for each element in \[`a`, `end()`).
1599
 
 
1612
  *directory-separator* characters will be backslashes rather than
1613
  slashes, but that does not affect `path` equality.
1614
 
1615
  — *end example*]
1616
 
1617
+ [*Note 7*: If symlink following semantics are desired, use the
1618
  operational function `relative()`. — *end note*]
1619
 
1620
+ [*Note 8*: If normalization [[fs.path.generic]] is needed to ensure
1621
+ consistent matching of elements, apply `lexically_normal()` to `*this`,
1622
+ `base`, or both. — *end note*]
1623
 
1624
  ``` cpp
1625
  path lexically_proximate(const path& base) const;
1626
  ```
1627
 
1628
  *Returns:* If the value of `lexically_relative(base)` is not an empty
1629
  path, return it. Otherwise return `*this`.
1630
 
1631
+ [*Note 9*: If symlink following semantics are desired, use the
1632
  operational function `proximate()`. — *end note*]
1633
 
1634
+ [*Note 10*: If normalization [[fs.path.generic]] is needed to ensure
1635
+ consistent matching of elements, apply `lexically_normal()` to `*this`,
1636
+ `base`, or both. — *end note*]
1637
 
1638
+ #### Iterators <a id="fs.path.itr">[[fs.path.itr]]</a>
1639
 
1640
  Path iterators iterate over the elements of the pathname in the generic
1641
+ format [[fs.path.generic]].
1642
 
1643
+ A `path::iterator` is a constant iterator meeting all the requirements
1644
+ of a bidirectional iterator [[bidirectional.iterators]] except that, for
1645
+ dereferenceable iterators `a` and `b` of type `path::iterator` with
1646
+ `a == b`, there is no requirement that `*a` and `*b` are bound to the
1647
+ same object. Its `value_type` is `path`.
1648
 
1649
  Calling any non-const member function of a `path` object invalidates all
1650
  iterators referring to elements of that object.
1651
 
1652
  For the elements of the pathname in the generic format, the forward
 
1673
  iterator end() const;
1674
  ```
1675
 
1676
  *Returns:* The end iterator.
1677
 
1678
+ #### Inserter and extractor <a id="fs.path.io">[[fs.path.io]]</a>
1679
+
1680
+ ``` cpp
1681
+ template<class charT, class traits>
1682
+ friend basic_ostream<charT, traits>&
1683
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
1684
+ ```
1685
+
1686
+ *Effects:* Equivalent to `os << quoted(p.string<charT, traits>())`.
1687
+
1688
+ [*Note 1*: The `quoted` function is described
1689
+ in  [[quoted.manip]]. — *end note*]
1690
+
1691
+ *Returns:* `os`.
1692
+
1693
+ ``` cpp
1694
+ template<class charT, class traits>
1695
+ friend basic_istream<charT, traits>&
1696
+ operator>>(basic_istream<charT, traits>& is, path& p);
1697
+ ```
1698
+
1699
+ *Effects:* Equivalent to:
1700
+
1701
+ ``` cpp
1702
+ basic_string<charT, traits> tmp;
1703
+ is >> quoted(tmp);
1704
+ p = tmp;
1705
+ ```
1706
+
1707
+ *Returns:* `is`.
1708
+
1709
+ #### Non-member functions <a id="fs.path.nonmember">[[fs.path.nonmember]]</a>
1710
 
1711
  ``` cpp
1712
  void swap(path& lhs, path& rhs) noexcept;
1713
  ```
1714
 
1715
+ *Effects:* Equivalent to `lhs.swap(rhs)`.
1716
 
1717
  ``` cpp
1718
  size_t hash_value (const path& p) noexcept;
1719
  ```
1720
 
1721
  *Returns:* A hash value for the path `p`. If for two paths, `p1 == p2`
1722
  then `hash_value(p1) == hash_value(p2)`.
1723
 
1724
  ``` cpp
1725
+ friend bool operator==(const path& lhs, const path& rhs) noexcept;
1726
  ```
1727
 
1728
+ *Returns:* `lhs.compare(rhs) == 0`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1729
 
1730
  [*Note 1*:
1731
 
1732
  Path equality and path equivalence have different semantics.
1733
 
1734
  - Equality is determined by the `path` non-member `operator==`, which
1735
+ considers the two paths’ lexical representations only.
1736
  \[*Example 1*: `path("foo") == "bar"` is never
1737
  `true`. — *end example*]
1738
  - Equivalence is determined by the `equivalent()` non-member function,
1739
+ which determines if two paths resolve [[fs.class.path]] to the same
1740
+ file system entity. \[*Example 2*: `equivalent("foo", "bar")` will be
1741
+ `true` when both paths resolve to the same file. — *end example*]
 
1742
 
1743
  Programmers wishing to determine if two paths are “the same” must decide
1744
  if “the same” means “the same representation” or “resolve to the same
1745
  actual file”, and choose the appropriate function accordingly.
1746
 
1747
  — *end note*]
1748
 
1749
  ``` cpp
1750
+ friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept;
1751
  ```
1752
 
1753
+ *Returns:* `lhs.compare(rhs) <=> 0`.
1754
 
1755
  ``` cpp
1756
+ friend path operator/ (const path& lhs, const path& rhs);
1757
  ```
1758
 
1759
  *Effects:* Equivalent to: `return path(lhs) /= rhs;`
1760
 
1761
+ ### Class `filesystem_error` <a id="fs.class.filesystem.error">[[fs.class.filesystem.error]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1762
 
1763
  ``` cpp
1764
  namespace std::filesystem {
1765
  class filesystem_error : public system_error {
1766
  public:
 
1776
  };
1777
  }
1778
  ```
1779
 
1780
  The class `filesystem_error` defines the type of objects thrown as
1781
+ exceptions to report file system errors from functions described in
1782
+ subclause  [[filesystems]].
1783
 
1784
+ #### Members <a id="fs.filesystem.error.members">[[fs.filesystem.error.members]]</a>
1785
 
1786
  Constructors are provided that store zero, one, or two paths associated
1787
  with an error.
1788
 
1789
  ``` cpp
1790
  filesystem_error(const string& what_arg, error_code ec);
1791
  ```
1792
 
1793
+ *Ensures:*
 
1794
 
1795
+ - `code() == ec`,
1796
+ - `path1().empty() == true`,
1797
+ - `path2().empty() == true`, and
1798
+ - `string_view(what()).find(what_arg.c_str())` `!= string_view::npos`.
 
 
 
 
1799
 
1800
  ``` cpp
1801
  filesystem_error(const string& what_arg, const path& p1, error_code ec);
1802
  ```
1803
 
1804
+ *Ensures:*
 
1805
 
1806
+ - `code() == ec`,
1807
+ - `path1()` returns a reference to the stored copy of `p1`,
1808
+ - `path2().empty() == true`, and
1809
+ - `string_view(what()).find(what_arg.c_str())` `!= string_view::npos`.
 
 
 
 
1810
 
1811
  ``` cpp
1812
  filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec);
1813
  ```
1814
 
1815
+ *Ensures:*
 
1816
 
1817
+ - `code() == ec`,
1818
+ - `path1()` returns a reference to the stored copy of `p1`,
1819
+ - `path2()` returns a reference to the stored copy of `p2`, and
1820
+ - `string_view(what()).find(what_arg.c_str())` `!= string_view::npos`.
 
 
 
 
1821
 
1822
  ``` cpp
1823
  const path& path1() const noexcept;
1824
  ```
1825
 
 
1835
 
1836
  ``` cpp
1837
  const char* what() const noexcept override;
1838
  ```
1839
 
1840
+ *Returns:* An NTBS that incorporates the `what_arg` argument supplied to
1841
+ the constructor. The exact format is unspecified. Implementations should
1842
+ include the `system_error::what()` string and the pathnames of `path1`
1843
+ and `path2` in the native format in the returned string.
1844
 
1845
  ### Enumerations <a id="fs.enum">[[fs.enum]]</a>
1846
 
1847
  #### Enum `path::format` <a id="fs.enum.path.format">[[fs.enum.path.format]]</a>
1848
 
1849
  This enum specifies constants used to identify the format of the
1850
+ character sequence, with the meanings listed in [[fs.enum.path.format]].
 
1851
 
1852
  [*Note 1*: For POSIX-based systems, native and generic formats are
1853
  equivalent and the character sequence should always be interpreted in
1854
  the same way. — *end note*]
1855
 
1856
+ #### Enum class `file_type` <a id="fs.enum.file.type">[[fs.enum.file.type]]</a>
1857
 
1858
  This enum class specifies constants used to identify file types, with
1859
+ the meanings listed in [[fs.enum.file.type]]. The values of the
1860
+ constants are distinct.
1861
 
1862
  [*Note 1*: The file not being found is not considered an error while
1863
  determining the type of a file. — *end note*]
1864
 
1865
  #### Enum class `copy_options` <a id="fs.enum.copy.opts">[[fs.enum.copy.opts]]</a>
1866
 
1867
+ The `enum class` type `copy_options` is a bitmask type [[bitmask.types]]
1868
+ that specifies bitmask constants used to control the semantics of copy
1869
+ operations. The constants are specified in option groups with the
1870
+ meanings listed in [[fs.enum.copy.opts]]. The constant `none` represents
1871
+ the empty bitmask, and is shown in each option group for purposes of
1872
  exposition; implementations shall provide only a single definition.
1873
+ Every other constant in the table represents a distinct bitmask element.
1874
 
1875
+ **Table: Enum class `copy_options`** <a id="fs.enum.copy.opts">[fs.enum.copy.opts]</a>
1876
 
1877
  | Constant | Meaning |
1878
  | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
1879
  | `none` | (Default) Error; file already exists. |
1880
  | `skip_existing` | Do not overwrite existing file, do not report an error. |
 
1888
  | `create_hard_links` | Make hard links instead of copies of files. |
1889
 
1890
 
1891
  #### Enum class `perms` <a id="fs.enum.perms">[[fs.enum.perms]]</a>
1892
 
1893
+ The `enum class` type `perms` is a bitmask type [[bitmask.types]] that
1894
+ specifies bitmask constants used to identify file permissions, with the
1895
+ meanings listed in [[fs.enum.perms]].
1896
 
1897
+ **Table: Enum class `perms`** <a id="fs.enum.perms">[fs.enum.perms]</a>
1898
 
1899
  | Name | Value (octal) | POSIX macro | Definition or notes |
1900
  | -------------- | ------------- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
1901
  | `none` | `0` | | There are no permissions set for the file. |
1902
  | `owner_read` | `0400` | `S_IRUSR` | Read permission, owner |
 
1919
  | `unknown` | `0xFFFF` | | The permissions are not known, such as when a `file_status` object is created without specifying the permissions |
1920
 
1921
 
1922
  #### Enum class `perm_options` <a id="fs.enum.perm.opts">[[fs.enum.perm.opts]]</a>
1923
 
1924
+ The `enum class` type `perm_options` is a bitmask type [[bitmask.types]]
1925
+ that specifies bitmask constants used to control the semantics of
1926
+ permissions operations, with the meanings listed in
1927
+ [[fs.enum.perm.opts]]. The bitmask constants are bitmask elements. In
1928
+ [[fs.enum.perm.opts]] `perm` denotes a value of type `perms` passed to
1929
+ `permissions`.
1930
 
1931
+ **Table: Enum class `perm_options`** <a id="fs.enum.perm.opts">[fs.enum.perm.opts]</a>
1932
 
1933
  | Name | Meaning |
1934
+ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
1935
  | `replace` | `permissions` shall replace the file's permission bits with `perm` |
1936
+ | `add` | `permissions` shall replace the file's permission bits with the bitwise \logop{OR} of `perm` and the file's current permission bits. |
1937
+ | `remove` | `permissions` shall replace the file's permission bits with the bitwise \logop{AND} of the complement of `perm` and the file's current permission bits. |
1938
  | `nofollow` | `permissions` shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. |
1939
 
1940
 
1941
  #### Enum class `directory_options` <a id="fs.enum.dir.opts">[[fs.enum.dir.opts]]</a>
1942
 
1943
+ The `enum class` type `directory_options` is a bitmask type
1944
+ [[bitmask.types]] that specifies bitmask constants used to identify
1945
+ directory traversal options, with the meanings listed in
1946
+ [[fs.enum.dir.opts]]. The constant `none` represents the empty bitmask;
1947
+ every other constant in the table represents a distinct bitmask element.
1948
 
1949
+ **Table: Enum class `directory_options`** <a id="fs.enum.dir.opts">[fs.enum.dir.opts]</a>
1950
 
1951
  | Name | Meaning |
1952
  | -------------------------- | ------------------------------------------------------------------ |
1953
  | `none` | (Default) Skip directory symlinks, permission denied is an error. |
1954
  | `follow_directory_symlink` | Follow rather than skip directory symlinks. |
1955
  | `skip_permission_denied` | Skip directories that would otherwise result in permission denied. |
1956
 
1957
 
1958
+ ### Class `file_status` <a id="fs.class.file.status">[[fs.class.file.status]]</a>
1959
 
1960
  ``` cpp
1961
  namespace std::filesystem {
1962
  class file_status {
1963
  public:
1964
+ // [fs.file.status.cons], constructors and destructor
1965
  file_status() noexcept : file_status(file_type::none) {}
1966
  explicit file_status(file_type ft,
1967
  perms prms = perms::unknown) noexcept;
1968
  file_status(const file_status&) noexcept = default;
1969
  file_status(file_status&&) noexcept = default;
1970
  ~file_status();
1971
 
1972
+ // assignments
1973
  file_status& operator=(const file_status&) noexcept = default;
1974
  file_status& operator=(file_status&&) noexcept = default;
1975
 
1976
+ // [fs.file.status.mods], modifiers
1977
  void type(file_type ft) noexcept;
1978
  void permissions(perms prms) noexcept;
1979
 
1980
+ // [fs.file.status.obs], observers
1981
  file_type type() const noexcept;
1982
  perms permissions() const noexcept;
1983
+
1984
+ friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept
1985
+ { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); }
1986
  };
1987
  }
1988
  ```
1989
 
1990
+ #### Constructors <a id="fs.file.status.cons">[[fs.file.status.cons]]</a>
1991
 
1992
  ``` cpp
1993
  explicit file_status(file_type ft, perms prms = perms::unknown) noexcept;
1994
  ```
1995
 
1996
+ *Ensures:* `type() == ft` and `permissions() == prms`.
1997
 
1998
+ #### Observers <a id="fs.file.status.obs">[[fs.file.status.obs]]</a>
1999
 
2000
  ``` cpp
2001
  file_type type() const noexcept;
2002
  ```
2003
 
 
2011
 
2012
  *Returns:* The value of `permissions()` specified by the postconditions
2013
  of the most recent call to a constructor, `operator=`, or
2014
  `permissions(perms)` function.
2015
 
2016
+ #### Modifiers <a id="fs.file.status.mods">[[fs.file.status.mods]]</a>
2017
 
2018
  ``` cpp
2019
  void type(file_type ft) noexcept;
2020
  ```
2021
 
2022
+ *Ensures:* `type() == ft`.
2023
 
2024
  ``` cpp
2025
  void permissions(perms prms) noexcept;
2026
  ```
2027
 
2028
+ *Ensures:* `permissions() == prms`.
2029
 
2030
+ ### Class `directory_entry` <a id="fs.class.directory.entry">[[fs.class.directory.entry]]</a>
2031
 
2032
  ``` cpp
2033
  namespace std::filesystem {
2034
  class directory_entry {
2035
  public:
2036
  // [fs.dir.entry.cons], constructors and destructor
2037
  directory_entry() noexcept = default;
2038
  directory_entry(const directory_entry&) = default;
2039
  directory_entry(directory_entry&&) noexcept = default;
2040
+ explicit directory_entry(const filesystem::path& p);
2041
+ directory_entry(const filesystem::path& p, error_code& ec);
2042
  ~directory_entry();
2043
 
2044
+ // assignments
2045
  directory_entry& operator=(const directory_entry&) = default;
2046
  directory_entry& operator=(directory_entry&&) noexcept = default;
2047
 
2048
  // [fs.dir.entry.mods], modifiers
2049
+ void assign(const filesystem::path& p);
2050
+ void assign(const filesystem::path& p, error_code& ec);
2051
+ void replace_filename(const filesystem::path& p);
2052
+ void replace_filename(const filesystem::path& p, error_code& ec);
2053
  void refresh();
2054
  void refresh(error_code& ec) noexcept;
2055
 
2056
  // [fs.dir.entry.obs], observers
2057
+ const filesystem::path& path() const noexcept;
2058
+ operator const filesystem::path&() const noexcept;
2059
  bool exists() const;
2060
  bool exists(error_code& ec) const noexcept;
2061
  bool is_block_file() const;
2062
  bool is_block_file(error_code& ec) const noexcept;
2063
  bool is_character_file() const;
 
2083
  file_status status() const;
2084
  file_status status(error_code& ec) const noexcept;
2085
  file_status symlink_status() const;
2086
  file_status symlink_status(error_code& ec) const noexcept;
2087
 
 
2088
  bool operator==(const directory_entry& rhs) const noexcept;
2089
+ strong_ordering operator<=>(const directory_entry& rhs) const noexcept;
 
 
 
2090
 
2091
  private:
2092
+ filesystem::path pathobject; // exposition only
2093
  friend class directory_iterator; // exposition only
2094
  };
2095
  }
2096
  ```
2097
 
2098
  A `directory_entry` object stores a `path` object and may store
2099
  additional objects for file attributes such as hard link count, status,
2100
  symlink status, file size, and last write time.
2101
 
2102
+ Implementations should store such additional file attributes during
2103
+ directory iteration if their values are available and storing the values
2104
+ would allow the implementation to eliminate file system accesses by
2105
+ `directory_entry` observer functions [[fs.op.funcs]]. Such stored file
2106
+ attribute values are said to be *cached*.
2107
 
2108
+ [*Note 1*: For purposes of exposition, class `directory_iterator`
2109
+ [[fs.class.directory.iterator]] is shown above as a friend of class
2110
  `directory_entry`. Friendship allows the `directory_iterator`
2111
  implementation to cache already available attribute values directly into
2112
  a `directory_entry` object without the cost of an unneeded call to
2113
  `refresh()`. — *end note*]
2114
 
 
2140
  `std::filesystem::last_write_time` function. The code is portable to any
2141
  implementation, regardless of whether or not it employs caching.
2142
 
2143
  — *end example*]
2144
 
2145
+ #### Constructors <a id="fs.dir.entry.cons">[[fs.dir.entry.cons]]</a>
2146
 
2147
  ``` cpp
2148
+ explicit directory_entry(const filesystem::path& p);
2149
+ directory_entry(const filesystem::path& p, error_code& ec);
2150
  ```
2151
 
2152
+ *Effects:* Calls `refresh()` or `refresh(ec)`, respectively.
 
2153
 
2154
+ *Ensures:* `path() == p` if no error occurs, otherwise
2155
+ `path() == filesystem::path()`.
2156
 
2157
  *Throws:* As specified in  [[fs.err.report]].
2158
 
2159
+ #### Modifiers <a id="fs.dir.entry.mods">[[fs.dir.entry.mods]]</a>
2160
 
2161
  ``` cpp
2162
+ void assign(const filesystem::path& p);
2163
+ void assign(const filesystem::path& p, error_code& ec);
2164
  ```
2165
 
2166
  *Effects:* Equivalent to `pathobject = p`, then `refresh()` or
2167
  `refresh(ec)`, respectively. If an error occurs, the values of any
2168
  cached attributes are unspecified.
2169
 
2170
  *Throws:* As specified in  [[fs.err.report]].
2171
 
2172
  ``` cpp
2173
+ void replace_filename(const filesystem::path& p);
2174
+ void replace_filename(const filesystem::path& p, error_code& ec);
2175
  ```
2176
 
2177
  *Effects:* Equivalent to `pathobject.replace_filename(p)`, then
2178
  `refresh()` or `refresh(ec)`, respectively. If an error occurs, the
2179
  values of any cached attributes are unspecified.
 
2185
  void refresh(error_code& ec) noexcept;
2186
  ```
2187
 
2188
  *Effects:* Stores the current values of any cached attributes of the
2189
  file `p` resolves to. If an error occurs, an error is
2190
+ reported [[fs.err.report]] and the values of any cached attributes are
2191
+ unspecified.
2192
 
2193
  *Throws:* As specified in  [[fs.err.report]].
2194
 
2195
+ [*Note 1*: Implementations of `directory_iterator`
2196
+ [[fs.class.directory.iterator]] are prohibited from directly or
2197
+ indirectly calling the `refresh` function since it must access the
2198
+ external file system, and the objective of caching is to avoid
2199
+ unnecessary file system accesses. — *end note*]
2200
 
2201
+ #### Observers <a id="fs.dir.entry.obs">[[fs.dir.entry.obs]]</a>
2202
 
2203
  Unqualified function names in the *Returns:* elements of the
2204
  `directory_entry` observers described below refer to members of the
2205
  `std::filesystem` namespace.
2206
 
2207
  ``` cpp
2208
+ const filesystem::path& path() const noexcept;
2209
+ operator const filesystem::path&() const noexcept;
2210
  ```
2211
 
2212
  *Returns:* `pathobject`.
2213
 
2214
  ``` cpp
2215
  bool exists() const;
2216
  bool exists(error_code& ec) const noexcept;
2217
  ```
2218
 
2219
+ *Returns:* `exists(this->status())` or `exists(this->status(ec))`,
2220
  respectively.
2221
 
2222
  *Throws:* As specified in  [[fs.err.report]].
2223
 
2224
  ``` cpp
2225
  bool is_block_file() const;
2226
  bool is_block_file(error_code& ec) const noexcept;
2227
  ```
2228
 
2229
  *Returns:* `is_block_file(this->status())` or
2230
+ `is_block_file(this->status(ec))`, respectively.
2231
 
2232
  *Throws:* As specified in  [[fs.err.report]].
2233
 
2234
  ``` cpp
2235
  bool is_character_file() const;
2236
  bool is_character_file(error_code& ec) const noexcept;
2237
  ```
2238
 
2239
  *Returns:* `is_character_file(this->status())` or
2240
+ `is_character_file(this->status(ec))`, respectively.
2241
 
2242
  *Throws:* As specified in  [[fs.err.report]].
2243
 
2244
  ``` cpp
2245
  bool is_directory() const;
2246
  bool is_directory(error_code& ec) const noexcept;
2247
  ```
2248
 
2249
  *Returns:* `is_directory(this->status())` or
2250
+ `is_directory(this->status(ec))`, respectively.
2251
 
2252
  *Throws:* As specified in  [[fs.err.report]].
2253
 
2254
  ``` cpp
2255
  bool is_fifo() const;
2256
  bool is_fifo(error_code& ec) const noexcept;
2257
  ```
2258
 
2259
+ *Returns:* `is_fifo(this->status())` or `is_fifo(this->status(ec))`,
2260
  respectively.
2261
 
2262
  *Throws:* As specified in  [[fs.err.report]].
2263
 
2264
  ``` cpp
2265
  bool is_other() const;
2266
  bool is_other(error_code& ec) const noexcept;
2267
  ```
2268
 
2269
+ *Returns:* `is_other(this->status())` or `is_other(this->status(ec))`,
2270
  respectively.
2271
 
2272
  *Throws:* As specified in  [[fs.err.report]].
2273
 
2274
  ``` cpp
2275
  bool is_regular_file() const;
2276
  bool is_regular_file(error_code& ec) const noexcept;
2277
  ```
2278
 
2279
  *Returns:* `is_regular_file(this->status())` or
2280
+ `is_regular_file(this->status(ec))`, respectively.
2281
 
2282
  *Throws:* As specified in  [[fs.err.report]].
2283
 
2284
  ``` cpp
2285
  bool is_socket() const;
2286
  bool is_socket(error_code& ec) const noexcept;
2287
  ```
2288
 
2289
+ *Returns:* `is_socket(this->status())` or `is_socket(this->status(ec))`,
2290
+ respectively.
2291
 
2292
  *Throws:* As specified in  [[fs.err.report]].
2293
 
2294
  ``` cpp
2295
  bool is_symlink() const;
2296
  bool is_symlink(error_code& ec) const noexcept;
2297
  ```
2298
 
2299
  *Returns:* `is_symlink(this->symlink_status())` or
2300
+ `is_symlink(this->symlink_status(ec))`, respectively.
2301
 
2302
  *Throws:* As specified in  [[fs.err.report]].
2303
 
2304
  ``` cpp
2305
  uintmax_t file_size() const;
 
2358
  ```
2359
 
2360
  *Returns:* `pathobject == rhs.pathobject`.
2361
 
2362
  ``` cpp
2363
+ strong_ordering operator<=>(const directory_entry& rhs) const noexcept;
2364
  ```
2365
 
2366
+ *Returns:* `pathobject <=> rhs.pathobject`.
2367
 
2368
+ ### Class `directory_iterator` <a id="fs.class.directory.iterator">[[fs.class.directory.iterator]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2369
 
2370
  An object of type `directory_iterator` provides an iterator for a
2371
  sequence of `directory_entry` elements representing the path and any
2372
+ cached attribute values [[fs.class.directory.entry]] for each file in a
2373
+ directory or in an *implementation-defined* directory-like file type.
2374
 
2375
  [*Note 1*: For iteration into sub-directories, see class
2376
+ `recursive_directory_iterator` [[fs.class.rec.dir.itr]]. — *end note*]
 
2377
 
2378
  ``` cpp
2379
  namespace std::filesystem {
2380
  class directory_iterator {
2381
  public:
 
2387
 
2388
  // [fs.dir.itr.members], member functions
2389
  directory_iterator() noexcept;
2390
  explicit directory_iterator(const path& p);
2391
  directory_iterator(const path& p, directory_options options);
2392
+ directory_iterator(const path& p, error_code& ec);
2393
  directory_iterator(const path& p, directory_options options,
2394
+ error_code& ec);
2395
  directory_iterator(const directory_iterator& rhs);
2396
  directory_iterator(directory_iterator&& rhs) noexcept;
2397
  ~directory_iterator();
2398
 
2399
  directory_iterator& operator=(const directory_iterator& rhs);
2400
  directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2401
 
2402
  const directory_entry& operator*() const;
2403
  const directory_entry* operator->() const;
2404
  directory_iterator& operator++();
2405
+ directory_iterator& increment(error_code& ec);
2406
 
2407
  // other members as required by [input.iterators], input iterators
2408
  };
2409
  }
2410
  ```
2411
 
2412
+ `directory_iterator` meets the *Cpp17InputIterator* requirements
2413
+ [[input.iterators]].
2414
 
2415
  If an iterator of type `directory_iterator` reports an error or is
2416
  advanced past the last directory element, that iterator shall become
2417
  equal to the end iterator value. The `directory_iterator` default
2418
  constructor shall create an iterator equal to the end iterator value,
 
2428
  to a `path` object composed of the directory argument from which the
2429
  iterator was constructed with filename of the directory entry appended
2430
  as if by `operator/=`.
2431
 
2432
  Directory iteration shall not yield directory entries for the current
2433
+ (dot) and parent (dot-dot) directories.
2434
 
2435
  The order of directory entries obtained by dereferencing successive
2436
  increments of a `directory_iterator` is unspecified.
2437
 
2438
  Constructors and non-const `directory_iterator` member functions store
2439
+ the values of any cached attributes [[fs.class.directory.entry]] in the
2440
+ `directory_entry` element returned by `operator*()`.
2441
  `directory_iterator` member functions shall not directly or indirectly
2442
  call any `directory_entry` `refresh` function.
2443
 
2444
  [*Note 2*: The exact mechanism for storing cached attribute values is
2445
  not exposed to users. For exposition, class `directory_iterator` is
2446
+ shown in [[fs.class.directory.entry]] as a friend of class
2447
  `directory_entry`. — *end note*]
2448
 
2449
  [*Note 3*: Programs performing directory iteration may wish to test if
2450
  the path obtained by dereferencing a directory iterator actually exists.
2451
  It could be a symbolic link to a non-existent file. Programs recursively
 
2456
  construction of a `directory_iterator` for the directory, it is
2457
  unspecified whether or not subsequently incrementing the iterator will
2458
  ever result in an iterator referencing the removed or added directory
2459
  entry. See POSIX `readdir_r`. — *end note*]
2460
 
2461
+ #### Members <a id="fs.dir.itr.members">[[fs.dir.itr.members]]</a>
2462
 
2463
  ``` cpp
2464
  directory_iterator() noexcept;
2465
  ```
2466
 
2467
  *Effects:* Constructs the end iterator.
2468
 
2469
  ``` cpp
2470
  explicit directory_iterator(const path& p);
2471
  directory_iterator(const path& p, directory_options options);
2472
+ directory_iterator(const path& p, error_code& ec);
2473
+ directory_iterator(const path& p, directory_options options, error_code& ec);
2474
  ```
2475
 
2476
  *Effects:* For the directory that `p` resolves to, constructs an
2477
  iterator for the first element in a sequence of `directory_entry`
2478
  elements representing the files in the directory, if any; otherwise the
 
2495
  ``` cpp
2496
  directory_iterator(const directory_iterator& rhs);
2497
  directory_iterator(directory_iterator&& rhs) noexcept;
2498
  ```
2499
 
2500
+ *Ensures:* `*this` has the original value of `rhs`.
 
 
2501
 
2502
  ``` cpp
2503
  directory_iterator& operator=(const directory_iterator& rhs);
2504
  directory_iterator& operator=(directory_iterator&& rhs) noexcept;
2505
  ```
2506
 
2507
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2508
  effect.
2509
 
2510
+ *Ensures:* `*this` has the original value of `rhs`.
2511
 
2512
  *Returns:* `*this`.
2513
 
2514
  ``` cpp
2515
  directory_iterator& operator++();
2516
+ directory_iterator& increment(error_code& ec);
2517
  ```
2518
 
2519
  *Effects:* As specified for the prefix increment operation of Input
2520
+ iterators [[input.iterators]].
2521
 
2522
  *Returns:* `*this`.
2523
 
2524
  *Throws:* As specified in  [[fs.err.report]].
2525
 
2526
+ #### Non-member functions <a id="fs.dir.itr.nonmembers">[[fs.dir.itr.nonmembers]]</a>
2527
 
2528
  These functions enable range access for `directory_iterator`.
2529
 
2530
  ``` cpp
2531
  directory_iterator begin(directory_iterator iter) noexcept;
 
2559
  // [fs.rec.dir.itr.members], constructors and destructor
2560
  recursive_directory_iterator() noexcept;
2561
  explicit recursive_directory_iterator(const path& p);
2562
  recursive_directory_iterator(const path& p, directory_options options);
2563
  recursive_directory_iterator(const path& p, directory_options options,
2564
+ error_code& ec);
2565
+ recursive_directory_iterator(const path& p, error_code& ec);
2566
  recursive_directory_iterator(const recursive_directory_iterator& rhs);
2567
  recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2568
  ~recursive_directory_iterator();
2569
 
2570
  // [fs.rec.dir.itr.members], observers
 
2580
  operator=(const recursive_directory_iterator& rhs);
2581
  recursive_directory_iterator&
2582
  operator=(recursive_directory_iterator&& rhs) noexcept;
2583
 
2584
  recursive_directory_iterator& operator++();
2585
+ recursive_directory_iterator& increment(error_code& ec);
2586
 
2587
  void pop();
2588
  void pop(error_code& ec);
2589
  void disable_recursion_pending();
2590
 
 
2601
  `directory_iterator` unless otherwise specified.
2602
 
2603
  [*Note 1*: If the directory structure being iterated over contains
2604
  cycles then the end iterator may be unreachable. — *end note*]
2605
 
2606
+ #### Members <a id="fs.rec.dir.itr.members">[[fs.rec.dir.itr.members]]</a>
2607
 
2608
  ``` cpp
2609
  recursive_directory_iterator() noexcept;
2610
  ```
2611
 
2612
  *Effects:* Constructs the end iterator.
2613
 
2614
  ``` cpp
2615
  explicit recursive_directory_iterator(const path& p);
2616
  recursive_directory_iterator(const path& p, directory_options options);
2617
+ recursive_directory_iterator(const path& p, directory_options options, error_code& ec);
2618
+ recursive_directory_iterator(const path& p, error_code& ec);
2619
  ```
2620
 
2621
+ *Effects:* Constructs an iterator representing the first entry in the
2622
+ directory to which `p` resolves, if any; otherwise, the end iterator.
2623
+ However, if
2624
 
2625
  ``` cpp
2626
  (options & directory_options::skip_permission_denied) != directory_options::none
2627
  ```
2628
 
2629
  and construction encounters an error indicating that permission to
2630
  access `p` is denied, constructs the end iterator and does not report an
2631
  error.
2632
 
2633
+ *Ensures:* `options() == options` for the signatures with a
2634
  `directory_options` argument, otherwise
2635
  `options() == directory_options::none`.
2636
 
2637
  *Throws:* As specified in  [[fs.err.report]].
2638
 
 
2640
  `recursive_directory_iterator(".")` rather than
2641
  `recursive_directory_iterator("")`. — *end note*]
2642
 
2643
  [*Note 2*: By default, `recursive_directory_iterator` does not follow
2644
  directory symlinks. To follow directory symlinks, specify `options` as
2645
+ `directory_options::follow_directory_symlink`. — *end note*]
2646
 
2647
  ``` cpp
2648
  recursive_directory_iterator(const recursive_directory_iterator& rhs);
2649
  ```
2650
 
2651
+ *Ensures:*
 
 
2652
 
2653
  - `options() == rhs.options()`
2654
  - `depth() == rhs.depth()`
2655
  - `recursion_pending() == rhs.recursion_pending()`
2656
 
2657
  ``` cpp
2658
  recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
2659
  ```
2660
 
2661
+ *Ensures:* `options()`, `depth()`, and `recursion_pending()` have the
2662
+ values that `rhs.options()`, `rhs.depth()`, and
 
 
2663
  `rhs.recursion_pending()`, respectively, had before the function call.
2664
 
2665
  ``` cpp
2666
  recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);
2667
  ```
2668
 
2669
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2670
  effect.
2671
 
2672
+ *Ensures:*
2673
 
2674
  - `options() == rhs.options()`
2675
  - `depth() == rhs.depth()`
2676
  - `recursion_pending() == rhs.recursion_pending()`
2677
 
 
2682
  ```
2683
 
2684
  *Effects:* If `*this` and `rhs` are the same object, the member has no
2685
  effect.
2686
 
2687
+ *Ensures:* `options()`, `depth()`, and `recursion_pending()` have the
2688
+ values that `rhs.options()`, `rhs.depth()`, and
2689
  `rhs.recursion_pending()`, respectively, had before the function call.
2690
 
2691
  *Returns:* `*this`.
2692
 
2693
  ``` cpp
 
2720
 
2721
  *Throws:* Nothing.
2722
 
2723
  ``` cpp
2724
  recursive_directory_iterator& operator++();
2725
+ recursive_directory_iterator& increment(error_code& ec);
2726
  ```
2727
 
2728
  *Effects:* As specified for the prefix increment operation of Input
2729
+ iterators [[input.iterators]], except that:
2730
 
2731
  - If there are no more entries at the current depth, then if
2732
  `depth() != 0` iteration over the parent directory resumes; otherwise
2733
  `*this = recursive_directory_iterator()`.
2734
  - Otherwise if
 
2762
  directory currently being iterated over, and continue iteration over the
2763
  parent directory.
2764
 
2765
  *Throws:* As specified in  [[fs.err.report]].
2766
 
2767
+ *Remarks:* Any copies of the previous value of `*this` are no longer
2768
+ required to be dereferenceable nor to be in the domain of `==`.
2769
+
2770
  ``` cpp
2771
  void disable_recursion_pending();
2772
  ```
2773
 
2774
+ *Ensures:* `recursion_pending() == false`.
2775
 
2776
  [*Note 4*: `disable_recursion_pending``()` is used to prevent unwanted
2777
  recursion into a directory. — *end note*]
2778
 
2779
+ #### Non-member functions <a id="fs.rec.dir.itr.nonmembers">[[fs.rec.dir.itr.nonmembers]]</a>
2780
 
2781
  These functions enable use of `recursive_directory_iterator` with
2782
  range-based for statements.
2783
 
2784
  ``` cpp
 
2797
 
2798
  Filesystem operation functions query or modify files, including
2799
  directories, in external storage.
2800
 
2801
  [*Note 1*: Because hardware failures, network failures, file system
2802
+ races [[fs.race.behavior]], and many other kinds of errors occur
2803
  frequently in file system operations, users should be aware that any
2804
  filesystem operation function, no matter how apparently innocuous, may
2805
  encounter an error; see  [[fs.err.report]]. — *end note*]
2806
 
2807
  #### Absolute <a id="fs.op.absolute">[[fs.op.absolute]]</a>
 
2810
  path absolute(const path& p);
2811
  path absolute(const path& p, error_code& ec);
2812
  ```
2813
 
2814
  *Effects:* Composes an absolute path referencing the same file system
2815
+ location as `p` according to the operating system [[fs.conform.os]].
2816
 
2817
  *Returns:* The composed path. The signature with argument `ec` returns
2818
  `path()` if an error occurs.
2819
 
2820
  [*Note 1*: For the returned path, `rp`, `rp.is_absolute()` is `true`
 
2822
 
2823
  *Throws:* As specified in  [[fs.err.report]].
2824
 
2825
  [*Note 2*: To resolve symlinks, or perform other sanitization which
2826
  might require queries to secondary storage, such as hard disks, consider
2827
+ `canonical` [[fs.op.canonical]]. — *end note*]
2828
 
2829
  [*Note 3*: Implementations are strongly encouraged to not query
2830
  secondary storage, and not consider `!exists(p)` an
2831
  error. — *end note*]
2832
 
 
2836
  `GetFullPathNameW`. — *end example*]
2837
 
2838
  #### Canonical <a id="fs.op.canonical">[[fs.op.canonical]]</a>
2839
 
2840
  ``` cpp
2841
+ path canonical(const path& p);
2842
  path canonical(const path& p, error_code& ec);
 
2843
  ```
2844
 
2845
+ *Effects:* Converts `p` to an absolute path that has no symbolic link,
2846
+ dot, or dot-dot elements in its pathname in the generic format.
 
2847
 
2848
  *Returns:* A path that refers to the same file system object as
2849
+ `absolute(p)`. The signature with argument `ec` returns `path()` if an
 
2850
  error occurs.
2851
 
2852
  *Throws:* As specified in  [[fs.err.report]].
2853
 
2854
  *Remarks:* `!exists(p)` is an error.
 
2860
  ```
2861
 
2862
  *Effects:* Equivalent to `copy(from, to, copy_options::none)`.
2863
 
2864
  ``` cpp
2865
+ void copy(const path& from, const path& to, error_code& ec);
2866
  ```
2867
 
2868
  *Effects:* Equivalent to `copy(from, to, copy_options::none, ec)`.
2869
 
2870
  ``` cpp
2871
  void copy(const path& from, const path& to, copy_options options);
2872
  void copy(const path& from, const path& to, copy_options options,
2873
+ error_code& ec);
2874
  ```
2875
 
2876
+ *Preconditions:* At most one element from each option
2877
+ group [[fs.enum.copy.opts]] is set in `options`.
2878
 
2879
  *Effects:* Before the first use of `f` and `t`:
2880
 
2881
  - If
2882
  ``` cpp
 
2897
  `auto t = status(to)`.
2898
 
2899
  Effects are then as follows:
2900
 
2901
  - If `f.type()` or `t.type()` is an implementation-defined file
2902
+ type [[fs.enum.file.type]], then the effects are
2903
  *implementation-defined*.
2904
  - Otherwise, an error is reported as specified in  [[fs.err.report]] if:
2905
+ - `exists(f)` is `false`, or
2906
+ - `equivalent(from, to)` is `true`, or
2907
+ - `is_other(f) || is_other(t)` is `true`, or
2908
+ - `is_directory(f) && is_regular_file(t)` is `true`.
2909
  - Otherwise, if `is_symlink(f)`, then:
2910
  - If `(options & copy_options::skip_symlinks) != copy_options::none`
2911
  then return.
2912
  - Otherwise if
2913
  ``` cpp
 
2927
  `(options & copy_options::create_hard_links) != copy_options::none`,
2928
  then create a hard link to the source file.
2929
  - Otherwise, if `is_directory(t)`, then
2930
  `copy_file(from, to/from.filename(), options)`.
2931
  - Otherwise, `copy_file(from, to, options)`.
2932
+ - Otherwise, if
2933
+ ``` cpp
2934
+ is_directory(f) &&
2935
+ (options & copy_options::create_symlinks) != copy_options::none
2936
+ ```
2937
+
2938
+ then report an error with an `error_code` argument equal to
2939
+ `make_error_code(errc::is_a_directory)`.
2940
  - Otherwise, if
2941
  ``` cpp
2942
  is_directory(f) &&
2943
  ((options & copy_options::recursive) != copy_options::none ||
2944
  options == copy_options::none)
2945
  ```
2946
 
2947
  then:
2948
+ - If `exists(t)` is `false`, then `create_directory(to, from)`.
2949
  - Then, iterate over the files in `from`, as if by
2950
  ``` cpp
2951
  for (const directory_entry& x : directory_iterator(from))
2952
+ copy(x.path(), to/x.path().filename(),
2953
+ options | copy_options::in-recursive-copy);
2954
  ```
2955
+
2956
+ where *`in-recursive-copy`* is a bitmask element of `copy_options`
2957
+ that is not one of the elements in  [[fs.enum.copy.opts]].
2958
  - Otherwise, for the signature with argument `ec`, `ec.clear()`.
2959
  - Otherwise, no effects.
2960
 
2961
  *Throws:* As specified in  [[fs.err.report]].
2962
 
 
3005
  file3
3006
  ```
3007
 
3008
  — *end example*]
3009
 
3010
+ #### Copy file <a id="fs.op.copy.file">[[fs.op.copy.file]]</a>
3011
 
3012
  ``` cpp
3013
  bool copy_file(const path& from, const path& to);
3014
+ bool copy_file(const path& from, const path& to, error_code& ec);
3015
  ```
3016
 
3017
  *Returns:* `copy_file(from, to, copy_options::none)` or
3018
  `copy_file(from, to, copy_options::none, ec)`, respectively.
3019
 
3020
  *Throws:* As specified in  [[fs.err.report]].
3021
 
3022
  ``` cpp
3023
  bool copy_file(const path& from, const path& to, copy_options options);
3024
  bool copy_file(const path& from, const path& to, copy_options options,
3025
+ error_code& ec);
3026
  ```
3027
 
3028
+ *Preconditions:* At most one element from each option
3029
+ group [[fs.enum.copy.opts]] is set in `options`.
3030
 
3031
  *Effects:* As follows:
3032
 
3033
+ - Report an error as specified in  [[fs.err.report]] if:
3034
+ - `is_regular_file(from)` is `false`, or
3035
+ - `exists(to)` is `true` and `is_regular_file(to)` is `false`, or
3036
+ - `exists(to)` is `true` and `equivalent(from, to)` is `true`, or
3037
+ - `exists(to)` is `true` and
 
3038
  ``` cpp
3039
  (options & (copy_options::skip_existing |
3040
  copy_options::overwrite_existing |
3041
  copy_options::update_existing)) == copy_options::none
3042
  ```
3043
  - Otherwise, copy the contents and attributes of the file `from`
3044
  resolves to, to the file `to` resolves to, if:
3045
+ - `exists(to)` is `false`, or
3046
  - `(options & copy_options::overwrite_existing) != copy_options::none`,
3047
  or
3048
  - `(options & copy_options::update_existing) `` `` != copy_options::none`
3049
  and `from` is more recent than `to`, determined as if by use of the
3050
+ `last_write_time` function [[fs.op.last.write.time]].
3051
  - Otherwise, no effects.
3052
 
3053
  *Returns:* `true` if the `from` file was copied, otherwise `false`. The
3054
  signature with argument `ec` returns `false` if an error occurs.
3055
 
3056
  *Throws:* As specified in  [[fs.err.report]].
3057
 
3058
  *Complexity:* At most one direct or indirect invocation of `status(to)`.
3059
 
3060
+ #### Copy symlink <a id="fs.op.copy.symlink">[[fs.op.copy.symlink]]</a>
3061
 
3062
  ``` cpp
3063
  void copy_symlink(const path& existing_symlink, const path& new_symlink);
3064
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
3065
  error_code& ec) noexcept;
 
3071
  respectively, where in each case *`function`* is `create_symlink` or
3072
  `create_directory_symlink` as appropriate.
3073
 
3074
  *Throws:* As specified in  [[fs.err.report]].
3075
 
3076
+ #### Create directories <a id="fs.op.create.directories">[[fs.op.create.directories]]</a>
3077
 
3078
  ``` cpp
3079
  bool create_directories(const path& p);
3080
+ bool create_directories(const path& p, error_code& ec);
3081
  ```
3082
 
3083
+ *Effects:* Calls `create_directory()` for each element of `p` that does
 
 
 
 
 
 
 
 
 
 
3084
  not exist.
3085
 
3086
+ *Returns:* `true` if a new directory was created for the directory `p`
3087
+ resolves to, otherwise `false`.
3088
+
3089
+ *Throws:* As specified in  [[fs.err.report]].
3090
+
3091
+ *Complexity:* 𝑂(n) where *n* is the number of elements of `p`.
3092
+
3093
+ #### Create directory <a id="fs.op.create.directory">[[fs.op.create.directory]]</a>
3094
 
3095
  ``` cpp
3096
  bool create_directory(const path& p);
3097
  bool create_directory(const path& p, error_code& ec) noexcept;
3098
  ```
3099
 
3100
+ *Effects:* Creates the directory `p` resolves to, as if by POSIX `mkdir`
3101
+ with a second argument of `static_cast<int>(perms::all)`. If `mkdir`
3102
+ fails because `p` resolves to an existing directory, no error is
3103
+ reported. Otherwise on failure an error is reported.
3104
 
3105
+ *Returns:* `true` if a new directory was created, otherwise `false`.
 
 
 
3106
 
3107
  *Throws:* As specified in  [[fs.err.report]].
3108
 
3109
  ``` cpp
3110
  bool create_directory(const path& p, const path& existing_p);
3111
  bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
3112
  ```
3113
 
3114
+ *Effects:* Creates the directory `p` resolves to, with attributes copied
3115
+ from directory `existing_p`. The set of attributes copied is operating
3116
+ system dependent. If `mkdir` fails because `p` resolves to an existing
3117
+ directory, no error is reported. Otherwise on failure an error is
3118
+ reported.
3119
 
3120
  [*Note 1*: For POSIX-based operating systems, the attributes are those
3121
  copied by native API `stat(existing_p.c_str(), &attributes_stat)`
3122
  followed by `mkdir(p.c_str(), attributes_stat.st_mode)`. For
3123
  Windows-based operating systems, the attributes are those copied by
3124
  native API
3125
  `CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)`. — *end note*]
3126
 
3127
+ *Returns:* `true` if a new directory was created with attributes copied
3128
+ from directory `existing_p`, otherwise `false`.
 
 
3129
 
3130
  *Throws:* As specified in  [[fs.err.report]].
3131
 
3132
+ #### Create directory symlink <a id="fs.op.create.dir.symlk">[[fs.op.create.dir.symlk]]</a>
3133
 
3134
  ``` cpp
3135
  void create_directory_symlink(const path& to, const path& new_symlink);
3136
  void create_directory_symlink(const path& to, const path& new_symlink,
3137
  error_code& ec) noexcept;
3138
  ```
3139
 
3140
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3141
 
3142
+ *Ensures:* `new_symlink` resolves to a symbolic link file that contains
3143
+ an unspecified representation of `to`.
3144
 
3145
  *Throws:* As specified in  [[fs.err.report]].
3146
 
3147
  [*Note 1*: Some operating systems require symlink creation to identify
3148
  that the link is to a directory. Portable code should use
 
3152
  [*Note 2*: Some operating systems do not support symbolic links at all
3153
  or support them only for regular files. Some file systems (such as the
3154
  FAT file system) do not support symbolic links regardless of the
3155
  operating system. — *end note*]
3156
 
3157
+ #### Create hard link <a id="fs.op.create.hard.lk">[[fs.op.create.hard.lk]]</a>
3158
 
3159
  ``` cpp
3160
  void create_hard_link(const path& to, const path& new_hard_link);
3161
  void create_hard_link(const path& to, const path& new_hard_link,
3162
  error_code& ec) noexcept;
3163
  ```
3164
 
3165
  *Effects:* Establishes the postcondition, as if by POSIX `link()`.
3166
 
3167
+ *Ensures:*
3168
 
3169
  - `exists(to) && exists(new_hard_link) && equivalent(to, new_hard_link)`
3170
  - The contents of the file or directory `to` resolves to are unchanged.
3171
 
3172
  *Throws:* As specified in  [[fs.err.report]].
 
3175
  support them only for regular files. Some file systems (such as the FAT
3176
  file system) do not support hard links regardless of the operating
3177
  system. Some file systems limit the number of links per
3178
  file. — *end note*]
3179
 
3180
+ #### Create symlink <a id="fs.op.create.symlink">[[fs.op.create.symlink]]</a>
3181
 
3182
  ``` cpp
3183
  void create_symlink(const path& to, const path& new_symlink);
3184
  void create_symlink(const path& to, const path& new_symlink,
3185
  error_code& ec) noexcept;
3186
  ```
3187
 
3188
  *Effects:* Establishes the postcondition, as if by POSIX `symlink()`.
3189
 
3190
+ *Ensures:* `new_symlink` resolves to a symbolic link file that contains
3191
+ an unspecified representation of `to`.
3192
 
3193
  *Throws:* As specified in  [[fs.err.report]].
3194
 
3195
  [*Note 1*: Some operating systems do not support symbolic links at all
3196
  or support them only for regular files. Some file systems (such as the
3197
  FAT file system) do not support symbolic links regardless of the
3198
  operating system. — *end note*]
3199
 
3200
+ #### Current path <a id="fs.op.current.path">[[fs.op.current.path]]</a>
3201
 
3202
  ``` cpp
3203
  path current_path();
3204
  path current_path(error_code& ec);
3205
  ```
 
3217
  [*Note 1*: The `current_path()` name was chosen to emphasize that the
3218
  returned value is a path, not just a single directory
3219
  name. — *end note*]
3220
 
3221
  [*Note 2*: The current path as returned by many operating systems is a
3222
+ dangerous global variable. It may be changed unexpectedly by third-party
3223
+ or system library functions, or by another thread. — *end note*]
 
3224
 
3225
  ``` cpp
3226
  void current_path(const path& p);
3227
  void current_path(const path& p, error_code& ec) noexcept;
3228
  ```
3229
 
3230
  *Effects:* Establishes the postcondition, as if by POSIX `chdir()`.
3231
 
3232
+ *Ensures:* `equivalent(p, current_path())`.
3233
 
3234
  *Throws:* As specified in  [[fs.err.report]].
3235
 
3236
  [*Note 3*: The current path for many operating systems is a dangerous
3237
  global state. It may be changed unexpectedly by a third-party or system
 
3242
  ``` cpp
3243
  bool equivalent(const path& p1, const path& p2);
3244
  bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
3245
  ```
3246
 
3247
+ *Returns:* `true`, if `p1` and `p2` resolve to the same file system
3248
+ entity, otherwise `false`. The signature with argument `ec` returns
3249
+ `false` if an error occurs.
 
 
 
 
 
 
 
3250
 
3251
  Two paths are considered to resolve to the same file system entity if
3252
  two candidate entities reside on the same device at the same location.
3253
+
3254
+ [*Note 1*: On POSIX platforms, this is determined as if by the values
3255
+ of the POSIX `stat` class, obtained as if by `stat()` for the two paths,
3256
+ having equal `st_dev` values and equal `st_ino` values. — *end note*]
3257
+
3258
+ *Remarks:* `!exists(p1) || !exists(p2)` is an error.
3259
 
3260
  *Throws:* As specified in  [[fs.err.report]].
3261
 
3262
  #### Exists <a id="fs.op.exists">[[fs.op.exists]]</a>
3263
 
 
3280
 
3281
  *Returns:* `exists(s)`.
3282
 
3283
  *Throws:* As specified in  [[fs.err.report]].
3284
 
3285
+ #### File size <a id="fs.op.file.size">[[fs.op.file.size]]</a>
3286
 
3287
  ``` cpp
3288
  uintmax_t file_size(const path& p);
3289
  uintmax_t file_size(const path& p, error_code& ec) noexcept;
3290
  ```
3291
 
3292
+ *Effects:* If `exists(p)` is `false`, an error is
3293
+ reported [[fs.err.report]].
3294
+
3295
  *Returns:*
3296
 
3297
+ - If `is_regular_file(p)`, the size in bytes of the file `p` resolves
3298
+ to, determined as if by the value of the POSIX `stat` class member
3299
+ `st_size` obtained as if by POSIX `stat()`.
 
3300
  - Otherwise, the result is *implementation-defined*.
3301
 
3302
  The signature with argument `ec` returns `static_cast<uintmax_t>(-1)` if
3303
  an error occurs.
3304
 
3305
  *Throws:* As specified in  [[fs.err.report]].
3306
 
3307
+ #### Hard link count <a id="fs.op.hard.lk.ct">[[fs.op.hard.lk.ct]]</a>
3308
 
3309
  ``` cpp
3310
  uintmax_t hard_link_count(const path& p);
3311
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
3312
  ```
 
3314
  *Returns:* The number of hard links for `p`. The signature with argument
3315
  `ec` returns `static_cast<uintmax_t>(-1)` if an error occurs.
3316
 
3317
  *Throws:* As specified in  [[fs.err.report]].
3318
 
3319
+ #### Is block file <a id="fs.op.is.block.file">[[fs.op.is.block.file]]</a>
3320
 
3321
  ``` cpp
3322
  bool is_block_file(file_status s) noexcept;
3323
  ```
3324
 
 
3333
  respectively. The signature with argument `ec` returns `false` if an
3334
  error occurs.
3335
 
3336
  *Throws:* As specified in  [[fs.err.report]].
3337
 
3338
+ #### Is character file <a id="fs.op.is.char.file">[[fs.op.is.char.file]]</a>
3339
 
3340
  ``` cpp
3341
  bool is_character_file(file_status s) noexcept;
3342
  ```
3343
 
 
3352
  `is_character_file(status(p, ec))`, respectively.
3353
  The signature with argument `ec` returns `false` if an error occurs.
3354
 
3355
  *Throws:* As specified in  [[fs.err.report]].
3356
 
3357
+ #### Is directory <a id="fs.op.is.directory">[[fs.op.is.directory]]</a>
3358
 
3359
  ``` cpp
3360
  bool is_directory(file_status s) noexcept;
3361
  ```
3362
 
 
3371
  respectively. The signature with argument `ec` returns `false` if an
3372
  error occurs.
3373
 
3374
  *Throws:* As specified in  [[fs.err.report]].
3375
 
3376
+ #### Is empty <a id="fs.op.is.empty">[[fs.op.is.empty]]</a>
3377
 
3378
  ``` cpp
3379
  bool is_empty(const path& p);
3380
+ bool is_empty(const path& p, error_code& ec);
3381
  ```
3382
 
3383
  *Effects:*
3384
 
3385
  - Determine `file_status s`, as if by `status(p)` or `status(p, ec)`,
 
3399
  occurred.
3400
  - Otherwise, return `sz == 0`.
3401
 
3402
  *Throws:* As specified in  [[fs.err.report]].
3403
 
3404
+ #### Is fifo <a id="fs.op.is.fifo">[[fs.op.is.fifo]]</a>
3405
 
3406
  ``` cpp
3407
  bool is_fifo(file_status s) noexcept;
3408
  ```
3409
 
 
3418
  respectively. The signature with argument `ec` returns `false` if an
3419
  error occurs.
3420
 
3421
  *Throws:* As specified in  [[fs.err.report]].
3422
 
3423
+ #### Is other <a id="fs.op.is.other">[[fs.op.is.other]]</a>
3424
 
3425
  ``` cpp
3426
  bool is_other(file_status s) noexcept;
3427
  ```
3428
 
 
3438
  respectively. The signature with argument `ec` returns `false` if an
3439
  error occurs.
3440
 
3441
  *Throws:* As specified in  [[fs.err.report]].
3442
 
3443
+ #### Is regular file <a id="fs.op.is.regular.file">[[fs.op.is.regular.file]]</a>
3444
 
3445
  ``` cpp
3446
  bool is_regular_file(file_status s) noexcept;
3447
  ```
3448
 
 
3453
  ```
3454
 
3455
  *Returns:* `is_regular_file(status(p))`.
3456
 
3457
  *Throws:* `filesystem_error` if `status(p)` would throw
3458
+ `filesystem_error`.
3459
 
3460
  ``` cpp
3461
  bool is_regular_file(const path& p, error_code& ec) noexcept;
3462
  ```
3463
 
 
3468
  between cases, call the `status` function directly. — *end note*]
3469
 
3470
  *Returns:* `is_regular_file(status(p, ec))`. Returns `false` if an error
3471
  occurs.
3472
 
3473
+ #### Is socket <a id="fs.op.is.socket">[[fs.op.is.socket]]</a>
3474
 
3475
  ``` cpp
3476
  bool is_socket(file_status s) noexcept;
3477
  ```
3478
 
 
3487
  respectively. The signature with argument `ec` returns `false` if an
3488
  error occurs.
3489
 
3490
  *Throws:* As specified in  [[fs.err.report]].
3491
 
3492
+ #### Is symlink <a id="fs.op.is.symlink">[[fs.op.is.symlink]]</a>
3493
 
3494
  ``` cpp
3495
  bool is_symlink(file_status s) noexcept;
3496
  ```
3497
 
 
3506
  `is_symlink(symlink_status(p, ec))`, respectively. The signature with
3507
  argument `ec` returns `false` if an error occurs.
3508
 
3509
  *Throws:* As specified in  [[fs.err.report]].
3510
 
3511
+ #### Last write time <a id="fs.op.last.write.time">[[fs.op.last.write.time]]</a>
3512
 
3513
  ``` cpp
3514
  file_time_type last_write_time(const path& p);
3515
  file_time_type last_write_time(const path& p, error_code& ec) noexcept;
3516
  ```
3517
 
3518
  *Returns:* The time of last data modification of `p`, determined as if
3519
+ by the value of the POSIX `stat` class member `st_mtime` obtained as if
3520
+ by POSIX `stat()`. The signature with argument `ec` returns
3521
  `file_time_type::min()` if an error occurs.
3522
 
3523
  *Throws:* As specified in  [[fs.err.report]].
3524
 
3525
  ``` cpp
 
3543
  void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
3544
  void permissions(const path& p, perms prms, error_code& ec) noexcept;
3545
  void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
3546
  ```
3547
 
3548
+ *Preconditions:* Exactly one of the `perm_options` constants `replace`,
3549
  `add`, or `remove` is present in `opts`.
3550
 
3551
  *Remarks:* The second signature behaves as if it had an additional
3552
  parameter `perm_options` `opts` with an argument of
3553
  `perm_options::replace`.
 
3591
 
3592
  or `path()` at the first error occurrence, if any.
3593
 
3594
  *Throws:* As specified in  [[fs.err.report]].
3595
 
3596
+ #### Read symlink <a id="fs.op.read.symlink">[[fs.op.read.symlink]]</a>
3597
 
3598
  ``` cpp
3599
  path read_symlink(const path& p);
3600
  path read_symlink(const path& p, error_code& ec);
3601
  ```
 
3651
  as if by POSIX `remove()`.
3652
 
3653
  [*Note 1*: A symbolic link is itself removed, rather than the file it
3654
  resolves to. — *end note*]
3655
 
3656
+ *Ensures:* `exists(symlink_status(p))` is `false`.
3657
 
3658
  *Returns:* `false` if `p` did not exist, otherwise `true`. The signature
3659
  with argument `ec` returns `false` if an error occurs.
3660
 
3661
  *Throws:* As specified in  [[fs.err.report]].
3662
 
3663
+ #### Remove all <a id="fs.op.remove.all">[[fs.op.remove.all]]</a>
3664
 
3665
  ``` cpp
3666
  uintmax_t remove_all(const path& p);
3667
+ uintmax_t remove_all(const path& p, error_code& ec);
3668
  ```
3669
 
3670
  *Effects:* Recursively deletes the contents of `p` if it exists, then
3671
  deletes file `p` itself, as if by POSIX `remove()`.
3672
 
3673
  [*Note 1*: A symbolic link is itself removed, rather than the file it
3674
  resolves to. — *end note*]
3675
 
3676
+ *Ensures:* `exists(symlink_status(p))` is `false`.
3677
 
3678
  *Returns:* The number of files removed. The signature with argument `ec`
3679
  returns `static_cast< uintmax_t>(-1)` if an error occurs.
3680
 
3681
  *Throws:* As specified in  [[fs.err.report]].
 
3704
 
3705
  — *end note*]
3706
 
3707
  *Throws:* As specified in  [[fs.err.report]].
3708
 
3709
+ #### Resize file <a id="fs.op.resize.file">[[fs.op.resize.file]]</a>
3710
 
3711
  ``` cpp
3712
  void resize_file(const path& p, uintmax_t new_size);
3713
  void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
3714
  ```
3715
 
3716
+ *Effects:* Causes the size that would be returned by `file_size(p)` to
3717
+ be equal to `new_size`, as if by POSIX `truncate()`.
3718
 
3719
  *Throws:* As specified in  [[fs.err.report]].
3720
 
 
 
3721
  #### Space <a id="fs.op.space">[[fs.op.space]]</a>
3722
 
3723
  ``` cpp
3724
  space_info space(const path& p);
3725
  space_info space(const path& p, error_code& ec) noexcept;
 
3818
  - Otherwise, if the attributes indicate a fifo or pipe file, as if by
3819
  POSIX `S_ISFIFO`, returns `file_status(file_type::fifo, prms)`.
3820
  - Otherwise, if the attributes indicate a socket, as if by POSIX
3821
  `S_ISSOCK`, returns `file_status(file_type::socket, prms)`.
3822
  - Otherwise, if the attributes indicate an implementation-defined file
3823
+ type [[fs.enum.file.type]], returns
3824
  `file_status(file_type::`*`A`*`, prms)`, where *A* is the constant
3825
  for the *implementation-defined* file type.
3826
  - Otherwise, returns `file_status(file_type::unknown, prms)`.
3827
 
3828
  *Remarks:* If a symbolic link is encountered during pathname resolution,
3829
  pathname resolution continues using the contents of the symbolic link.
3830
 
3831
+ #### Status known <a id="fs.op.status.known">[[fs.op.status.known]]</a>
3832
 
3833
  ``` cpp
3834
  bool status_known(file_status s) noexcept;
3835
  ```
3836
 
3837
  *Returns:* `s.type() != file_type::none`.
3838
 
3839
+ #### Symlink status <a id="fs.op.symlink.status">[[fs.op.symlink.status]]</a>
3840
 
3841
  ``` cpp
3842
  file_status symlink_status(const path& p);
3843
  file_status symlink_status(const path& p, error_code& ec) noexcept;
3844
  ```
 
3858
 
3859
  *Remarks:* Pathname resolution terminates if `p` names a symbolic link.
3860
 
3861
  *Throws:* As specified in  [[fs.err.report]].
3862
 
3863
+ #### Temporary directory path <a id="fs.op.temp.dir.path">[[fs.op.temp.dir.path]]</a>
3864
 
3865
  ``` cpp
3866
  path temp_directory_path();
3867
  path temp_directory_path(error_code& ec);
3868
  ```
3869
 
3870
+ Let `p` be an unspecified directory path suitable for temporary files.
3871
+
3872
+ *Effects:* If `exists(p)` is `false` or `is_directory(p)` is `false`, an
3873
+ error is reported [[fs.err.report]].
3874
+
3875
+ *Returns:* The path `p`. The signature with argument `ec` returns
3876
  `path()` if an error occurs.
3877
 
3878
  *Throws:* As specified in  [[fs.err.report]].
3879
 
3880
  [*Example 1*: For POSIX-based operating systems, an implementation
 
3882
  in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found,
3883
  `"/tmp"`. For Windows-based operating systems, an implementation might
3884
  return the path reported by the Windows `GetTempPath` API
3885
  function. — *end example*]
3886
 
3887
+ #### Weakly canonical <a id="fs.op.weakly.canonical">[[fs.op.weakly.canonical]]</a>
3888
 
3889
  ``` cpp
3890
  path weakly_canonical(const path& p);
3891
  path weakly_canonical(const path& p, error_code& ec);
3892
  ```
3893
 
3894
  *Returns:* `p` with symlinks resolved and the result
3895
+ normalized [[fs.path.generic]].
3896
 
3897
  *Effects:* Using `status(p)` or `status(p, ec)`, respectively, to
3898
  determine existence, return a path composed by `operator/=` from the
3899
+ result of calling `canonical()` with a path argument composed of the
3900
+ leading elements of `p` that exist, if any, followed by the elements of
3901
+ `p` that do not exist, if any. For the first form, `canonical()` is
3902
+ called without an `error_code` argument. For the second form,
3903
+ `canonical()` is called with `ec` as an `error_code` argument, and
3904
+ `path()` is returned at the first error occurrence, if any.
 
3905
 
3906
+ *Ensures:* The returned path is in normal form [[fs.path.generic]].
 
3907
 
3908
+ *Remarks:* Implementations should avoid unnecessary normalization such
3909
+ as when `canonical` has already been called on the entirety of `p`.
 
3910
 
3911
  *Throws:* As specified in  [[fs.err.report]].
3912