[
Note: 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
. —
end note ]
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;
enum format;
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();
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);
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);
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);
void 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;
const 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 string() const;
std::wstring wstring() const;
std::string u8string() const;
std::u16string u16string() const;
std::u32string u32string() const;
template <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_string() const;
std::wstring generic_wstring() const;
std::string generic_u8string() const;
std::u16string generic_u16string() const;
std::u32string generic_u32string() const;
int 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;
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;
bool 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;
path lexically_normal() const;
path lexically_relative(const path& base) const;
path lexically_proximate(const path& base) const;
class iterator;
using const_iterator = iterator;
iterator begin() const;
iterator end() const;
};
}
path() noexcept;
Effects: Constructs an object of class
path. Postconditions: empty() == true. path(const path& p);
path(path&& p) noexcept;
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);
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);
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);
Requires:
The value type of
Source and
InputIterator is
char. Effects: Let
s be the effective range of
source
or the range
[first, last),
after converting the encoding as
follows:
If
value_type is
wchar_t, converts to the native
wide encoding (
[fs.def.native.encode]) using the
codecvt<wchar_t, char, mbstate_t>
facet of
loc.Otherwise a conversion is performed using the
codecvt<wchar_t, char, mbstate_t> facet of
loc, and then a second
conversion to the current narrow encoding
.
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: 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 using
latin1_facet to convert ISO/IEC 8859-1 encoded
latin1_string to a wide character string in the native wide
encoding (
[fs.def.native.encode])
. The resulting wide string is then
converted to a narrow character
pathname string in the current native narrow encoding
. If the
native wide encoding is UTF-16 or UTF-32, and the current native narrow
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
narrow 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 encoded
latin1_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 ]
path& operator=(const path& p);
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.path& operator=(path&& p) noexcept;
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: A valid implementation is
swap(p). —
end note ]
path& operator=(string_type&& source);
path& assign(string_type&& source);
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
. 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);
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.The append operations use
operator/= to denote their semantic effect of appending
preferred-separator when needed
. path& operator/=(const path& p);
Effects: If
p.is_absolute() || (p.has_root_name() && p.root_name() != root_name()),
then
operator=(p). Otherwise, modifies
*this as if by these steps:
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
.Then appends the native format pathname of
p,
omitting any
root-name from its generic format pathname,
to the native format pathname
.
[
Example: Even if
//host is interpreted as a
root-name,
both of the paths
path("//host")/"foo" and
path("//host/")/"foo"
equal
"//host/foo".Expression examples:
path("foo") / ""; path("foo") / "/bar";
path("foo") / "c:/bar"; path("foo") / "c:"; path("c:") / ""; path("c:foo") / "/bar"; path("c:foo") / "c:bar";
—
end example ]
template <class Source>
path& operator/=(const Source& source);
template <class Source>
path& append(const Source& source);
Effects: Equivalent to: return operator/=(path(source));
template <class InputIterator>
path& append(InputIterator first, InputIterator last);
Effects: Equivalent to: return operator/=(path(first, last));
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);
Effects: Appends
path(x).native() to the pathname in the native format
. [
Note: This directly manipulates the value of
native()
and may not be portable between operating systems
. —
end note ]
template <class InputIterator>
path& concat(InputIterator first, InputIterator last);
Effects: Equivalent to
return *this += path(first, last). void clear() noexcept;
Postconditions: empty() == true. path& make_preferred();
[
Example:
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();
Postconditions: !has_filename(). Effects: Remove the generic format pathname of
filename() from the generic format pathname
. [
Example:
path("foo/bar").remove_filename(); path("foo/").remove_filename(); path("/foo").remove_filename(); path("/").remove_filename();
—
end example ]
path& replace_filename(const path& replacement);
Effects:
Equivalent to:
remove_filename();
operator/=(replacement);
[
Example:
path("/foo").replace_filename("bar"); path("/").replace_filename("bar");
—
end example ]
path& replace_extension(const path& replacement = path());
void swap(path& rhs) noexcept;
Effects: Swaps the contents (in all formats) of the two paths
. Complexity: Constant time
. The string returned by all native format observers is in the native pathname format (
[fs.def.native])
. const string_type& native() const noexcept;
Returns: The pathname in the native format
. const value_type* c_str() const noexcept;
Returns: Equivalent to
native().c_str(). operator string_type() const;
[
Note: Conversion to
string_type is provided so that an
object of class
path can be given as an argument to existing
standard library file stream constructors and open functions
. —
end note ]
template <class EcharT, class traits = char_traits<EcharT>,
class Allocator = allocator<EcharT>>
basic_string<EcharT, traits, Allocator>
string(const Allocator& a = Allocator()) const;
Remarks: All memory allocation, including for the return value, shall
be performed by
a. std::string string() const;
std::wstring wstring() const;
std::string u8string() const;
std::u16string u16string() const;
std::u32string u32string() const;
Remarks: Conversion, if any, is performed as specified
by
[fs.path.cvt]. The encoding of the string returned by
u8string() is always UTF-8
.Generic format observer functions return strings formatted according to the
generic pathname format (
[fs.path.generic])
. [
Example: 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;
Returns: The pathname in the generic format
. Remarks: All memory allocation, including for the return value, shall
be performed by
a. std::string generic_string() const;
std::wstring generic_wstring() const;
std::string generic_u8string() const;
std::u16string generic_u16string() const;
std::u32string generic_u32string() const;
Returns: The pathname in the generic format
. The encoding of the string returned by
generic_u8string() is always
UTF-8
. int compare(const path& p) const noexcept;
Returns:
A value less than 0,
if native() for the elements of *this
are lexicographically less than native() for the elements of p;
otherwise,
a value greater than 0,
if native() for the elements of *this
are lexicographically greater than native() for the elements of p;
otherwise,
Remarks: The elements are determined as if by iteration over the half-open
range
[begin(), end()) for
*this and
p. int compare(const string_type& s) const
int compare(basic_string_view<value_type> s) const;
Returns: compare(path(s)). int compare(const value_type* s) const
Returns: compare(path(s)). path root_name() const;
Returns: root-name, if the pathname in the generic format
includes
root-name, otherwise
path(). path root_directory() const;
path root_path() const;
Returns: root_name() / root_directory(). path relative_path() const;
Returns: A
path composed from the pathname in the generic format,
if
!empty(), beginning
with the first
filename after
root-path. path parent_path() const;
Returns: *this if
!has_relative_path(),
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;
Returns: relative_path().empty() ? path() : *--end(). [
Example:
path("/foo/bar.txt").filename(); path("/foo/bar").filename(); path("/foo/bar/").filename(); path("/").filename(); path("//host").filename(); path(".").filename(); path("..").filename();
—
end example ]
path stem() const;
Returns: Let
f be the generic format pathname of
filename(). Returns a path whose pathname in the generic format is
[
Example:
std::cout << path("/foo/bar.txt").stem(); path p = "foo.bar.baz.tar";
for (; !p.extension().empty(); p = p.stem())
std::cout << p.extension() << '\n';
—
end example ]
path extension() const;
Returns: a path whose pathname in the generic format is
the suffix of
filename() not included in
stem(). [
Example:
path("/foo/bar.txt").extension(); path("/foo/bar").extension(); path("/foo/.profile").extension(); path(".bar").extension(); path("..bar").extension();
—
end example ]
[
Note: The period is included in the return value so that it is
possible to distinguish between no extension and an empty extension
. —
end note ]
[
Note: On non-POSIX operating systems, for a path
p,
it may not be the case that
p.stem() + p.extension() == p.filename(),
even though the generic format pathnames are the same
. —
end note ]
bool empty() const noexcept;
Returns: true if the pathname in the generic format is empty, else
false. bool has_root_path() const;
Returns: !root_path().empty(). bool has_root_name() const;
Returns: !root_name().empty(). bool has_root_directory() const;
Returns: !root_directory().empty(). bool has_relative_path() const;
Returns: !relative_path().empty(). bool has_parent_path() const;
Returns: !parent_path().empty(). bool has_filename() const;
Returns: !filename().empty(). bool has_stem() const;
Returns: !stem().empty(). bool has_extension() const;
Returns: !extension().empty(). bool is_absolute() const;
[
Example: path("/").is_absolute() is
true for POSIX-based operating systems, and
false for Windows-based
operating systems
. —
end example ]
bool is_relative() const;
Returns: !is_absolute(). path lexically_normal() const;
Returns: A path whose pathname in the generic format is
the normal form (
[fs.def.normal.form]) of the pathname
in the generic format of
*this. [
Example:
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;
Returns: *this made relative to
base. 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,
returns
path(). Determines the first mismatched element of
*this and
base
as if by:
auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
Then,
if a == end() and b == base.end(), returns path("."); otherwise
let
n be the number of
filename elements in
[b, base.end())
that are not
dot or
dot-dot minus the number that are
dot-dot. If n<0, returns path(); otherwise
returns an object of class
path that is default-constructed, followed by
[
Example:
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 ]
[
Note: If symlink following semantics are desired,
use the operational function
relative(). —
end note ]
[
Note: If normalization (
[fs.def.normal.form]) 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;
Returns: If the value of
lexically_relative(base) is not an empty path,
return it
. [
Note: If symlink following semantics are desired,
use the operational function
proximate(). —
end note ]
[
Note: If normalization (
[fs.def.normal.form]) is needed
to ensure consistent matching of elements,
apply
lexically_normal() to
*this,
base, or both
. —
end note ]
void swap(path& lhs, path& rhs) noexcept;
Effects: Equivalent to: lhs.swap(rhs);
size_t hash_value (const path& p) noexcept;
Returns: A hash value for the path
p. If
for two paths,
p1 == p2 then
hash_value(p1) == hash_value(p2).bool operator< (const path& lhs, const path& rhs) noexcept;
Returns: lhs.compare(rhs) < 0. bool operator<=(const path& lhs, const path& rhs) noexcept;
bool operator> (const path& lhs, const path& rhs) noexcept;
bool operator>=(const path& lhs, const path& rhs) noexcept;
bool operator==(const path& lhs, const path& rhs) noexcept;
Returns: !(lhs < rhs) && !(rhs < lhs). [
Note: Path equality and path equivalence have different semantics
. Equality is determined by the
path non-member
operator==,
which considers the two path's lexical representations only
. [
Example: path("foo") == "bar" is never
true. —
end example ]
Equivalence is determined by the
equivalent() non-member function, which
determines if two paths resolve (
[fs.def.pathres]) to the same file system entity
. [
Example: equivalent("foo", "bar") will be
true when both paths resolve to the same file
. —
end example ]
Programmers wishing to determine if two paths are “the same” must decide if
“the same” means “the same representation” or “resolve to the same actual
file”, and choose the appropriate function accordingly
. —
end note ]
bool operator!=(const path& lhs, const path& rhs) noexcept;
path operator/ (const path& lhs, const path& rhs);
Effects: Equivalent to: return path(lhs) /= rhs;
template <class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const path& p);
Effects: Equivalent to:
os << quoted(p.string<charT, traits>());
template <class charT, class traits>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, path& p);
Effects:
Equivalent to:
basic_string<charT, traits> tmp;
is >> quoted(tmp);
p = tmp;
template <class Source>
path u8path(const Source& source);
template <class InputIterator>
path u8path(InputIterator first, InputIterator last);
Requires: The
source and
[first, last)
sequences are UTF-8 encoded
. The value type of
Source
and
InputIterator is
char.Returns:
If
value_type is
char and the current native
narrow encoding (
[fs.def.native.encode]) is UTF-8,
return
path(source) or
path(first, last);
otherwise,
if value_type is wchar_t and the
native wide encoding is UTF-16, or
if value_type is char16_t or char32_t,
convert source or [first, last)
to a temporary, tmp, of type string_type and
return path(tmp);
otherwise,
convert
source or
[first, last)
to a temporary,
tmp, of type
u32string and
return
path(tmp).
Remarks: Argument format conversion (
[fs.path.fmt.cvt]) applies to the
arguments for these functions
. How Unicode encoding conversions are performed is
unspecified
.[
Example: A string is to be read from a database that is encoded in UTF-8, and used
to create a directory using the native encoding for filenames:
namespace fs = std::filesystem;
std::string utf8_string = read_utf8_data();
fs::create_directory(fs::u8path(utf8_string));
For POSIX-based operating systems with the native narrow encoding set
to UTF-8, no encoding or type conversion occurs
. For POSIX-based operating systems with the native narrow encoding not
set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the
current native narrow encoding
. Some Unicode characters may have no native character
set representation
. For Windows-based operating systems a conversion from UTF-8 to
UTF-16 occurs
. —
end example ]