An object of class path represents a path and contains a pathname. Such an object is concerned only with the lexical and syntactic aspects of a path. 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.
[ 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; // [fs.enum.path.format], enumeration format enum format; // [fs.path.construct], 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], 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], 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], 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], modifiers 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; // [fs.path.native.obs], native format observers 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; // [fs.path.generic.obs], generic format observers 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; // [fs.path.compare], compare 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; // [fs.path.decompose], 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], query 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; // [fs.path.gen], generation path lexically_normal() const; path lexically_relative(const path& base) const; path lexically_proximate(const path& base) const; // [fs.path.itr], iterators class iterator; using const_iterator = iterator; iterator begin() const; iterator end() const; }; }
value_type is a typedef for the operating system dependent encoded character type used to represent pathnames.
The value of the preferred_separator member is the operating system dependent preferred-separator character ([fs.path.generic]).
[ Example: For POSIX-based operating systems, value_type is char and preferred_separator is the slash character ('/'). For Windows-based operating systems, value_type is wchar_t and preferred_separator is the backslash character (L'\\'). — end example ]
pathname: root-nameopt root-directoryopt relative-path
root-name: operating system dependent sequences of characters implementation-defined sequences of characters
root-directory: directory-separator
relative-path: filename filename directory-separator relative-path an empty path
filename: non-empty sequence of characters other than directory-separator characters
directory-separator: preferred-separator directory-separatoropt fallback-separator directory-separatoropt
preferred-separator: operating system dependent directory separator character
fallback-separator: /, if preferred-separator is not /
[ Note:
Operating systems often place restrictions
on the characters that may be used in a filename.
For wide portability, users may wish to limit filename
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 ]
Except in a root-name, multiple successive directory-separator characters are considered to be the same as one directory-separator character.
The filename dot ([fs.def.filename]) is treated as a reference to the current directory. The filename dot-dot ([fs.def.filename]) is treated as a reference to the parent directory. What the filename dot-dot refers to relative to root-directory is implementation-defined. Specific filenames may have special meanings for a particular operating system.
A root-name identifies the starting location for pathname resolution ([fs.def.pathres]). If there are no operating system dependent root-names, at least one implementation-defined root-name is required. [ Note: Many operating systems define a name beginning with two directory-separator characters as a root-name that identifies network or other resource locations. Some operating systems define a single letter followed by a colon as a drive specifier – a root-name identifying a specific device such as a disk drive. — end note ]
If a root-name is otherwise ambiguous, the possibility with the longest sequence of characters is chosen. [ Note: On a POSIX-like operating system, it is impossible to have a root-name and a relative-path without an intervening root-directory element. — end note ]
[ Note: The format conversions described in this section are not applied on POSIX-based operating systems because on these systems:
The generic format is acceptable as a native path.
There is no need to distinguish between native format and generic format in function arguments.
Paths for regular files and paths for directories share the same syntax.
— end note ]
Several functions are defined to accept detected-format arguments, which are character sequences. A detected-format argument represents a path using either a pathname in the generic format or a pathname in the native format. 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.
[ Note: Some operating systems may have no unambiguous way to distinguish between native format and generic format arguments. This is by design as it simplifies use for operating systems that do not require disambiguation. An implementation for an operating system where disambiguation is required is permitted to distinguish between the formats. — end note ]
Pathnames are converted as needed between the generic and native formats in an operating-system-dependent manner. 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. If g=G(n) for some n, then G(N(g))=g; if n=N(g) for some g, then N(G(n))=n. [ Note: Neither G nor N need be invertible. — end note ]
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, otherwise it shall be treated as a path to a regular file.
[ Note: A path stores a native format pathname ([fs.path.native.obs]) and acts as if it also stores a generic format pathname, related as given below. The implementation may generate the generic format pathname based on the native format pathname (and possibly other information) when requested. — end note ]
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).
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. The value q converts to p (by G or N as appropriate) if any such value does so; q is otherwise unspecified. [ Note: If q is the result of converting any path at all, it is the result of converting p. — end note ]
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 from path::value_type. For the argument or return value, the method of conversion and the encoding to be converted to is determined by its value type:
char: The encoding is the native narrow encoding ([fs.def.native.encode]). The method of conversion, if any, is operating system dependent. [ Note: 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. For Windows-based operating systems, the native narrow encoding is determined by calling a Windows API function. — end note ] [ Note: This results in behavior identical to other C and C++ standard library functions that perform file operations using narrow character strings to identify paths. Changing this behavior would be surprising and error prone. — end note ]
wchar_t: The encoding is the native wide encoding. The method of conversion is unspecified. [ Note: 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. — end note ]
char16_t: The encoding is UTF-16. The method of conversion is unspecified.
char32_t: The encoding is UTF-32. The method of conversion is unspecified.
In addition to the requirements ([fs.req]), function template parameters named Source shall be one of:
basic_string<EcharT, traits, Allocator>. A function argument const Source& source shall have an effective range [source.begin(), source.end()).
basic_string_view<EcharT, traits>. A function argument const Source& source shall have an effective range [source.begin(), source.end()).
A type meeting the input iterator requirements that iterates over a NTCTS. The value type shall be an encoded character type. 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().
A character array that after array-to-pointer decay results in a pointer to the start of a NTCTS. The value type shall be an encoded character type. 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().
Functions taking template parameters named Source shall not participate in overload resolution unless either
Source is a specialization of basic_string or basic_string_view, or
the qualified-id iterator_traits<decay_t<Source>>::value_type is valid and denotes a possibly const encoded character type ([temp.deduct]).
[ Note: See path conversions for how the value types above and their encodings convert to path::value_type and its encoding. — end note ]
path() noexcept;
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);
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:
// On POSIX, path("foo") / ""; // yields "foo/" path("foo") / "/bar"; // yields "/bar" // On Windows, backslashes replace slashes in the above yields // On Windows, path("foo") / "c:/bar"; // yields "c:/bar" path("foo") / "c:"; // yields "c:" path("c:") / ""; // yields "c:" path("c:foo") / "/bar"; // yields "c:/bar" path("c:foo") / "c:bar"; // yields "c:foo/bar"
— end example ]
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);
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);
void clear() noexcept;
path& make_preferred();
Effects: Each directory-separator of the pathname in the generic format is converted to preferred-separator.
[ 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();
[ Example:
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);
[ Example:
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());
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);.
void swap(path& rhs) noexcept;
const string_type& native() const noexcept;
const value_type* c_str() const noexcept;
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. Conversion, if any, is specified by [fs.path.cvt].
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. A single slash ('/') character is used as the directory-separator.
[ 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;
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_string() const;
std::wstring generic_wstring() const;
std::string generic_u8string() const;
std::u16string generic_u16string() const;
std::u32string generic_u32string() const;
Remarks: Conversion, if any, is specified by [fs.path.cvt]. 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,
0.
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;
int compare(const value_type* s) const
path root_name() const;
path root_directory() const;
Returns: root-directory, if the pathname in the generic format includes root-directory, otherwise path().
path root_path() const;
path relative_path() const;
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;
[ Example:
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;
[ Example:
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;
Returns: a path whose pathname in the generic format is the suffix of filename() not included in stem().
[ Example:
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 ]
[ 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 ]
bool empty() const noexcept;
bool has_root_path() const;
bool has_root_name() const;
bool has_root_directory() 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;
Returns: true if the pathname in the native format contains an absolute path, else false.
[ Example: path("/").is_absolute() is true for POSIX-based operating systems, and false for Windows-based operating systems. — end example ]
bool is_relative() const;
path lexically_normal() const;
Returns: A path whose pathname in the generic format is the 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;
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
application of operator/=(path("..")) n times, and then
application of operator/= for each element in [a, end()).
[ 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 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. Otherwise return *this.
[ Note: If symlink following semantics are desired, use the operational function proximate(). — end note ]
[ Note: If normalization is needed to ensure consistent matching of elements, apply lexically_normal() to *this, base, or both. — end note ]
A path::iterator is a constant iterator satisfying all the requirements of a bidirectional iterator 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. Its value_type is path.
Calling any non-const member function of a path object invalidates all iterators referring to elements of that object.
For the elements of the pathname in the generic format, the forward traversal order is as follows:
The root-name element, if present.
The root-directory element, if present. [ Note: The generic format is required to ensure lexicographical comparison works correctly. — end note ]
Each successive filename element, if present.
An empty element, if a trailing non-root directory-separator is present.
iterator begin() const;
Returns: An iterator for the first present element in the traversal list above. If no elements are present, the end iterator.
iterator end() const;
void swap(path& lhs, path& rhs) noexcept;
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;
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;
[ 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 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);
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>()); [ Note: The quoted function is described in [quoted.manip]. — end note ]
template <class charT, class traits>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, path& p);
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 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 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 ]