2163 lines
88 KiB
Markdown
2163 lines
88 KiB
Markdown
[fs.class.path]
|
||
|
||
# 31 Input/output library [[input.output]](./#input.output)
|
||
|
||
## 31.12 File systems [[filesystems]](filesystems#fs.class.path)
|
||
|
||
### 31.12.6 Class path [fs.class.path]
|
||
|
||
#### [31.12.6.1](#general) General [[fs.class.path.general]](fs.class.path.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13559)
|
||
|
||
An object of class path represents a path
|
||
and contains a pathname[.](#general-1.sentence-1)
|
||
|
||
Such an object is concerned only with the lexical and syntactic aspects
|
||
of a path[.](#general-1.sentence-2)
|
||
|
||
The path does not necessarily exist in external storage, and the
|
||
pathname is not necessarily valid for the current operating
|
||
system or for a particular file system[.](#general-1.sentence-3)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13567)
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
Class path is used to support the differences
|
||
between the string types used by different operating systems
|
||
to represent pathnames,
|
||
and to perform conversions between encodings when necessary[.](#general-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13575)
|
||
|
||
A [*path*](#def:path "31.12.6.1 General [fs.class.path.general]") is
|
||
a sequence of elements that identify
|
||
the location of a file within a filesystem[.](#general-3.sentence-1)
|
||
|
||
The elements are the[*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")opt,[*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]")opt,
|
||
and an optional sequence of [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]")*s* ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format"))[.](#general-3.sentence-2)
|
||
|
||
The maximum number of elements in the sequence is
|
||
operating system dependent ([[fs.conform.os]](fs.conform.os "31.12.2.3 Operating system dependent behavior conformance"))[.](#general-3.sentence-3)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13586)
|
||
|
||
An [*absolute path*](#def:path,absolute "31.12.6.1 General [fs.class.path.general]") is a path that unambiguously
|
||
identifies the location of a file without reference to an additional starting
|
||
location[.](#general-4.sentence-1)
|
||
|
||
The elements of a path that determine if it is absolute are
|
||
operating system dependent[.](#general-4.sentence-2)
|
||
|
||
A [*relative path*](#def:path,relative "31.12.6.1 General [fs.class.path.general]") is
|
||
a path that is not absolute, and as such, only unambiguously
|
||
identifies the location of a file when resolved relative to
|
||
an implied starting location[.](#general-4.sentence-3)
|
||
|
||
The elements of a path that determine if it is
|
||
relative are operating system dependent[.](#general-4.sentence-4)
|
||
|
||
[*Note [2](#general-note-2)*:
|
||
|
||
Pathnames â.â and â..â are relative paths[.](#general-4.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[5](#general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13600)
|
||
|
||
A [*pathname*](#def:pathname "31.12.6.1 General [fs.class.path.general]") is
|
||
a character string that represents the name of a path[.](#general-5.sentence-1)
|
||
|
||
Pathnames are
|
||
formatted according to the generic pathname format grammar ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format"))
|
||
or according to an
|
||
operating system dependent[*native pathname format*](#def:native_pathname_format "31.12.6.1 General [fs.class.path.general]") accepted by the host operating system[.](#general-5.sentence-2)
|
||
|
||
[6](#general-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13608)
|
||
|
||
[*Pathname resolution*](#def:pathname_resolution "31.12.6.1 General [fs.class.path.general]") is the operating system dependent mechanism for resolving
|
||
a pathname to a particular file in a file hierarchy[.](#general-6.sentence-1)
|
||
|
||
There may be multiple
|
||
pathnames that resolve to the same file[.](#general-6.sentence-2)
|
||
|
||
[*Example [1](#general-example-1)*:
|
||
|
||
For POSIX-based operating systems,
|
||
this mechanism is specified in POSIX, section 4.12, Pathname resolution[.](#general-6.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
namespace std::filesystem {class path {public:using value_type = *see below*; using string_type = basic_string<value_type>; static constexpr value_type preferred_separator = *see below*; // [[fs.enum.path.format]](fs.enum.path.format "31.12.8.1 Enum path::format"), enumeration formatenum format; // [[fs.path.construct]](#fs.path.construct "31.12.6.5.1 Constructors"), constructors and destructor path() noexcept;
|
||
path(const path& p);
|
||
path(path&& p) noexcept;
|
||
path(string_type&& source, format fmt = auto_format); template<class Source> path(const Source& source, format fmt = auto_format); template<class InputIterator> path(InputIterator first, InputIterator last, format fmt = auto_format); template<class Source> path(const Source& source, const locale& loc, format fmt = auto_format); template<class InputIterator> path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); ~path(); // [[fs.path.assign]](#fs.path.assign "31.12.6.5.2 Assignments"), assignments path& operator=(const path& p);
|
||
path& operator=(path&& p) noexcept;
|
||
path& operator=(string_type&& source);
|
||
path& assign(string_type&& source); template<class Source> path& operator=(const Source& source); template<class Source> path& assign(const Source& source); template<class InputIterator> path& assign(InputIterator first, InputIterator last); // [[fs.path.append]](#fs.path.append "31.12.6.5.3 Appends"), appends path& operator/=(const path& p); template<class Source> path& operator/=(const Source& source); template<class Source> path& append(const Source& source); template<class InputIterator> path& append(InputIterator first, InputIterator last); // [[fs.path.concat]](#fs.path.concat "31.12.6.5.4 Concatenation"), concatenation path& operator+=(const path& x);
|
||
path& operator+=(const string_type& x);
|
||
path& operator+=(basic_string_view<value_type> x);
|
||
path& operator+=(const value_type* x);
|
||
path& operator+=(value_type x); template<class Source> path& operator+=(const Source& x); template<class EcharT> path& operator+=(EcharT x); template<class Source> path& concat(const Source& x); template<class InputIterator> path& concat(InputIterator first, InputIterator last); // [[fs.path.modifiers]](#fs.path.modifiers "31.12.6.5.5 Modifiers"), modifiersvoid clear() noexcept;
|
||
path& make_preferred();
|
||
path& remove_filename();
|
||
path& replace_filename(const path& replacement);
|
||
path& replace_extension(const path& replacement = path()); void swap(path& rhs) noexcept; // [[fs.path.nonmember]](#fs.path.nonmember "31.12.6.8 Non-member functions"), non-member operatorsfriend bool operator==(const path& lhs, const path& rhs) noexcept; friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; friend path operator/(const path& lhs, const path& rhs); // [[fs.path.native.obs]](#fs.path.native.obs "31.12.6.5.6 Native format observers"), native format observersconst string_type& native() const noexcept; const value_type* c_str() const noexcept; operator string_type() const; template<class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>> basic_string<EcharT, traits, Allocator> string(const Allocator& a = Allocator()) const;
|
||
std::string display_string() const;
|
||
std::string system_encoded_string() const;
|
||
std::wstring wstring() const;
|
||
std::u8string u8string() const;
|
||
std::u16string u16string() const;
|
||
std::u32string u32string() const; // [[fs.path.generic.obs]](#fs.path.generic.obs "31.12.6.5.7 Generic format observers"), generic format observerstemplate<class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>> basic_string<EcharT, traits, Allocator> generic_string(const Allocator& a = Allocator()) const;
|
||
std::string generic_display_string() const;
|
||
std::string generic_system_encoded_string() const;
|
||
std::wstring generic_wstring() const;
|
||
std::u8string generic_u8string() const;
|
||
std::u16string generic_u16string() const;
|
||
std::u32string generic_u32string() const; // [[fs.path.compare]](#fs.path.compare "31.12.6.5.8 Compare"), compareint compare(const path& p) const noexcept; int compare(const string_type& s) const; int compare(basic_string_view<value_type> s) const; int compare(const value_type* s) const; // [[fs.path.decompose]](#fs.path.decompose "31.12.6.5.9 Decomposition"), decomposition path root_name() const;
|
||
path root_directory() const;
|
||
path root_path() const;
|
||
path relative_path() const;
|
||
path parent_path() const;
|
||
path filename() const;
|
||
path stem() const;
|
||
path extension() const; // [[fs.path.query]](#fs.path.query "31.12.6.5.10 Query"), querybool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; bool has_root_path() const; bool has_relative_path() const; bool has_parent_path() const; bool has_filename() const; bool has_stem() const; bool has_extension() const; bool is_absolute() const; bool is_relative() const; // [[fs.path.gen]](#fs.path.gen "31.12.6.5.11 Generation"), generation path lexically_normal() const;
|
||
path lexically_relative(const path& base) const;
|
||
path lexically_proximate(const path& base) const; // [[fs.path.itr]](#fs.path.itr "31.12.6.6 Iterators"), iteratorsclass iterator; using const_iterator = iterator;
|
||
|
||
iterator begin() const;
|
||
iterator end() const; // [[fs.path.io]](#fs.path.io "31.12.6.7 Inserter and extractor"), path inserter and extractortemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const path& p); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, path& p); };}
|
||
|
||
[7](#general-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13775)
|
||
|
||
value_type is a typedef for the
|
||
operating system dependent encoded character type used to represent pathnames[.](#general-7.sentence-1)
|
||
|
||
[8](#general-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13780)
|
||
|
||
The value of the preferred_separator member
|
||
is the operating system dependent [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") character ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format"))[.](#general-8.sentence-1)
|
||
|
||
[9](#general-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13784)
|
||
|
||
[*Example [2](#general-example-2)*:
|
||
|
||
For POSIX-based operating systems,value_type is char andpreferred_separator is the slash character ('/')[.](#general-9.sentence-1)
|
||
|
||
For Windows-based operating systems,value_type is wchar_t andpreferred_separator is the backslash character (L'\\')[.](#general-9.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
#### [31.12.6.2](#fs.path.generic) Generic pathname format [[fs.path.generic]](fs.path.generic)
|
||
|
||
[pathname:](#nt:pathname "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
[*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")opt [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]")opt [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
|
||
[root-name:](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
operating system dependent sequences of characters
|
||
implementation-defined sequences of characters
|
||
|
||
[root-directory:](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
[*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
|
||
[relative-path:](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
[*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
[*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
an empty path
|
||
|
||
[filename:](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
non-empty sequence of characters other than [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
|
||
|
||
[directory-separator:](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
[*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")opt
|
||
[*fallback-separator*](#nt:fallback-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")opt
|
||
|
||
[preferred-separator:](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
operating system dependent directory separator character
|
||
|
||
[fallback-separator:](#nt:fallback-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
|
||
/, if [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") is not /
|
||
|
||
[1](#fs.path.generic-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13843)
|
||
|
||
A [*filename*](#def:filename "31.12.6.2 Generic pathname format [fs.path.generic]") is
|
||
the name of a file[.](#fs.path.generic-1.sentence-1)
|
||
|
||
The [*dot*](#def:dot,filename "31.12.6.2 Generic pathname format [fs.path.generic]") and [*dot-dot*](#def:dot-dot,filename "31.12.6.2 Generic pathname format [fs.path.generic]") filenames,
|
||
consisting solely of one and two period characters respectively,
|
||
have special meaning[.](#fs.path.generic-1.sentence-2)
|
||
|
||
The following characteristics of filenames are operating system dependent:
|
||
|
||
- [(1.1)](#fs.path.generic-1.1)
|
||
|
||
The permitted characters[.](#fs.path.generic-1.1.sentence-1)
|
||
[*Example [1](#fs.path.generic-example-1)*:
|
||
Some operating systems prohibit
|
||
the ASCII control characters (0x00 â 0x1F) in filenames[.](#fs.path.generic-1.1.sentence-2)
|
||
â *end example*]
|
||
[*Note [1](#fs.path.generic-note-1)*:
|
||
Wider portability can be achieved by limiting [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") characters to the POSIX Portable Filename Character Set:
|
||
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
|
||
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
|
||
0 1 2 3 4 5 6 7 8 9 . _ -
|
||
â *end note*]
|
||
|
||
- [(1.2)](#fs.path.generic-1.2)
|
||
|
||
The maximum permitted length[.](#fs.path.generic-1.2.sentence-1)
|
||
|
||
- [(1.3)](#fs.path.generic-1.3)
|
||
|
||
Filenames that are not permitted[.](#fs.path.generic-1.3.sentence-1)
|
||
|
||
- [(1.4)](#fs.path.generic-1.4)
|
||
|
||
Filenames that have special meaning[.](#fs.path.generic-1.4.sentence-1)
|
||
|
||
- [(1.5)](#fs.path.generic-1.5)
|
||
|
||
Case awareness and sensitivity during path resolution[.](#fs.path.generic-1.5.sentence-1)
|
||
|
||
- [(1.6)](#fs.path.generic-1.6)
|
||
|
||
Special rules that may apply to file types other than regular
|
||
files, such as directories[.](#fs.path.generic-1.6.sentence-1)
|
||
|
||
[2](#fs.path.generic-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13870)
|
||
|
||
Except in a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"),
|
||
multiple successive [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters are considered to
|
||
be the same as one [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") character[.](#fs.path.generic-2.sentence-1)
|
||
|
||
[3](#fs.path.generic-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13875)
|
||
|
||
The dot filename is treated as a reference to the current directory[.](#fs.path.generic-3.sentence-1)
|
||
|
||
The dot-dot filename is treated as a reference to the parent directory[.](#fs.path.generic-3.sentence-2)
|
||
|
||
What the dot-dot filename refers to
|
||
relative to [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]") is implementation-defined[.](#fs.path.generic-3.sentence-3)
|
||
|
||
Specific filenames may have special meanings for a particular operating system[.](#fs.path.generic-3.sentence-4)
|
||
|
||
[4](#fs.path.generic-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13882)
|
||
|
||
A [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") identifies the
|
||
starting location for pathname resolution ([fs.class.path])[.](#fs.path.generic-4.sentence-1)
|
||
|
||
If there are no operating system dependent [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")*s*,
|
||
at least one implementation-defined [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") is required[.](#fs.path.generic-4.sentence-2)
|
||
|
||
[*Note [2](#fs.path.generic-note-2)*:
|
||
|
||
Many operating systems define a name
|
||
beginning with two [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
|
||
as a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") that identifies
|
||
network or other resource locations[.](#fs.path.generic-4.sentence-3)
|
||
|
||
Some operating systems
|
||
define a single letter followed by a colon
|
||
as a drive specifier â a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") identifying a specific device such as a disk drive[.](#fs.path.generic-4.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[5](#fs.path.generic-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13898)
|
||
|
||
If a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") is otherwise ambiguous,
|
||
the possibility with the longest sequence of characters is chosen[.](#fs.path.generic-5.sentence-1)
|
||
|
||
[*Note [3](#fs.path.generic-note-3)*:
|
||
|
||
On a POSIX-like operating system, it is impossible to have a[*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") and a [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]") without an intervening [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]") element[.](#fs.path.generic-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[6](#fs.path.generic-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13907)
|
||
|
||
[*Normalization*](#def:normalization,path "31.12.6.2 Generic pathname format [fs.path.generic]") of a generic format pathname means:
|
||
|
||
| [1.](#fs.path.generic-6.1) | If the path is empty, stop[.](#fs.path.generic-6.1.sentence-1) |
|
||
| --- | --- |
|
||
| [2.](#fs.path.generic-6.2) | Replace each slash character in the [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") with a [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic-6.2.sentence-1) |
|
||
| [3.](#fs.path.generic-6.3) | Replace each [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") with a [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic-6.3.sentence-1)<br>[*Note [4](#fs.path.generic-note-4)*:<br>The generic pathname grammar defines [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") as one or more slashes and [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")*s*[.](#fs.path.generic-6.3.sentence-2) â *end note*] |
|
||
| [4.](#fs.path.generic-6.4) | Remove each dot filename and any immediately following [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic-6.4.sentence-1) |
|
||
| [5.](#fs.path.generic-6.5) | As long as any appear, remove a non-dot-dot filename immediately followed by a [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") and a dot-dot filename, along with any immediately following [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic-6.5.sentence-1) |
|
||
| [6.](#fs.path.generic-6.6) | If there is a [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]"), remove all dot-dot filenames and any [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")*s* immediately following them[.](#fs.path.generic-6.6.sentence-1)<br>[*Note [5](#fs.path.generic-note-5)*:<br>These dot-dot filenames attempt to refer to nonexistent parent directories[.](#fs.path.generic-6.6.sentence-2) â *end note*] |
|
||
| [7.](#fs.path.generic-6.7) | If the last filename is dot-dot, remove any trailing [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic-6.7.sentence-1) |
|
||
| [8.](#fs.path.generic-6.8) | If the path is empty, add a dot[.](#fs.path.generic-6.8.sentence-1) |
|
||
|
||
The result of normalization is a path in [*normal form*](#def:normal_form,path "31.12.6.2 Generic pathname format [fs.path.generic]"),
|
||
which is said to be [*normalized*](#def:normalized)[.](#fs.path.generic-6.sentence-2)
|
||
|
||
#### [31.12.6.3](#fs.path.cvt) Conversions [[fs.path.cvt]](fs.path.cvt)
|
||
|
||
#### [31.12.6.3.1](#fs.path.fmt.cvt) Argument format conversions [[fs.path.fmt.cvt]](fs.path.fmt.cvt)
|
||
|
||
[1](#fs.path.fmt.cvt-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13935)
|
||
|
||
[*Note [1](#fs.path.fmt.cvt-note-1)*:
|
||
|
||
The format conversions described in this subclause
|
||
are not applied on POSIX-based operating systems
|
||
because on these systems:
|
||
|
||
- [(1.1)](#fs.path.fmt.cvt-1.1)
|
||
|
||
The generic format is acceptable as a native path[.](#fs.path.fmt.cvt-1.1.sentence-1)
|
||
|
||
- [(1.2)](#fs.path.fmt.cvt-1.2)
|
||
|
||
There is no need to distinguish between native format and generic format in function arguments[.](#fs.path.fmt.cvt-1.2.sentence-1)
|
||
|
||
- [(1.3)](#fs.path.fmt.cvt-1.3)
|
||
|
||
Paths for regular files and paths for directories share the same syntax[.](#fs.path.fmt.cvt-1.3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#fs.path.fmt.cvt-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13947)
|
||
|
||
Several functions are defined to accept [*detected-format*](#def:detected-format) arguments,
|
||
which are character sequences[.](#fs.path.fmt.cvt-2.sentence-1)
|
||
|
||
A detected-format argument represents a path
|
||
using either a pathname in the generic format ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format"))
|
||
or a pathname in the native format ([fs.class.path])[.](#fs.path.fmt.cvt-2.sentence-2)
|
||
|
||
Such an argument is taken to be in the generic format if and only if
|
||
it matches the generic format and is not acceptable to the operating system
|
||
as a native path[.](#fs.path.fmt.cvt-2.sentence-3)
|
||
|
||
[3](#fs.path.fmt.cvt-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13956)
|
||
|
||
[*Note [2](#fs.path.fmt.cvt-note-2)*:
|
||
|
||
Some operating systems have no unambiguous way to distinguish between native format and generic format arguments[.](#fs.path.fmt.cvt-3.sentence-1)
|
||
|
||
This is by design as it simplifies use for operating systems that do not require
|
||
disambiguation[.](#fs.path.fmt.cvt-3.sentence-2)
|
||
|
||
It is possible that an implementation for an operating system
|
||
where disambiguation is needed distinguishes between the formats[.](#fs.path.fmt.cvt-3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[4](#fs.path.fmt.cvt-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13964)
|
||
|
||
Pathnames are converted as needed between the generic and native formats
|
||
in an operating-system-dependent manner[.](#fs.path.fmt.cvt-4.sentence-1)
|
||
|
||
Let *G(n)* and *N(g)* in a mathematical sense
|
||
be the implementation's functions that convert native-to-generic
|
||
and generic-to-native formats respectively[.](#fs.path.fmt.cvt-4.sentence-2)
|
||
|
||
If *g=G(n)* for some *n*, then *G(N(g))=g*;
|
||
if *n=N(g)* for some *g*, then *N(G(n))=n*[.](#fs.path.fmt.cvt-4.sentence-3)
|
||
|
||
[*Note [3](#fs.path.fmt.cvt-note-3)*:
|
||
|
||
Neither *G* nor *N* need be invertible[.](#fs.path.fmt.cvt-4.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[5](#fs.path.fmt.cvt-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13976)
|
||
|
||
If the native format requires paths for regular files to be formatted
|
||
differently from paths for directories, the path shall be treated as a directory
|
||
path if its last element is a [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]"),
|
||
otherwise it shall be treated as a path to a regular file[.](#fs.path.fmt.cvt-5.sentence-1)
|
||
|
||
[6](#fs.path.fmt.cvt-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13982)
|
||
|
||
[*Note [4](#fs.path.fmt.cvt-note-4)*:
|
||
|
||
A path stores a native format pathname ([[fs.path.native.obs]](#fs.path.native.obs "31.12.6.5.6 Native format observers"))
|
||
and acts as if it also stores a generic format pathname,
|
||
related as given below[.](#fs.path.fmt.cvt-6.sentence-1)
|
||
|
||
The implementation can generate the generic format pathname
|
||
based on the native format pathname (and possibly other information)
|
||
when requested[.](#fs.path.fmt.cvt-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[7](#fs.path.fmt.cvt-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13992)
|
||
|
||
When a path is constructed from or is assigned a single representation
|
||
separate from any path, the other representation is selected
|
||
by the appropriate conversion function (*G* or *N*)[.](#fs.path.fmt.cvt-7.sentence-1)
|
||
|
||
[8](#fs.path.fmt.cvt-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13997)
|
||
|
||
When the (new) value *p* of one representation of a path
|
||
is derived from the representation of that or another path,
|
||
a value *q* is chosen for the other representation[.](#fs.path.fmt.cvt-8.sentence-1)
|
||
|
||
The value *q* converts to *p* (by *G* or *N* as appropriate)
|
||
if any such value does so;*q* is otherwise unspecified[.](#fs.path.fmt.cvt-8.sentence-2)
|
||
|
||
[*Note [5](#fs.path.fmt.cvt-note-5)*:
|
||
|
||
If *q* is the result of converting any path at all,
|
||
it is the result of converting *p*[.](#fs.path.fmt.cvt-8.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
#### [31.12.6.3.2](#fs.path.type.cvt) Type and encoding conversions [[fs.path.type.cvt]](fs.path.type.cvt)
|
||
|
||
[1](#fs.path.type.cvt-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14013)
|
||
|
||
The [*native encoding*](#def:native_encoding "31.12.6.3.2 Type and encoding conversions [fs.path.type.cvt]") of an ordinary character string is
|
||
the operating system dependent current encoding
|
||
for pathnames ([fs.class.path])[.](#fs.path.type.cvt-1.sentence-1)
|
||
|
||
The [*native encoding*](#def:native_encoding "31.12.6.3.2 Type and encoding conversions [fs.path.type.cvt]") for wide character strings is
|
||
the implementation-defined execution
|
||
wide-character set encoding ([[character.seq]](character.seq "16.3.3.3.4 Character sequences"))[.](#fs.path.type.cvt-1.sentence-2)
|
||
|
||
[2](#fs.path.type.cvt-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14021)
|
||
|
||
For member function arguments that take character sequences representing
|
||
paths and for member functions returning strings, value type and encoding
|
||
conversion is performed if the value type of the argument or return value differs frompath::value_type[.](#fs.path.type.cvt-2.sentence-1)
|
||
|
||
For the argument or return value, the method of conversion and the encoding
|
||
to be converted to is determined
|
||
by its value type:
|
||
|
||
- [(2.1)](#fs.path.type.cvt-2.1)
|
||
|
||
char: The encoding is the native ordinary encoding[.](#fs.path.type.cvt-2.1.sentence-1)
|
||
The method of conversion, if any, is operating system dependent[.](#fs.path.type.cvt-2.1.sentence-2)
|
||
[*Note [1](#fs.path.type.cvt-note-1)*:
|
||
For POSIX-based operating systems path::value_type is char so no conversion from char value type arguments or to char value type return values is performed[.](#fs.path.type.cvt-2.1.sentence-3)
|
||
For Windows-based operating systems, the
|
||
native ordinary encoding is determined by calling a Windows API function[.](#fs.path.type.cvt-2.1.sentence-4)
|
||
â *end note*]
|
||
[*Note [2](#fs.path.type.cvt-note-2)*:
|
||
This results in behavior identical to other C and C++
|
||
standard library functions that perform file operations using ordinary character
|
||
strings to identify paths[.](#fs.path.type.cvt-2.1.sentence-5)
|
||
Changing this behavior would be surprising and
|
||
error-prone[.](#fs.path.type.cvt-2.1.sentence-6)
|
||
â *end note*]
|
||
|
||
- [(2.2)](#fs.path.type.cvt-2.2)
|
||
|
||
wchar_t: The encoding is the native wide encoding[.](#fs.path.type.cvt-2.2.sentence-1)
|
||
The method of conversion is unspecified[.](#fs.path.type.cvt-2.2.sentence-2)
|
||
[*Note [3](#fs.path.type.cvt-note-3)*:
|
||
For Windows-based operating systems path::value_type is wchar_t so no conversion from wchar_t value type arguments or to wchar_t value type return values is performed[.](#fs.path.type.cvt-2.2.sentence-3)
|
||
â *end note*]
|
||
|
||
- [(2.3)](#fs.path.type.cvt-2.3)
|
||
|
||
char8_t: The encoding is UTF-8[.](#fs.path.type.cvt-2.3.sentence-1)
|
||
The method of conversion
|
||
is unspecified[.](#fs.path.type.cvt-2.3.sentence-2)
|
||
|
||
- [(2.4)](#fs.path.type.cvt-2.4)
|
||
|
||
char16_t: The encoding is UTF-16[.](#fs.path.type.cvt-2.4.sentence-1)
|
||
The method of conversion
|
||
is unspecified[.](#fs.path.type.cvt-2.4.sentence-2)
|
||
|
||
- [(2.5)](#fs.path.type.cvt-2.5)
|
||
|
||
char32_t: The encoding is UTF-32[.](#fs.path.type.cvt-2.5.sentence-1)
|
||
The method of conversion
|
||
is unspecified[.](#fs.path.type.cvt-2.5.sentence-2)
|
||
|
||
[3](#fs.path.type.cvt-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14066)
|
||
|
||
If the encoding being converted to has no representation for source
|
||
characters, the resulting converted characters, if any, are unspecified[.](#fs.path.type.cvt-3.sentence-1)
|
||
|
||
Implementations should not modify member function arguments
|
||
if already of type path::value_type[.](#fs.path.type.cvt-3.sentence-2)
|
||
|
||
#### [31.12.6.4](#fs.path.req) Requirements [[fs.path.req]](fs.path.req)
|
||
|
||
[1](#fs.path.req-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14074)
|
||
|
||
In addition to the requirements ([[fs.req]](fs.req "31.12.3 Requirements")),
|
||
function template parameters named Source shall be one of:
|
||
|
||
- [(1.1)](#fs.path.req-1.1)
|
||
|
||
basic_string<EcharT, traits, Allocator>[.](#fs.path.req-1.1.sentence-1)
|
||
A function
|
||
argument const Source& source shall have an
|
||
effective range [source.begin(), source.end())[.](#fs.path.req-1.1.sentence-2)
|
||
|
||
- [(1.2)](#fs.path.req-1.2)
|
||
|
||
basic_string_view<EcharT, traits>[.](#fs.path.req-1.2.sentence-1)
|
||
A function
|
||
argument const Source& source shall have an
|
||
effective range [source.begin(), source.end())[.](#fs.path.req-1.2.sentence-2)
|
||
|
||
- [(1.3)](#fs.path.req-1.3)
|
||
|
||
A type meeting the [*Cpp17InputIterator*](input.iterators#:Cpp17InputIterator "24.3.5.3 Input iterators [input.iterators]") requirements that iterates over an NTCTS[.](#fs.path.req-1.3.sentence-1)
|
||
The value type shall be an encoded character type[.](#fs.path.req-1.3.sentence-2)
|
||
A function argument const Source& source shall have an effective range
|
||
[source, end) where end is the first
|
||
iterator value with an element value equal to iterator_traits<Source>::value_type()[.](#fs.path.req-1.3.sentence-3)
|
||
|
||
- [(1.4)](#fs.path.req-1.4)
|
||
|
||
A character array that after array-to-pointer decay results in a
|
||
pointer to the start of an NTCTS[.](#fs.path.req-1.4.sentence-1)
|
||
The value type shall be an encoded character type[.](#fs.path.req-1.4.sentence-2)
|
||
A
|
||
function argument const Source& source shall
|
||
have an effective range [source, end) where end is the first iterator value with an element value equal to iterator_traits<decay_t<Source>>::value_type()[.](#fs.path.req-1.4.sentence-3)
|
||
|
||
[2](#fs.path.req-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14099)
|
||
|
||
Functions taking template parameters named Source shall not participate in overload resolution unlessSource denotes a type other than path, and
|
||
either
|
||
|
||
- [(2.1)](#fs.path.req-2.1)
|
||
|
||
Source is a specialization ofbasic_string or basic_string_view, or
|
||
|
||
- [(2.2)](#fs.path.req-2.2)
|
||
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") iterator_traits<decay_t<Source>>::value_type is valid and
|
||
denotes a possibly const encoded character type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction"))[.](#fs.path.req-2.sentence-1)
|
||
|
||
[3](#fs.path.req-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14113)
|
||
|
||
[*Note [1](#fs.path.req-note-1)*:
|
||
|
||
See [path conversions](#fs.path.cvt "31.12.6.3 Conversions [fs.path.cvt]") for how the value types above and their encodings convert topath::value_type and its encoding[.](#fs.path.req-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[4](#fs.path.req-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14120)
|
||
|
||
Arguments of type Source shall not be null pointers[.](#fs.path.req-4.sentence-1)
|
||
|
||
#### [31.12.6.5](#fs.path.member) Members [[fs.path.member]](fs.path.member)
|
||
|
||
#### [31.12.6.5.1](#fs.path.construct) Constructors [[fs.path.construct]](fs.path.construct)
|
||
|
||
[ð](#lib:path,constructor)
|
||
|
||
`path() noexcept;
|
||
`
|
||
|
||
[1](#fs.path.construct-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14134)
|
||
|
||
*Postconditions*: empty() is true[.](#fs.path.construct-1.sentence-1)
|
||
|
||
[ð](#lib:path,constructor_)
|
||
|
||
`path(const path& p);
|
||
path(path&& p) noexcept;
|
||
`
|
||
|
||
[2](#fs.path.construct-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14146)
|
||
|
||
*Effects*: Constructs an object of class path having the same pathname in the native and generic formats, respectively,
|
||
as the original value of p[.](#fs.path.construct-2.sentence-1)
|
||
|
||
In the second form, p is left in a valid but unspecified state[.](#fs.path.construct-2.sentence-2)
|
||
|
||
[ð](#lib:path,constructor__)
|
||
|
||
`path(string_type&& source, format fmt = auto_format);
|
||
`
|
||
|
||
[3](#fs.path.construct-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14160)
|
||
|
||
*Effects*: Constructs an object of class path for which the pathname in the detected-format of source has the original value of source ([[fs.path.fmt.cvt]](#fs.path.fmt.cvt "31.12.6.3.1 Argument format conversions")),
|
||
converting format if required ([[fs.path.fmt.cvt]](#fs.path.fmt.cvt "31.12.6.3.1 Argument format conversions"))[.](#fs.path.construct-3.sentence-1)
|
||
|
||
source is left in a valid but unspecified state[.](#fs.path.construct-3.sentence-2)
|
||
|
||
[ð](#lib:path,constructor___)
|
||
|
||
`template<class Source>
|
||
path(const Source& source, format fmt = auto_format);
|
||
template<class InputIterator>
|
||
path(InputIterator first, InputIterator last, format fmt = auto_format);
|
||
`
|
||
|
||
[4](#fs.path.construct-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14178)
|
||
|
||
*Effects*: Let s be the effective range of source ([[fs.path.req]](#fs.path.req "31.12.6.4 Requirements"))
|
||
or the range [first, last), with the encoding converted if required ([[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions"))[.](#fs.path.construct-4.sentence-1)
|
||
|
||
Finds the detected-format of s ([[fs.path.fmt.cvt]](#fs.path.fmt.cvt "31.12.6.3.1 Argument format conversions"))
|
||
and constructs an object of class path for which the pathname in that format is s[.](#fs.path.construct-4.sentence-2)
|
||
|
||
[ð](#lib:path,constructor____)
|
||
|
||
`template<class Source>
|
||
path(const Source& source, const locale& loc, format fmt = auto_format);
|
||
template<class InputIterator>
|
||
path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
|
||
`
|
||
|
||
[5](#fs.path.construct-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14196)
|
||
|
||
*Mandates*: The value type of Source and InputIterator ischar[.](#fs.path.construct-5.sentence-1)
|
||
|
||
[6](#fs.path.construct-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14201)
|
||
|
||
*Effects*: Let s be the effective range of source or the range [first, last),
|
||
after converting the encoding as
|
||
follows:
|
||
|
||
- [(6.1)](#fs.path.construct-6.1)
|
||
|
||
If value_type is wchar_t, converts to the native
|
||
wide encoding ([[fs.path.type.cvt]](#fs.path.type.cvt "31.12.6.3.2 Type and encoding conversions")) using the codecvt<wchar_t, char, mbstate_t> facet of loc[.](#fs.path.construct-6.1.sentence-1)
|
||
|
||
- [(6.2)](#fs.path.construct-6.2)
|
||
|
||
Otherwise a conversion is performed using thecodecvt<wchar_t, char, mbstate_t> facet of loc, and then a second
|
||
conversion to the current ordinary encoding[.](#fs.path.construct-6.2.sentence-1)
|
||
|
||
[7](#fs.path.construct-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14218)
|
||
|
||
Finds the detected-format of s ([[fs.path.fmt.cvt]](#fs.path.fmt.cvt "31.12.6.3.1 Argument format conversions"))
|
||
and constructs an object of class path for which the pathname in that format is s[.](#fs.path.construct-7.sentence-1)
|
||
|
||
[*Example [1](#fs.path.construct-example-1)*:
|
||
|
||
A string is to be read from a database
|
||
that is encoded in ISO/IEC 8859-1, and used to create a directory:namespace fs = std::filesystem;
|
||
std::string latin1_string = read_latin1_data();
|
||
codecvt_8859_1<wchar_t> latin1_facet;
|
||
std::locale latin1_locale(std::locale(), latin1_facet);
|
||
fs::create_directory(fs::path(latin1_string, latin1_locale));
|
||
|
||
For POSIX-based operating systems, the path is constructed by first usinglatin1_facet to convert ISO/IEC 8859-1 encodedlatin1_string to a wide character string in the native wide
|
||
encoding ([[fs.path.type.cvt]](#fs.path.type.cvt "31.12.6.3.2 Type and encoding conversions"))[.](#fs.path.construct-7.sentence-3)
|
||
|
||
The resulting wide string is then
|
||
converted to an ordinary character
|
||
pathname string in the current native ordinary encoding[.](#fs.path.construct-7.sentence-4)
|
||
|
||
If the
|
||
native wide encoding is UTF-16 or UTF-32, and the current native ordinary
|
||
encoding is UTF-8, all of the characters in the ISO/IEC 8859-1 character set
|
||
will be converted to their Unicode representation, but for other native
|
||
ordinary encodings some characters may have no representation[.](#fs.path.construct-7.sentence-5)
|
||
|
||
For Windows-based operating systems, the path is constructed by
|
||
using latin1_facet to convert ISO/IEC 8859-1 encodedlatin1_string to a UTF-16 encoded wide character pathname
|
||
string[.](#fs.path.construct-7.sentence-6)
|
||
|
||
All of the characters in the ISO/IEC 8859-1 character set will be
|
||
converted to their Unicode representation[.](#fs.path.construct-7.sentence-7)
|
||
|
||
â *end example*]
|
||
|
||
#### [31.12.6.5.2](#fs.path.assign) Assignments [[fs.path.assign]](fs.path.assign)
|
||
|
||
[ð](#lib:operator=,path)
|
||
|
||
`path& operator=(const path& p);
|
||
`
|
||
|
||
[1](#fs.path.assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14260)
|
||
|
||
*Effects*: If *this and p are the same
|
||
object, has no effect[.](#fs.path.assign-1.sentence-1)
|
||
|
||
Otherwise,
|
||
sets both respective pathnames of *this to the respective pathnames of p[.](#fs.path.assign-1.sentence-2)
|
||
|
||
[2](#fs.path.assign-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14268)
|
||
|
||
*Returns*: *this[.](#fs.path.assign-2.sentence-1)
|
||
|
||
[ð](#lib:operator=,path_)
|
||
|
||
`path& operator=(path&& p) noexcept;
|
||
`
|
||
|
||
[3](#fs.path.assign-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14279)
|
||
|
||
*Effects*: If *this and p are the same
|
||
object, has no effect[.](#fs.path.assign-3.sentence-1)
|
||
|
||
Otherwise,
|
||
sets both respective pathnames of *this to the respective pathnames of p[.](#fs.path.assign-3.sentence-2)
|
||
|
||
p is left in a valid but unspecified state[.](#fs.path.assign-3.sentence-3)
|
||
|
||
[*Note [1](#fs.path.assign-note-1)*:
|
||
|
||
A valid implementation is swap(p)[.](#fs.path.assign-3.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[4](#fs.path.assign-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14290)
|
||
|
||
*Returns*: *this[.](#fs.path.assign-4.sentence-1)
|
||
|
||
[ð](#lib:operator=,path__)
|
||
|
||
`path& operator=(string_type&& source);
|
||
path& assign(string_type&& source);
|
||
`
|
||
|
||
[5](#fs.path.assign-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14303)
|
||
|
||
*Effects*: Sets the pathname in the detected-format of source to the original value of source[.](#fs.path.assign-5.sentence-1)
|
||
|
||
source is left in a valid but unspecified state[.](#fs.path.assign-5.sentence-2)
|
||
|
||
[6](#fs.path.assign-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14309)
|
||
|
||
*Returns*: *this[.](#fs.path.assign-6.sentence-1)
|
||
|
||
[ð](#lib:operator=,path___)
|
||
|
||
`template<class Source>
|
||
path& operator=(const Source& source);
|
||
template<class Source>
|
||
path& assign(const Source& source);
|
||
template<class InputIterator>
|
||
path& assign(InputIterator first, InputIterator last);
|
||
`
|
||
|
||
[7](#fs.path.assign-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14326)
|
||
|
||
*Effects*: Let s be the effective range of source ([[fs.path.req]](#fs.path.req "31.12.6.4 Requirements"))
|
||
or the range [first, last), with the encoding converted if required ([[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions"))[.](#fs.path.assign-7.sentence-1)
|
||
|
||
Finds the detected-format of s ([[fs.path.fmt.cvt]](#fs.path.fmt.cvt "31.12.6.3.1 Argument format conversions"))
|
||
and sets the pathname in that format to s[.](#fs.path.assign-7.sentence-2)
|
||
|
||
[8](#fs.path.assign-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14333)
|
||
|
||
*Returns*: *this[.](#fs.path.assign-8.sentence-1)
|
||
|
||
#### [31.12.6.5.3](#fs.path.append) Appends [[fs.path.append]](fs.path.append)
|
||
|
||
[1](#fs.path.append-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14340)
|
||
|
||
The append operations use operator/= to denote their semantic effect of appending[*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") when needed[.](#fs.path.append-1.sentence-1)
|
||
|
||
[ð](#lib:operator/=,path)
|
||
|
||
`path& operator/=(const path& p);
|
||
`
|
||
|
||
[2](#fs.path.append-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14350)
|
||
|
||
*Effects*: If p.is_absolute() || (p.has_root_name() && p.root_name() != root_name()),
|
||
then operator=(p)[.](#fs.path.append-2.sentence-1)
|
||
|
||
[3](#fs.path.append-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14355)
|
||
|
||
Otherwise, modifies *this as if by these steps:
|
||
|
||
- [(3.1)](#fs.path.append-3.1)
|
||
|
||
If p.has_root_directory(),
|
||
then removes any root directory and relative path
|
||
from the generic format pathname[.](#fs.path.append-3.1.sentence-1)
|
||
Otherwise,
|
||
if !has_root_directory() && is_absolute() is true or if has_filename() is true,
|
||
then appends path::preferred_separator to the generic format pathname[.](#fs.path.append-3.1.sentence-2)
|
||
|
||
- [(3.2)](#fs.path.append-3.2)
|
||
|
||
Then appends the native format pathname of p,
|
||
omitting any [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") from its generic format pathname,
|
||
to the native format pathname[.](#fs.path.append-3.2.sentence-1)
|
||
|
||
[4](#fs.path.append-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14370)
|
||
|
||
[*Example [1](#fs.path.append-example-1)*:
|
||
|
||
Even if //host is interpreted as a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"),
|
||
both of the paths path("//host")/"foo" and path("//host/")/"foo" equal "//host/foo" (although the former might use backslash as the
|
||
preferred separator)[.](#fs.path.append-4.sentence-1)
|
||
|
||
Expression examples:// On POSIX, path("foo") /= path(""); // yields path("foo/") path("foo") /= path("/bar"); // yields path("/bar")// On Windows, path("foo") /= path(""); // yields path("foo\\") path("foo") /= path("/bar"); // yields path("/bar") path("foo") /= path("c:/bar"); // yields path("c:/bar") path("foo") /= path("c:"); // yields path("c:") path("c:") /= path(""); // yields path("c:") path("c:foo") /= path("/bar"); // yields path("c:/bar") path("c:foo") /= path("c:bar"); // yields path("c:foo\\bar")
|
||
|
||
â *end example*]
|
||
|
||
[5](#fs.path.append-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14394)
|
||
|
||
*Returns*: *this[.](#fs.path.append-5.sentence-1)
|
||
|
||
[ð](#lib:operator/=,path_)
|
||
|
||
`template<class Source>
|
||
path& operator/=(const Source& source);
|
||
template<class Source>
|
||
path& append(const Source& source);
|
||
`
|
||
|
||
[6](#fs.path.append-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14409)
|
||
|
||
*Effects*: Equivalent to: return operator/=(path(source));
|
||
|
||
[ð](#lib:operator/=,path__)
|
||
|
||
`template<class InputIterator>
|
||
path& append(InputIterator first, InputIterator last);
|
||
`
|
||
|
||
[7](#fs.path.append-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14422)
|
||
|
||
*Effects*: Equivalent to: return operator/=(path(first, last));
|
||
|
||
#### [31.12.6.5.4](#fs.path.concat) Concatenation [[fs.path.concat]](fs.path.concat)
|
||
|
||
[ð](#lib:operator+=,path)
|
||
|
||
`path& operator+=(const path& x);
|
||
path& operator+=(const string_type& x);
|
||
path& operator+=(basic_string_view<value_type> x);
|
||
path& operator+=(const value_type* x);
|
||
template<class Source>
|
||
path& operator+=(const Source& x);
|
||
template<class Source>
|
||
path& concat(const Source& x);
|
||
`
|
||
|
||
[1](#fs.path.concat-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14443)
|
||
|
||
*Effects*: Appends path(x).native() to the pathname in the native format[.](#fs.path.concat-1.sentence-1)
|
||
|
||
[*Note [1](#fs.path.concat-note-1)*:
|
||
|
||
This directly manipulates the value of native(),
|
||
which is not necessarily portable between operating systems[.](#fs.path.concat-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#fs.path.concat-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14451)
|
||
|
||
*Returns*: *this[.](#fs.path.concat-2.sentence-1)
|
||
|
||
[ð](#lib:operator+=,path_)
|
||
|
||
`path& operator+=(value_type x);
|
||
template<class EcharT>
|
||
path& operator+=(EcharT x);
|
||
`
|
||
|
||
[3](#fs.path.concat-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14465)
|
||
|
||
*Effects*: Equivalent to: return *this += basic_string_view(&x, 1);
|
||
|
||
[ð](#lib:concat,path__)
|
||
|
||
`template<class InputIterator>
|
||
path& concat(InputIterator first, InputIterator last);
|
||
`
|
||
|
||
[4](#fs.path.concat-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14477)
|
||
|
||
*Effects*: Equivalent to: return *this += path(first, last);
|
||
|
||
#### [31.12.6.5.5](#fs.path.modifiers) Modifiers [[fs.path.modifiers]](fs.path.modifiers)
|
||
|
||
[ð](#lib:clear,path)
|
||
|
||
`void clear() noexcept;
|
||
`
|
||
|
||
[1](#fs.path.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14490)
|
||
|
||
*Postconditions*: empty() is true[.](#fs.path.modifiers-1.sentence-1)
|
||
|
||
[ð](#lib:make_preferred,path)
|
||
|
||
`path& make_preferred();
|
||
`
|
||
|
||
[2](#fs.path.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14501)
|
||
|
||
*Effects*: Each [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") of the pathname in the generic format
|
||
is converted to [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.modifiers-2.sentence-1)
|
||
|
||
[3](#fs.path.modifiers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14507)
|
||
|
||
*Returns*: *this[.](#fs.path.modifiers-3.sentence-1)
|
||
|
||
[4](#fs.path.modifiers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14511)
|
||
|
||
[*Example [1](#fs.path.modifiers-example-1)*: path p("foo/bar");
|
||
std::cout << p << '\n';
|
||
p.make_preferred();
|
||
std::cout << p << '\n';
|
||
|
||
On an operating system where [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") is a slash,
|
||
the output is:"foo/bar""foo/bar"
|
||
|
||
On an operating system where [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") is a backslash, the
|
||
output is:"foo/bar""foo\bar"
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:remove_filename,path)
|
||
|
||
`path& remove_filename();
|
||
`
|
||
|
||
[5](#fs.path.modifiers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14540)
|
||
|
||
*Effects*: Remove the generic format pathname of filename() from the generic format pathname[.](#fs.path.modifiers-5.sentence-1)
|
||
|
||
[6](#fs.path.modifiers-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14544)
|
||
|
||
*Postconditions*: !has_filename()[.](#fs.path.modifiers-6.sentence-1)
|
||
|
||
[7](#fs.path.modifiers-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14548)
|
||
|
||
*Returns*: *this[.](#fs.path.modifiers-7.sentence-1)
|
||
|
||
[8](#fs.path.modifiers-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14552)
|
||
|
||
[*Example [2](#fs.path.modifiers-example-2)*: path("foo/bar").remove_filename(); // yields "foo/" path("foo/").remove_filename(); // yields "foo/" path("/foo").remove_filename(); // yields "/" path("/").remove_filename(); // yields "/" â *end example*]
|
||
|
||
[ð](#lib:replace_filename,path)
|
||
|
||
`path& replace_filename(const path& replacement);
|
||
`
|
||
|
||
[9](#fs.path.modifiers-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14569)
|
||
|
||
*Effects*: Equivalent to:remove_filename();operator/=(replacement);
|
||
|
||
[10](#fs.path.modifiers-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14577)
|
||
|
||
*Returns*: *this[.](#fs.path.modifiers-10.sentence-1)
|
||
|
||
[11](#fs.path.modifiers-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14581)
|
||
|
||
[*Example [3](#fs.path.modifiers-example-3)*: path("/foo").replace_filename("bar"); // yields "/bar" on POSIX path("/").replace_filename("bar"); // yields "/bar" on POSIX â *end example*]
|
||
|
||
[ð](#lib:replace_extension,path)
|
||
|
||
`path& replace_extension(const path& replacement = path());
|
||
`
|
||
|
||
[12](#fs.path.modifiers-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14596)
|
||
|
||
*Effects*:
|
||
|
||
- [(12.1)](#fs.path.modifiers-12.1)
|
||
|
||
Any existing extension() ([[fs.path.decompose]](#fs.path.decompose "31.12.6.5.9 Decomposition")) is removed from the
|
||
pathname in the generic format,
|
||
then
|
||
|
||
- [(12.2)](#fs.path.modifiers-12.2)
|
||
|
||
If replacement is not empty and does not begin with a dot
|
||
character, a dot character is appended to the pathname in the generic format, then
|
||
|
||
- [(12.3)](#fs.path.modifiers-12.3)
|
||
|
||
operator+=(replacement);[.](#fs.path.modifiers-12.sentence-1)
|
||
|
||
[13](#fs.path.modifiers-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14608)
|
||
|
||
*Returns*: *this[.](#fs.path.modifiers-13.sentence-1)
|
||
|
||
[ð](#lib:swap,path)
|
||
|
||
`void swap(path& rhs) noexcept;
|
||
`
|
||
|
||
[14](#fs.path.modifiers-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14619)
|
||
|
||
*Effects*: Swaps the contents (in all formats) of the two paths[.](#fs.path.modifiers-14.sentence-1)
|
||
|
||
[15](#fs.path.modifiers-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14623)
|
||
|
||
*Complexity*: Constant time[.](#fs.path.modifiers-15.sentence-1)
|
||
|
||
#### [31.12.6.5.6](#fs.path.native.obs) Native format observers [[fs.path.native.obs]](fs.path.native.obs)
|
||
|
||
[1](#fs.path.native.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14630)
|
||
|
||
The string returned by all native format observers is in the native pathname format ([fs.class.path])[.](#fs.path.native.obs-1.sentence-1)
|
||
|
||
[ð](#lib:native,path)
|
||
|
||
`const string_type& native() const noexcept;
|
||
`
|
||
|
||
[2](#fs.path.native.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14639)
|
||
|
||
*Returns*: The pathname in the native format[.](#fs.path.native.obs-2.sentence-1)
|
||
|
||
[ð](#lib:c_str,path)
|
||
|
||
`const value_type* c_str() const noexcept;
|
||
`
|
||
|
||
[3](#fs.path.native.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14650)
|
||
|
||
*Effects*: Equivalent to: return native().c_str();
|
||
|
||
[ð](#lib:operator_string_type,path)
|
||
|
||
`operator string_type() const;
|
||
`
|
||
|
||
[4](#fs.path.native.obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14661)
|
||
|
||
*Returns*: native()[.](#fs.path.native.obs-4.sentence-1)
|
||
|
||
[ð](#lib:string,path)
|
||
|
||
`template<class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>>
|
||
basic_string<EcharT, traits, Allocator> string(const Allocator& a = Allocator()) const;
|
||
`
|
||
|
||
[5](#fs.path.native.obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14673)
|
||
|
||
*Returns*: native()[.](#fs.path.native.obs-5.sentence-1)
|
||
|
||
[6](#fs.path.native.obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14677)
|
||
|
||
*Remarks*: All memory allocation, including for the return value, shall
|
||
be performed by a[.](#fs.path.native.obs-6.sentence-1)
|
||
|
||
Conversion, if any, is specified by[[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions")[.](#fs.path.native.obs-6.sentence-2)
|
||
|
||
[ð](#lib:system_encoded_string,path)
|
||
|
||
`std::string system_encoded_string() const;
|
||
std::wstring wstring() const;
|
||
std::u8string u8string() const;
|
||
std::u16string u16string() const;
|
||
std::u32string u32string() const;
|
||
`
|
||
|
||
[7](#fs.path.native.obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14698)
|
||
|
||
*Returns*: native()[.](#fs.path.native.obs-7.sentence-1)
|
||
|
||
[8](#fs.path.native.obs-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14702)
|
||
|
||
*Remarks*: Conversion, if any, is performed as specified
|
||
by [[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions")[.](#fs.path.native.obs-8.sentence-1)
|
||
|
||
[ð](#lib:display_string,path)
|
||
|
||
`std::string display_string() const;
|
||
`
|
||
|
||
[9](#fs.path.native.obs-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14714)
|
||
|
||
*Returns*: format("{}", *this)[.](#fs.path.native.obs-9.sentence-1)
|
||
|
||
[*Note [1](#fs.path.native.obs-note-1)*:
|
||
|
||
The returned string is suitable for use with formatting ([[format.functions]](format.functions "28.5.5 Formatting functions"))
|
||
and print functions ([[print.fun]](print.fun "31.7.10 Print functions"))[.](#fs.path.native.obs-9.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [31.12.6.5.7](#fs.path.generic.obs) Generic format observers [[fs.path.generic.obs]](fs.path.generic.obs)
|
||
|
||
[1](#fs.path.generic.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14725)
|
||
|
||
Generic format observer functions return strings formatted according to the[generic pathname format](#fs.path.generic "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic.obs-1.sentence-1)
|
||
|
||
A single slash ('/') character is used as
|
||
the [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.generic.obs-1.sentence-2)
|
||
|
||
[2](#fs.path.generic.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14731)
|
||
|
||
[*Example [1](#fs.path.generic.obs-example-1)*:
|
||
|
||
On an operating system that uses backslash as
|
||
its [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]"),path("foo\\bar").generic_string() returns "foo/bar"[.](#fs.path.generic.obs-2.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:generic_string,path)
|
||
|
||
`template<class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>>
|
||
basic_string<EcharT, traits, Allocator> generic_string(const Allocator& a = Allocator()) const;
|
||
`
|
||
|
||
[3](#fs.path.generic.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14748)
|
||
|
||
*Returns*: The pathname in the generic format[.](#fs.path.generic.obs-3.sentence-1)
|
||
|
||
[4](#fs.path.generic.obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14752)
|
||
|
||
*Remarks*: All memory allocation, including for the return value, shall
|
||
be performed by a[.](#fs.path.generic.obs-4.sentence-1)
|
||
|
||
Conversion, if any, is specified by[[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions")[.](#fs.path.generic.obs-4.sentence-2)
|
||
|
||
[ð](#lib:generic_system_encoded_string,path)
|
||
|
||
`std::string generic_system_encoded_string() const;
|
||
std::wstring generic_wstring() const;
|
||
std::u8string generic_u8string() const;
|
||
std::u16string generic_u16string() const;
|
||
std::u32string generic_u32string() const;
|
||
`
|
||
|
||
[5](#fs.path.generic.obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14773)
|
||
|
||
*Returns*: The pathname in the generic format[.](#fs.path.generic.obs-5.sentence-1)
|
||
|
||
[6](#fs.path.generic.obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14777)
|
||
|
||
*Remarks*: Conversion, if any, is specified by [[fs.path.cvt]](#fs.path.cvt "31.12.6.3 Conversions")[.](#fs.path.generic.obs-6.sentence-1)
|
||
|
||
[ð](#lib:generic_display_string,path)
|
||
|
||
`std::string generic_display_string() const;
|
||
`
|
||
|
||
[7](#fs.path.generic.obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14788)
|
||
|
||
*Returns*: format("{:g}", *this)[.](#fs.path.generic.obs-7.sentence-1)
|
||
|
||
[*Note [1](#fs.path.generic.obs-note-1)*:
|
||
|
||
The returned string is suitable for use with formatting ([[format.functions]](format.functions "28.5.5 Formatting functions"))
|
||
and print functions ([[print.fun]](print.fun "31.7.10 Print functions"))[.](#fs.path.generic.obs-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [31.12.6.5.8](#fs.path.compare) Compare [[fs.path.compare]](fs.path.compare)
|
||
|
||
[ð](#lib:compare,path)
|
||
|
||
`int compare(const path& p) const noexcept;
|
||
`
|
||
|
||
[1](#fs.path.compare-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14805)
|
||
|
||
*Returns*:
|
||
|
||
- [(1.1)](#fs.path.compare-1.1)
|
||
|
||
Let rootNameComparison be the result of this->root_name().native().compare(p.root_name().native())[.](#fs.path.compare-1.1.sentence-1)
|
||
If rootNameComparison is not 0, rootNameComparison[.](#fs.path.compare-1.1.sentence-2)
|
||
|
||
- [(1.2)](#fs.path.compare-1.2)
|
||
|
||
Otherwise, if !this->has_root_directory() and p.has_root_directory(),
|
||
a value less than 0[.](#fs.path.compare-1.2.sentence-1)
|
||
|
||
- [(1.3)](#fs.path.compare-1.3)
|
||
|
||
Otherwise, if this->has_root_directory() and !p.has_root_directory(),
|
||
a value greater than 0[.](#fs.path.compare-1.3.sentence-1)
|
||
|
||
- [(1.4)](#fs.path.compare-1.4)
|
||
|
||
Otherwise, if native() for the elements of this->relative_path() are lexicographically less than native() for the elements of p.relative_path(),
|
||
a value less than 0[.](#fs.path.compare-1.4.sentence-1)
|
||
|
||
- [(1.5)](#fs.path.compare-1.5)
|
||
|
||
Otherwise, if native() for the elements of this->relative_path() are lexicographically greater than native() for the elements of p.relative_path(),
|
||
a value greater than 0[.](#fs.path.compare-1.5.sentence-1)
|
||
|
||
- [(1.6)](#fs.path.compare-1.6)
|
||
|
||
Otherwise, 0[.](#fs.path.compare-1.6.sentence-1)
|
||
|
||
[ð](#lib:compare,path_)
|
||
|
||
`int compare(const string_type& s) const;
|
||
int compare(basic_string_view<value_type> s) const;
|
||
int compare(const value_type* s) const;
|
||
`
|
||
|
||
[2](#fs.path.compare-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14846)
|
||
|
||
*Effects*: Equivalent to: return compare(path(s));
|
||
|
||
#### [31.12.6.5.9](#fs.path.decompose) Decomposition [[fs.path.decompose]](fs.path.decompose)
|
||
|
||
[ð](#lib:root_name,path)
|
||
|
||
`path root_name() const;
|
||
`
|
||
|
||
[1](#fs.path.decompose-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14859)
|
||
|
||
*Returns*: [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"), if the pathname in the generic format
|
||
includes [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"), otherwise path()[.](#fs.path.decompose-1.sentence-1)
|
||
|
||
[ð](#lib:root_directory,path)
|
||
|
||
`path root_directory() const;
|
||
`
|
||
|
||
[2](#fs.path.decompose-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14871)
|
||
|
||
*Returns*: [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]"), if the pathname in the generic format
|
||
includes [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]"), otherwise path()[.](#fs.path.decompose-2.sentence-1)
|
||
|
||
[ð](#lib:root_path,path)
|
||
|
||
`path root_path() const;
|
||
`
|
||
|
||
[3](#fs.path.decompose-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14883)
|
||
|
||
*Returns*: root_name() / root_directory()[.](#fs.path.decompose-3.sentence-1)
|
||
|
||
[ð](#lib:relative_path,path)
|
||
|
||
`path relative_path() const;
|
||
`
|
||
|
||
[4](#fs.path.decompose-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14894)
|
||
|
||
*Returns*: A path composed from the pathname in the generic format,
|
||
if empty() is false, beginning
|
||
with the first [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") after root_path()[.](#fs.path.decompose-4.sentence-1)
|
||
|
||
Otherwise, path()[.](#fs.path.decompose-4.sentence-2)
|
||
|
||
[ð](#lib:parent_path,path)
|
||
|
||
`path parent_path() const;
|
||
`
|
||
|
||
[5](#fs.path.decompose-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14907)
|
||
|
||
*Returns*: *this if has_relative_path() is false,
|
||
otherwise a path whose generic format pathname is
|
||
the longest prefix of the generic format pathname of *this that produces one fewer element in its iteration[.](#fs.path.decompose-5.sentence-1)
|
||
|
||
[ð](#lib:filename,path)
|
||
|
||
`path filename() const;
|
||
`
|
||
|
||
[6](#fs.path.decompose-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14921)
|
||
|
||
*Returns*: relative_path().empty() ? path() : *--end()[.](#fs.path.decompose-6.sentence-1)
|
||
|
||
[7](#fs.path.decompose-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14925)
|
||
|
||
[*Example [1](#fs.path.decompose-example-1)*: path("/foo/bar.txt").filename(); // yields "bar.txt" path("/foo/bar").filename(); // yields "bar" path("/foo/bar/").filename(); // yields "" path("/").filename(); // yields "" path("//host").filename(); // yields "" path(".").filename(); // yields "." path("..").filename(); // yields ".." â *end example*]
|
||
|
||
[ð](#lib:stem,path)
|
||
|
||
`path stem() const;
|
||
`
|
||
|
||
[8](#fs.path.decompose-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14945)
|
||
|
||
*Returns*: Let f be the generic format pathname of filename()[.](#fs.path.decompose-8.sentence-1)
|
||
|
||
Returns a path whose pathname in the generic format is
|
||
|
||
- [(8.1)](#fs.path.decompose-8.1)
|
||
|
||
f, if it contains no periods other than a leading period
|
||
or consists solely of one or two periods;
|
||
|
||
- [(8.2)](#fs.path.decompose-8.2)
|
||
|
||
otherwise, the prefix of f ending before its last period[.](#fs.path.decompose-8.sentence-2)
|
||
|
||
[9](#fs.path.decompose-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14955)
|
||
|
||
[*Example [2](#fs.path.decompose-example-2)*: std::cout << path("/foo/bar.txt").stem(); // outputs "bar" path p = "foo.bar.baz.tar";for (; !p.extension().empty(); p = p.stem()) std::cout << p.extension() << '\n'; // outputs: .tar// .baz// .bar â *end example*]
|
||
|
||
[ð](#lib:extension,path)
|
||
|
||
`path extension() const;
|
||
`
|
||
|
||
[10](#fs.path.decompose-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14975)
|
||
|
||
*Returns*: A path whose pathname in the generic format is
|
||
the suffix of filename() not included in stem()[.](#fs.path.decompose-10.sentence-1)
|
||
|
||
[11](#fs.path.decompose-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14980)
|
||
|
||
[*Example [3](#fs.path.decompose-example-3)*: path("/foo/bar.txt").extension(); // yields ".txt" and stem() is "bar" path("/foo/bar").extension(); // yields "" and stem() is "bar" path("/foo/.profile").extension(); // yields "" and stem() is ".profile" path(".bar").extension(); // yields "" and stem() is ".bar" path("..bar").extension(); // yields ".bar" and stem() is "." â *end example*]
|
||
|
||
[12](#fs.path.decompose-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14991)
|
||
|
||
[*Note [1](#fs.path.decompose-note-1)*:
|
||
|
||
The period is included in the return value so that it is
|
||
possible to distinguish between no extension and an empty extension[.](#fs.path.decompose-12.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[13](#fs.path.decompose-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L14997)
|
||
|
||
[*Note [2](#fs.path.decompose-note-2)*:
|
||
|
||
On non-POSIX operating systems, for a path p,
|
||
it is possible that p.stem() + p.extension() == p.filename() is false,
|
||
even though the generic format pathnames are the same[.](#fs.path.decompose-13.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [31.12.6.5.10](#fs.path.query) Query [[fs.path.query]](fs.path.query)
|
||
|
||
[ð](#lib:empty,path)
|
||
|
||
`bool empty() const noexcept;
|
||
`
|
||
|
||
[1](#fs.path.query-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15013)
|
||
|
||
*Returns*: true if the pathname in the generic format is empty, otherwise false[.](#fs.path.query-1.sentence-1)
|
||
|
||
[ð](#lib:has_root_path,path)
|
||
|
||
`bool has_root_path() const;
|
||
`
|
||
|
||
[2](#fs.path.query-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15024)
|
||
|
||
*Returns*: !root_path().empty()[.](#fs.path.query-2.sentence-1)
|
||
|
||
[ð](#lib:has_root_name,path)
|
||
|
||
`bool has_root_name() const;
|
||
`
|
||
|
||
[3](#fs.path.query-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15035)
|
||
|
||
*Returns*: !root_name().empty()[.](#fs.path.query-3.sentence-1)
|
||
|
||
[ð](#lib:has_root_directory,path)
|
||
|
||
`bool has_root_directory() const;
|
||
`
|
||
|
||
[4](#fs.path.query-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15046)
|
||
|
||
*Returns*: !root_directory().empty()[.](#fs.path.query-4.sentence-1)
|
||
|
||
[ð](#lib:has_relative_path,path)
|
||
|
||
`bool has_relative_path() const;
|
||
`
|
||
|
||
[5](#fs.path.query-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15057)
|
||
|
||
*Returns*: !relative_path().empty()[.](#fs.path.query-5.sentence-1)
|
||
|
||
[ð](#lib:has_parent_path,path)
|
||
|
||
`bool has_parent_path() const;
|
||
`
|
||
|
||
[6](#fs.path.query-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15068)
|
||
|
||
*Returns*: !parent_path().empty()[.](#fs.path.query-6.sentence-1)
|
||
|
||
[ð](#lib:has_filename,path)
|
||
|
||
`bool has_filename() const;
|
||
`
|
||
|
||
[7](#fs.path.query-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15079)
|
||
|
||
*Returns*: !filename().empty()[.](#fs.path.query-7.sentence-1)
|
||
|
||
[ð](#lib:has_stem,path)
|
||
|
||
`bool has_stem() const;
|
||
`
|
||
|
||
[8](#fs.path.query-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15090)
|
||
|
||
*Returns*: !stem().empty()[.](#fs.path.query-8.sentence-1)
|
||
|
||
[ð](#lib:has_extension,path)
|
||
|
||
`bool has_extension() const;
|
||
`
|
||
|
||
[9](#fs.path.query-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15101)
|
||
|
||
*Returns*: !extension().empty()[.](#fs.path.query-9.sentence-1)
|
||
|
||
[ð](#lib:is_absolute,path)
|
||
|
||
`bool is_absolute() const;
|
||
`
|
||
|
||
[10](#fs.path.query-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15112)
|
||
|
||
*Returns*: true if the pathname in the native format
|
||
contains an absolute path ([fs.class.path]), otherwise false[.](#fs.path.query-10.sentence-1)
|
||
|
||
[11](#fs.path.query-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15117)
|
||
|
||
[*Example [1](#fs.path.query-example-1)*:
|
||
|
||
path("/").is_absolute() is true for POSIX-based operating systems, and false for Windows-based
|
||
operating systems[.](#fs.path.query-11.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:is_relative,path)
|
||
|
||
`bool is_relative() const;
|
||
`
|
||
|
||
[12](#fs.path.query-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15131)
|
||
|
||
*Returns*: !is_absolute()[.](#fs.path.query-12.sentence-1)
|
||
|
||
#### [31.12.6.5.11](#fs.path.gen) Generation [[fs.path.gen]](fs.path.gen)
|
||
|
||
[ð](#lib:lexically_normal,path)
|
||
|
||
`path lexically_normal() const;
|
||
`
|
||
|
||
[1](#fs.path.gen-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15144)
|
||
|
||
*Returns*: A path whose pathname in the generic format is
|
||
the normal form ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format")) of the pathname
|
||
in the generic format of *this[.](#fs.path.gen-1.sentence-1)
|
||
|
||
[2](#fs.path.gen-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15150)
|
||
|
||
[*Example [1](#fs.path.gen-example-1)*: assert(path("foo/./bar/..").lexically_normal() == "foo/");
|
||
assert(path("foo/.///bar/../").lexically_normal() == "foo/");
|
||
|
||
The above assertions will succeed[.](#fs.path.gen-2.sentence-1)
|
||
|
||
On Windows, the returned path's [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
|
||
will be backslashes rather than slashes,
|
||
but that does not affect path equality[.](#fs.path.gen-2.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:lexically_relative,path)
|
||
|
||
`path lexically_relative(const path& base) const;
|
||
`
|
||
|
||
[3](#fs.path.gen-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15169)
|
||
|
||
*Effects*: If:
|
||
|
||
- [(3.1)](#fs.path.gen-3.1)
|
||
|
||
root_name() != base.root_name() is true, or
|
||
|
||
- [(3.2)](#fs.path.gen-3.2)
|
||
|
||
is_absolute() != base.is_absolute() is true, or
|
||
|
||
- [(3.3)](#fs.path.gen-3.3)
|
||
|
||
!has_root_directory() && base.has_root_directory() is true, or
|
||
|
||
- [(3.4)](#fs.path.gen-3.4)
|
||
|
||
any [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") inrelative_path() or base.relative_path() can be interpreted as a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"),
|
||
|
||
returns path()[.](#fs.path.gen-3.sentence-1)
|
||
|
||
[*Note [1](#fs.path.gen-note-1)*:
|
||
|
||
On a POSIX implementation, no [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") in a [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]") is acceptable as a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.gen-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
Determines the first mismatched element of *this and base as if by:auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
|
||
|
||
Then,
|
||
|
||
- [(3.5)](#fs.path.gen-3.5)
|
||
|
||
if a == end() and b == base.end(), returns path("."); otherwise
|
||
|
||
- [(3.6)](#fs.path.gen-3.6)
|
||
|
||
let n be the number of [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") elements in [b, base.end())
|
||
that are not dot or dot-dot or empty, minus the number that are dot-dot[.](#fs.path.gen-3.6.sentence-1)
|
||
If n<0, returns path(); otherwise
|
||
|
||
- [(3.7)](#fs.path.gen-3.7)
|
||
|
||
if n == 0 and (a == end() || a->empty()),
|
||
returns path("."); otherwise
|
||
|
||
- [(3.8)](#fs.path.gen-3.8)
|
||
|
||
returns an object of class path that is default-constructed, followed by
|
||
* [(3.8.1)](#fs.path.gen-3.8.1)
|
||
|
||
application of operator/=(path(".."))n times, and then
|
||
|
||
* [(3.8.2)](#fs.path.gen-3.8.2)
|
||
|
||
application of operator/= for each element in [a, end())[.](#fs.path.gen-3.8.sentence-1)
|
||
|
||
[4](#fs.path.gen-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15215)
|
||
|
||
*Returns*: *this made relative to base[.](#fs.path.gen-4.sentence-1)
|
||
|
||
Does not resolve ([fs.class.path]) symlinks[.](#fs.path.gen-4.sentence-2)
|
||
|
||
Does not first normalize ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format")) *this or base[.](#fs.path.gen-4.sentence-3)
|
||
|
||
[5](#fs.path.gen-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15221)
|
||
|
||
[*Example [2](#fs.path.gen-example-2)*: assert(path("/a/d").lexically_relative("/a/b/c") == "../../d");
|
||
assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
|
||
assert(path("a/b/c").lexically_relative("a") == "b/c");
|
||
assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
|
||
assert(path("a/b/c").lexically_relative("a/b/c") == ".");
|
||
assert(path("a/b").lexically_relative("c/d") == "../../a/b");
|
||
|
||
The above assertions will succeed[.](#fs.path.gen-5.sentence-1)
|
||
|
||
On Windows, the returned path's [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
|
||
will be backslashes rather than slashes,
|
||
but that does not affect path equality[.](#fs.path.gen-5.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[6](#fs.path.gen-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15237)
|
||
|
||
[*Note [2](#fs.path.gen-note-2)*:
|
||
|
||
If symlink following semantics are desired,
|
||
use the operational function relative()[.](#fs.path.gen-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[7](#fs.path.gen-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15243)
|
||
|
||
[*Note [3](#fs.path.gen-note-3)*:
|
||
|
||
If normalization ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format")) is needed
|
||
to ensure consistent matching of elements,
|
||
apply lexically_normal() to *this, base, or both[.](#fs.path.gen-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:lexically_proximate,path)
|
||
|
||
`path lexically_proximate(const path& base) const;
|
||
`
|
||
|
||
[8](#fs.path.gen-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15258)
|
||
|
||
*Returns*: If the value of lexically_relative(base) is not an empty path,
|
||
return it[.](#fs.path.gen-8.sentence-1)
|
||
|
||
Otherwise return *this[.](#fs.path.gen-8.sentence-2)
|
||
|
||
[9](#fs.path.gen-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15263)
|
||
|
||
[*Note [4](#fs.path.gen-note-4)*:
|
||
|
||
If symlink following semantics are desired,
|
||
use the operational function proximate()[.](#fs.path.gen-9.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[10](#fs.path.gen-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15269)
|
||
|
||
[*Note [5](#fs.path.gen-note-5)*:
|
||
|
||
If normalization ([[fs.path.generic]](#fs.path.generic "31.12.6.2 Generic pathname format")) is needed
|
||
to ensure consistent matching of elements,
|
||
apply lexically_normal() to *this, base, or both[.](#fs.path.gen-10.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [31.12.6.6](#fs.path.itr) Iterators [[fs.path.itr]](fs.path.itr)
|
||
|
||
[1](#fs.path.itr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15281)
|
||
|
||
Path iterators iterate over the elements of the pathname
|
||
in the [generic format](#fs.path.generic "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#fs.path.itr-1.sentence-1)
|
||
|
||
[2](#fs.path.itr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15285)
|
||
|
||
A path::iterator is a constant iterator meeting all the
|
||
requirements of a [bidirectional iterator](bidirectional.iterators "24.3.5.6 Bidirectional iterators [bidirectional.iterators]") except that,
|
||
for dereferenceable iterators a and b of type path::iterator with a == b,
|
||
there is no requirement that *a and *b are bound to the same object[.](#fs.path.itr-2.sentence-1)
|
||
|
||
Its value_type is path[.](#fs.path.itr-2.sentence-2)
|
||
|
||
[3](#fs.path.itr-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15296)
|
||
|
||
Calling any non-const member function of a path object
|
||
invalidates all iterators referring to elements of that object[.](#fs.path.itr-3.sentence-1)
|
||
|
||
[4](#fs.path.itr-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15300)
|
||
|
||
For the elements of the pathname in the generic format,
|
||
the forward traversal order is as follows:
|
||
|
||
- [(4.1)](#fs.path.itr-4.1)
|
||
|
||
The [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") element, if present[.](#fs.path.itr-4.1.sentence-1)
|
||
|
||
- [(4.2)](#fs.path.itr-4.2)
|
||
|
||
The [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]") element, if present[.](#fs.path.itr-4.2.sentence-1)
|
||
[*Note [1](#fs.path.itr-note-1)*:
|
||
It is possible that the use of the generic format is needed
|
||
to ensure correct lexicographical comparison[.](#fs.path.itr-4.2.sentence-2)
|
||
â *end note*]
|
||
|
||
- [(4.3)](#fs.path.itr-4.3)
|
||
|
||
Each successive [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") element, if present[.](#fs.path.itr-4.3.sentence-1)
|
||
|
||
- [(4.4)](#fs.path.itr-4.4)
|
||
|
||
An empty element, if a trailing non-root [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") is present[.](#fs.path.itr-4.4.sentence-1)
|
||
|
||
[5](#fs.path.itr-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15315)
|
||
|
||
The backward traversal order is the reverse of forward traversal[.](#fs.path.itr-5.sentence-1)
|
||
|
||
[ð](#lib:begin,path)
|
||
|
||
`iterator begin() const;
|
||
`
|
||
|
||
[6](#fs.path.itr-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15324)
|
||
|
||
*Returns*: An iterator for the first present element in the traversal
|
||
list above[.](#fs.path.itr-6.sentence-1)
|
||
|
||
If no elements are present, the end iterator[.](#fs.path.itr-6.sentence-2)
|
||
|
||
[ð](#lib:end,path)
|
||
|
||
`iterator end() const;
|
||
`
|
||
|
||
[7](#fs.path.itr-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15336)
|
||
|
||
*Returns*: The end iterator[.](#fs.path.itr-7.sentence-1)
|
||
|
||
#### [31.12.6.7](#fs.path.io) Inserter and extractor [[fs.path.io]](fs.path.io)
|
||
|
||
[ð](#lib:operator%3c%3c,path)
|
||
|
||
`template<class charT, class traits>
|
||
friend basic_ostream<charT, traits>&
|
||
operator<<(basic_ostream<charT, traits>& os, const path& p);
|
||
`
|
||
|
||
[1](#fs.path.io-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15351)
|
||
|
||
*Effects*: Equivalent to os << quoted(p.string<charT, traits>())[.](#fs.path.io-1.sentence-1)
|
||
|
||
[*Note [1](#fs.path.io-note-1)*:
|
||
|
||
The quoted function is described in [[quoted.manip]](quoted.manip "31.7.9 Quoted manipulators")[.](#fs.path.io-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#fs.path.io-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15358)
|
||
|
||
*Returns*: os[.](#fs.path.io-2.sentence-1)
|
||
|
||
[ð](#lib:operator%3e%3e,path)
|
||
|
||
`template<class charT, class traits>
|
||
friend basic_istream<charT, traits>&
|
||
operator>>(basic_istream<charT, traits>& is, path& p);
|
||
`
|
||
|
||
[3](#fs.path.io-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15371)
|
||
|
||
*Effects*: Equivalent to:basic_string<charT, traits> tmp;
|
||
is >> quoted(tmp);
|
||
p = tmp;
|
||
|
||
[4](#fs.path.io-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15380)
|
||
|
||
*Returns*: is[.](#fs.path.io-4.sentence-1)
|
||
|
||
#### [31.12.6.8](#fs.path.nonmember) Non-member functions [[fs.path.nonmember]](fs.path.nonmember)
|
||
|
||
[ð](#lib:swap,path_)
|
||
|
||
`void swap(path& lhs, path& rhs) noexcept;
|
||
`
|
||
|
||
[1](#fs.path.nonmember-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15393)
|
||
|
||
*Effects*: Equivalent to lhs.swap(rhs)[.](#fs.path.nonmember-1.sentence-1)
|
||
|
||
[ð](#lib:hash_value,path)
|
||
|
||
`size_t hash_value(const path& p) noexcept;
|
||
`
|
||
|
||
[2](#fs.path.nonmember-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15404)
|
||
|
||
*Returns*: A hash value for the path p[.](#fs.path.nonmember-2.sentence-1)
|
||
|
||
If
|
||
for two paths, p1 == p2 then hash_value(p1) == hash_value(p2)[.](#fs.path.nonmember-2.sentence-2)
|
||
|
||
[ð](#lib:operator==,path)
|
||
|
||
`friend bool operator==(const path& lhs, const path& rhs) noexcept;
|
||
`
|
||
|
||
[3](#fs.path.nonmember-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15416)
|
||
|
||
*Returns*: lhs.compare(rhs) == 0[.](#fs.path.nonmember-3.sentence-1)
|
||
|
||
[4](#fs.path.nonmember-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15421)
|
||
|
||
[*Note [1](#fs.path.nonmember-note-1)*:
|
||
|
||
Path equality and path equivalence have different semantics[.](#fs.path.nonmember-4.sentence-1)
|
||
|
||
- [(4.1)](#fs.path.nonmember-4.1)
|
||
|
||
Equality is determined by the path non-member operator==,
|
||
which considers the two paths' lexical representations only[.](#fs.path.nonmember-4.1.sentence-1)
|
||
[*Example [1](#fs.path.nonmember-example-1)*:
|
||
path("foo") == "bar" is never true[.](#fs.path.nonmember-4.1.sentence-2)
|
||
â *end example*]
|
||
|
||
- [(4.2)](#fs.path.nonmember-4.2)
|
||
|
||
Equivalence is determined by the equivalent() non-member function, which
|
||
determines if two paths resolve ([fs.class.path]) to the same file system entity[.](#fs.path.nonmember-4.2.sentence-1)
|
||
[*Example [2](#fs.path.nonmember-example-2)*:
|
||
equivalent("foo", "bar") will be true when both paths resolve to the same file[.](#fs.path.nonmember-4.2.sentence-2)
|
||
â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator%3c=%3e,path)
|
||
|
||
`friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept;
|
||
`
|
||
|
||
[5](#fs.path.nonmember-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15445)
|
||
|
||
*Returns*: lhs.compare(rhs) <=> 0[.](#fs.path.nonmember-5.sentence-1)
|
||
|
||
[ð](#lib:operator/,path)
|
||
|
||
`friend path operator/(const path& lhs, const path& rhs);
|
||
`
|
||
|
||
[6](#fs.path.nonmember-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15456)
|
||
|
||
*Effects*: Equivalent to: return path(lhs) /= rhs;
|
||
|
||
#### [31.12.6.9](#fs.path.fmtr) Formatting support [[fs.path.fmtr]](fs.path.fmtr)
|
||
|
||
#### [31.12.6.9.1](#fs.path.fmtr.general) Formatting support overview [[fs.path.fmtr.general]](fs.path.fmtr.general)
|
||
|
||
[ð](#lib:formatter)
|
||
|
||
namespace std {template<class charT> struct formatter<filesystem::path, charT> {constexpr void set_debug_format(); constexpr typename basic_format_parse_context<charT>::iterator
|
||
parse(basic_format_parse_context<charT>& ctx); template<class FormatContext>typename FormatContext::iterator
|
||
format(const filesystem::path& path, FormatContext& ctx) const; };}
|
||
|
||
#### [31.12.6.9.2](#fs.path.fmtr.funcs) Formatting support functions [[fs.path.fmtr.funcs]](fs.path.fmtr.funcs)
|
||
|
||
[1](#fs.path.fmtr.funcs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15483)
|
||
|
||
Formatting of paths uses formatting specifiers of the form
|
||
|
||
[path-format-spec:](#nt:path-format-spec "31.12.6.9.2 Formatting support functions [fs.path.fmtr.funcs]")
|
||
fill-and-alignopt widthopt ?opt gopt
|
||
|
||
where the productions *fill-and-align* and *width* are described in [[format.string]](format.string "28.5.2 Format string")[.](#fs.path.fmtr.funcs-1.sentence-1)
|
||
|
||
If the ? option is used then
|
||
the path is formatted as an escaped string ([[format.string.escaped]](format.string.escaped "28.5.6.5 Formatting escaped characters and strings"))[.](#fs.path.fmtr.funcs-1.sentence-2)
|
||
|
||
[ð](#lib:formatter,set_debug_format)
|
||
|
||
`constexpr void set_debug_format();
|
||
`
|
||
|
||
[2](#fs.path.fmtr.funcs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15500)
|
||
|
||
*Effects*: Modifies the state of the formatter to be as if
|
||
the *path-format-spec* parsed by the last call to parse contained the ? option[.](#fs.path.fmtr.funcs-2.sentence-1)
|
||
|
||
[ð](#lib:formatter,basic_format_parse_context)
|
||
|
||
`constexpr typename basic_format_parse_context<charT>::iterator
|
||
parse(basic_format_parse_context<charT>& ctx);
|
||
`
|
||
|
||
[3](#fs.path.fmtr.funcs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15514)
|
||
|
||
*Effects*: Parses the format specifier as a *path-format-spec* and
|
||
stores the parsed specifiers in *this[.](#fs.path.fmtr.funcs-3.sentence-1)
|
||
|
||
[4](#fs.path.fmtr.funcs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15519)
|
||
|
||
*Returns*: An iterator past the end of the *path-format-spec*[.](#fs.path.fmtr.funcs-4.sentence-1)
|
||
|
||
[ð](#lib:formatter,format)
|
||
|
||
`template<class FormatContext>
|
||
typename FormatContext::iterator
|
||
format(const filesystem::path& p, FormatContext& ctx) const;
|
||
`
|
||
|
||
[5](#fs.path.fmtr.funcs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15532)
|
||
|
||
*Effects*: Let s be p.generic_string<filesystem::path::value_type>() if the g option is used,
|
||
otherwise p.native()[.](#fs.path.fmtr.funcs-5.sentence-1)
|
||
|
||
Writes s into ctx.out(),
|
||
adjusted according to the *path-format-spec*[.](#fs.path.fmtr.funcs-5.sentence-2)
|
||
|
||
If charT is char,path::value_type is wchar_t, and
|
||
the literal encoding is UTF-8,
|
||
then the escaped path is transcoded from the native encoding for
|
||
wide character strings to UTF-8 with
|
||
maximal subparts of ill-formed subsequences
|
||
substituted with U+fffd replacement character per the Unicode Standard, Chapter 3.9 U+fffd Substitution in Conversion[.](#fs.path.fmtr.funcs-5.sentence-3)
|
||
|
||
If charT and path::value_type are the same
|
||
then no transcoding is performed[.](#fs.path.fmtr.funcs-5.sentence-4)
|
||
|
||
Otherwise, transcoding isimplementation-defined[.](#fs.path.fmtr.funcs-5.sentence-5)
|
||
|
||
[6](#fs.path.fmtr.funcs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15552)
|
||
|
||
*Returns*: An iterator past the end of the output range[.](#fs.path.fmtr.funcs-6.sentence-1)
|
||
|
||
#### [31.12.6.10](#fs.path.hash) Hash support [[fs.path.hash]](fs.path.hash)
|
||
|
||
[ð](#fs.path.hash-itemdecl:1)
|
||
|
||
`template<> struct hash<filesystem::path>;
|
||
`
|
||
|
||
[1](#fs.path.hash-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L15564)
|
||
|
||
For an object p of type filesystem::path,hash<filesystem::path>()(p) evaluates to the same result asfilesystem::hash_value(p)[.](#fs.path.hash-1.sentence-1)
|