Files
2025-10-25 03:02:53 +03:00

43 KiB
Raw Permalink Blame History

[fs.path.member]

31 Input/output library [input.output]

31.12 File systems [filesystems]

31.12.6 Class path [fs.class.path]

31.12.6.5 Members [fs.path.member]

31.12.6.5.1 Constructors [fs.path.construct]

🔗

path() noexcept;

1

#

Postconditions: empty() is true.

🔗

path(const path& p); path(path&& p) noexcept;

2

#

Effects: Constructs an object of class path having the same pathname in the native and generic formats, respectively, as the original value of p.

In the second form, p is left in a valid but unspecified state.

🔗

path(string_type&& source, format fmt = auto_format);

3

#

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]), converting format if required ([fs.path.fmt.cvt]).

source is left in a valid but unspecified state.

🔗

template<class Source> path(const Source& source, format fmt = auto_format); template<class InputIterator> path(InputIterator first, InputIterator last, format fmt = auto_format);

4

#

Effects: Let s be the effective range of source ([fs.path.req]) or the range [first, last), with the encoding converted if required ([fs.path.cvt]).

Finds the detected-format of s ([fs.path.fmt.cvt]) and constructs an object of class path for which the pathname in that format is s.

🔗

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

#

Mandates: The value type of Source and InputIterator ischar.

6

#

Effects: Let s be the effective range of source or the range [first, last), after converting the encoding as follows:

  • (6.1)

    If value_type is wchar_t, converts to the native wide encoding ([fs.path.type.cvt]) using the codecvt<wchar_t, char, mbstate_t> facet of loc.

  • (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.

7

#

Finds the detected-format of s ([fs.path.fmt.cvt]) and constructs an object of class path for which the pathname in that format is s.

[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]).

The resulting wide string is then converted to an ordinary character pathname string in the current native ordinary encoding.

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.

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.

All of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation.

— end example]

31.12.6.5.2 Assignments [fs.path.assign]

🔗

path& operator=(const path& p);

1

#

Effects: If *this and p are the same object, has no effect.

Otherwise, sets both respective pathnames of *this to the respective pathnames of p.

2

#

Returns: *this.

🔗

path& operator=(path&& p) noexcept;

3

#

Effects: If *this and p are the same object, has no effect.

Otherwise, sets both respective pathnames of *this to the respective pathnames of p.

p is left in a valid but unspecified state.

[Note 1:

A valid implementation is swap(p).

— end note]

4

#

Returns: *this.

🔗

path& operator=(string_type&& source); path& assign(string_type&& source);

5

#

Effects: Sets the pathname in the detected-format of source to the original value of source.

source is left in a valid but unspecified state.

6

#

Returns: *this.

🔗

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

#

Effects: Let s be the effective range of source ([fs.path.req]) or the range [first, last), with the encoding converted if required ([fs.path.cvt]).

Finds the detected-format of s ([fs.path.fmt.cvt]) and sets the pathname in that format to s.

8

#

Returns: *this.

31.12.6.5.3 Appends [fs.path.append]

1

#

The append operations use operator/= to denote their semantic effect of appendingpreferred-separator when needed.

🔗

path& operator/=(const path& p);

2

#

Effects: If p.is_absolute() || (p.has_root_name() && p.root_name() != root_name()), then operator=(p).

3

#

Otherwise, modifies *this as if by these steps:

  • (3.1)

    If p.has_root_directory(), then removes any root directory and relative path from the generic format pathname. 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.

  • (3.2)

    Then appends the native format pathname of p, omitting any root-name from its generic format pathname, to the native format pathname.

4

#

[Example 1:

Even if //host is interpreted as a root-name, both of the paths path("//host")/"foo" and path("//host/")/"foo" equal "//host/foo" (although the former might use backslash as the preferred separator).

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

#

Returns: *this.

🔗

template<class Source> path& operator/=(const Source& source); template<class Source> path& append(const Source& source);

6

#

Effects: Equivalent to: return operator/=(path(source));

🔗

template<class InputIterator> path& append(InputIterator first, InputIterator last);

7

#

Effects: Equivalent to: return operator/=(path(first, last));

31.12.6.5.4 Concatenation [fs.path.concat]

🔗

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

#

Effects: Appends path(x).native() to the pathname in the native format.

[Note 1:

This directly manipulates the value of native(), which is not necessarily portable between operating systems.

— end note]

2

#

Returns: *this.

🔗

path& operator+=(value_type x); template<class EcharT> path& operator+=(EcharT x);

3

#

Effects: Equivalent to: return *this += basic_string_view(&x, 1);

🔗

template<class InputIterator> path& concat(InputIterator first, InputIterator last);

4

#

Effects: Equivalent to: return *this += path(first, last);

31.12.6.5.5 Modifiers [fs.path.modifiers]

🔗

void clear() noexcept;

1

#

Postconditions: empty() is true.

🔗

path& make_preferred();

2

#

Effects: Each directory-separator of the pathname in the generic format is converted to preferred-separator.

3

#

Returns: *this.

4

#

[Example 1: path p("foo/bar"); std::cout << p << '\n'; p.make_preferred(); std::cout << p << '\n';

On an operating system where preferred-separator is a slash, the output is:"foo/bar""foo/bar"

On an operating system where preferred-separator is a backslash, the output is:"foo/bar""foo\bar"

— end example]

🔗

path& remove_filename();

5

#

Effects: Remove the generic format pathname of filename() from the generic format pathname.

6

#

Postconditions: !has_filename().

7

#

Returns: *this.

8

#

[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]

🔗

path& replace_filename(const path& replacement);

9

#

Effects: Equivalent to:remove_filename();operator/=(replacement);

10

#

Returns: *this.

11

#

[Example 3: path("/foo").replace_filename("bar"); // yields "/bar" on POSIX path("/").replace_filename("bar"); // yields "/bar" on POSIX — end example]

🔗

path& replace_extension(const path& replacement = path());

12

#

Effects:

Any existing extension() ([fs.path.decompose]) is removed from the pathname in the generic format, then

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

operator+=(replacement);.

13

#

Returns: *this.

🔗

void swap(path& rhs) noexcept;

14

#

Effects: Swaps the contents (in all formats) of the two paths.

15

#

Complexity: Constant time.

31.12.6.5.6 Native format observers [fs.path.native.obs]

1

#

The string returned by all native format observers is in the native pathname format ([fs.class.path]).

🔗

const string_type& native() const noexcept;

2

#

Returns: The pathname in the native format.

🔗

const value_type* c_str() const noexcept;

3

#

Effects: Equivalent to: return native().c_str();

🔗

operator string_type() const;

4

#

Returns: native().

🔗

template<class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>> basic_string<EcharT, traits, Allocator> string(const Allocator& a = Allocator()) const;

5

#

Returns: native().

6

#

Remarks: All memory allocation, including for the return value, shall be performed by a.

Conversion, if any, is specified by[fs.path.cvt].

🔗

std::string system_encoded_string() const; std::wstring wstring() const; std::u8string u8string() const; std::u16string u16string() const; std::u32string u32string() const;

7

#

Returns: native().

8

#

Remarks: Conversion, if any, is performed as specified by [fs.path.cvt].

🔗

std::string display_string() const;

9

#

Returns: format("{}", *this).

[Note 1:

The returned string is suitable for use with formatting ([format.functions]) and print functions ([print.fun]).

— end note]

31.12.6.5.7 Generic format observers [fs.path.generic.obs]

1

#

Generic format observer functions return strings formatted according to thegeneric pathname format.

A single slash ('/') character is used as the directory-separator.

2

#

[Example 1:

On an operating system that uses backslash as its preferred-separator,path("foo\bar").generic_string() returns "foo/bar".

— end example]

🔗

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

#

Returns: The pathname in the generic format.

4

#

Remarks: All memory allocation, including for the return value, shall be performed by a.

Conversion, if any, is specified by[fs.path.cvt].

🔗

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

#

Returns: The pathname in the generic format.

6

#

Remarks: Conversion, if any, is specified by [fs.path.cvt].

🔗

std::string generic_display_string() const;

7

#

Returns: format("{:g}", *this).

[Note 1:

The returned string is suitable for use with formatting ([format.functions]) and print functions ([print.fun]).

— end note]

31.12.6.5.8 Compare [fs.path.compare]

🔗

int compare(const path& p) const noexcept;

1

#

Returns:

  • (1.1)

    Let rootNameComparison be the result of this->root_name().native().compare(p.root_name().native()). If rootNameComparison is not 0, rootNameComparison.

  • (1.2)

    Otherwise, if !this->has_root_directory() and p.has_root_directory(), a value less than 0.

  • (1.3)

    Otherwise, if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.

  • (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.

  • (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.

  • (1.6)

    Otherwise, 0.

🔗

int compare(const string_type& s) const; int compare(basic_string_view<value_type> s) const; int compare(const value_type* s) const;

2

#

Effects: Equivalent to: return compare(path(s));

31.12.6.5.9 Decomposition [fs.path.decompose]

🔗

path root_name() const;

1

#

Returns: root-name, if the pathname in the generic format includes root-name, otherwise path().

🔗

path root_directory() const;

2

#

Returns: root-directory, if the pathname in the generic format includes root-directory, otherwise path().

🔗

path root_path() const;

3

#

Returns: root_name() / root_directory().

🔗

path relative_path() const;

4

#

Returns: A path composed from the pathname in the generic format, if empty() is false, beginning with the first filename after root_path().

Otherwise, path().

🔗

path parent_path() const;

5

#

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.

🔗

path filename() const;

6

#

Returns: relative_path().empty() ? path() : *--end().

7

#

[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]

🔗

path stem() const;

8

#

Returns: Let f be the generic format pathname of filename().

Returns a path whose pathname in the generic format is

f, if it contains no periods other than a leading period or consists solely of one or two periods;

otherwise, the prefix of f ending before its last period.

9

#

[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]

🔗

path extension() const;

10

#

Returns: A path whose pathname in the generic format is the suffix of filename() not included in stem().

11

#

[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

#

[Note 1:

The period is included in the return value so that it is possible to distinguish between no extension and an empty extension.

— end note]

13

#

[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.

— end note]

31.12.6.5.10 Query [fs.path.query]

🔗

bool empty() const noexcept;

1

#

Returns: true if the pathname in the generic format is empty, otherwise false.

🔗

bool has_root_path() const;

2

#

Returns: !root_path().empty().

🔗

bool has_root_name() const;

3

#

Returns: !root_name().empty().

🔗

bool has_root_directory() const;

4

#

Returns: !root_directory().empty().

🔗

bool has_relative_path() const;

5

#

Returns: !relative_path().empty().

🔗

bool has_parent_path() const;

6

#

Returns: !parent_path().empty().

🔗

bool has_filename() const;

7

#

Returns: !filename().empty().

🔗

bool has_stem() const;

8

#

Returns: !stem().empty().

🔗

bool has_extension() const;

9

#

Returns: !extension().empty().

🔗

bool is_absolute() const;

10

#

Returns: true if the pathname in the native format contains an absolute path ([fs.class.path]), otherwise false.

11

#

[Example 1:

path("/").is_absolute() is true for POSIX-based operating systems, and false for Windows-based operating systems.

— end example]

🔗

bool is_relative() const;

12

#

Returns: !is_absolute().

31.12.6.5.11 Generation [fs.path.gen]

🔗

path lexically_normal() const;

1

#

Returns: A path whose pathname in the generic format is the normal form ([fs.path.generic]) of the pathname in the generic format of *this.

2

#

[Example 1: assert(path("foo/./bar/..").lexically_normal() == "foo/"); assert(path("foo/.///bar/../").lexically_normal() == "foo/");

The above assertions will succeed.

On Windows, the returned path's directory-separator characters will be backslashes rather than slashes, but that does not affect path equality.

— end example]

🔗

path lexically_relative(const path& base) const;

3

#

Effects: If:

root_name() != base.root_name() is true, or

is_absolute() != base.is_absolute() is true, or

!has_root_directory() && base.has_root_directory() is true, or

any filename inrelative_path() or base.relative_path() can be interpreted as a root-name,

returns path().

[Note 1:

On a POSIX implementation, no filename in a relative-path is acceptable as a root-name.

— 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)

    if a == end() and b == base.end(), returns path("."); otherwise

  • (3.6)

    let n be the number of filename elements in [b, base.end()) that are not dot or dot-dot or empty, minus the number that are dot-dot. If n<0, returns path(); otherwise

  • (3.7)

    if n == 0 and (a == end() || a->empty()), returns path("."); otherwise

  • (3.8)

    returns an object of class path that is default-constructed, followed by

application of operator/=(path(".."))n times, and then

application of operator/= for each element in [a, end()).

4

#

Returns: *this made relative to base.

Does not resolve ([fs.class.path]) symlinks.

Does not first normalize ([fs.path.generic]) *this or base.

5

#

[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.

On Windows, the returned path's directory-separator characters will be backslashes rather than slashes, but that does not affect path equality.

— end example]

6

#

[Note 2:

If symlink following semantics are desired, use the operational function relative().

— end note]

7

#

[Note 3:

If normalization ([fs.path.generic]) is needed to ensure consistent matching of elements, apply lexically_normal() to *this, base, or both.

— end note]

🔗

path lexically_proximate(const path& base) const;

8

#

Returns: If the value of lexically_relative(base) is not an empty path, return it.

Otherwise return *this.

9

#

[Note 4:

If symlink following semantics are desired, use the operational function proximate().

— end note]

10

#

[Note 5:

If normalization ([fs.path.generic]) is needed to ensure consistent matching of elements, apply lexically_normal() to *this, base, or both.

— end note]