From Jason Turner

[fs.class.path]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpsdt8aye1/{from.md → to.md} +320 -299
tmp/tmpsdt8aye1/{from.md → to.md} RENAMED
@@ -1,19 +1,46 @@
1
  ### Class `path` <a id="fs.class.path">[[fs.class.path]]</a>
2
 
3
- An object of class `path` represents a path ([[fs.def.path]]) and
4
- contains a pathname ([[fs.def.pathname]]). Such an object is concerned
5
- only with the lexical and syntactic aspects of a path. The path does not
6
- necessarily exist in external storage, and the pathname is not
7
- necessarily valid for the current operating system or for a particular
8
- file system.
9
 
10
  [*Note 1*: Class `path` is used to support the differences between the
11
  string types used by different operating systems to represent pathnames,
12
  and to perform conversions between encodings when
13
  necessary. — *end note*]
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  ``` cpp
16
  namespace std::filesystem {
17
  class path {
18
  public:
19
  using value_type = see below;
@@ -44,11 +71,11 @@ namespace std::filesystem {
44
  path& operator=(string_type&& source);
45
  path& assign(string_type&& source);
46
  template<class Source>
47
  path& operator=(const Source& source);
48
  template<class Source>
49
- path& assign(const Source& source)
50
  template<class InputIterator>
51
  path& assign(InputIterator first, InputIterator last);
52
 
53
  // [fs.path.append], appends
54
  path& operator/=(const path& p);
@@ -80,10 +107,16 @@ namespace std::filesystem {
80
  path& remove_filename();
81
  path& replace_filename(const path& replacement);
82
  path& replace_extension(const path& replacement = path());
83
  void swap(path& rhs) noexcept;
84
 
 
 
 
 
 
 
85
  // [fs.path.native.obs], native format observers
86
  const string_type& native() const noexcept;
87
  const value_type* c_str() const noexcept;
88
  operator string_type() const;
89
 
@@ -91,22 +124,22 @@ namespace std::filesystem {
91
  class Allocator = allocator<EcharT>>
92
  basic_string<EcharT, traits, Allocator>
93
  string(const Allocator& a = Allocator()) const;
94
  std::string string() const;
95
  std::wstring wstring() const;
96
- std::string u8string() const;
97
  std::u16string u16string() const;
98
  std::u32string u32string() const;
99
 
100
  // [fs.path.generic.obs], generic format observers
101
  template<class EcharT, class traits = char_traits<EcharT>,
102
  class Allocator = allocator<EcharT>>
103
  basic_string<EcharT, traits, Allocator>
104
  generic_string(const Allocator& a = Allocator()) const;
105
  std::string generic_string() const;
106
  std::wstring generic_wstring() const;
107
- std::string generic_u8string() const;
108
  std::u16string generic_u16string() const;
109
  std::u32string generic_u32string() const;
110
 
111
  // [fs.path.compare], compare
112
  int compare(const path& p) const noexcept;
@@ -123,11 +156,11 @@ namespace std::filesystem {
123
  path filename() const;
124
  path stem() const;
125
  path extension() const;
126
 
127
  // [fs.path.query], query
128
- bool empty() const noexcept;
129
  bool has_root_name() const;
130
  bool has_root_directory() const;
131
  bool has_root_path() const;
132
  bool has_relative_path() const;
133
  bool has_parent_path() const;
@@ -146,21 +179,29 @@ namespace std::filesystem {
146
  class iterator;
147
  using const_iterator = iterator;
148
 
149
  iterator begin() const;
150
  iterator end() const;
 
 
 
 
 
 
 
 
151
  };
152
  }
153
  ```
154
 
155
  `value_type` is a `typedef` for the operating system dependent encoded
156
  character type used to represent pathnames.
157
 
158
  The value of the `preferred_separator` member is the operating system
159
- dependent *preferred-separator* character ([[fs.path.generic]]).
160
 
161
- [*Example 1*: For POSIX-based operating systems, `value_type` is `char`
162
  and `preferred_separator` is the slash character (`'/'`). For
163
  Windows-based operating systems, `value_type` is `wchar_t` and
164
  `preferred_separator` is the backslash character
165
  (`L'\\'`). — *end example*]
166
 
@@ -208,31 +249,42 @@ preferred-separator:
208
  ``` bnf
209
  fallback-separator:
210
  /, if *preferred-separator* is not /
211
  ```
212
 
213
- [*Note 1*: Operating systems often place restrictions on the characters
214
- that may be used in a *filename*. For wide portability, users may wish
215
- to limit *filename* characters to the POSIX Portable Filename Character
216
- Set:
 
 
 
 
 
 
217
  `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`
218
  `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`
219
  `0 1 2 3 4 5 6 7 8 9 . _ -` — *end note*]
 
 
 
 
 
 
220
 
221
  Except in a *root-name*, multiple successive *directory-separator*
222
  characters are considered to be the same as one *directory-separator*
223
  character.
224
 
225
- The filename *dot* ([[fs.def.filename]]) is treated as a reference to
226
- the current directory. The filename *dot-dot* ([[fs.def.filename]]) is
227
- treated as a reference to the parent directory. What the filename
228
- *dot-dot* refers to relative to *root-directory* is
229
  *implementation-defined*. Specific filenames may have special meanings
230
  for a particular operating system.
231
 
232
- A *root-name* identifies the starting location for pathname resolution (
233
- [[fs.def.pathres]]). If there are no operating system dependent
234
  *root-name*s, at least one *implementation-defined* *root-name* is
235
  required.
236
 
237
  [*Note 2*: Many operating systems define a name beginning with two
238
  *directory-separator* characters as a *root-name* that identifies
@@ -245,17 +297,42 @@ longest sequence of characters is chosen.
245
 
246
  [*Note 3*: On a POSIX-like operating system, it is impossible to have a
247
  *root-name* and a *relative-path* without an intervening
248
  *root-directory* element. — *end note*]
249
 
250
- #### `path` conversions <a id="fs.path.cvt">[[fs.path.cvt]]</a>
251
 
252
- ##### `path` argument format conversions <a id="fs.path.fmt.cvt">[[fs.path.fmt.cvt]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
  [*Note 1*:
255
 
256
- The format conversions described in this section are not applied on
257
  POSIX-based operating systems because on these systems:
258
 
259
  - The generic format is acceptable as a native path.
260
  - There is no need to distinguish between native format and generic
261
  format in function arguments.
@@ -264,15 +341,15 @@ POSIX-based operating systems because on these systems:
264
 
265
  — *end note*]
266
 
267
  Several functions are defined to accept *detected-format* arguments,
268
  which are character sequences. A detected-format argument represents a
269
- path using either a pathname in the generic format (
270
- [[fs.path.generic]]) or a pathname in the native format (
271
- [[fs.def.native]]). Such an argument is taken to be in the generic
272
- format if and only if it matches the generic format and is not
273
- acceptable to the operating system as a native path.
274
 
275
  [*Note 2*: Some operating systems may have no unambiguous way to
276
  distinguish between native format and generic format arguments. This is
277
  by design as it simplifies use for operating systems that do not require
278
  disambiguation. An implementation for an operating system where
@@ -291,12 +368,12 @@ native-to-generic and generic-to-native formats respectively. If
291
  If the native format requires paths for regular files to be formatted
292
  differently from paths for directories, the path shall be treated as a
293
  directory path if its last element is a *directory-separator*, otherwise
294
  it shall be treated as a path to a regular file.
295
 
296
- [*Note 4*: A path stores a native format pathname (
297
- [[fs.path.native.obs]]) and acts as if it also stores a generic format
298
  pathname, related as given below. The implementation may generate the
299
  generic format pathname based on the native format pathname (and
300
  possibly other information) when requested. — *end note*]
301
 
302
  When a path is constructed from or is assigned a single representation
@@ -309,95 +386,101 @@ the other representation. The value *q* converts to *p* (by *G* or *N*
309
  as appropriate) if any such value does so; *q* is otherwise unspecified.
310
 
311
  [*Note 5*: If *q* is the result of converting any path at all, it is
312
  the result of converting *p*. — *end note*]
313
 
314
- ##### `path` type and encoding conversions <a id="fs.path.type.cvt">[[fs.path.type.cvt]]</a>
 
 
 
 
 
 
315
 
316
  For member function arguments that take character sequences representing
317
  paths and for member functions returning strings, value type and
318
  encoding conversion is performed if the value type of the argument or
319
  return value differs from `path::value_type`. For the argument or return
320
  value, the method of conversion and the encoding to be converted to is
321
  determined by its value type:
322
 
323
- - `char`: The encoding is the native narrow encoding (
324
- [[fs.def.native.encode]]). The method of conversion, if any, is
325
- operating system dependent. \[*Note 6*: For POSIX-based operating
326
- systems `path::value_type` is `char` so no conversion from `char`
327
- value type arguments or to `char` value type return values is
328
- performed. For Windows-based operating systems, the native narrow
329
- encoding is determined by calling a Windows API
330
  function. — *end note*] \[*Note 7*: This results in behavior
331
  identical to other C and C++ standard library functions that perform
332
- file operations using narrow character strings to identify paths.
333
  Changing this behavior would be surprising and error
334
  prone. — *end note*]
335
- - `wchar_t`: The encoding is the native wide encoding (
336
- [[fs.def.native.encode]]). The method of conversion is unspecified.
337
- \[*Note 8*: For Windows-based operating systems `path::value_type` is
338
- `wchar_t` so no conversion from `wchar_t` value type arguments or to
339
- `wchar_t` value type return values is performed. — *end note*]
 
 
340
  - `char16_t`: The encoding is UTF-16. The method of conversion is
341
  unspecified.
342
  - `char32_t`: The encoding is UTF-32. The method of conversion is
343
  unspecified.
344
 
345
  If the encoding being converted to has no representation for source
346
  characters, the resulting converted characters, if any, are unspecified.
347
  Implementations should not modify member function arguments if already
348
  of type `path::value_type`.
349
 
350
- #### `path` requirements <a id="fs.path.req">[[fs.path.req]]</a>
351
 
352
- In addition to the requirements ([[fs.req]]), function template
353
- parameters named `Source` shall be one of:
354
 
355
  - `basic_string<EcharT, traits, Allocator>`. A function argument
356
  `const Source&` `source` shall have an effective range
357
  \[`source.begin()`, `source.end()`).
358
  - `basic_string_view<EcharT, traits>`. A function argument
359
  `const Source&` `source` shall have an effective range
360
  \[`source.begin()`, `source.end()`).
361
- - A type meeting the input iterator requirements that iterates over a
362
- NTCTS. The value type shall be an encoded character type. A function
363
- argument `const Source&` `source` shall have an effective range
364
- \[`source`, `end`) where `end` is the first iterator value with an
365
- element value equal to `iterator_traits<Source>::value_type()`.
366
  - A character array that after array-to-pointer decay results in a
367
  pointer to the start of a NTCTS. The value type shall be an encoded
368
  character type. A function argument `const Source&` `source` shall
369
  have an effective range \[`source`, `end`) where `end` is the first
370
  iterator value with an element value equal to
371
  `iterator_traits<decay_t<Source>>::value_type()`.
372
 
373
  Functions taking template parameters named `Source` shall not
374
- participate in overload resolution unless either
 
375
 
376
  - `Source` is a specialization of `basic_string` or `basic_string_view`,
377
  or
378
  - the *qualified-id* `iterator_traits<decay_t<Source>>::value_type` is
379
- valid and denotes a possibly `const` encoded character type (
380
- [[temp.deduct]]).
381
 
382
- [*Note 1*: See path conversions ([[fs.path.cvt]]) for how the value
383
- types above and their encodings convert to `path::value_type` and its
384
  encoding. — *end note*]
385
 
386
  Arguments of type `Source` shall not be null pointers.
387
 
388
- #### `path` members <a id="fs.path.member">[[fs.path.member]]</a>
389
 
390
- ##### `path` constructors <a id="fs.path.construct">[[fs.path.construct]]</a>
391
 
392
  ``` cpp
393
  path() noexcept;
394
  ```
395
 
396
- *Effects:* Constructs an object of class `path`.
397
-
398
- *Postconditions:* `empty() == true`.
399
 
400
  ``` cpp
401
  path(const path& p);
402
  path(path&& p) noexcept;
403
  ```
@@ -410,49 +493,48 @@ state.
410
  ``` cpp
411
  path(string_type&& source, format fmt = auto_format);
412
  ```
413
 
414
  *Effects:* Constructs an object of class `path` for which the pathname
415
- in the detected-format of `source` has the original value of
416
- `source` ([[fs.path.fmt.cvt]]), converting format if
417
- required ([[fs.path.fmt.cvt]]). `source` is left in a valid but
418
- unspecified state.
419
 
420
  ``` cpp
421
  template<class Source>
422
  path(const Source& source, format fmt = auto_format);
423
  template<class InputIterator>
424
  path(InputIterator first, InputIterator last, format fmt = auto_format);
425
  ```
426
 
427
- *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
428
- or the range \[`first`, `last`), with the encoding converted if
429
- required ([[fs.path.cvt]]). Finds the detected-format of
430
- `s` ([[fs.path.fmt.cvt]]) and constructs an object of class `path` for
431
- which the pathname in that format is `s`.
432
 
433
  ``` cpp
434
  template<class Source>
435
  path(const Source& source, const locale& loc, format fmt = auto_format);
436
  template<class InputIterator>
437
  path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
438
  ```
439
 
440
- *Requires:* The value type of `Source` and `InputIterator` is `char`.
441
 
442
  *Effects:* Let `s` be the effective range of `source` or the range
443
  \[`first`, `last`), after converting the encoding as follows:
444
 
445
  - If `value_type` is `wchar_t`, converts to the native wide
446
- encoding ([[fs.def.native.encode]]) using the
447
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`.
448
  - Otherwise a conversion is performed using the
449
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`, and then a second
450
- conversion to the current narrow encoding.
451
 
452
- Finds the detected-format of `s` ([[fs.path.fmt.cvt]]) and constructs
453
- an object of class `path` for which the pathname in that format is `s`.
454
 
455
  [*Example 1*:
456
 
457
  A string is to be read from a database that is encoded in ISO/IEC
458
  8859-1, and used to create a directory:
@@ -466,27 +548,27 @@ fs::create_directory(fs::path(latin1_string, latin1_locale));
466
  ```
467
 
468
  For POSIX-based operating systems, the path is constructed by first
469
  using `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string`
470
  to a wide character string in the native wide
471
- encoding ([[fs.def.native.encode]]). The resulting wide string is then
472
- converted to a narrow character pathname string in the current native
473
- narrow encoding. If the native wide encoding is UTF-16 or UTF-32, and
474
- the current native narrow encoding is UTF-8, all of the characters in
475
  the ISO/IEC 8859-1 character set will be converted to their Unicode
476
- representation, but for other native narrow encodings some characters
477
  may have no representation.
478
 
479
  For Windows-based operating systems, the path is constructed by using
480
  `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string` to a
481
  UTF-16 encoded wide character pathname string. All of the characters in
482
  the ISO/IEC 8859-1 character set will be converted to their Unicode
483
  representation.
484
 
485
  — *end example*]
486
 
487
- ##### `path` assignments <a id="fs.path.assign">[[fs.path.assign]]</a>
488
 
489
  ``` cpp
490
  path& operator=(const path& p);
491
  ```
492
 
@@ -526,18 +608,18 @@ template <class Source>
526
  path& assign(const Source& source);
527
  template<class InputIterator>
528
  path& assign(InputIterator first, InputIterator last);
529
  ```
530
 
531
- *Effects:* Let `s` be the effective range of `source` ([[fs.path.req]])
532
- or the range \[`first`, `last`), with the encoding converted if
533
- required ([[fs.path.cvt]]). Finds the detected-format of
534
- `s` ([[fs.path.fmt.cvt]]) and sets the pathname in that format to `s`.
535
 
536
  *Returns:* `*this`.
537
 
538
- ##### `path` appends <a id="fs.path.append">[[fs.path.append]]</a>
539
 
540
  The append operations use `operator/=` to denote their semantic effect
541
  of appending *preferred-separator* when needed.
542
 
543
  ``` cpp
@@ -560,26 +642,28 @@ Otherwise, modifies `*this` as if by these steps:
560
  pathname.
561
 
562
  [*Example 2*:
563
 
564
  Even if `//host` is interpreted as a *root-name*, both of the paths
565
- `path("//host")/"foo"` and `path("//host/")/"foo"` equal `"//host/foo"`.
 
566
 
567
  Expression examples:
568
 
569
  ``` cpp
570
  // On POSIX,
571
- path("foo") / ""; // yields "foo/"
572
- path("foo") / "/bar"; // yields "/bar"
573
- // On Windows, backslashes replace slashes in the above yields
574
 
575
  // On Windows,
576
- path("foo") / "c:/bar"; // yields "c:/bar"
577
- path("foo") / "c:"; // yields "c:"
578
- path("c:") / ""; // yields "c:"
579
- path("c:foo") / "/bar"; // yields "c:/bar"
580
- path("c:foo") / "c:bar"; // yields "c:foo/bar"
 
 
581
  ```
582
 
583
  — *end example*]
584
 
585
  *Returns:* `*this`.
@@ -598,22 +682,19 @@ template <class InputIterator>
598
  path& append(InputIterator first, InputIterator last);
599
  ```
600
 
601
  *Effects:* Equivalent to: `return operator/=(path(first, last));`
602
 
603
- ##### `path` concatenation <a id="fs.path.concat">[[fs.path.concat]]</a>
604
 
605
  ``` cpp
606
  path& operator+=(const path& x);
607
  path& operator+=(const string_type& x);
608
  path& operator+=(basic_string_view<value_type> x);
609
  path& operator+=(const value_type* x);
610
- path& operator+=(value_type x);
611
  template<class Source>
612
  path& operator+=(const Source& x);
613
- template <class EcharT>
614
- path& operator+=(EcharT x);
615
  template<class Source>
616
  path& concat(const Source& x);
617
  ```
618
 
619
  *Effects:* Appends `path(x).native()` to the pathname in the native
@@ -622,24 +703,32 @@ format.
622
  [*Note 2*: This directly manipulates the value of `native()` and may
623
  not be portable between operating systems. — *end note*]
624
 
625
  *Returns:* `*this`.
626
 
 
 
 
 
 
 
 
 
627
  ``` cpp
628
  template<class InputIterator>
629
  path& concat(InputIterator first, InputIterator last);
630
  ```
631
 
632
- *Effects:* Equivalent to `return *this += path(first, last)`.
633
 
634
- ##### `path` modifiers <a id="fs.path.modifiers">[[fs.path.modifiers]]</a>
635
 
636
  ``` cpp
637
  void clear() noexcept;
638
  ```
639
 
640
- *Postconditions:* `empty() == true`.
641
 
642
  ``` cpp
643
  path& make_preferred();
644
  ```
645
 
@@ -677,15 +766,15 @@ output is:
677
 
678
  ``` cpp
679
  path& remove_filename();
680
  ```
681
 
682
- *Postconditions:* `!has_filename()`.
683
-
684
  *Effects:* Remove the generic format pathname of `filename()` from the
685
  generic format pathname.
686
 
 
 
687
  *Returns:* `*this`.
688
 
689
  [*Example 4*:
690
 
691
  ``` cpp
@@ -723,12 +812,12 @@ path("/").replace_filename("bar"); // yields "/bar" on POSIX
723
  path& replace_extension(const path& replacement = path());
724
  ```
725
 
726
  *Effects:*
727
 
728
- - Any existing `extension()(` [[fs.path.decompose]]`)` is removed from
729
- the pathname in the generic format, then
730
  - If `replacement` is not empty and does not begin with a dot character,
731
  a dot character is appended to the pathname in the generic format,
732
  then
733
  - `operator+=(replacement);`.
734
 
@@ -740,14 +829,14 @@ void swap(path& rhs) noexcept;
740
 
741
  *Effects:* Swaps the contents (in all formats) of the two paths.
742
 
743
  *Complexity:* Constant time.
744
 
745
- ##### `path` native format observers <a id="fs.path.native.obs">[[fs.path.native.obs]]</a>
746
 
747
  The string returned by all native format observers is in the native
748
- pathname format ([[fs.def.native]]).
749
 
750
  ``` cpp
751
  const string_type& native() const noexcept;
752
  ```
753
 
@@ -755,11 +844,11 @@ const string_type& native() const noexcept;
755
 
756
  ``` cpp
757
  const value_type* c_str() const noexcept;
758
  ```
759
 
760
- *Returns:* Equivalent to `native().c_str()`.
761
 
762
  ``` cpp
763
  operator string_type() const;
764
  ```
765
 
@@ -783,26 +872,25 @@ be performed by `a`. Conversion, if any, is specified by
783
  [[fs.path.cvt]].
784
 
785
  ``` cpp
786
  std::string string() const;
787
  std::wstring wstring() const;
788
- std::string u8string() const;
789
  std::u16string u16string() const;
790
  std::u32string u32string() const;
791
  ```
792
 
793
- *Returns:* `pathstring`.
794
 
795
  *Remarks:* Conversion, if any, is performed as specified by
796
- [[fs.path.cvt]]. The encoding of the string returned by `u8string()` is
797
- always UTF-8.
798
 
799
- ##### `path` generic format observers <a id="fs.path.generic.obs">[[fs.path.generic.obs]]</a>
800
 
801
  Generic format observer functions return strings formatted according to
802
- the generic pathname format ([[fs.path.generic]]). A single slash
803
- (`'/'`) character is used as the *directory-separator*.
804
 
805
  [*Example 1*:
806
 
807
  On an operating system that uses backslash as its *preferred-separator*,
808
 
@@ -828,53 +916,51 @@ be performed by `a`. Conversion, if any, is specified by
828
  [[fs.path.cvt]].
829
 
830
  ``` cpp
831
  std::string generic_string() const;
832
  std::wstring generic_wstring() const;
833
- std::string generic_u8string() const;
834
  std::u16string generic_u16string() const;
835
  std::u32string generic_u32string() const;
836
  ```
837
 
838
  *Returns:* The pathname in the generic format.
839
 
840
- *Remarks:* Conversion, if any, is specified by  [[fs.path.cvt]]. The
841
- encoding of the string returned by `generic_u8string()` is always UTF-8.
842
 
843
- ##### `path` compare <a id="fs.path.compare">[[fs.path.compare]]</a>
844
 
845
  ``` cpp
846
  int compare(const path& p) const noexcept;
847
  ```
848
 
849
  *Returns:*
850
 
851
- - A value less than `0`, if `native()` for the elements of `*this` are
852
- lexicographically less than `native()` for the elements of `p`;
853
- otherwise,
854
- - a value greater than `0`, if `native()` for the elements of `*this`
855
- are lexicographically greater than `native()` for the elements of `p`;
856
- otherwise,
857
- - `0`.
858
-
859
- *Remarks:* The elements are determined as if by iteration over the
860
- half-open range \[`begin()`, `end()`) for `*this` and `p`.
 
 
 
 
861
 
862
  ``` cpp
863
- int compare(const string_type& s) const
864
  int compare(basic_string_view<value_type> s) const;
 
865
  ```
866
 
867
- *Returns:* `compare(path(s))`.
868
 
869
- ``` cpp
870
- int compare(const value_type* s) const
871
- ```
872
-
873
- *Returns:* `compare(path(s))`.
874
-
875
- ##### `path` decomposition <a id="fs.path.decompose">[[fs.path.decompose]]</a>
876
 
877
  ``` cpp
878
  path root_name() const;
879
  ```
880
 
@@ -897,20 +983,21 @@ path root_path() const;
897
  ``` cpp
898
  path relative_path() const;
899
  ```
900
 
901
  *Returns:* A `path` composed from the pathname in the generic format, if
902
- `!empty()`, beginning with the first *filename* after *root-path*.
903
- Otherwise, `path()`.
904
 
905
  ``` cpp
906
  path parent_path() const;
907
  ```
908
 
909
- *Returns:* `*this` if `!has_relative_path()`, otherwise a path whose
910
- generic format pathname is the longest prefix of the generic format
911
- pathname of `*this` that produces one fewer element in its iteration.
 
912
 
913
  ``` cpp
914
  path filename() const;
915
  ```
916
 
@@ -957,11 +1044,11 @@ for (; !p.extension().empty(); p = p.stem())
957
 
958
  ``` cpp
959
  path extension() const;
960
  ```
961
 
962
- *Returns:* a path whose pathname in the generic format is the suffix of
963
  `filename()` not included in `stem()`.
964
 
965
  [*Example 8*:
966
 
967
  ``` cpp
@@ -980,18 +1067,18 @@ extension. — *end note*]
980
 
981
  [*Note 5*: On non-POSIX operating systems, for a path `p`, it may not
982
  be the case that `p.stem() + p.extension() == p.filename()`, even though
983
  the generic format pathnames are the same. — *end note*]
984
 
985
- ##### `path` query <a id="fs.path.query">[[fs.path.query]]</a>
986
 
987
  ``` cpp
988
- bool empty() const noexcept;
989
  ```
990
 
991
- *Returns:* `true` if the pathname in the generic format is empty, else
992
- `false`.
993
 
994
  ``` cpp
995
  bool has_root_path() const;
996
  ```
997
 
@@ -1042,11 +1129,11 @@ bool has_extension() const;
1042
  ``` cpp
1043
  bool is_absolute() const;
1044
  ```
1045
 
1046
  *Returns:* `true` if the pathname in the native format contains an
1047
- absolute path ([[fs.def.absolute.path]]), else `false`.
1048
 
1049
  [*Example 9*: `path("/").is_absolute()` is `true` for POSIX-based
1050
  operating systems, and `false` for Windows-based operating
1051
  systems. — *end example*]
1052
 
@@ -1054,18 +1141,18 @@ systems. — *end example*]
1054
  bool is_relative() const;
1055
  ```
1056
 
1057
  *Returns:* `!is_absolute()`.
1058
 
1059
- ##### `path` generation <a id="fs.path.gen">[[fs.path.gen]]</a>
1060
 
1061
  ``` cpp
1062
  path lexically_normal() const;
1063
  ```
1064
 
1065
  *Returns:* A path whose pathname in the generic format is the normal
1066
- form ([[fs.def.normal.form]]) of the pathname in the generic format of
1067
  `*this`.
1068
 
1069
  [*Example 10*:
1070
 
1071
  ``` cpp
@@ -1082,29 +1169,40 @@ slashes, but that does not affect `path` equality.
1082
  ``` cpp
1083
  path lexically_relative(const path& base) const;
1084
  ```
1085
 
1086
  *Returns:* `*this` made relative to `base`. Does not
1087
- resolve ([[fs.def.pathres]]) symlinks. Does not first
1088
- normalize ([[fs.def.normal.form]]) `*this` or `base`.
1089
-
1090
- *Effects:* If `root_name() != base.root_name()` is `true` or
1091
- `is_absolute() != base.is_absolute()` is `true` or
1092
- `!has_root_directory() && base.has_root_directory()` is `true`, returns
1093
- `path()`. Determines the first mismatched element of `*this` and `base`
1094
- as if by:
 
 
 
 
 
 
 
 
 
1095
 
1096
  ``` cpp
1097
  auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
1098
  ```
1099
 
1100
  Then,
1101
 
1102
  - if `a == end()` and `b == base.end()`, returns `path(".")`; otherwise
1103
  - let `n` be the number of *filename* elements in \[`b`, `base.end()`)
1104
- that are not *dot* or *dot-dot* minus the number that are *dot-dot*.
1105
- If `n<0,` returns `path()`; otherwise
 
 
1106
  - returns an object of class `path` that is default-constructed,
1107
  followed by
1108
  - application of `operator/=(path(".."))` `n` times, and then
1109
  - application of `operator/=` for each element in \[`a`, `end()`).
1110
 
@@ -1123,41 +1221,41 @@ The above assertions will succeed. On Windows, the returned path’s
1123
  *directory-separator* characters will be backslashes rather than
1124
  slashes, but that does not affect `path` equality.
1125
 
1126
  — *end example*]
1127
 
1128
- [*Note 6*: If symlink following semantics are desired, use the
1129
  operational function `relative()`. — *end note*]
1130
 
1131
- [*Note 7*: If normalization ([[fs.def.normal.form]]) is needed to
1132
- ensure consistent matching of elements, apply `lexically_normal()` to
1133
- `*this`, `base`, or both. — *end note*]
1134
 
1135
  ``` cpp
1136
  path lexically_proximate(const path& base) const;
1137
  ```
1138
 
1139
  *Returns:* If the value of `lexically_relative(base)` is not an empty
1140
  path, return it. Otherwise return `*this`.
1141
 
1142
- [*Note 8*: If symlink following semantics are desired, use the
1143
  operational function `proximate()`. — *end note*]
1144
 
1145
- [*Note 9*: If normalization ([[fs.def.normal.form]]) is needed to
1146
- ensure consistent matching of elements, apply `lexically_normal()` to
1147
- `*this`, `base`, or both. — *end note*]
1148
 
1149
- #### `path` iterators <a id="fs.path.itr">[[fs.path.itr]]</a>
1150
 
1151
  Path iterators iterate over the elements of the pathname in the generic
1152
- format ([[fs.path.generic]]).
1153
 
1154
- A `path::iterator` is a constant iterator satisfying all the
1155
- requirements of a bidirectional iterator ([[bidirectional.iterators]])
1156
- except that, for dereferenceable iterators `a` and `b` of type
1157
- `path::iterator` with `a == b`, there is no requirement that `*a` and
1158
- `*b` are bound to the same object. Its `value_type` is `path`.
1159
 
1160
  Calling any non-const member function of a `path` object invalidates all
1161
  iterators referring to elements of that object.
1162
 
1163
  For the elements of the pathname in the generic format, the forward
@@ -1184,165 +1282,88 @@ list above. If no elements are present, the end iterator.
1184
  iterator end() const;
1185
  ```
1186
 
1187
  *Returns:* The end iterator.
1188
 
1189
- #### `path` non-member functions <a id="fs.path.nonmember">[[fs.path.nonmember]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1190
 
1191
  ``` cpp
1192
  void swap(path& lhs, path& rhs) noexcept;
1193
  ```
1194
 
1195
- *Effects:* Equivalent to: `lhs.swap(rhs);`
1196
 
1197
  ``` cpp
1198
  size_t hash_value (const path& p) noexcept;
1199
  ```
1200
 
1201
  *Returns:* A hash value for the path `p`. If for two paths, `p1 == p2`
1202
  then `hash_value(p1) == hash_value(p2)`.
1203
 
1204
  ``` cpp
1205
- bool operator< (const path& lhs, const path& rhs) noexcept;
1206
  ```
1207
 
1208
- *Returns:* `lhs.compare(rhs) < 0`.
1209
-
1210
- ``` cpp
1211
- bool operator<=(const path& lhs, const path& rhs) noexcept;
1212
- ```
1213
-
1214
- *Returns:* `!(rhs < lhs)`.
1215
-
1216
- ``` cpp
1217
- bool operator> (const path& lhs, const path& rhs) noexcept;
1218
- ```
1219
-
1220
- *Returns:* `rhs < lhs`.
1221
-
1222
- ``` cpp
1223
- bool operator>=(const path& lhs, const path& rhs) noexcept;
1224
- ```
1225
-
1226
- *Returns:* `!(lhs < rhs)`.
1227
-
1228
- ``` cpp
1229
- bool operator==(const path& lhs, const path& rhs) noexcept;
1230
- ```
1231
-
1232
- *Returns:* `!(lhs < rhs) && !(rhs < lhs)`.
1233
 
1234
  [*Note 1*:
1235
 
1236
  Path equality and path equivalence have different semantics.
1237
 
1238
  - Equality is determined by the `path` non-member `operator==`, which
1239
- considers the two paths lexical representations only.
1240
  \[*Example 1*: `path("foo") == "bar"` is never
1241
  `true`. — *end example*]
1242
  - Equivalence is determined by the `equivalent()` non-member function,
1243
- which determines if two paths resolve ([[fs.def.pathres]]) to the
1244
- same file system entity. \[*Example 2*: `equivalent("foo", "bar")`
1245
- will be `true` when both paths resolve to the same
1246
- file. — *end example*]
1247
 
1248
  Programmers wishing to determine if two paths are “the same” must decide
1249
  if “the same” means “the same representation” or “resolve to the same
1250
  actual file”, and choose the appropriate function accordingly.
1251
 
1252
  — *end note*]
1253
 
1254
  ``` cpp
1255
- bool operator!=(const path& lhs, const path& rhs) noexcept;
1256
  ```
1257
 
1258
- *Returns:* `!(lhs == rhs)`.
1259
 
1260
  ``` cpp
1261
- path operator/ (const path& lhs, const path& rhs);
1262
  ```
1263
 
1264
  *Effects:* Equivalent to: `return path(lhs) /= rhs;`
1265
 
1266
- ##### `path` inserter and extractor <a id="fs.path.io">[[fs.path.io]]</a>
1267
-
1268
- ``` cpp
1269
- template <class charT, class traits>
1270
- basic_ostream<charT, traits>&
1271
- operator<<(basic_ostream<charT, traits>& os, const path& p);
1272
- ```
1273
-
1274
- *Effects:* Equivalent to: `os << quoted(p.string<charT, traits>());`
1275
-
1276
- [*Note 2*: The `quoted` function is described
1277
- in  [[quoted.manip]]. — *end note*]
1278
-
1279
- *Returns:* `os`.
1280
-
1281
- ``` cpp
1282
- template <class charT, class traits>
1283
- basic_istream<charT, traits>&
1284
- operator>>(basic_istream<charT, traits>& is, path& p);
1285
- ```
1286
-
1287
- *Effects:* Equivalent to:
1288
-
1289
- ``` cpp
1290
- basic_string<charT, traits> tmp;
1291
- is >> quoted(tmp);
1292
- p = tmp;
1293
- ```
1294
-
1295
- *Returns:* `is`.
1296
-
1297
- ##### `path` factory functions <a id="fs.path.factory">[[fs.path.factory]]</a>
1298
-
1299
- ``` cpp
1300
- template <class Source>
1301
- path u8path(const Source& source);
1302
- template <class InputIterator>
1303
- path u8path(InputIterator first, InputIterator last);
1304
- ```
1305
-
1306
- *Requires:* The `source` and \[`first`, `last`) sequences are UTF-8
1307
- encoded. The value type of `Source` and `InputIterator` is `char`.
1308
-
1309
- *Returns:*
1310
-
1311
- - If `value_type` is `char` and the current native narrow
1312
- encoding ([[fs.def.native.encode]]) is UTF-8, return `path(source)`
1313
- or `path(first, last)`; otherwise,
1314
- - if `value_type` is `wchar_t` and the native wide encoding is UTF-16,
1315
- or if `value_type` is `char16_t` or `char32_t`, convert `source` or
1316
- \[`first`, `last`) to a temporary, `tmp`, of type `string_type` and
1317
- return `path(tmp)`; otherwise,
1318
- - convert `source` or \[`first`, `last`) to a temporary, `tmp`, of type
1319
- `u32string` and return `path(tmp)`.
1320
-
1321
- *Remarks:* Argument format conversion ([[fs.path.fmt.cvt]]) applies to
1322
- the arguments for these functions. How Unicode encoding conversions are
1323
- performed is unspecified.
1324
-
1325
- [*Example 1*:
1326
-
1327
- A string is to be read from a database that is encoded in UTF-8, and
1328
- used to create a directory using the native encoding for filenames:
1329
-
1330
- ``` cpp
1331
- namespace fs = std::filesystem;
1332
- std::string utf8_string = read_utf8_data();
1333
- fs::create_directory(fs::u8path(utf8_string));
1334
- ```
1335
-
1336
- For POSIX-based operating systems with the native narrow encoding set to
1337
- UTF-8, no encoding or type conversion occurs.
1338
-
1339
- For POSIX-based operating systems with the native narrow encoding not
1340
- set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to
1341
- the current native narrow encoding. Some Unicode characters may have no
1342
- native character set representation.
1343
-
1344
- For Windows-based operating systems a conversion from UTF-8 to UTF-16
1345
- occurs.
1346
-
1347
- — *end example*]
1348
-
 
1
  ### Class `path` <a id="fs.class.path">[[fs.class.path]]</a>
2
 
3
+ An object of class `path` represents a path and contains a pathname.
4
+ Such an object is concerned only with the lexical and syntactic aspects
5
+ of a path. The path does not necessarily exist in external storage, and
6
+ the pathname is not necessarily valid for the current operating system
7
+ or for a particular file system.
 
8
 
9
  [*Note 1*: Class `path` is used to support the differences between the
10
  string types used by different operating systems to represent pathnames,
11
  and to perform conversions between encodings when
12
  necessary. — *end note*]
13
 
14
+ A *path* is a sequence of elements that identify the location of a file
15
+ within a filesystem. The elements are the *root-name*ₒₚₜ ,
16
+ *root-directory*ₒₚₜ , and an optional sequence of *filename*s
17
+ [[fs.path.generic]]. The maximum number of elements in the sequence is
18
+ operating system dependent [[fs.conform.os]].
19
+
20
+ An *absolute path* is a path that unambiguously identifies the location
21
+ of a file without reference to an additional starting location. The
22
+ elements of a path that determine if it is absolute are operating system
23
+ dependent. A *relative path* is a path that is not absolute, and as
24
+ such, only unambiguously identifies the location of a file when resolved
25
+ relative to an implied starting location. The elements of a path that
26
+ determine if it is relative are operating system dependent.
27
+
28
+ [*Note 2*: Pathnames “.” and “..” are relative paths. — *end note*]
29
+
30
+ A *pathname* is a character string that represents the name of a path.
31
+ Pathnames are formatted according to the generic pathname format grammar
32
+ [[fs.path.generic]] or according to an operating system dependent
33
+ *native pathname format* accepted by the host operating system.
34
+
35
+ *Pathname resolution* is the operating system dependent mechanism for
36
+ resolving a pathname to a particular file in a file hierarchy. There may
37
+ be multiple pathnames that resolve to the same file.
38
+
39
+ [*Example 1*: POSIX specifies the mechanism in section 4.11, Pathname
40
+ resolution. — *end example*]
41
+
42
  ``` cpp
43
  namespace std::filesystem {
44
  class path {
45
  public:
46
  using value_type = see below;
 
71
  path& operator=(string_type&& source);
72
  path& assign(string_type&& source);
73
  template<class Source>
74
  path& operator=(const Source& source);
75
  template<class Source>
76
+ path& assign(const Source& source);
77
  template<class InputIterator>
78
  path& assign(InputIterator first, InputIterator last);
79
 
80
  // [fs.path.append], appends
81
  path& operator/=(const path& p);
 
107
  path& remove_filename();
108
  path& replace_filename(const path& replacement);
109
  path& replace_extension(const path& replacement = path());
110
  void swap(path& rhs) noexcept;
111
 
112
+ // [fs.path.nonmember], non-member operators
113
+ friend bool operator==(const path& lhs, const path& rhs) noexcept;
114
+ friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept;
115
+
116
+ friend path operator/ (const path& lhs, const path& rhs);
117
+
118
  // [fs.path.native.obs], native format observers
119
  const string_type& native() const noexcept;
120
  const value_type* c_str() const noexcept;
121
  operator string_type() const;
122
 
 
124
  class Allocator = allocator<EcharT>>
125
  basic_string<EcharT, traits, Allocator>
126
  string(const Allocator& a = Allocator()) const;
127
  std::string string() const;
128
  std::wstring wstring() const;
129
+ std::u8string u8string() const;
130
  std::u16string u16string() const;
131
  std::u32string u32string() const;
132
 
133
  // [fs.path.generic.obs], generic format observers
134
  template<class EcharT, class traits = char_traits<EcharT>,
135
  class Allocator = allocator<EcharT>>
136
  basic_string<EcharT, traits, Allocator>
137
  generic_string(const Allocator& a = Allocator()) const;
138
  std::string generic_string() const;
139
  std::wstring generic_wstring() const;
140
+ std::u8string generic_u8string() const;
141
  std::u16string generic_u16string() const;
142
  std::u32string generic_u32string() const;
143
 
144
  // [fs.path.compare], compare
145
  int compare(const path& p) const noexcept;
 
156
  path filename() const;
157
  path stem() const;
158
  path extension() const;
159
 
160
  // [fs.path.query], query
161
+ [[nodiscard]] bool empty() const noexcept;
162
  bool has_root_name() const;
163
  bool has_root_directory() const;
164
  bool has_root_path() const;
165
  bool has_relative_path() const;
166
  bool has_parent_path() const;
 
179
  class iterator;
180
  using const_iterator = iterator;
181
 
182
  iterator begin() const;
183
  iterator end() const;
184
+
185
+ // [fs.path.io], path inserter and extractor
186
+ template<class charT, class traits>
187
+ friend basic_ostream<charT, traits>&
188
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
189
+ template<class charT, class traits>
190
+ friend basic_istream<charT, traits>&
191
+ operator>>(basic_istream<charT, traits>& is, path& p);
192
  };
193
  }
194
  ```
195
 
196
  `value_type` is a `typedef` for the operating system dependent encoded
197
  character type used to represent pathnames.
198
 
199
  The value of the `preferred_separator` member is the operating system
200
+ dependent *preferred-separator* character [[fs.path.generic]].
201
 
202
+ [*Example 2*: For POSIX-based operating systems, `value_type` is `char`
203
  and `preferred_separator` is the slash character (`'/'`). For
204
  Windows-based operating systems, `value_type` is `wchar_t` and
205
  `preferred_separator` is the backslash character
206
  (`L'\\'`). — *end example*]
207
 
 
249
  ``` bnf
250
  fallback-separator:
251
  /, if *preferred-separator* is not /
252
  ```
253
 
254
+ A *filename* is the name of a file. The *dot* and *dot-dot* filenames,
255
+ consisting solely of one and two period characters respectively, have
256
+ special meaning. The following characteristics of filenames are
257
+ operating system dependent:
258
+
259
+ - The permitted characters. \[*Example 1*: Some operating systems
260
+ prohibit the ASCII control characters (0x00 – 0x1F) in
261
+ filenames. — *end example*] \[*Note 1*: For wide portability, users
262
+ may wish to limit *filename* characters to the POSIX Portable Filename
263
+ Character Set:
264
  `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`
265
  `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`
266
  `0 1 2 3 4 5 6 7 8 9 . _ -` — *end note*]
267
+ - The maximum permitted length.
268
+ - Filenames that are not permitted.
269
+ - Filenames that have special meaning.
270
+ - Case awareness and sensitivity during path resolution.
271
+ - Special rules that may apply to file types other than regular files,
272
+ such as directories.
273
 
274
  Except in a *root-name*, multiple successive *directory-separator*
275
  characters are considered to be the same as one *directory-separator*
276
  character.
277
 
278
+ The dot filename is treated as a reference to the current directory. The
279
+ dot-dot filename is treated as a reference to the parent directory. What
280
+ the dot-dot filename refers to relative to *root-directory* is
 
281
  *implementation-defined*. Specific filenames may have special meanings
282
  for a particular operating system.
283
 
284
+ A *root-name* identifies the starting location for pathname resolution
285
+ [[fs.class.path]]. If there are no operating system dependent
286
  *root-name*s, at least one *implementation-defined* *root-name* is
287
  required.
288
 
289
  [*Note 2*: Many operating systems define a name beginning with two
290
  *directory-separator* characters as a *root-name* that identifies
 
297
 
298
  [*Note 3*: On a POSIX-like operating system, it is impossible to have a
299
  *root-name* and a *relative-path* without an intervening
300
  *root-directory* element. — *end note*]
301
 
302
+ *Normalization* of a generic format pathname means:
303
 
304
+ 1. If the path is empty, stop.
305
+ 2. Replace each slash character in the *root-name* with a
306
+ *preferred-separator*.
307
+ 3. Replace each *directory-separator* with a *preferred-separator*.
308
+ \[*Note 4*: The generic pathname grammar [[fs.path.generic]] defines
309
+ *directory-separator* as one or more slashes and
310
+ *preferred-separator*s. — *end note*]
311
+ 4. Remove each dot filename and any immediately following
312
+ *directory-separator*.
313
+ 5. As long as any appear, remove a non-dot-dot filename immediately
314
+ followed by a *directory-separator* and a dot-dot filename, along
315
+ with any immediately following *directory-separator*.
316
+ 6. If there is a *root-directory*, remove all dot-dot filenames and any
317
+ *directory-separator*s immediately following them. \[*Note 5*: These
318
+ dot-dot filenames attempt to refer to nonexistent parent
319
+ directories. — *end note*]
320
+ 7. If the last filename is dot-dot, remove any trailing
321
+ *directory-separator*.
322
+ 8. If the path is empty, add a dot.
323
+
324
+ The result of normalization is a path in *normal form*, which is said to
325
+ be *normalized*.
326
+
327
+ #### Conversions <a id="fs.path.cvt">[[fs.path.cvt]]</a>
328
+
329
+ ##### Argument format conversions <a id="fs.path.fmt.cvt">[[fs.path.fmt.cvt]]</a>
330
 
331
  [*Note 1*:
332
 
333
+ The format conversions described in this subclause are not applied on
334
  POSIX-based operating systems because on these systems:
335
 
336
  - The generic format is acceptable as a native path.
337
  - There is no need to distinguish between native format and generic
338
  format in function arguments.
 
341
 
342
  — *end note*]
343
 
344
  Several functions are defined to accept *detected-format* arguments,
345
  which are character sequences. A detected-format argument represents a
346
+ path using either a pathname in the generic format [[fs.path.generic]]
347
+ or a pathname in the native format [[fs.class.path]]. Such an argument
348
+ is taken to be in the generic format if and only if it matches the
349
+ generic format and is not acceptable to the operating system as a native
350
+ path.
351
 
352
  [*Note 2*: Some operating systems may have no unambiguous way to
353
  distinguish between native format and generic format arguments. This is
354
  by design as it simplifies use for operating systems that do not require
355
  disambiguation. An implementation for an operating system where
 
368
  If the native format requires paths for regular files to be formatted
369
  differently from paths for directories, the path shall be treated as a
370
  directory path if its last element is a *directory-separator*, otherwise
371
  it shall be treated as a path to a regular file.
372
 
373
+ [*Note 4*: A path stores a native format pathname
374
+ [[fs.path.native.obs]] and acts as if it also stores a generic format
375
  pathname, related as given below. The implementation may generate the
376
  generic format pathname based on the native format pathname (and
377
  possibly other information) when requested. — *end note*]
378
 
379
  When a path is constructed from or is assigned a single representation
 
386
  as appropriate) if any such value does so; *q* is otherwise unspecified.
387
 
388
  [*Note 5*: If *q* is the result of converting any path at all, it is
389
  the result of converting *p*. — *end note*]
390
 
391
+ ##### Type and encoding conversions <a id="fs.path.type.cvt">[[fs.path.type.cvt]]</a>
392
+
393
+ The *native encoding* of an ordinary character string is the operating
394
+ system dependent current encoding for pathnames [[fs.class.path]]. The
395
+ *native encoding* for wide character strings is the
396
+ implementation-defined execution wide-character set encoding
397
+ [[lex.charset]].
398
 
399
  For member function arguments that take character sequences representing
400
  paths and for member functions returning strings, value type and
401
  encoding conversion is performed if the value type of the argument or
402
  return value differs from `path::value_type`. For the argument or return
403
  value, the method of conversion and the encoding to be converted to is
404
  determined by its value type:
405
 
406
+ - `char`: The encoding is the native ordinary encoding. The method of
407
+ conversion, if any, is operating system dependent. \[*Note 6*: For
408
+ POSIX-based operating systems `path::value_type` is `char` so no
409
+ conversion from `char` value type arguments or to `char` value type
410
+ return values is performed. For Windows-based operating systems, the
411
+ native ordinary encoding is determined by calling a Windows API
 
412
  function. — *end note*] \[*Note 7*: This results in behavior
413
  identical to other C and C++ standard library functions that perform
414
+ file operations using ordinary character strings to identify paths.
415
  Changing this behavior would be surprising and error
416
  prone. — *end note*]
417
+ - `wchar_t`: The encoding is the native wide encoding. The method of
418
+ conversion is unspecified. \[*Note 8*: For Windows-based operating
419
+ systems `path::value_type` is `wchar_t` so no conversion from
420
+ `wchar_t` value type arguments or to `wchar_t` value type return
421
+ values is performed. — *end note*]
422
+ - `char8_t`: The encoding is UTF-8. The method of conversion is
423
+ unspecified.
424
  - `char16_t`: The encoding is UTF-16. The method of conversion is
425
  unspecified.
426
  - `char32_t`: The encoding is UTF-32. The method of conversion is
427
  unspecified.
428
 
429
  If the encoding being converted to has no representation for source
430
  characters, the resulting converted characters, if any, are unspecified.
431
  Implementations should not modify member function arguments if already
432
  of type `path::value_type`.
433
 
434
+ #### Requirements <a id="fs.path.req">[[fs.path.req]]</a>
435
 
436
+ In addition to the requirements [[fs.req]], function template parameters
437
+ named `Source` shall be one of:
438
 
439
  - `basic_string<EcharT, traits, Allocator>`. A function argument
440
  `const Source&` `source` shall have an effective range
441
  \[`source.begin()`, `source.end()`).
442
  - `basic_string_view<EcharT, traits>`. A function argument
443
  `const Source&` `source` shall have an effective range
444
  \[`source.begin()`, `source.end()`).
445
+ - A type meeting the *Cpp17InputIterator* requirements that iterates
446
+ over a NTCTS. The value type shall be an encoded character type. A
447
+ function argument `const Source&` `source` shall have an effective
448
+ range \[`source`, `end`) where `end` is the first iterator value with
449
+ an element value equal to `iterator_traits<Source>::value_type()`.
450
  - A character array that after array-to-pointer decay results in a
451
  pointer to the start of a NTCTS. The value type shall be an encoded
452
  character type. A function argument `const Source&` `source` shall
453
  have an effective range \[`source`, `end`) where `end` is the first
454
  iterator value with an element value equal to
455
  `iterator_traits<decay_t<Source>>::value_type()`.
456
 
457
  Functions taking template parameters named `Source` shall not
458
+ participate in overload resolution unless `Source` denotes a type other
459
+ than `path`, and either
460
 
461
  - `Source` is a specialization of `basic_string` or `basic_string_view`,
462
  or
463
  - the *qualified-id* `iterator_traits<decay_t<Source>>::value_type` is
464
+ valid and denotes a possibly `const` encoded character type
465
+ [[temp.deduct]].
466
 
467
+ [*Note 1*: See path conversions [[fs.path.cvt]] for how the value types
468
+ above and their encodings convert to `path::value_type` and its
469
  encoding. — *end note*]
470
 
471
  Arguments of type `Source` shall not be null pointers.
472
 
473
+ #### Members <a id="fs.path.member">[[fs.path.member]]</a>
474
 
475
+ ##### Constructors <a id="fs.path.construct">[[fs.path.construct]]</a>
476
 
477
  ``` cpp
478
  path() noexcept;
479
  ```
480
 
481
+ *Ensures:* `empty() == true`.
 
 
482
 
483
  ``` cpp
484
  path(const path& p);
485
  path(path&& p) noexcept;
486
  ```
 
493
  ``` cpp
494
  path(string_type&& source, format fmt = auto_format);
495
  ```
496
 
497
  *Effects:* Constructs an object of class `path` for which the pathname
498
+ in the detected-format of `source` has the original value of `source`
499
+ [[fs.path.fmt.cvt]], converting format if required [[fs.path.fmt.cvt]].
500
+ `source` is left in a valid but unspecified state.
 
501
 
502
  ``` cpp
503
  template<class Source>
504
  path(const Source& source, format fmt = auto_format);
505
  template<class InputIterator>
506
  path(InputIterator first, InputIterator last, format fmt = auto_format);
507
  ```
508
 
509
+ *Effects:* Let `s` be the effective range of `source` [[fs.path.req]] or
510
+ the range \[`first`, `last`), with the encoding converted if
511
+ required [[fs.path.cvt]]. Finds the detected-format of `s`
512
+ [[fs.path.fmt.cvt]] and constructs an object of class `path` for which
513
+ the pathname in that format is `s`.
514
 
515
  ``` cpp
516
  template<class Source>
517
  path(const Source& source, const locale& loc, format fmt = auto_format);
518
  template<class InputIterator>
519
  path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
520
  ```
521
 
522
+ *Mandates:* The value type of `Source` and `InputIterator` is `char`.
523
 
524
  *Effects:* Let `s` be the effective range of `source` or the range
525
  \[`first`, `last`), after converting the encoding as follows:
526
 
527
  - If `value_type` is `wchar_t`, converts to the native wide
528
+ encoding [[fs.path.type.cvt]] using the
529
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`.
530
  - Otherwise a conversion is performed using the
531
  `codecvt<wchar_t, char, mbstate_t>` facet of `loc`, and then a second
532
+ conversion to the current ordinary encoding.
533
 
534
+ Finds the detected-format of `s` [[fs.path.fmt.cvt]] and constructs an
535
+ object of class `path` for which the pathname in that format is `s`.
536
 
537
  [*Example 1*:
538
 
539
  A string is to be read from a database that is encoded in ISO/IEC
540
  8859-1, and used to create a directory:
 
548
  ```
549
 
550
  For POSIX-based operating systems, the path is constructed by first
551
  using `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string`
552
  to a wide character string in the native wide
553
+ encoding [[fs.path.type.cvt]]. The resulting wide string is then
554
+ converted to an ordinary character pathname string in the current native
555
+ ordinary encoding. If the native wide encoding is UTF-16 or UTF-32, and
556
+ the current native ordinary encoding is UTF-8, all of the characters in
557
  the ISO/IEC 8859-1 character set will be converted to their Unicode
558
+ representation, but for other native ordinary encodings some characters
559
  may have no representation.
560
 
561
  For Windows-based operating systems, the path is constructed by using
562
  `latin1_facet` to convert ISO/IEC 8859-1 encoded `latin1_string` to a
563
  UTF-16 encoded wide character pathname string. All of the characters in
564
  the ISO/IEC 8859-1 character set will be converted to their Unicode
565
  representation.
566
 
567
  — *end example*]
568
 
569
+ ##### Assignments <a id="fs.path.assign">[[fs.path.assign]]</a>
570
 
571
  ``` cpp
572
  path& operator=(const path& p);
573
  ```
574
 
 
608
  path& assign(const Source& source);
609
  template<class InputIterator>
610
  path& assign(InputIterator first, InputIterator last);
611
  ```
612
 
613
+ *Effects:* Let `s` be the effective range of `source` [[fs.path.req]] or
614
+ the range \[`first`, `last`), with the encoding converted if
615
+ required [[fs.path.cvt]]. Finds the detected-format of `s`
616
+ [[fs.path.fmt.cvt]] and sets the pathname in that format to `s`.
617
 
618
  *Returns:* `*this`.
619
 
620
+ ##### Appends <a id="fs.path.append">[[fs.path.append]]</a>
621
 
622
  The append operations use `operator/=` to denote their semantic effect
623
  of appending *preferred-separator* when needed.
624
 
625
  ``` cpp
 
642
  pathname.
643
 
644
  [*Example 2*:
645
 
646
  Even if `//host` is interpreted as a *root-name*, both of the paths
647
+ `path("//host")/"foo"` and `path("//host/")/"foo"` equal `"//host/foo"`
648
+ (although the former might use backslash as the preferred separator).
649
 
650
  Expression examples:
651
 
652
  ``` cpp
653
  // On POSIX,
654
+ path("foo") /= path(""); // yields path("foo/")
655
+ path("foo") /= path("/bar"); // yields path("/bar")
 
656
 
657
  // On Windows,
658
+ path("foo") /= path(""); // yields path("foo\{")}
659
+ path("foo") /= path("/bar"); // yields path("/bar")
660
+ path("foo") /= path("c:/bar"); // yields path("c:/bar")
661
+ path("foo") /= path("c:"); // yields path("c:")
662
+ path("c:") /= path(""); // yields path("c:")
663
+ path("c:foo") /= path("/bar"); // yields path("c:/bar")
664
+ path("c:foo") /= path("c:bar"); // yields path("c:foo\{bar")}
665
  ```
666
 
667
  — *end example*]
668
 
669
  *Returns:* `*this`.
 
682
  path& append(InputIterator first, InputIterator last);
683
  ```
684
 
685
  *Effects:* Equivalent to: `return operator/=(path(first, last));`
686
 
687
+ ##### Concatenation <a id="fs.path.concat">[[fs.path.concat]]</a>
688
 
689
  ``` cpp
690
  path& operator+=(const path& x);
691
  path& operator+=(const string_type& x);
692
  path& operator+=(basic_string_view<value_type> x);
693
  path& operator+=(const value_type* x);
 
694
  template<class Source>
695
  path& operator+=(const Source& x);
 
 
696
  template<class Source>
697
  path& concat(const Source& x);
698
  ```
699
 
700
  *Effects:* Appends `path(x).native()` to the pathname in the native
 
703
  [*Note 2*: This directly manipulates the value of `native()` and may
704
  not be portable between operating systems. — *end note*]
705
 
706
  *Returns:* `*this`.
707
 
708
+ ``` cpp
709
+ path& operator+=(value_type x);
710
+ template<class EcharT>
711
+ path& operator+=(EcharT x);
712
+ ```
713
+
714
+ *Effects:* Equivalent to: `return *this += basic_string_view(&x, 1);`
715
+
716
  ``` cpp
717
  template<class InputIterator>
718
  path& concat(InputIterator first, InputIterator last);
719
  ```
720
 
721
+ *Effects:* Equivalent to: `return *this += path(first, last);`
722
 
723
+ ##### Modifiers <a id="fs.path.modifiers">[[fs.path.modifiers]]</a>
724
 
725
  ``` cpp
726
  void clear() noexcept;
727
  ```
728
 
729
+ *Ensures:* `empty() == true`.
730
 
731
  ``` cpp
732
  path& make_preferred();
733
  ```
734
 
 
766
 
767
  ``` cpp
768
  path& remove_filename();
769
  ```
770
 
 
 
771
  *Effects:* Remove the generic format pathname of `filename()` from the
772
  generic format pathname.
773
 
774
+ *Ensures:* `!has_filename()`.
775
+
776
  *Returns:* `*this`.
777
 
778
  [*Example 4*:
779
 
780
  ``` cpp
 
812
  path& replace_extension(const path& replacement = path());
813
  ```
814
 
815
  *Effects:*
816
 
817
+ - Any existing `extension()` [[fs.path.decompose]] is removed from the
818
+ pathname in the generic format, then
819
  - If `replacement` is not empty and does not begin with a dot character,
820
  a dot character is appended to the pathname in the generic format,
821
  then
822
  - `operator+=(replacement);`.
823
 
 
829
 
830
  *Effects:* Swaps the contents (in all formats) of the two paths.
831
 
832
  *Complexity:* Constant time.
833
 
834
+ ##### Native format observers <a id="fs.path.native.obs">[[fs.path.native.obs]]</a>
835
 
836
  The string returned by all native format observers is in the native
837
+ pathname format [[fs.class.path]].
838
 
839
  ``` cpp
840
  const string_type& native() const noexcept;
841
  ```
842
 
 
844
 
845
  ``` cpp
846
  const value_type* c_str() const noexcept;
847
  ```
848
 
849
+ *Effects:* Equivalent to: `return native().c_str();`
850
 
851
  ``` cpp
852
  operator string_type() const;
853
  ```
854
 
 
872
  [[fs.path.cvt]].
873
 
874
  ``` cpp
875
  std::string string() const;
876
  std::wstring wstring() const;
877
+ std::u8string u8string() const;
878
  std::u16string u16string() const;
879
  std::u32string u32string() const;
880
  ```
881
 
882
+ *Returns:* `native()`.
883
 
884
  *Remarks:* Conversion, if any, is performed as specified by
885
+ [[fs.path.cvt]].
 
886
 
887
+ ##### Generic format observers <a id="fs.path.generic.obs">[[fs.path.generic.obs]]</a>
888
 
889
  Generic format observer functions return strings formatted according to
890
+ the generic pathname format [[fs.path.generic]]. A single slash (`'/'`)
891
+ character is used as the *directory-separator*.
892
 
893
  [*Example 1*:
894
 
895
  On an operating system that uses backslash as its *preferred-separator*,
896
 
 
916
  [[fs.path.cvt]].
917
 
918
  ``` cpp
919
  std::string generic_string() const;
920
  std::wstring generic_wstring() const;
921
+ std::u8string generic_u8string() const;
922
  std::u16string generic_u16string() const;
923
  std::u32string generic_u32string() const;
924
  ```
925
 
926
  *Returns:* The pathname in the generic format.
927
 
928
+ *Remarks:* Conversion, if any, is specified by  [[fs.path.cvt]].
 
929
 
930
+ ##### Compare <a id="fs.path.compare">[[fs.path.compare]]</a>
931
 
932
  ``` cpp
933
  int compare(const path& p) const noexcept;
934
  ```
935
 
936
  *Returns:*
937
 
938
+ - Let `rootNameComparison` be the result of
939
+ `this->root_name().native().compare(p.root_name().native())`. If
940
+ `rootNameComparison` is not `0`, `rootNameComparison`.
941
+ - Otherwise, if `!this->has_root_directory()` and
942
+ `p.has_root_directory()`, a value less than `0`.
943
+ - Otherwise, if `this->has_root_directory()` and
944
+ `!p.has_root_directory()`, a value greater than `0`.
945
+ - Otherwise, if `native()` for the elements of `this->relative_path()`
946
+ are lexicographically less than `native()` for the elements of
947
+ `p.relative_path()`, a value less than `0`.
948
+ - Otherwise, if `native()` for the elements of `this->relative_path()`
949
+ are lexicographically greater than `native()` for the elements of
950
+ `p.relative_path()`, a value greater than `0`.
951
+ - Otherwise, `0`.
952
 
953
  ``` cpp
954
+ int compare(const string_type& s) const;
955
  int compare(basic_string_view<value_type> s) const;
956
+ int compare(const value_type* s) const;
957
  ```
958
 
959
+ *Effects:* Equivalent to: `return compare(path(s));`
960
 
961
+ ##### Decomposition <a id="fs.path.decompose">[[fs.path.decompose]]</a>
 
 
 
 
 
 
962
 
963
  ``` cpp
964
  path root_name() const;
965
  ```
966
 
 
983
  ``` cpp
984
  path relative_path() const;
985
  ```
986
 
987
  *Returns:* A `path` composed from the pathname in the generic format, if
988
+ `empty()` is `false`, beginning with the first *filename* after
989
+ `root_path()`. Otherwise, `path()`.
990
 
991
  ``` cpp
992
  path parent_path() const;
993
  ```
994
 
995
+ *Returns:* `*this` if `has_relative_path()` is `false`, otherwise a path
996
+ whose generic format pathname is the longest prefix of the generic
997
+ format pathname of `*this` that produces one fewer element in its
998
+ iteration.
999
 
1000
  ``` cpp
1001
  path filename() const;
1002
  ```
1003
 
 
1044
 
1045
  ``` cpp
1046
  path extension() const;
1047
  ```
1048
 
1049
+ *Returns:* A path whose pathname in the generic format is the suffix of
1050
  `filename()` not included in `stem()`.
1051
 
1052
  [*Example 8*:
1053
 
1054
  ``` cpp
 
1067
 
1068
  [*Note 5*: On non-POSIX operating systems, for a path `p`, it may not
1069
  be the case that `p.stem() + p.extension() == p.filename()`, even though
1070
  the generic format pathnames are the same. — *end note*]
1071
 
1072
+ ##### Query <a id="fs.path.query">[[fs.path.query]]</a>
1073
 
1074
  ``` cpp
1075
+ [[nodiscard]] bool empty() const noexcept;
1076
  ```
1077
 
1078
+ *Returns:* `true` if the pathname in the generic format is empty,
1079
+ otherwise `false`.
1080
 
1081
  ``` cpp
1082
  bool has_root_path() const;
1083
  ```
1084
 
 
1129
  ``` cpp
1130
  bool is_absolute() const;
1131
  ```
1132
 
1133
  *Returns:* `true` if the pathname in the native format contains an
1134
+ absolute path [[fs.class.path]], otherwise `false`.
1135
 
1136
  [*Example 9*: `path("/").is_absolute()` is `true` for POSIX-based
1137
  operating systems, and `false` for Windows-based operating
1138
  systems. — *end example*]
1139
 
 
1141
  bool is_relative() const;
1142
  ```
1143
 
1144
  *Returns:* `!is_absolute()`.
1145
 
1146
+ ##### Generation <a id="fs.path.gen">[[fs.path.gen]]</a>
1147
 
1148
  ``` cpp
1149
  path lexically_normal() const;
1150
  ```
1151
 
1152
  *Returns:* A path whose pathname in the generic format is the normal
1153
+ form [[fs.path.generic]] of the pathname in the generic format of
1154
  `*this`.
1155
 
1156
  [*Example 10*:
1157
 
1158
  ``` cpp
 
1169
  ``` cpp
1170
  path lexically_relative(const path& base) const;
1171
  ```
1172
 
1173
  *Returns:* `*this` made relative to `base`. Does not
1174
+ resolve [[fs.class.path]] symlinks. Does not first
1175
+ normalize [[fs.path.generic]] `*this` or `base`.
1176
+
1177
+ *Effects:* If:
1178
+
1179
+ - `root_name() != base.root_name()` is `true`, or
1180
+ - `is_absolute() != base.is_absolute()` is `true`, or
1181
+ - `!has_root_directory() && base.has_root_directory()` is `true`, or
1182
+ - any *filename* in `relative_path()` or `base.relative_path()` can be
1183
+ interpreted as a *root-name*,
1184
+
1185
+ returns `path()`.
1186
+
1187
+ [*Note 6*: On a POSIX implementation, no *filename* in a
1188
+ *relative-path* is acceptable as a *root-name*. — *end note*]
1189
+
1190
+ Determines the first mismatched element of `*this` and `base` as if by:
1191
 
1192
  ``` cpp
1193
  auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
1194
  ```
1195
 
1196
  Then,
1197
 
1198
  - if `a == end()` and `b == base.end()`, returns `path(".")`; otherwise
1199
  - let `n` be the number of *filename* elements in \[`b`, `base.end()`)
1200
+ that are not dot or dot-dot or empty, minus the number that are
1201
+ dot-dot. If `n<0,` returns `path()`; otherwise
1202
+ - if `n == 0` and `(a == end() || a->empty())`, returns `path(".")`;
1203
+ otherwise
1204
  - returns an object of class `path` that is default-constructed,
1205
  followed by
1206
  - application of `operator/=(path(".."))` `n` times, and then
1207
  - application of `operator/=` for each element in \[`a`, `end()`).
1208
 
 
1221
  *directory-separator* characters will be backslashes rather than
1222
  slashes, but that does not affect `path` equality.
1223
 
1224
  — *end example*]
1225
 
1226
+ [*Note 7*: If symlink following semantics are desired, use the
1227
  operational function `relative()`. — *end note*]
1228
 
1229
+ [*Note 8*: If normalization [[fs.path.generic]] is needed to ensure
1230
+ consistent matching of elements, apply `lexically_normal()` to `*this`,
1231
+ `base`, or both. — *end note*]
1232
 
1233
  ``` cpp
1234
  path lexically_proximate(const path& base) const;
1235
  ```
1236
 
1237
  *Returns:* If the value of `lexically_relative(base)` is not an empty
1238
  path, return it. Otherwise return `*this`.
1239
 
1240
+ [*Note 9*: If symlink following semantics are desired, use the
1241
  operational function `proximate()`. — *end note*]
1242
 
1243
+ [*Note 10*: If normalization [[fs.path.generic]] is needed to ensure
1244
+ consistent matching of elements, apply `lexically_normal()` to `*this`,
1245
+ `base`, or both. — *end note*]
1246
 
1247
+ #### Iterators <a id="fs.path.itr">[[fs.path.itr]]</a>
1248
 
1249
  Path iterators iterate over the elements of the pathname in the generic
1250
+ format [[fs.path.generic]].
1251
 
1252
+ A `path::iterator` is a constant iterator meeting all the requirements
1253
+ of a bidirectional iterator [[bidirectional.iterators]] except that, for
1254
+ dereferenceable iterators `a` and `b` of type `path::iterator` with
1255
+ `a == b`, there is no requirement that `*a` and `*b` are bound to the
1256
+ same object. Its `value_type` is `path`.
1257
 
1258
  Calling any non-const member function of a `path` object invalidates all
1259
  iterators referring to elements of that object.
1260
 
1261
  For the elements of the pathname in the generic format, the forward
 
1282
  iterator end() const;
1283
  ```
1284
 
1285
  *Returns:* The end iterator.
1286
 
1287
+ #### Inserter and extractor <a id="fs.path.io">[[fs.path.io]]</a>
1288
+
1289
+ ``` cpp
1290
+ template<class charT, class traits>
1291
+ friend basic_ostream<charT, traits>&
1292
+ operator<<(basic_ostream<charT, traits>& os, const path& p);
1293
+ ```
1294
+
1295
+ *Effects:* Equivalent to `os << quoted(p.string<charT, traits>())`.
1296
+
1297
+ [*Note 1*: The `quoted` function is described
1298
+ in  [[quoted.manip]]. — *end note*]
1299
+
1300
+ *Returns:* `os`.
1301
+
1302
+ ``` cpp
1303
+ template<class charT, class traits>
1304
+ friend basic_istream<charT, traits>&
1305
+ operator>>(basic_istream<charT, traits>& is, path& p);
1306
+ ```
1307
+
1308
+ *Effects:* Equivalent to:
1309
+
1310
+ ``` cpp
1311
+ basic_string<charT, traits> tmp;
1312
+ is >> quoted(tmp);
1313
+ p = tmp;
1314
+ ```
1315
+
1316
+ *Returns:* `is`.
1317
+
1318
+ #### Non-member functions <a id="fs.path.nonmember">[[fs.path.nonmember]]</a>
1319
 
1320
  ``` cpp
1321
  void swap(path& lhs, path& rhs) noexcept;
1322
  ```
1323
 
1324
+ *Effects:* Equivalent to `lhs.swap(rhs)`.
1325
 
1326
  ``` cpp
1327
  size_t hash_value (const path& p) noexcept;
1328
  ```
1329
 
1330
  *Returns:* A hash value for the path `p`. If for two paths, `p1 == p2`
1331
  then `hash_value(p1) == hash_value(p2)`.
1332
 
1333
  ``` cpp
1334
+ friend bool operator==(const path& lhs, const path& rhs) noexcept;
1335
  ```
1336
 
1337
+ *Returns:* `lhs.compare(rhs) == 0`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1338
 
1339
  [*Note 1*:
1340
 
1341
  Path equality and path equivalence have different semantics.
1342
 
1343
  - Equality is determined by the `path` non-member `operator==`, which
1344
+ considers the two paths’ lexical representations only.
1345
  \[*Example 1*: `path("foo") == "bar"` is never
1346
  `true`. — *end example*]
1347
  - Equivalence is determined by the `equivalent()` non-member function,
1348
+ which determines if two paths resolve [[fs.class.path]] to the same
1349
+ file system entity. \[*Example 2*: `equivalent("foo", "bar")` will be
1350
+ `true` when both paths resolve to the same file. — *end example*]
 
1351
 
1352
  Programmers wishing to determine if two paths are “the same” must decide
1353
  if “the same” means “the same representation” or “resolve to the same
1354
  actual file”, and choose the appropriate function accordingly.
1355
 
1356
  — *end note*]
1357
 
1358
  ``` cpp
1359
+ friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept;
1360
  ```
1361
 
1362
+ *Returns:* `lhs.compare(rhs) <=> 0`.
1363
 
1364
  ``` cpp
1365
+ friend path operator/ (const path& lhs, const path& rhs);
1366
  ```
1367
 
1368
  *Effects:* Equivalent to: `return path(lhs) /= rhs;`
1369