xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/filesystem (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===--------------------------- filesystem -------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg#ifndef _LIBCPP_FILESYSTEM
10*4d6fc14bSjoerg#define _LIBCPP_FILESYSTEM
11*4d6fc14bSjoerg/*
12*4d6fc14bSjoerg    filesystem synopsis
13*4d6fc14bSjoerg
14*4d6fc14bSjoerg    namespace std { namespace filesystem {
15*4d6fc14bSjoerg
16*4d6fc14bSjoerg    class path;
17*4d6fc14bSjoerg
18*4d6fc14bSjoerg    void swap(path& lhs, path& rhs) noexcept;
19*4d6fc14bSjoerg    size_t hash_value(const path& p) noexcept;
20*4d6fc14bSjoerg
21*4d6fc14bSjoerg    bool operator==(const path& lhs, const path& rhs) noexcept;
22*4d6fc14bSjoerg    bool operator!=(const path& lhs, const path& rhs) noexcept;
23*4d6fc14bSjoerg    bool operator< (const path& lhs, const path& rhs) noexcept;
24*4d6fc14bSjoerg    bool operator<=(const path& lhs, const path& rhs) noexcept;
25*4d6fc14bSjoerg    bool operator> (const path& lhs, const path& rhs) noexcept;
26*4d6fc14bSjoerg    bool operator>=(const path& lhs, const path& rhs) noexcept;
27*4d6fc14bSjoerg
28*4d6fc14bSjoerg    path operator/ (const path& lhs, const path& rhs);
29*4d6fc14bSjoerg
30*4d6fc14bSjoerg    // fs.path.io operators are friends of path.
31*4d6fc14bSjoerg    template <class charT, class traits>
32*4d6fc14bSjoerg    friend basic_ostream<charT, traits>&
33*4d6fc14bSjoerg    operator<<(basic_ostream<charT, traits>& os, const path& p);
34*4d6fc14bSjoerg
35*4d6fc14bSjoerg    template <class charT, class traits>
36*4d6fc14bSjoerg    friend basic_istream<charT, traits>&
37*4d6fc14bSjoerg    operator>>(basic_istream<charT, traits>& is, path& p);
38*4d6fc14bSjoerg
39*4d6fc14bSjoerg    template <class Source>
40*4d6fc14bSjoerg      path u8path(const Source& source);
41*4d6fc14bSjoerg    template <class InputIterator>
42*4d6fc14bSjoerg      path u8path(InputIterator first, InputIterator last);
43*4d6fc14bSjoerg
44*4d6fc14bSjoerg    class filesystem_error;
45*4d6fc14bSjoerg    class directory_entry;
46*4d6fc14bSjoerg
47*4d6fc14bSjoerg    class directory_iterator;
48*4d6fc14bSjoerg
49*4d6fc14bSjoerg    // enable directory_iterator range-based for statements
50*4d6fc14bSjoerg    directory_iterator begin(directory_iterator iter) noexcept;
51*4d6fc14bSjoerg    directory_iterator end(const directory_iterator&) noexcept;
52*4d6fc14bSjoerg
53*4d6fc14bSjoerg    class recursive_directory_iterator;
54*4d6fc14bSjoerg
55*4d6fc14bSjoerg    // enable recursive_directory_iterator range-based for statements
56*4d6fc14bSjoerg    recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
57*4d6fc14bSjoerg    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
58*4d6fc14bSjoerg
59*4d6fc14bSjoerg    class file_status;
60*4d6fc14bSjoerg
61*4d6fc14bSjoerg    struct space_info
62*4d6fc14bSjoerg    {
63*4d6fc14bSjoerg      uintmax_t capacity;
64*4d6fc14bSjoerg      uintmax_t free;
65*4d6fc14bSjoerg      uintmax_t available;
66*4d6fc14bSjoerg    };
67*4d6fc14bSjoerg
68*4d6fc14bSjoerg    enum class file_type;
69*4d6fc14bSjoerg    enum class perms;
70*4d6fc14bSjoerg    enum class perm_options;
71*4d6fc14bSjoerg    enum class copy_options;
72*4d6fc14bSjoerg    enum class directory_options;
73*4d6fc14bSjoerg
74*4d6fc14bSjoerg    typedef chrono::time_point<trivial-clock>  file_time_type;
75*4d6fc14bSjoerg
76*4d6fc14bSjoerg    // operational functions
77*4d6fc14bSjoerg
78*4d6fc14bSjoerg    path absolute(const path& p);
79*4d6fc14bSjoerg    path absolute(const path& p, error_code &ec);
80*4d6fc14bSjoerg
81*4d6fc14bSjoerg    path canonical(const path& p);
82*4d6fc14bSjoerg    path canonical(const path& p, error_code& ec);
83*4d6fc14bSjoerg
84*4d6fc14bSjoerg    void copy(const path& from, const path& to);
85*4d6fc14bSjoerg    void copy(const path& from, const path& to, error_code& ec);
86*4d6fc14bSjoerg    void copy(const path& from, const path& to, copy_options options);
87*4d6fc14bSjoerg    void copy(const path& from, const path& to, copy_options options,
88*4d6fc14bSjoerg                   error_code& ec);
89*4d6fc14bSjoerg
90*4d6fc14bSjoerg    bool copy_file(const path& from, const path& to);
91*4d6fc14bSjoerg    bool copy_file(const path& from, const path& to, error_code& ec);
92*4d6fc14bSjoerg    bool copy_file(const path& from, const path& to, copy_options option);
93*4d6fc14bSjoerg    bool copy_file(const path& from, const path& to, copy_options option,
94*4d6fc14bSjoerg                           error_code& ec);
95*4d6fc14bSjoerg
96*4d6fc14bSjoerg    void copy_symlink(const path& existing_symlink, const path& new_symlink);
97*4d6fc14bSjoerg    void copy_symlink(const path& existing_symlink, const path& new_symlink,
98*4d6fc14bSjoerg                              error_code& ec) noexcept;
99*4d6fc14bSjoerg
100*4d6fc14bSjoerg    bool create_directories(const path& p);
101*4d6fc14bSjoerg    bool create_directories(const path& p, error_code& ec);
102*4d6fc14bSjoerg
103*4d6fc14bSjoerg    bool create_directory(const path& p);
104*4d6fc14bSjoerg    bool create_directory(const path& p, error_code& ec) noexcept;
105*4d6fc14bSjoerg
106*4d6fc14bSjoerg    bool create_directory(const path& p, const path& attributes);
107*4d6fc14bSjoerg    bool create_directory(const path& p, const path& attributes,
108*4d6fc14bSjoerg                                  error_code& ec) noexcept;
109*4d6fc14bSjoerg
110*4d6fc14bSjoerg    void create_directory_symlink(const path& to, const path& new_symlink);
111*4d6fc14bSjoerg    void create_directory_symlink(const path& to, const path& new_symlink,
112*4d6fc14bSjoerg                                          error_code& ec) noexcept;
113*4d6fc14bSjoerg
114*4d6fc14bSjoerg    void create_hard_link(const path& to, const path& new_hard_link);
115*4d6fc14bSjoerg    void create_hard_link(const path& to, const path& new_hard_link,
116*4d6fc14bSjoerg                                  error_code& ec) noexcept;
117*4d6fc14bSjoerg
118*4d6fc14bSjoerg    void create_symlink(const path& to, const path& new_symlink);
119*4d6fc14bSjoerg    void create_symlink(const path& to, const path& new_symlink,
120*4d6fc14bSjoerg                                error_code& ec) noexcept;
121*4d6fc14bSjoerg
122*4d6fc14bSjoerg    path current_path();
123*4d6fc14bSjoerg    path current_path(error_code& ec);
124*4d6fc14bSjoerg    void current_path(const path& p);
125*4d6fc14bSjoerg    void current_path(const path& p, error_code& ec) noexcept;
126*4d6fc14bSjoerg
127*4d6fc14bSjoerg    bool exists(file_status s) noexcept;
128*4d6fc14bSjoerg    bool exists(const path& p);
129*4d6fc14bSjoerg    bool exists(const path& p, error_code& ec) noexcept;
130*4d6fc14bSjoerg
131*4d6fc14bSjoerg    bool equivalent(const path& p1, const path& p2);
132*4d6fc14bSjoerg    bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
133*4d6fc14bSjoerg
134*4d6fc14bSjoerg    uintmax_t    file_size(const path& p);
135*4d6fc14bSjoerg    uintmax_t    file_size(const path& p, error_code& ec) noexcept;
136*4d6fc14bSjoerg
137*4d6fc14bSjoerg    uintmax_t    hard_link_count(const path& p);
138*4d6fc14bSjoerg    uintmax_t    hard_link_count(const path& p, error_code& ec) noexcept;
139*4d6fc14bSjoerg
140*4d6fc14bSjoerg    bool is_block_file(file_status s) noexcept;
141*4d6fc14bSjoerg    bool is_block_file(const path& p);
142*4d6fc14bSjoerg    bool is_block_file(const path& p, error_code& ec) noexcept;
143*4d6fc14bSjoerg
144*4d6fc14bSjoerg    bool is_character_file(file_status s) noexcept;
145*4d6fc14bSjoerg    bool is_character_file(const path& p);
146*4d6fc14bSjoerg    bool is_character_file(const path& p, error_code& ec) noexcept;
147*4d6fc14bSjoerg
148*4d6fc14bSjoerg    bool is_directory(file_status s) noexcept;
149*4d6fc14bSjoerg    bool is_directory(const path& p);
150*4d6fc14bSjoerg    bool is_directory(const path& p, error_code& ec) noexcept;
151*4d6fc14bSjoerg
152*4d6fc14bSjoerg    bool is_empty(const path& p);
153*4d6fc14bSjoerg    bool is_empty(const path& p, error_code& ec) noexcept;
154*4d6fc14bSjoerg
155*4d6fc14bSjoerg    bool is_fifo(file_status s) noexcept;
156*4d6fc14bSjoerg    bool is_fifo(const path& p);
157*4d6fc14bSjoerg    bool is_fifo(const path& p, error_code& ec) noexcept;
158*4d6fc14bSjoerg
159*4d6fc14bSjoerg    bool is_other(file_status s) noexcept;
160*4d6fc14bSjoerg    bool is_other(const path& p);
161*4d6fc14bSjoerg    bool is_other(const path& p, error_code& ec) noexcept;
162*4d6fc14bSjoerg
163*4d6fc14bSjoerg    bool is_regular_file(file_status s) noexcept;
164*4d6fc14bSjoerg    bool is_regular_file(const path& p);
165*4d6fc14bSjoerg    bool is_regular_file(const path& p, error_code& ec) noexcept;
166*4d6fc14bSjoerg
167*4d6fc14bSjoerg    bool is_socket(file_status s) noexcept;
168*4d6fc14bSjoerg    bool is_socket(const path& p);
169*4d6fc14bSjoerg    bool is_socket(const path& p, error_code& ec) noexcept;
170*4d6fc14bSjoerg
171*4d6fc14bSjoerg    bool is_symlink(file_status s) noexcept;
172*4d6fc14bSjoerg    bool is_symlink(const path& p);
173*4d6fc14bSjoerg    bool is_symlink(const path& p, error_code& ec) noexcept;
174*4d6fc14bSjoerg
175*4d6fc14bSjoerg    file_time_type  last_write_time(const path& p);
176*4d6fc14bSjoerg    file_time_type  last_write_time(const path& p, error_code& ec) noexcept;
177*4d6fc14bSjoerg    void last_write_time(const path& p, file_time_type new_time);
178*4d6fc14bSjoerg    void last_write_time(const path& p, file_time_type new_time,
179*4d6fc14bSjoerg                                 error_code& ec) noexcept;
180*4d6fc14bSjoerg
181*4d6fc14bSjoerg    void permissions(const path& p, perms prms,
182*4d6fc14bSjoerg                     perm_options opts=perm_options::replace);
183*4d6fc14bSjoerg    void permissions(const path& p, perms prms, error_code& ec) noexcept;
184*4d6fc14bSjoerg    void permissions(const path& p, perms prms, perm_options opts,
185*4d6fc14bSjoerg                     error_code& ec);
186*4d6fc14bSjoerg
187*4d6fc14bSjoerg    path proximate(const path& p, error_code& ec);
188*4d6fc14bSjoerg    path proximate(const path& p, const path& base = current_path());
189*4d6fc14bSjoerg    path proximate(const path& p, const path& base, error_code &ec);
190*4d6fc14bSjoerg
191*4d6fc14bSjoerg    path read_symlink(const path& p);
192*4d6fc14bSjoerg    path read_symlink(const path& p, error_code& ec);
193*4d6fc14bSjoerg
194*4d6fc14bSjoerg    path relative(const path& p, error_code& ec);
195*4d6fc14bSjoerg    path relative(const path& p, const path& base=current_path());
196*4d6fc14bSjoerg    path relative(const path& p, const path& base, error_code& ec);
197*4d6fc14bSjoerg
198*4d6fc14bSjoerg    bool remove(const path& p);
199*4d6fc14bSjoerg    bool remove(const path& p, error_code& ec) noexcept;
200*4d6fc14bSjoerg
201*4d6fc14bSjoerg    uintmax_t    remove_all(const path& p);
202*4d6fc14bSjoerg    uintmax_t    remove_all(const path& p, error_code& ec);
203*4d6fc14bSjoerg
204*4d6fc14bSjoerg    void rename(const path& from, const path& to);
205*4d6fc14bSjoerg    void rename(const path& from, const path& to, error_code& ec) noexcept;
206*4d6fc14bSjoerg
207*4d6fc14bSjoerg    void resize_file(const path& p, uintmax_t size);
208*4d6fc14bSjoerg    void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
209*4d6fc14bSjoerg
210*4d6fc14bSjoerg    space_info   space(const path& p);
211*4d6fc14bSjoerg    space_info   space(const path& p, error_code& ec) noexcept;
212*4d6fc14bSjoerg
213*4d6fc14bSjoerg    file_status  status(const path& p);
214*4d6fc14bSjoerg    file_status  status(const path& p, error_code& ec) noexcept;
215*4d6fc14bSjoerg
216*4d6fc14bSjoerg    bool status_known(file_status s) noexcept;
217*4d6fc14bSjoerg
218*4d6fc14bSjoerg    file_status  symlink_status(const path& p);
219*4d6fc14bSjoerg    file_status  symlink_status(const path& p, error_code& ec) noexcept;
220*4d6fc14bSjoerg
221*4d6fc14bSjoerg    path temp_directory_path();
222*4d6fc14bSjoerg    path temp_directory_path(error_code& ec);
223*4d6fc14bSjoerg
224*4d6fc14bSjoerg    path weakly_canonical(path const& p);
225*4d6fc14bSjoerg    path weakly_canonical(path const& p, error_code& ec);
226*4d6fc14bSjoerg
227*4d6fc14bSjoerg
228*4d6fc14bSjoerg} }  // namespaces std::filesystem
229*4d6fc14bSjoerg
230*4d6fc14bSjoerg*/
231*4d6fc14bSjoerg
232*4d6fc14bSjoerg#include <__config>
233*4d6fc14bSjoerg#include <__availability>
234*4d6fc14bSjoerg#include <cstddef>
235*4d6fc14bSjoerg#include <cstdlib>
236*4d6fc14bSjoerg#include <chrono>
237*4d6fc14bSjoerg#include <compare>
238*4d6fc14bSjoerg#include <iterator>
239*4d6fc14bSjoerg#include <iosfwd>
240*4d6fc14bSjoerg#include <memory>
241*4d6fc14bSjoerg#include <stack>
242*4d6fc14bSjoerg#include <string>
243*4d6fc14bSjoerg#include <system_error>
244*4d6fc14bSjoerg#include <utility>
245*4d6fc14bSjoerg#include <string_view>
246*4d6fc14bSjoerg#include <version>
247*4d6fc14bSjoerg
248*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
249*4d6fc14bSjoerg# include <locale>
250*4d6fc14bSjoerg# include <iomanip> // for quoted
251*4d6fc14bSjoerg#endif
252*4d6fc14bSjoerg
253*4d6fc14bSjoerg#include <__debug>
254*4d6fc14bSjoerg
255*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
256*4d6fc14bSjoerg# error "The Filesystem library is not supported by this configuration of libc++"
257*4d6fc14bSjoerg#endif
258*4d6fc14bSjoerg
259*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
260*4d6fc14bSjoerg#pragma GCC system_header
261*4d6fc14bSjoerg#endif
262*4d6fc14bSjoerg
263*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS
264*4d6fc14bSjoerg#include <__undef_macros>
265*4d6fc14bSjoerg
266*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
267*4d6fc14bSjoerg
268*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
269*4d6fc14bSjoerg
270*4d6fc14bSjoerg_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
271*4d6fc14bSjoerg
272*4d6fc14bSjoergtypedef chrono::time_point<_FilesystemClock> file_time_type;
273*4d6fc14bSjoerg
274*4d6fc14bSjoergstruct _LIBCPP_TYPE_VIS space_info {
275*4d6fc14bSjoerg  uintmax_t capacity;
276*4d6fc14bSjoerg  uintmax_t free;
277*4d6fc14bSjoerg  uintmax_t available;
278*4d6fc14bSjoerg};
279*4d6fc14bSjoerg
280*4d6fc14bSjoerg// On Windows, the library never identifies files as  block, character, fifo
281*4d6fc14bSjoerg// or socket.
282*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS file_type : signed char {
283*4d6fc14bSjoerg  none = 0,
284*4d6fc14bSjoerg  not_found = -1,
285*4d6fc14bSjoerg  regular = 1,
286*4d6fc14bSjoerg  directory = 2,
287*4d6fc14bSjoerg  symlink = 3,
288*4d6fc14bSjoerg  block = 4,
289*4d6fc14bSjoerg  character = 5,
290*4d6fc14bSjoerg  fifo = 6,
291*4d6fc14bSjoerg  socket = 7,
292*4d6fc14bSjoerg  unknown = 8
293*4d6fc14bSjoerg};
294*4d6fc14bSjoerg
295*4d6fc14bSjoerg// On Windows, these permission bits map to one single readonly flag per
296*4d6fc14bSjoerg// file, and the executable bit is always returned as set. When setting
297*4d6fc14bSjoerg// permissions, as long as the write bit is set for either owner, group or
298*4d6fc14bSjoerg// others, the readonly flag is cleared.
299*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS perms : unsigned {
300*4d6fc14bSjoerg  none = 0,
301*4d6fc14bSjoerg
302*4d6fc14bSjoerg  owner_read = 0400,
303*4d6fc14bSjoerg  owner_write = 0200,
304*4d6fc14bSjoerg  owner_exec = 0100,
305*4d6fc14bSjoerg  owner_all = 0700,
306*4d6fc14bSjoerg
307*4d6fc14bSjoerg  group_read = 040,
308*4d6fc14bSjoerg  group_write = 020,
309*4d6fc14bSjoerg  group_exec = 010,
310*4d6fc14bSjoerg  group_all = 070,
311*4d6fc14bSjoerg
312*4d6fc14bSjoerg  others_read = 04,
313*4d6fc14bSjoerg  others_write = 02,
314*4d6fc14bSjoerg  others_exec = 01,
315*4d6fc14bSjoerg  others_all = 07,
316*4d6fc14bSjoerg
317*4d6fc14bSjoerg  all = 0777,
318*4d6fc14bSjoerg
319*4d6fc14bSjoerg  set_uid = 04000,
320*4d6fc14bSjoerg  set_gid = 02000,
321*4d6fc14bSjoerg  sticky_bit = 01000,
322*4d6fc14bSjoerg  mask = 07777,
323*4d6fc14bSjoerg  unknown = 0xFFFF,
324*4d6fc14bSjoerg};
325*4d6fc14bSjoerg
326*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
327*4d6fc14bSjoerginline constexpr perms operator&(perms _LHS, perms _RHS) {
328*4d6fc14bSjoerg  return static_cast<perms>(static_cast<unsigned>(_LHS) &
329*4d6fc14bSjoerg                            static_cast<unsigned>(_RHS));
330*4d6fc14bSjoerg}
331*4d6fc14bSjoerg
332*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
333*4d6fc14bSjoerginline constexpr perms operator|(perms _LHS, perms _RHS) {
334*4d6fc14bSjoerg  return static_cast<perms>(static_cast<unsigned>(_LHS) |
335*4d6fc14bSjoerg                            static_cast<unsigned>(_RHS));
336*4d6fc14bSjoerg}
337*4d6fc14bSjoerg
338*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
339*4d6fc14bSjoerginline constexpr perms operator^(perms _LHS, perms _RHS) {
340*4d6fc14bSjoerg  return static_cast<perms>(static_cast<unsigned>(_LHS) ^
341*4d6fc14bSjoerg                            static_cast<unsigned>(_RHS));
342*4d6fc14bSjoerg}
343*4d6fc14bSjoerg
344*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
345*4d6fc14bSjoerginline constexpr perms operator~(perms _LHS) {
346*4d6fc14bSjoerg  return static_cast<perms>(~static_cast<unsigned>(_LHS));
347*4d6fc14bSjoerg}
348*4d6fc14bSjoerg
349*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
350*4d6fc14bSjoerginline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
351*4d6fc14bSjoerg
352*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
353*4d6fc14bSjoerginline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
354*4d6fc14bSjoerg
355*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
356*4d6fc14bSjoerginline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
357*4d6fc14bSjoerg
358*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
359*4d6fc14bSjoerg  replace = 1,
360*4d6fc14bSjoerg  add = 2,
361*4d6fc14bSjoerg  remove = 4,
362*4d6fc14bSjoerg  nofollow = 8
363*4d6fc14bSjoerg};
364*4d6fc14bSjoerg
365*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
366*4d6fc14bSjoerginline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
367*4d6fc14bSjoerg  return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
368*4d6fc14bSjoerg                                   static_cast<unsigned>(_RHS));
369*4d6fc14bSjoerg}
370*4d6fc14bSjoerg
371*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
372*4d6fc14bSjoerginline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
373*4d6fc14bSjoerg  return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
374*4d6fc14bSjoerg                                   static_cast<unsigned>(_RHS));
375*4d6fc14bSjoerg}
376*4d6fc14bSjoerg
377*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
378*4d6fc14bSjoerginline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
379*4d6fc14bSjoerg  return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
380*4d6fc14bSjoerg                                   static_cast<unsigned>(_RHS));
381*4d6fc14bSjoerg}
382*4d6fc14bSjoerg
383*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
384*4d6fc14bSjoerginline constexpr perm_options operator~(perm_options _LHS) {
385*4d6fc14bSjoerg  return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
386*4d6fc14bSjoerg}
387*4d6fc14bSjoerg
388*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
389*4d6fc14bSjoerginline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
390*4d6fc14bSjoerg  return _LHS = _LHS & _RHS;
391*4d6fc14bSjoerg}
392*4d6fc14bSjoerg
393*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
394*4d6fc14bSjoerginline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
395*4d6fc14bSjoerg  return _LHS = _LHS | _RHS;
396*4d6fc14bSjoerg}
397*4d6fc14bSjoerg
398*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
399*4d6fc14bSjoerginline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
400*4d6fc14bSjoerg  return _LHS = _LHS ^ _RHS;
401*4d6fc14bSjoerg}
402*4d6fc14bSjoerg
403*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
404*4d6fc14bSjoerg  none = 0,
405*4d6fc14bSjoerg  skip_existing = 1,
406*4d6fc14bSjoerg  overwrite_existing = 2,
407*4d6fc14bSjoerg  update_existing = 4,
408*4d6fc14bSjoerg  recursive = 8,
409*4d6fc14bSjoerg  copy_symlinks = 16,
410*4d6fc14bSjoerg  skip_symlinks = 32,
411*4d6fc14bSjoerg  directories_only = 64,
412*4d6fc14bSjoerg  create_symlinks = 128,
413*4d6fc14bSjoerg  create_hard_links = 256,
414*4d6fc14bSjoerg  __in_recursive_copy = 512,
415*4d6fc14bSjoerg};
416*4d6fc14bSjoerg
417*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
418*4d6fc14bSjoerginline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
419*4d6fc14bSjoerg  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
420*4d6fc14bSjoerg                                   static_cast<unsigned short>(_RHS));
421*4d6fc14bSjoerg}
422*4d6fc14bSjoerg
423*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
424*4d6fc14bSjoerginline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
425*4d6fc14bSjoerg  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
426*4d6fc14bSjoerg                                   static_cast<unsigned short>(_RHS));
427*4d6fc14bSjoerg}
428*4d6fc14bSjoerg
429*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
430*4d6fc14bSjoerginline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
431*4d6fc14bSjoerg  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
432*4d6fc14bSjoerg                                   static_cast<unsigned short>(_RHS));
433*4d6fc14bSjoerg}
434*4d6fc14bSjoerg
435*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
436*4d6fc14bSjoerginline constexpr copy_options operator~(copy_options _LHS) {
437*4d6fc14bSjoerg  return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
438*4d6fc14bSjoerg}
439*4d6fc14bSjoerg
440*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
441*4d6fc14bSjoerginline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
442*4d6fc14bSjoerg  return _LHS = _LHS & _RHS;
443*4d6fc14bSjoerg}
444*4d6fc14bSjoerg
445*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
446*4d6fc14bSjoerginline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
447*4d6fc14bSjoerg  return _LHS = _LHS | _RHS;
448*4d6fc14bSjoerg}
449*4d6fc14bSjoerg
450*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
451*4d6fc14bSjoerginline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
452*4d6fc14bSjoerg  return _LHS = _LHS ^ _RHS;
453*4d6fc14bSjoerg}
454*4d6fc14bSjoerg
455*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
456*4d6fc14bSjoerg  none = 0,
457*4d6fc14bSjoerg  follow_directory_symlink = 1,
458*4d6fc14bSjoerg  skip_permission_denied = 2
459*4d6fc14bSjoerg};
460*4d6fc14bSjoerg
461*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
462*4d6fc14bSjoerginline constexpr directory_options operator&(directory_options _LHS,
463*4d6fc14bSjoerg                                             directory_options _RHS) {
464*4d6fc14bSjoerg  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
465*4d6fc14bSjoerg                                        static_cast<unsigned char>(_RHS));
466*4d6fc14bSjoerg}
467*4d6fc14bSjoerg
468*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
469*4d6fc14bSjoerginline constexpr directory_options operator|(directory_options _LHS,
470*4d6fc14bSjoerg                                             directory_options _RHS) {
471*4d6fc14bSjoerg  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
472*4d6fc14bSjoerg                                        static_cast<unsigned char>(_RHS));
473*4d6fc14bSjoerg}
474*4d6fc14bSjoerg
475*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
476*4d6fc14bSjoerginline constexpr directory_options operator^(directory_options _LHS,
477*4d6fc14bSjoerg                                             directory_options _RHS) {
478*4d6fc14bSjoerg  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
479*4d6fc14bSjoerg                                        static_cast<unsigned char>(_RHS));
480*4d6fc14bSjoerg}
481*4d6fc14bSjoerg
482*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
483*4d6fc14bSjoerginline constexpr directory_options operator~(directory_options _LHS) {
484*4d6fc14bSjoerg  return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
485*4d6fc14bSjoerg}
486*4d6fc14bSjoerg
487*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
488*4d6fc14bSjoerginline directory_options& operator&=(directory_options& _LHS,
489*4d6fc14bSjoerg                                     directory_options _RHS) {
490*4d6fc14bSjoerg  return _LHS = _LHS & _RHS;
491*4d6fc14bSjoerg}
492*4d6fc14bSjoerg
493*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
494*4d6fc14bSjoerginline directory_options& operator|=(directory_options& _LHS,
495*4d6fc14bSjoerg                                     directory_options _RHS) {
496*4d6fc14bSjoerg  return _LHS = _LHS | _RHS;
497*4d6fc14bSjoerg}
498*4d6fc14bSjoerg
499*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
500*4d6fc14bSjoerginline directory_options& operator^=(directory_options& _LHS,
501*4d6fc14bSjoerg                                     directory_options _RHS) {
502*4d6fc14bSjoerg  return _LHS = _LHS ^ _RHS;
503*4d6fc14bSjoerg}
504*4d6fc14bSjoerg
505*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS file_status {
506*4d6fc14bSjoergpublic:
507*4d6fc14bSjoerg  // constructors
508*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
509*4d6fc14bSjoerg  file_status() noexcept : file_status(file_type::none) {}
510*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
511*4d6fc14bSjoerg  explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
512*4d6fc14bSjoerg      : __ft_(__ft),
513*4d6fc14bSjoerg        __prms_(__prms) {}
514*4d6fc14bSjoerg
515*4d6fc14bSjoerg  file_status(const file_status&) noexcept = default;
516*4d6fc14bSjoerg  file_status(file_status&&) noexcept = default;
517*4d6fc14bSjoerg
518*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
519*4d6fc14bSjoerg  ~file_status() {}
520*4d6fc14bSjoerg
521*4d6fc14bSjoerg  file_status& operator=(const file_status&) noexcept = default;
522*4d6fc14bSjoerg  file_status& operator=(file_status&&) noexcept = default;
523*4d6fc14bSjoerg
524*4d6fc14bSjoerg  // observers
525*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
526*4d6fc14bSjoerg  file_type type() const noexcept { return __ft_; }
527*4d6fc14bSjoerg
528*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
529*4d6fc14bSjoerg  perms permissions() const noexcept { return __prms_; }
530*4d6fc14bSjoerg
531*4d6fc14bSjoerg  // modifiers
532*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
533*4d6fc14bSjoerg  void type(file_type __ft) noexcept { __ft_ = __ft; }
534*4d6fc14bSjoerg
535*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
536*4d6fc14bSjoerg  void permissions(perms __p) noexcept { __prms_ = __p; }
537*4d6fc14bSjoerg
538*4d6fc14bSjoergprivate:
539*4d6fc14bSjoerg  file_type __ft_;
540*4d6fc14bSjoerg  perms __prms_;
541*4d6fc14bSjoerg};
542*4d6fc14bSjoerg
543*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS directory_entry;
544*4d6fc14bSjoerg
545*4d6fc14bSjoergtemplate <class _Tp>
546*4d6fc14bSjoergstruct __can_convert_char {
547*4d6fc14bSjoerg  static const bool value = false;
548*4d6fc14bSjoerg};
549*4d6fc14bSjoergtemplate <class _Tp>
550*4d6fc14bSjoergstruct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
551*4d6fc14bSjoergtemplate <>
552*4d6fc14bSjoergstruct __can_convert_char<char> {
553*4d6fc14bSjoerg  static const bool value = true;
554*4d6fc14bSjoerg  using __char_type = char;
555*4d6fc14bSjoerg};
556*4d6fc14bSjoergtemplate <>
557*4d6fc14bSjoergstruct __can_convert_char<wchar_t> {
558*4d6fc14bSjoerg  static const bool value = true;
559*4d6fc14bSjoerg  using __char_type = wchar_t;
560*4d6fc14bSjoerg};
561*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
562*4d6fc14bSjoergtemplate <>
563*4d6fc14bSjoergstruct __can_convert_char<char8_t> {
564*4d6fc14bSjoerg  static const bool value = true;
565*4d6fc14bSjoerg  using __char_type = char8_t;
566*4d6fc14bSjoerg};
567*4d6fc14bSjoerg#endif
568*4d6fc14bSjoergtemplate <>
569*4d6fc14bSjoergstruct __can_convert_char<char16_t> {
570*4d6fc14bSjoerg  static const bool value = true;
571*4d6fc14bSjoerg  using __char_type = char16_t;
572*4d6fc14bSjoerg};
573*4d6fc14bSjoergtemplate <>
574*4d6fc14bSjoergstruct __can_convert_char<char32_t> {
575*4d6fc14bSjoerg  static const bool value = true;
576*4d6fc14bSjoerg  using __char_type = char32_t;
577*4d6fc14bSjoerg};
578*4d6fc14bSjoerg
579*4d6fc14bSjoergtemplate <class _ECharT>
580*4d6fc14bSjoergtypename enable_if<__can_convert_char<_ECharT>::value, bool>::type
581*4d6fc14bSjoerg__is_separator(_ECharT __e) {
582*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
583*4d6fc14bSjoerg  return __e == _ECharT('/') || __e == _ECharT('\\');
584*4d6fc14bSjoerg#else
585*4d6fc14bSjoerg  return __e == _ECharT('/');
586*4d6fc14bSjoerg#endif
587*4d6fc14bSjoerg}
588*4d6fc14bSjoerg
589*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
590*4d6fc14bSjoergtypedef u8string __u8_string;
591*4d6fc14bSjoerg#else
592*4d6fc14bSjoergtypedef string __u8_string;
593*4d6fc14bSjoerg#endif
594*4d6fc14bSjoerg
595*4d6fc14bSjoergstruct _NullSentinel {};
596*4d6fc14bSjoerg
597*4d6fc14bSjoergtemplate <class _Tp>
598*4d6fc14bSjoergusing _Void = void;
599*4d6fc14bSjoerg
600*4d6fc14bSjoergtemplate <class _Tp, class = void>
601*4d6fc14bSjoergstruct __is_pathable_string : public false_type {};
602*4d6fc14bSjoerg
603*4d6fc14bSjoergtemplate <class _ECharT, class _Traits, class _Alloc>
604*4d6fc14bSjoergstruct __is_pathable_string<
605*4d6fc14bSjoerg    basic_string<_ECharT, _Traits, _Alloc>,
606*4d6fc14bSjoerg    _Void<typename __can_convert_char<_ECharT>::__char_type> >
607*4d6fc14bSjoerg    : public __can_convert_char<_ECharT> {
608*4d6fc14bSjoerg  using _Str = basic_string<_ECharT, _Traits, _Alloc>;
609*4d6fc14bSjoerg  using _Base = __can_convert_char<_ECharT>;
610*4d6fc14bSjoerg  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
611*4d6fc14bSjoerg  static _ECharT const* __range_end(_Str const& __s) {
612*4d6fc14bSjoerg    return __s.data() + __s.length();
613*4d6fc14bSjoerg  }
614*4d6fc14bSjoerg  static _ECharT __first_or_null(_Str const& __s) {
615*4d6fc14bSjoerg    return __s.empty() ? _ECharT{} : __s[0];
616*4d6fc14bSjoerg  }
617*4d6fc14bSjoerg};
618*4d6fc14bSjoerg
619*4d6fc14bSjoergtemplate <class _ECharT, class _Traits>
620*4d6fc14bSjoergstruct __is_pathable_string<
621*4d6fc14bSjoerg    basic_string_view<_ECharT, _Traits>,
622*4d6fc14bSjoerg    _Void<typename __can_convert_char<_ECharT>::__char_type> >
623*4d6fc14bSjoerg    : public __can_convert_char<_ECharT> {
624*4d6fc14bSjoerg  using _Str = basic_string_view<_ECharT, _Traits>;
625*4d6fc14bSjoerg  using _Base = __can_convert_char<_ECharT>;
626*4d6fc14bSjoerg  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
627*4d6fc14bSjoerg  static _ECharT const* __range_end(_Str const& __s) {
628*4d6fc14bSjoerg    return __s.data() + __s.length();
629*4d6fc14bSjoerg  }
630*4d6fc14bSjoerg  static _ECharT __first_or_null(_Str const& __s) {
631*4d6fc14bSjoerg    return __s.empty() ? _ECharT{} : __s[0];
632*4d6fc14bSjoerg  }
633*4d6fc14bSjoerg};
634*4d6fc14bSjoerg
635*4d6fc14bSjoergtemplate <class _Source, class _DS = typename decay<_Source>::type,
636*4d6fc14bSjoerg          class _UnqualPtrType =
637*4d6fc14bSjoerg              typename remove_const<typename remove_pointer<_DS>::type>::type,
638*4d6fc14bSjoerg          bool _IsCharPtr = is_pointer<_DS>::value&&
639*4d6fc14bSjoerg              __can_convert_char<_UnqualPtrType>::value>
640*4d6fc14bSjoergstruct __is_pathable_char_array : false_type {};
641*4d6fc14bSjoerg
642*4d6fc14bSjoergtemplate <class _Source, class _ECharT, class _UPtr>
643*4d6fc14bSjoergstruct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
644*4d6fc14bSjoerg    : __can_convert_char<typename remove_const<_ECharT>::type> {
645*4d6fc14bSjoerg  using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
646*4d6fc14bSjoerg
647*4d6fc14bSjoerg  static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
648*4d6fc14bSjoerg  static _ECharT const* __range_end(const _ECharT* __b) {
649*4d6fc14bSjoerg    using _Iter = const _ECharT*;
650*4d6fc14bSjoerg    const _ECharT __sentinel = _ECharT{};
651*4d6fc14bSjoerg    _Iter __e = __b;
652*4d6fc14bSjoerg    for (; *__e != __sentinel; ++__e)
653*4d6fc14bSjoerg      ;
654*4d6fc14bSjoerg    return __e;
655*4d6fc14bSjoerg  }
656*4d6fc14bSjoerg
657*4d6fc14bSjoerg  static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
658*4d6fc14bSjoerg};
659*4d6fc14bSjoerg
660*4d6fc14bSjoergtemplate <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value,
661*4d6fc14bSjoerg          class = void>
662*4d6fc14bSjoergstruct __is_pathable_iter : false_type {};
663*4d6fc14bSjoerg
664*4d6fc14bSjoergtemplate <class _Iter>
665*4d6fc14bSjoergstruct __is_pathable_iter<
666*4d6fc14bSjoerg    _Iter, true,
667*4d6fc14bSjoerg    _Void<typename __can_convert_char<
668*4d6fc14bSjoerg        typename iterator_traits<_Iter>::value_type>::__char_type> >
669*4d6fc14bSjoerg    : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
670*4d6fc14bSjoerg  using _ECharT = typename iterator_traits<_Iter>::value_type;
671*4d6fc14bSjoerg  using _Base = __can_convert_char<_ECharT>;
672*4d6fc14bSjoerg
673*4d6fc14bSjoerg  static _Iter __range_begin(_Iter __b) { return __b; }
674*4d6fc14bSjoerg  static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; }
675*4d6fc14bSjoerg
676*4d6fc14bSjoerg  static _ECharT __first_or_null(_Iter __b) { return *__b; }
677*4d6fc14bSjoerg};
678*4d6fc14bSjoerg
679*4d6fc14bSjoergtemplate <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
680*4d6fc14bSjoerg          bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
681*4d6fc14bSjoerg          bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
682*4d6fc14bSjoergstruct __is_pathable : false_type {
683*4d6fc14bSjoerg  static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
684*4d6fc14bSjoerg};
685*4d6fc14bSjoerg
686*4d6fc14bSjoergtemplate <class _Tp>
687*4d6fc14bSjoergstruct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
688*4d6fc14bSjoerg
689*4d6fc14bSjoergtemplate <class _Tp>
690*4d6fc14bSjoergstruct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
691*4d6fc14bSjoerg};
692*4d6fc14bSjoerg
693*4d6fc14bSjoergtemplate <class _Tp>
694*4d6fc14bSjoergstruct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
695*4d6fc14bSjoerg
696*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
697*4d6fc14bSjoergtypedef wstring __path_string;
698*4d6fc14bSjoergtypedef wchar_t __path_value;
699*4d6fc14bSjoerg#else
700*4d6fc14bSjoergtypedef string __path_string;
701*4d6fc14bSjoergtypedef char __path_value;
702*4d6fc14bSjoerg#endif
703*4d6fc14bSjoerg
704*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
705*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
706*4d6fc14bSjoergsize_t __wide_to_char(const wstring&, char*, size_t);
707*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
708*4d6fc14bSjoergsize_t __char_to_wide(const string&, wchar_t*, size_t);
709*4d6fc14bSjoerg#endif
710*4d6fc14bSjoerg
711*4d6fc14bSjoergtemplate <class _ECharT>
712*4d6fc14bSjoergstruct _PathCVT;
713*4d6fc14bSjoerg
714*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
715*4d6fc14bSjoergtemplate <class _ECharT>
716*4d6fc14bSjoergstruct _PathCVT {
717*4d6fc14bSjoerg  static_assert(__can_convert_char<_ECharT>::value,
718*4d6fc14bSjoerg                "Char type not convertible");
719*4d6fc14bSjoerg
720*4d6fc14bSjoerg  typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
721*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
722*4d6fc14bSjoerg  typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
723*4d6fc14bSjoerg#endif
724*4d6fc14bSjoerg
725*4d6fc14bSjoerg  static void __append_range(__path_string& __dest, _ECharT const* __b,
726*4d6fc14bSjoerg                             _ECharT const* __e) {
727*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
728*4d6fc14bSjoerg    string __utf8;
729*4d6fc14bSjoerg    _Narrower()(back_inserter(__utf8), __b, __e);
730*4d6fc14bSjoerg    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
731*4d6fc14bSjoerg#else
732*4d6fc14bSjoerg    _Narrower()(back_inserter(__dest), __b, __e);
733*4d6fc14bSjoerg#endif
734*4d6fc14bSjoerg  }
735*4d6fc14bSjoerg
736*4d6fc14bSjoerg  template <class _Iter>
737*4d6fc14bSjoerg  static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
738*4d6fc14bSjoerg    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
739*4d6fc14bSjoerg    if (__b == __e)
740*4d6fc14bSjoerg      return;
741*4d6fc14bSjoerg    basic_string<_ECharT> __tmp(__b, __e);
742*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
743*4d6fc14bSjoerg    string __utf8;
744*4d6fc14bSjoerg    _Narrower()(back_inserter(__utf8), __tmp.data(),
745*4d6fc14bSjoerg                __tmp.data() + __tmp.length());
746*4d6fc14bSjoerg    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
747*4d6fc14bSjoerg#else
748*4d6fc14bSjoerg    _Narrower()(back_inserter(__dest), __tmp.data(),
749*4d6fc14bSjoerg                __tmp.data() + __tmp.length());
750*4d6fc14bSjoerg#endif
751*4d6fc14bSjoerg  }
752*4d6fc14bSjoerg
753*4d6fc14bSjoerg  template <class _Iter>
754*4d6fc14bSjoerg  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
755*4d6fc14bSjoerg    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
756*4d6fc14bSjoerg    const _ECharT __sentinel = _ECharT{};
757*4d6fc14bSjoerg    if (*__b == __sentinel)
758*4d6fc14bSjoerg      return;
759*4d6fc14bSjoerg    basic_string<_ECharT> __tmp;
760*4d6fc14bSjoerg    for (; *__b != __sentinel; ++__b)
761*4d6fc14bSjoerg      __tmp.push_back(*__b);
762*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
763*4d6fc14bSjoerg    string __utf8;
764*4d6fc14bSjoerg    _Narrower()(back_inserter(__utf8), __tmp.data(),
765*4d6fc14bSjoerg                __tmp.data() + __tmp.length());
766*4d6fc14bSjoerg    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
767*4d6fc14bSjoerg#else
768*4d6fc14bSjoerg    _Narrower()(back_inserter(__dest), __tmp.data(),
769*4d6fc14bSjoerg                __tmp.data() + __tmp.length());
770*4d6fc14bSjoerg#endif
771*4d6fc14bSjoerg  }
772*4d6fc14bSjoerg
773*4d6fc14bSjoerg  template <class _Source>
774*4d6fc14bSjoerg  static void __append_source(__path_string& __dest, _Source const& __s) {
775*4d6fc14bSjoerg    using _Traits = __is_pathable<_Source>;
776*4d6fc14bSjoerg    __append_range(__dest, _Traits::__range_begin(__s),
777*4d6fc14bSjoerg                   _Traits::__range_end(__s));
778*4d6fc14bSjoerg  }
779*4d6fc14bSjoerg};
780*4d6fc14bSjoerg#endif // !_LIBCPP_HAS_NO_LOCALIZATION
781*4d6fc14bSjoerg
782*4d6fc14bSjoergtemplate <>
783*4d6fc14bSjoergstruct _PathCVT<__path_value> {
784*4d6fc14bSjoerg
785*4d6fc14bSjoerg  template <class _Iter>
786*4d6fc14bSjoerg  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
787*4d6fc14bSjoerg  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
788*4d6fc14bSjoerg    for (; __b != __e; ++__b)
789*4d6fc14bSjoerg      __dest.push_back(*__b);
790*4d6fc14bSjoerg  }
791*4d6fc14bSjoerg
792*4d6fc14bSjoerg  template <class _Iter>
793*4d6fc14bSjoerg  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
794*4d6fc14bSjoerg  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
795*4d6fc14bSjoerg    __dest.append(__b, __e);
796*4d6fc14bSjoerg  }
797*4d6fc14bSjoerg
798*4d6fc14bSjoerg  template <class _Iter>
799*4d6fc14bSjoerg  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
800*4d6fc14bSjoerg    const char __sentinel = char{};
801*4d6fc14bSjoerg    for (; *__b != __sentinel; ++__b)
802*4d6fc14bSjoerg      __dest.push_back(*__b);
803*4d6fc14bSjoerg  }
804*4d6fc14bSjoerg
805*4d6fc14bSjoerg  template <class _Source>
806*4d6fc14bSjoerg  static void __append_source(__path_string& __dest, _Source const& __s) {
807*4d6fc14bSjoerg    using _Traits = __is_pathable<_Source>;
808*4d6fc14bSjoerg    __append_range(__dest, _Traits::__range_begin(__s),
809*4d6fc14bSjoerg                   _Traits::__range_end(__s));
810*4d6fc14bSjoerg  }
811*4d6fc14bSjoerg};
812*4d6fc14bSjoerg
813*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
814*4d6fc14bSjoergtemplate <>
815*4d6fc14bSjoergstruct _PathCVT<char> {
816*4d6fc14bSjoerg
817*4d6fc14bSjoerg  static void
818*4d6fc14bSjoerg  __append_string(__path_string& __dest, const basic_string<char> &__str) {
819*4d6fc14bSjoerg      size_t __size = __char_to_wide(__str, nullptr, 0);
820*4d6fc14bSjoerg      size_t __pos = __dest.size();
821*4d6fc14bSjoerg      __dest.resize(__pos + __size);
822*4d6fc14bSjoerg      __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size);
823*4d6fc14bSjoerg  }
824*4d6fc14bSjoerg
825*4d6fc14bSjoerg  template <class _Iter>
826*4d6fc14bSjoerg  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
827*4d6fc14bSjoerg  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
828*4d6fc14bSjoerg    basic_string<char> __tmp(__b, __e);
829*4d6fc14bSjoerg    __append_string(__dest, __tmp);
830*4d6fc14bSjoerg  }
831*4d6fc14bSjoerg
832*4d6fc14bSjoerg  template <class _Iter>
833*4d6fc14bSjoerg  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
834*4d6fc14bSjoerg  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
835*4d6fc14bSjoerg    basic_string<char> __tmp(__b, __e);
836*4d6fc14bSjoerg    __append_string(__dest, __tmp);
837*4d6fc14bSjoerg  }
838*4d6fc14bSjoerg
839*4d6fc14bSjoerg  template <class _Iter>
840*4d6fc14bSjoerg  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
841*4d6fc14bSjoerg    const char __sentinel = char{};
842*4d6fc14bSjoerg    basic_string<char> __tmp;
843*4d6fc14bSjoerg    for (; *__b != __sentinel; ++__b)
844*4d6fc14bSjoerg      __tmp.push_back(*__b);
845*4d6fc14bSjoerg    __append_string(__dest, __tmp);
846*4d6fc14bSjoerg  }
847*4d6fc14bSjoerg
848*4d6fc14bSjoerg  template <class _Source>
849*4d6fc14bSjoerg  static void __append_source(__path_string& __dest, _Source const& __s) {
850*4d6fc14bSjoerg    using _Traits = __is_pathable<_Source>;
851*4d6fc14bSjoerg    __append_range(__dest, _Traits::__range_begin(__s),
852*4d6fc14bSjoerg                   _Traits::__range_end(__s));
853*4d6fc14bSjoerg  }
854*4d6fc14bSjoerg};
855*4d6fc14bSjoerg
856*4d6fc14bSjoergtemplate <class _ECharT>
857*4d6fc14bSjoergstruct _PathExport {
858*4d6fc14bSjoerg  typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
859*4d6fc14bSjoerg  typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
860*4d6fc14bSjoerg
861*4d6fc14bSjoerg  template <class _Str>
862*4d6fc14bSjoerg  static void __append(_Str& __dest, const __path_string& __src) {
863*4d6fc14bSjoerg    string __utf8;
864*4d6fc14bSjoerg    _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
865*4d6fc14bSjoerg    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
866*4d6fc14bSjoerg  }
867*4d6fc14bSjoerg};
868*4d6fc14bSjoerg
869*4d6fc14bSjoergtemplate <>
870*4d6fc14bSjoergstruct _PathExport<char> {
871*4d6fc14bSjoerg  template <class _Str>
872*4d6fc14bSjoerg  static void __append(_Str& __dest, const __path_string& __src) {
873*4d6fc14bSjoerg    size_t __size = __wide_to_char(__src, nullptr, 0);
874*4d6fc14bSjoerg    size_t __pos = __dest.size();
875*4d6fc14bSjoerg    __dest.resize(__size);
876*4d6fc14bSjoerg    __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size);
877*4d6fc14bSjoerg  }
878*4d6fc14bSjoerg};
879*4d6fc14bSjoerg
880*4d6fc14bSjoergtemplate <>
881*4d6fc14bSjoergstruct _PathExport<wchar_t> {
882*4d6fc14bSjoerg  template <class _Str>
883*4d6fc14bSjoerg  static void __append(_Str& __dest, const __path_string& __src) {
884*4d6fc14bSjoerg    __dest.append(__src.begin(), __src.end());
885*4d6fc14bSjoerg  }
886*4d6fc14bSjoerg};
887*4d6fc14bSjoerg
888*4d6fc14bSjoergtemplate <>
889*4d6fc14bSjoergstruct _PathExport<char16_t> {
890*4d6fc14bSjoerg  template <class _Str>
891*4d6fc14bSjoerg  static void __append(_Str& __dest, const __path_string& __src) {
892*4d6fc14bSjoerg    __dest.append(__src.begin(), __src.end());
893*4d6fc14bSjoerg  }
894*4d6fc14bSjoerg};
895*4d6fc14bSjoerg
896*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
897*4d6fc14bSjoergtemplate <>
898*4d6fc14bSjoergstruct _PathExport<char8_t> {
899*4d6fc14bSjoerg  typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
900*4d6fc14bSjoerg
901*4d6fc14bSjoerg  template <class _Str>
902*4d6fc14bSjoerg  static void __append(_Str& __dest, const __path_string& __src) {
903*4d6fc14bSjoerg    _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
904*4d6fc14bSjoerg  }
905*4d6fc14bSjoerg};
906*4d6fc14bSjoerg#endif /* !_LIBCPP_HAS_NO_CHAR8_T */
907*4d6fc14bSjoerg#endif /* _LIBCPP_WIN32API */
908*4d6fc14bSjoerg
909*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS path {
910*4d6fc14bSjoerg  template <class _SourceOrIter, class _Tp = path&>
911*4d6fc14bSjoerg  using _EnableIfPathable =
912*4d6fc14bSjoerg      typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
913*4d6fc14bSjoerg
914*4d6fc14bSjoerg  template <class _Tp>
915*4d6fc14bSjoerg  using _SourceChar = typename __is_pathable<_Tp>::__char_type;
916*4d6fc14bSjoerg
917*4d6fc14bSjoerg  template <class _Tp>
918*4d6fc14bSjoerg  using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
919*4d6fc14bSjoerg
920*4d6fc14bSjoergpublic:
921*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
922*4d6fc14bSjoerg  typedef wchar_t value_type;
923*4d6fc14bSjoerg  static constexpr value_type preferred_separator = L'\\';
924*4d6fc14bSjoerg#else
925*4d6fc14bSjoerg  typedef char value_type;
926*4d6fc14bSjoerg  static constexpr value_type preferred_separator = '/';
927*4d6fc14bSjoerg#endif
928*4d6fc14bSjoerg  typedef basic_string<value_type> string_type;
929*4d6fc14bSjoerg  typedef basic_string_view<value_type> __string_view;
930*4d6fc14bSjoerg
931*4d6fc14bSjoerg  enum _LIBCPP_ENUM_VIS format : unsigned char {
932*4d6fc14bSjoerg    auto_format,
933*4d6fc14bSjoerg    native_format,
934*4d6fc14bSjoerg    generic_format
935*4d6fc14bSjoerg  };
936*4d6fc14bSjoerg
937*4d6fc14bSjoerg  // constructors and destructor
938*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path() noexcept {}
939*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
940*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
941*4d6fc14bSjoerg      : __pn_(_VSTD::move(__p.__pn_)) {}
942*4d6fc14bSjoerg
943*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
944*4d6fc14bSjoerg  path(string_type&& __s, format = format::auto_format) noexcept
945*4d6fc14bSjoerg      : __pn_(_VSTD::move(__s)) {}
946*4d6fc14bSjoerg
947*4d6fc14bSjoerg  template <class _Source, class = _EnableIfPathable<_Source, void> >
948*4d6fc14bSjoerg  path(const _Source& __src, format = format::auto_format) {
949*4d6fc14bSjoerg    _SourceCVT<_Source>::__append_source(__pn_, __src);
950*4d6fc14bSjoerg  }
951*4d6fc14bSjoerg
952*4d6fc14bSjoerg  template <class _InputIt>
953*4d6fc14bSjoerg  path(_InputIt __first, _InputIt __last, format = format::auto_format) {
954*4d6fc14bSjoerg    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
955*4d6fc14bSjoerg    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
956*4d6fc14bSjoerg  }
957*4d6fc14bSjoerg
958*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
959*4d6fc14bSjoerg  // TODO Implement locale conversions.
960*4d6fc14bSjoerg  template <class _Source, class = _EnableIfPathable<_Source, void> >
961*4d6fc14bSjoerg  path(const _Source& __src, const locale& __loc, format = format::auto_format);
962*4d6fc14bSjoerg  template <class _InputIt>
963*4d6fc14bSjoerg  path(_InputIt __first, _InputIt _last, const locale& __loc,
964*4d6fc14bSjoerg       format = format::auto_format);
965*4d6fc14bSjoerg#endif
966*4d6fc14bSjoerg
967*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
968*4d6fc14bSjoerg  ~path() = default;
969*4d6fc14bSjoerg
970*4d6fc14bSjoerg  // assignments
971*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
972*4d6fc14bSjoerg  path& operator=(const path& __p) {
973*4d6fc14bSjoerg    __pn_ = __p.__pn_;
974*4d6fc14bSjoerg    return *this;
975*4d6fc14bSjoerg  }
976*4d6fc14bSjoerg
977*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
978*4d6fc14bSjoerg  path& operator=(path&& __p) noexcept {
979*4d6fc14bSjoerg    __pn_ = _VSTD::move(__p.__pn_);
980*4d6fc14bSjoerg    return *this;
981*4d6fc14bSjoerg  }
982*4d6fc14bSjoerg
983*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
984*4d6fc14bSjoerg  path& operator=(string_type&& __s) noexcept {
985*4d6fc14bSjoerg    __pn_ = _VSTD::move(__s);
986*4d6fc14bSjoerg    return *this;
987*4d6fc14bSjoerg  }
988*4d6fc14bSjoerg
989*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
990*4d6fc14bSjoerg  path& assign(string_type&& __s) noexcept {
991*4d6fc14bSjoerg    __pn_ = _VSTD::move(__s);
992*4d6fc14bSjoerg    return *this;
993*4d6fc14bSjoerg  }
994*4d6fc14bSjoerg
995*4d6fc14bSjoerg  template <class _Source>
996*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
997*4d6fc14bSjoerg  operator=(const _Source& __src) {
998*4d6fc14bSjoerg    return this->assign(__src);
999*4d6fc14bSjoerg  }
1000*4d6fc14bSjoerg
1001*4d6fc14bSjoerg  template <class _Source>
1002*4d6fc14bSjoerg  _EnableIfPathable<_Source> assign(const _Source& __src) {
1003*4d6fc14bSjoerg    __pn_.clear();
1004*4d6fc14bSjoerg    _SourceCVT<_Source>::__append_source(__pn_, __src);
1005*4d6fc14bSjoerg    return *this;
1006*4d6fc14bSjoerg  }
1007*4d6fc14bSjoerg
1008*4d6fc14bSjoerg  template <class _InputIt>
1009*4d6fc14bSjoerg  path& assign(_InputIt __first, _InputIt __last) {
1010*4d6fc14bSjoerg    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1011*4d6fc14bSjoerg    __pn_.clear();
1012*4d6fc14bSjoerg    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1013*4d6fc14bSjoerg    return *this;
1014*4d6fc14bSjoerg  }
1015*4d6fc14bSjoerg
1016*4d6fc14bSjoergpublic:
1017*4d6fc14bSjoerg  // appends
1018*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1019*4d6fc14bSjoerg  path& operator/=(const path& __p) {
1020*4d6fc14bSjoerg    auto __p_root_name = __p.__root_name();
1021*4d6fc14bSjoerg    auto __p_root_name_size = __p_root_name.size();
1022*4d6fc14bSjoerg    if (__p.is_absolute() ||
1023*4d6fc14bSjoerg        (!__p_root_name.empty() && __p_root_name != root_name())) {
1024*4d6fc14bSjoerg      __pn_ = __p.__pn_;
1025*4d6fc14bSjoerg      return *this;
1026*4d6fc14bSjoerg    }
1027*4d6fc14bSjoerg    if (__p.has_root_directory()) {
1028*4d6fc14bSjoerg      path __root_name_str = root_name();
1029*4d6fc14bSjoerg      __pn_ = __root_name_str.native();
1030*4d6fc14bSjoerg      __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1031*4d6fc14bSjoerg      return *this;
1032*4d6fc14bSjoerg    }
1033*4d6fc14bSjoerg    if (has_filename() || (!has_root_directory() && is_absolute()))
1034*4d6fc14bSjoerg      __pn_ += preferred_separator;
1035*4d6fc14bSjoerg    __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1036*4d6fc14bSjoerg    return *this;
1037*4d6fc14bSjoerg  }
1038*4d6fc14bSjoerg  template <class _Source>
1039*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1040*4d6fc14bSjoerg  operator/=(const _Source& __src) {
1041*4d6fc14bSjoerg    return operator/=(path(__src));
1042*4d6fc14bSjoerg  }
1043*4d6fc14bSjoerg
1044*4d6fc14bSjoerg  template <class _Source>
1045*4d6fc14bSjoerg  _EnableIfPathable<_Source> append(const _Source& __src) {
1046*4d6fc14bSjoerg    return operator/=(path(__src));
1047*4d6fc14bSjoerg  }
1048*4d6fc14bSjoerg
1049*4d6fc14bSjoerg  template <class _InputIt>
1050*4d6fc14bSjoerg  path& append(_InputIt __first, _InputIt __last) {
1051*4d6fc14bSjoerg    return operator/=(path(__first, __last));
1052*4d6fc14bSjoerg  }
1053*4d6fc14bSjoerg#else
1054*4d6fc14bSjoerg  path& operator/=(const path& __p) {
1055*4d6fc14bSjoerg    if (__p.is_absolute()) {
1056*4d6fc14bSjoerg      __pn_ = __p.__pn_;
1057*4d6fc14bSjoerg      return *this;
1058*4d6fc14bSjoerg    }
1059*4d6fc14bSjoerg    if (has_filename())
1060*4d6fc14bSjoerg      __pn_ += preferred_separator;
1061*4d6fc14bSjoerg    __pn_ += __p.native();
1062*4d6fc14bSjoerg    return *this;
1063*4d6fc14bSjoerg  }
1064*4d6fc14bSjoerg
1065*4d6fc14bSjoerg  // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
1066*4d6fc14bSjoerg  // is known at compile time to be "/' since the user almost certainly intended
1067*4d6fc14bSjoerg  // to append a separator instead of overwriting the path with "/"
1068*4d6fc14bSjoerg  template <class _Source>
1069*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1070*4d6fc14bSjoerg  operator/=(const _Source& __src) {
1071*4d6fc14bSjoerg    return this->append(__src);
1072*4d6fc14bSjoerg  }
1073*4d6fc14bSjoerg
1074*4d6fc14bSjoerg  template <class _Source>
1075*4d6fc14bSjoerg  _EnableIfPathable<_Source> append(const _Source& __src) {
1076*4d6fc14bSjoerg    using _Traits = __is_pathable<_Source>;
1077*4d6fc14bSjoerg    using _CVT = _PathCVT<_SourceChar<_Source> >;
1078*4d6fc14bSjoerg    bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
1079*4d6fc14bSjoerg    if (__source_is_absolute)
1080*4d6fc14bSjoerg      __pn_.clear();
1081*4d6fc14bSjoerg    else if (has_filename())
1082*4d6fc14bSjoerg      __pn_ += preferred_separator;
1083*4d6fc14bSjoerg    _CVT::__append_source(__pn_, __src);
1084*4d6fc14bSjoerg    return *this;
1085*4d6fc14bSjoerg  }
1086*4d6fc14bSjoerg
1087*4d6fc14bSjoerg  template <class _InputIt>
1088*4d6fc14bSjoerg  path& append(_InputIt __first, _InputIt __last) {
1089*4d6fc14bSjoerg    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1090*4d6fc14bSjoerg    static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
1091*4d6fc14bSjoerg    using _CVT = _PathCVT<_ItVal>;
1092*4d6fc14bSjoerg    if (__first != __last && __is_separator(*__first))
1093*4d6fc14bSjoerg      __pn_.clear();
1094*4d6fc14bSjoerg    else if (has_filename())
1095*4d6fc14bSjoerg      __pn_ += preferred_separator;
1096*4d6fc14bSjoerg    _CVT::__append_range(__pn_, __first, __last);
1097*4d6fc14bSjoerg    return *this;
1098*4d6fc14bSjoerg  }
1099*4d6fc14bSjoerg#endif
1100*4d6fc14bSjoerg
1101*4d6fc14bSjoerg  // concatenation
1102*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1103*4d6fc14bSjoerg  path& operator+=(const path& __x) {
1104*4d6fc14bSjoerg    __pn_ += __x.__pn_;
1105*4d6fc14bSjoerg    return *this;
1106*4d6fc14bSjoerg  }
1107*4d6fc14bSjoerg
1108*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1109*4d6fc14bSjoerg  path& operator+=(const string_type& __x) {
1110*4d6fc14bSjoerg    __pn_ += __x;
1111*4d6fc14bSjoerg    return *this;
1112*4d6fc14bSjoerg  }
1113*4d6fc14bSjoerg
1114*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1115*4d6fc14bSjoerg  path& operator+=(__string_view __x) {
1116*4d6fc14bSjoerg    __pn_ += __x;
1117*4d6fc14bSjoerg    return *this;
1118*4d6fc14bSjoerg  }
1119*4d6fc14bSjoerg
1120*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1121*4d6fc14bSjoerg  path& operator+=(const value_type* __x) {
1122*4d6fc14bSjoerg    __pn_ += __x;
1123*4d6fc14bSjoerg    return *this;
1124*4d6fc14bSjoerg  }
1125*4d6fc14bSjoerg
1126*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1127*4d6fc14bSjoerg  path& operator+=(value_type __x) {
1128*4d6fc14bSjoerg    __pn_ += __x;
1129*4d6fc14bSjoerg    return *this;
1130*4d6fc14bSjoerg  }
1131*4d6fc14bSjoerg
1132*4d6fc14bSjoerg  template <class _ECharT>
1133*4d6fc14bSjoerg  typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
1134*4d6fc14bSjoerg  operator+=(_ECharT __x) {
1135*4d6fc14bSjoerg    _PathCVT<_ECharT>::__append_source(__pn_,
1136*4d6fc14bSjoerg                                       basic_string_view<_ECharT>(&__x, 1));
1137*4d6fc14bSjoerg    return *this;
1138*4d6fc14bSjoerg  }
1139*4d6fc14bSjoerg
1140*4d6fc14bSjoerg  template <class _Source>
1141*4d6fc14bSjoerg  _EnableIfPathable<_Source> operator+=(const _Source& __x) {
1142*4d6fc14bSjoerg    return this->concat(__x);
1143*4d6fc14bSjoerg  }
1144*4d6fc14bSjoerg
1145*4d6fc14bSjoerg  template <class _Source>
1146*4d6fc14bSjoerg  _EnableIfPathable<_Source> concat(const _Source& __x) {
1147*4d6fc14bSjoerg    _SourceCVT<_Source>::__append_source(__pn_, __x);
1148*4d6fc14bSjoerg    return *this;
1149*4d6fc14bSjoerg  }
1150*4d6fc14bSjoerg
1151*4d6fc14bSjoerg  template <class _InputIt>
1152*4d6fc14bSjoerg  path& concat(_InputIt __first, _InputIt __last) {
1153*4d6fc14bSjoerg    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1154*4d6fc14bSjoerg    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1155*4d6fc14bSjoerg    return *this;
1156*4d6fc14bSjoerg  }
1157*4d6fc14bSjoerg
1158*4d6fc14bSjoerg  // modifiers
1159*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1160*4d6fc14bSjoerg  void clear() noexcept { __pn_.clear(); }
1161*4d6fc14bSjoerg
1162*4d6fc14bSjoerg  path& make_preferred() {
1163*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1164*4d6fc14bSjoerg    _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
1165*4d6fc14bSjoerg#endif
1166*4d6fc14bSjoerg    return *this;
1167*4d6fc14bSjoerg  }
1168*4d6fc14bSjoerg
1169*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1170*4d6fc14bSjoerg  path& remove_filename() {
1171*4d6fc14bSjoerg    auto __fname = __filename();
1172*4d6fc14bSjoerg    if (!__fname.empty())
1173*4d6fc14bSjoerg      __pn_.erase(__fname.data() - __pn_.data());
1174*4d6fc14bSjoerg    return *this;
1175*4d6fc14bSjoerg  }
1176*4d6fc14bSjoerg
1177*4d6fc14bSjoerg  path& replace_filename(const path& __replacement) {
1178*4d6fc14bSjoerg    remove_filename();
1179*4d6fc14bSjoerg    return (*this /= __replacement);
1180*4d6fc14bSjoerg  }
1181*4d6fc14bSjoerg
1182*4d6fc14bSjoerg  path& replace_extension(const path& __replacement = path());
1183*4d6fc14bSjoerg
1184*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1185*4d6fc14bSjoerg  void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
1186*4d6fc14bSjoerg
1187*4d6fc14bSjoerg  // private helper to allow reserving memory in the path
1188*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1189*4d6fc14bSjoerg  void __reserve(size_t __s) { __pn_.reserve(__s); }
1190*4d6fc14bSjoerg
1191*4d6fc14bSjoerg  // native format observers
1192*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1193*4d6fc14bSjoerg  const string_type& native() const noexcept { return __pn_; }
1194*4d6fc14bSjoerg
1195*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1196*4d6fc14bSjoerg  const value_type* c_str() const noexcept { return __pn_.c_str(); }
1197*4d6fc14bSjoerg
1198*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
1199*4d6fc14bSjoerg
1200*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1201*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
1202*4d6fc14bSjoerg
1203*4d6fc14bSjoerg  _VSTD::wstring generic_wstring() const {
1204*4d6fc14bSjoerg    _VSTD::wstring __s;
1205*4d6fc14bSjoerg    __s.resize(__pn_.size());
1206*4d6fc14bSjoerg    _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
1207*4d6fc14bSjoerg    return __s;
1208*4d6fc14bSjoerg  }
1209*4d6fc14bSjoerg
1210*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1211*4d6fc14bSjoerg  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1212*4d6fc14bSjoerg            class _Allocator = allocator<_ECharT> >
1213*4d6fc14bSjoerg  basic_string<_ECharT, _Traits, _Allocator>
1214*4d6fc14bSjoerg  string(const _Allocator& __a = _Allocator()) const {
1215*4d6fc14bSjoerg    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1216*4d6fc14bSjoerg    _Str __s(__a);
1217*4d6fc14bSjoerg    __s.reserve(__pn_.size());
1218*4d6fc14bSjoerg    _PathExport<_ECharT>::__append(__s, __pn_);
1219*4d6fc14bSjoerg    return __s;
1220*4d6fc14bSjoerg  }
1221*4d6fc14bSjoerg
1222*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
1223*4d6fc14bSjoerg    return string<char>();
1224*4d6fc14bSjoerg  }
1225*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
1226*4d6fc14bSjoerg    using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1227*4d6fc14bSjoerg    __u8_string __s;
1228*4d6fc14bSjoerg    __s.reserve(__pn_.size());
1229*4d6fc14bSjoerg    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1230*4d6fc14bSjoerg    return __s;
1231*4d6fc14bSjoerg  }
1232*4d6fc14bSjoerg
1233*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1234*4d6fc14bSjoerg    return string<char16_t>();
1235*4d6fc14bSjoerg  }
1236*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1237*4d6fc14bSjoerg    return string<char32_t>();
1238*4d6fc14bSjoerg  }
1239*4d6fc14bSjoerg
1240*4d6fc14bSjoerg  // generic format observers
1241*4d6fc14bSjoerg  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1242*4d6fc14bSjoerg            class _Allocator = allocator<_ECharT> >
1243*4d6fc14bSjoerg  basic_string<_ECharT, _Traits, _Allocator>
1244*4d6fc14bSjoerg  generic_string(const _Allocator& __a = _Allocator()) const {
1245*4d6fc14bSjoerg    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1246*4d6fc14bSjoerg    _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
1247*4d6fc14bSjoerg    // Note: This (and generic_u8string below) is slightly suboptimal as
1248*4d6fc14bSjoerg    // it iterates twice over the string; once to convert it to the right
1249*4d6fc14bSjoerg    // character type, and once to replace path delimiters.
1250*4d6fc14bSjoerg    _VSTD::replace(__s.begin(), __s.end(),
1251*4d6fc14bSjoerg                   static_cast<_ECharT>('\\'), static_cast<_ECharT>('/'));
1252*4d6fc14bSjoerg    return __s;
1253*4d6fc14bSjoerg  }
1254*4d6fc14bSjoerg
1255*4d6fc14bSjoerg  _VSTD::string generic_string() const { return generic_string<char>(); }
1256*4d6fc14bSjoerg  _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
1257*4d6fc14bSjoerg  _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1258*4d6fc14bSjoerg  __u8_string generic_u8string() const {
1259*4d6fc14bSjoerg    __u8_string __s = u8string();
1260*4d6fc14bSjoerg    _VSTD::replace(__s.begin(), __s.end(), '\\', '/');
1261*4d6fc14bSjoerg    return __s;
1262*4d6fc14bSjoerg  }
1263*4d6fc14bSjoerg#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1264*4d6fc14bSjoerg#else /* _LIBCPP_WIN32API */
1265*4d6fc14bSjoerg
1266*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
1267*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
1268*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1269*4d6fc14bSjoerg#else
1270*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
1271*4d6fc14bSjoerg#endif
1272*4d6fc14bSjoerg
1273*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1274*4d6fc14bSjoerg  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1275*4d6fc14bSjoerg            class _Allocator = allocator<_ECharT> >
1276*4d6fc14bSjoerg  basic_string<_ECharT, _Traits, _Allocator>
1277*4d6fc14bSjoerg  string(const _Allocator& __a = _Allocator()) const {
1278*4d6fc14bSjoerg    using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
1279*4d6fc14bSjoerg    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1280*4d6fc14bSjoerg    _Str __s(__a);
1281*4d6fc14bSjoerg    __s.reserve(__pn_.size());
1282*4d6fc14bSjoerg    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1283*4d6fc14bSjoerg    return __s;
1284*4d6fc14bSjoerg  }
1285*4d6fc14bSjoerg
1286*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
1287*4d6fc14bSjoerg    return string<wchar_t>();
1288*4d6fc14bSjoerg  }
1289*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1290*4d6fc14bSjoerg    return string<char16_t>();
1291*4d6fc14bSjoerg  }
1292*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1293*4d6fc14bSjoerg    return string<char32_t>();
1294*4d6fc14bSjoerg  }
1295*4d6fc14bSjoerg#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1296*4d6fc14bSjoerg
1297*4d6fc14bSjoerg  // generic format observers
1298*4d6fc14bSjoerg  _VSTD::string generic_string() const { return __pn_; }
1299*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
1300*4d6fc14bSjoerg  _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1301*4d6fc14bSjoerg#else
1302*4d6fc14bSjoerg  _VSTD::string generic_u8string() const { return __pn_; }
1303*4d6fc14bSjoerg#endif
1304*4d6fc14bSjoerg
1305*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1306*4d6fc14bSjoerg  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1307*4d6fc14bSjoerg            class _Allocator = allocator<_ECharT> >
1308*4d6fc14bSjoerg  basic_string<_ECharT, _Traits, _Allocator>
1309*4d6fc14bSjoerg  generic_string(const _Allocator& __a = _Allocator()) const {
1310*4d6fc14bSjoerg    return string<_ECharT, _Traits, _Allocator>(__a);
1311*4d6fc14bSjoerg  }
1312*4d6fc14bSjoerg
1313*4d6fc14bSjoerg  _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
1314*4d6fc14bSjoerg  _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
1315*4d6fc14bSjoerg  _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
1316*4d6fc14bSjoerg#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1317*4d6fc14bSjoerg#endif /* !_LIBCPP_WIN32API */
1318*4d6fc14bSjoerg
1319*4d6fc14bSjoergprivate:
1320*4d6fc14bSjoerg  int __compare(__string_view) const;
1321*4d6fc14bSjoerg  __string_view __root_name() const;
1322*4d6fc14bSjoerg  __string_view __root_directory() const;
1323*4d6fc14bSjoerg  __string_view __root_path_raw() const;
1324*4d6fc14bSjoerg  __string_view __relative_path() const;
1325*4d6fc14bSjoerg  __string_view __parent_path() const;
1326*4d6fc14bSjoerg  __string_view __filename() const;
1327*4d6fc14bSjoerg  __string_view __stem() const;
1328*4d6fc14bSjoerg  __string_view __extension() const;
1329*4d6fc14bSjoerg
1330*4d6fc14bSjoergpublic:
1331*4d6fc14bSjoerg  // compare
1332*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
1333*4d6fc14bSjoerg    return __compare(__p.__pn_);
1334*4d6fc14bSjoerg  }
1335*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
1336*4d6fc14bSjoerg    return __compare(__s);
1337*4d6fc14bSjoerg  }
1338*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
1339*4d6fc14bSjoerg    return __compare(__s);
1340*4d6fc14bSjoerg  }
1341*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
1342*4d6fc14bSjoerg    return __compare(__s);
1343*4d6fc14bSjoerg  }
1344*4d6fc14bSjoerg
1345*4d6fc14bSjoerg  // decomposition
1346*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path root_name() const {
1347*4d6fc14bSjoerg    return string_type(__root_name());
1348*4d6fc14bSjoerg  }
1349*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path root_directory() const {
1350*4d6fc14bSjoerg    return string_type(__root_directory());
1351*4d6fc14bSjoerg  }
1352*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path root_path() const {
1353*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1354*4d6fc14bSjoerg    return string_type(__root_path_raw());
1355*4d6fc14bSjoerg#else
1356*4d6fc14bSjoerg    return root_name().append(string_type(__root_directory()));
1357*4d6fc14bSjoerg#endif
1358*4d6fc14bSjoerg  }
1359*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path relative_path() const {
1360*4d6fc14bSjoerg    return string_type(__relative_path());
1361*4d6fc14bSjoerg  }
1362*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path parent_path() const {
1363*4d6fc14bSjoerg    return string_type(__parent_path());
1364*4d6fc14bSjoerg  }
1365*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path filename() const {
1366*4d6fc14bSjoerg    return string_type(__filename());
1367*4d6fc14bSjoerg  }
1368*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
1369*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path extension() const {
1370*4d6fc14bSjoerg    return string_type(__extension());
1371*4d6fc14bSjoerg  }
1372*4d6fc14bSjoerg
1373*4d6fc14bSjoerg  // query
1374*4d6fc14bSjoerg  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
1375*4d6fc14bSjoerg  empty() const noexcept {
1376*4d6fc14bSjoerg    return __pn_.empty();
1377*4d6fc14bSjoerg  }
1378*4d6fc14bSjoerg
1379*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
1380*4d6fc14bSjoerg    return !__root_name().empty();
1381*4d6fc14bSjoerg  }
1382*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
1383*4d6fc14bSjoerg    return !__root_directory().empty();
1384*4d6fc14bSjoerg  }
1385*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
1386*4d6fc14bSjoerg    return !__root_path_raw().empty();
1387*4d6fc14bSjoerg  }
1388*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
1389*4d6fc14bSjoerg    return !__relative_path().empty();
1390*4d6fc14bSjoerg  }
1391*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
1392*4d6fc14bSjoerg    return !__parent_path().empty();
1393*4d6fc14bSjoerg  }
1394*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
1395*4d6fc14bSjoerg    return !__filename().empty();
1396*4d6fc14bSjoerg  }
1397*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1398*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
1399*4d6fc14bSjoerg    return !__extension().empty();
1400*4d6fc14bSjoerg  }
1401*4d6fc14bSjoerg
1402*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1403*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1404*4d6fc14bSjoerg    __string_view __root_name_str = __root_name();
1405*4d6fc14bSjoerg    __string_view __root_dir = __root_directory();
1406*4d6fc14bSjoerg    if (__root_name_str.size() == 2 && __root_name_str[1] == ':') {
1407*4d6fc14bSjoerg      // A drive letter with no root directory is relative, e.g. x:example.
1408*4d6fc14bSjoerg      return !__root_dir.empty();
1409*4d6fc14bSjoerg    }
1410*4d6fc14bSjoerg    // If no root name, it's relative, e.g. \example is relative to the current drive
1411*4d6fc14bSjoerg    if (__root_name_str.empty())
1412*4d6fc14bSjoerg      return false;
1413*4d6fc14bSjoerg    if (__root_name_str.size() < 3)
1414*4d6fc14bSjoerg      return false;
1415*4d6fc14bSjoerg    // A server root name, like \\server, is always absolute
1416*4d6fc14bSjoerg    if (__root_name_str[0] != '/' && __root_name_str[0] != '\\')
1417*4d6fc14bSjoerg      return false;
1418*4d6fc14bSjoerg    if (__root_name_str[1] != '/' && __root_name_str[1] != '\\')
1419*4d6fc14bSjoerg      return false;
1420*4d6fc14bSjoerg    // Seems to be a server root name
1421*4d6fc14bSjoerg    return true;
1422*4d6fc14bSjoerg#else
1423*4d6fc14bSjoerg    return has_root_directory();
1424*4d6fc14bSjoerg#endif
1425*4d6fc14bSjoerg  }
1426*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1427*4d6fc14bSjoerg
1428*4d6fc14bSjoerg  // relative paths
1429*4d6fc14bSjoerg  path lexically_normal() const;
1430*4d6fc14bSjoerg  path lexically_relative(const path& __base) const;
1431*4d6fc14bSjoerg
1432*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1433*4d6fc14bSjoerg    path __result = this->lexically_relative(__base);
1434*4d6fc14bSjoerg    if (__result.native().empty())
1435*4d6fc14bSjoerg      return *this;
1436*4d6fc14bSjoerg    return __result;
1437*4d6fc14bSjoerg  }
1438*4d6fc14bSjoerg
1439*4d6fc14bSjoerg  // iterators
1440*4d6fc14bSjoerg  class _LIBCPP_TYPE_VIS iterator;
1441*4d6fc14bSjoerg  typedef iterator const_iterator;
1442*4d6fc14bSjoerg
1443*4d6fc14bSjoerg  iterator begin() const;
1444*4d6fc14bSjoerg  iterator end() const;
1445*4d6fc14bSjoerg
1446*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1447*4d6fc14bSjoerg  template <class _CharT, class _Traits>
1448*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend
1449*4d6fc14bSjoerg      typename enable_if<is_same<_CharT, value_type>::value &&
1450*4d6fc14bSjoerg                             is_same<_Traits, char_traits<value_type> >::value,
1451*4d6fc14bSjoerg                         basic_ostream<_CharT, _Traits>&>::type
1452*4d6fc14bSjoerg      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1453*4d6fc14bSjoerg    __os << _VSTD::__quoted(__p.native());
1454*4d6fc14bSjoerg    return __os;
1455*4d6fc14bSjoerg  }
1456*4d6fc14bSjoerg
1457*4d6fc14bSjoerg  template <class _CharT, class _Traits>
1458*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend
1459*4d6fc14bSjoerg      typename enable_if<!is_same<_CharT, value_type>::value ||
1460*4d6fc14bSjoerg                             !is_same<_Traits, char_traits<value_type> >::value,
1461*4d6fc14bSjoerg                         basic_ostream<_CharT, _Traits>&>::type
1462*4d6fc14bSjoerg      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1463*4d6fc14bSjoerg    __os << _VSTD::__quoted(__p.string<_CharT, _Traits>());
1464*4d6fc14bSjoerg    return __os;
1465*4d6fc14bSjoerg  }
1466*4d6fc14bSjoerg
1467*4d6fc14bSjoerg  template <class _CharT, class _Traits>
1468*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
1469*4d6fc14bSjoerg  operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
1470*4d6fc14bSjoerg    basic_string<_CharT, _Traits> __tmp;
1471*4d6fc14bSjoerg    __is >> __quoted(__tmp);
1472*4d6fc14bSjoerg    __p = __tmp;
1473*4d6fc14bSjoerg    return __is;
1474*4d6fc14bSjoerg  }
1475*4d6fc14bSjoerg#endif // !_LIBCPP_HAS_NO_LOCALIZATION
1476*4d6fc14bSjoerg
1477*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
1478*4d6fc14bSjoerg    return __lhs.compare(__rhs) == 0;
1479*4d6fc14bSjoerg  }
1480*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
1481*4d6fc14bSjoerg    return __lhs.compare(__rhs) != 0;
1482*4d6fc14bSjoerg  }
1483*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
1484*4d6fc14bSjoerg    return __lhs.compare(__rhs) < 0;
1485*4d6fc14bSjoerg  }
1486*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
1487*4d6fc14bSjoerg    return __lhs.compare(__rhs) <= 0;
1488*4d6fc14bSjoerg  }
1489*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
1490*4d6fc14bSjoerg    return __lhs.compare(__rhs) > 0;
1491*4d6fc14bSjoerg  }
1492*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
1493*4d6fc14bSjoerg    return __lhs.compare(__rhs) >= 0;
1494*4d6fc14bSjoerg  }
1495*4d6fc14bSjoerg
1496*4d6fc14bSjoerg  friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1497*4d6fc14bSjoerg                                                  const path& __rhs) {
1498*4d6fc14bSjoerg    path __result(__lhs);
1499*4d6fc14bSjoerg    __result /= __rhs;
1500*4d6fc14bSjoerg    return __result;
1501*4d6fc14bSjoerg  }
1502*4d6fc14bSjoergprivate:
1503*4d6fc14bSjoerg  inline _LIBCPP_INLINE_VISIBILITY path&
1504*4d6fc14bSjoerg  __assign_view(__string_view const& __s) noexcept {
1505*4d6fc14bSjoerg    __pn_ = string_type(__s);
1506*4d6fc14bSjoerg    return *this;
1507*4d6fc14bSjoerg  }
1508*4d6fc14bSjoerg  string_type __pn_;
1509*4d6fc14bSjoerg};
1510*4d6fc14bSjoerg
1511*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
1512*4d6fc14bSjoerg  __lhs.swap(__rhs);
1513*4d6fc14bSjoerg}
1514*4d6fc14bSjoerg
1515*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1516*4d6fc14bSjoergsize_t hash_value(const path& __p) noexcept;
1517*4d6fc14bSjoerg
1518*4d6fc14bSjoergtemplate <class _InputIt>
1519*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1520*4d6fc14bSjoerg    typename enable_if<__is_pathable<_InputIt>::value, path>::type
1521*4d6fc14bSjoerg    u8path(_InputIt __f, _InputIt __l) {
1522*4d6fc14bSjoerg  static_assert(
1523*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
1524*4d6fc14bSjoerg      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1525*4d6fc14bSjoerg#endif
1526*4d6fc14bSjoerg      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1527*4d6fc14bSjoerg      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1528*4d6fc14bSjoerg      " or 'char8_t'");
1529*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1530*4d6fc14bSjoerg  string __tmp(__f, __l);
1531*4d6fc14bSjoerg  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1532*4d6fc14bSjoerg  _VSTD::wstring __w;
1533*4d6fc14bSjoerg  __w.reserve(__tmp.size());
1534*4d6fc14bSjoerg  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1535*4d6fc14bSjoerg  return path(__w);
1536*4d6fc14bSjoerg#else
1537*4d6fc14bSjoerg  return path(__f, __l);
1538*4d6fc14bSjoerg#endif /* !_LIBCPP_WIN32API */
1539*4d6fc14bSjoerg}
1540*4d6fc14bSjoerg
1541*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1542*4d6fc14bSjoergtemplate <class _InputIt>
1543*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1544*4d6fc14bSjoerg    typename enable_if<__is_pathable<_InputIt>::value, path>::type
1545*4d6fc14bSjoerg    u8path(_InputIt __f, _NullSentinel) {
1546*4d6fc14bSjoerg  static_assert(
1547*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
1548*4d6fc14bSjoerg      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1549*4d6fc14bSjoerg#endif
1550*4d6fc14bSjoerg      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1551*4d6fc14bSjoerg      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1552*4d6fc14bSjoerg      " or 'char8_t'");
1553*4d6fc14bSjoerg  string __tmp;
1554*4d6fc14bSjoerg  const char __sentinel = char{};
1555*4d6fc14bSjoerg  for (; *__f != __sentinel; ++__f)
1556*4d6fc14bSjoerg    __tmp.push_back(*__f);
1557*4d6fc14bSjoerg  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1558*4d6fc14bSjoerg  _VSTD::wstring __w;
1559*4d6fc14bSjoerg  __w.reserve(__tmp.size());
1560*4d6fc14bSjoerg  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1561*4d6fc14bSjoerg  return path(__w);
1562*4d6fc14bSjoerg}
1563*4d6fc14bSjoerg#endif /* _LIBCPP_WIN32API */
1564*4d6fc14bSjoerg
1565*4d6fc14bSjoergtemplate <class _Source>
1566*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1567*4d6fc14bSjoerg    typename enable_if<__is_pathable<_Source>::value, path>::type
1568*4d6fc14bSjoerg    u8path(const _Source& __s) {
1569*4d6fc14bSjoerg  static_assert(
1570*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_CHAR8_T
1571*4d6fc14bSjoerg      is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
1572*4d6fc14bSjoerg#endif
1573*4d6fc14bSjoerg      is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1574*4d6fc14bSjoerg      "u8path(Source const&) requires Source have a character type of type "
1575*4d6fc14bSjoerg      "'char' or 'char8_t'");
1576*4d6fc14bSjoerg#if defined(_LIBCPP_WIN32API)
1577*4d6fc14bSjoerg  using _Traits = __is_pathable<_Source>;
1578*4d6fc14bSjoerg  return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s)));
1579*4d6fc14bSjoerg#else
1580*4d6fc14bSjoerg  return path(__s);
1581*4d6fc14bSjoerg#endif
1582*4d6fc14bSjoerg}
1583*4d6fc14bSjoerg
1584*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS path::iterator {
1585*4d6fc14bSjoergpublic:
1586*4d6fc14bSjoerg  enum _ParserState : unsigned char {
1587*4d6fc14bSjoerg    _Singular,
1588*4d6fc14bSjoerg    _BeforeBegin,
1589*4d6fc14bSjoerg    _InRootName,
1590*4d6fc14bSjoerg    _InRootDir,
1591*4d6fc14bSjoerg    _InFilenames,
1592*4d6fc14bSjoerg    _InTrailingSep,
1593*4d6fc14bSjoerg    _AtEnd
1594*4d6fc14bSjoerg  };
1595*4d6fc14bSjoerg
1596*4d6fc14bSjoergpublic:
1597*4d6fc14bSjoerg  typedef bidirectional_iterator_tag iterator_category;
1598*4d6fc14bSjoerg
1599*4d6fc14bSjoerg  typedef path value_type;
1600*4d6fc14bSjoerg  typedef ptrdiff_t difference_type;
1601*4d6fc14bSjoerg  typedef const path* pointer;
1602*4d6fc14bSjoerg  typedef const path& reference;
1603*4d6fc14bSjoerg
1604*4d6fc14bSjoerg  typedef void
1605*4d6fc14bSjoerg      __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1606*4d6fc14bSjoerg
1607*4d6fc14bSjoergpublic:
1608*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1609*4d6fc14bSjoerg  iterator()
1610*4d6fc14bSjoerg      : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
1611*4d6fc14bSjoerg        __state_(_Singular) {}
1612*4d6fc14bSjoerg
1613*4d6fc14bSjoerg  iterator(const iterator&) = default;
1614*4d6fc14bSjoerg  ~iterator() = default;
1615*4d6fc14bSjoerg
1616*4d6fc14bSjoerg  iterator& operator=(const iterator&) = default;
1617*4d6fc14bSjoerg
1618*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1619*4d6fc14bSjoerg  reference operator*() const { return __stashed_elem_; }
1620*4d6fc14bSjoerg
1621*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1622*4d6fc14bSjoerg  pointer operator->() const { return &__stashed_elem_; }
1623*4d6fc14bSjoerg
1624*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1625*4d6fc14bSjoerg  iterator& operator++() {
1626*4d6fc14bSjoerg    _LIBCPP_ASSERT(__state_ != _Singular,
1627*4d6fc14bSjoerg                   "attempting to increment a singular iterator");
1628*4d6fc14bSjoerg    _LIBCPP_ASSERT(__state_ != _AtEnd,
1629*4d6fc14bSjoerg                   "attempting to increment the end iterator");
1630*4d6fc14bSjoerg    return __increment();
1631*4d6fc14bSjoerg  }
1632*4d6fc14bSjoerg
1633*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1634*4d6fc14bSjoerg  iterator operator++(int) {
1635*4d6fc14bSjoerg    iterator __it(*this);
1636*4d6fc14bSjoerg    this->operator++();
1637*4d6fc14bSjoerg    return __it;
1638*4d6fc14bSjoerg  }
1639*4d6fc14bSjoerg
1640*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1641*4d6fc14bSjoerg  iterator& operator--() {
1642*4d6fc14bSjoerg    _LIBCPP_ASSERT(__state_ != _Singular,
1643*4d6fc14bSjoerg                   "attempting to decrement a singular iterator");
1644*4d6fc14bSjoerg    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1645*4d6fc14bSjoerg                   "attempting to decrement the begin iterator");
1646*4d6fc14bSjoerg    return __decrement();
1647*4d6fc14bSjoerg  }
1648*4d6fc14bSjoerg
1649*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1650*4d6fc14bSjoerg  iterator operator--(int) {
1651*4d6fc14bSjoerg    iterator __it(*this);
1652*4d6fc14bSjoerg    this->operator--();
1653*4d6fc14bSjoerg    return __it;
1654*4d6fc14bSjoerg  }
1655*4d6fc14bSjoerg
1656*4d6fc14bSjoergprivate:
1657*4d6fc14bSjoerg  friend class path;
1658*4d6fc14bSjoerg
1659*4d6fc14bSjoerg  inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
1660*4d6fc14bSjoerg                                                          const iterator&);
1661*4d6fc14bSjoerg
1662*4d6fc14bSjoerg  iterator& __increment();
1663*4d6fc14bSjoerg  iterator& __decrement();
1664*4d6fc14bSjoerg
1665*4d6fc14bSjoerg  path __stashed_elem_;
1666*4d6fc14bSjoerg  const path* __path_ptr_;
1667*4d6fc14bSjoerg  path::__string_view __entry_;
1668*4d6fc14bSjoerg  _ParserState __state_;
1669*4d6fc14bSjoerg};
1670*4d6fc14bSjoerg
1671*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
1672*4d6fc14bSjoerg                                                 const path::iterator& __rhs) {
1673*4d6fc14bSjoerg  return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1674*4d6fc14bSjoerg         __lhs.__entry_.data() == __rhs.__entry_.data();
1675*4d6fc14bSjoerg}
1676*4d6fc14bSjoerg
1677*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
1678*4d6fc14bSjoerg                                                 const path::iterator& __rhs) {
1679*4d6fc14bSjoerg  return !(__lhs == __rhs);
1680*4d6fc14bSjoerg}
1681*4d6fc14bSjoerg
1682*4d6fc14bSjoerg// TODO(ldionne): We need to pop the pragma and push it again after
1683*4d6fc14bSjoerg//                filesystem_error to work around PR41078.
1684*4d6fc14bSjoerg_LIBCPP_AVAILABILITY_FILESYSTEM_POP
1685*4d6fc14bSjoerg
1686*4d6fc14bSjoergclass _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
1687*4d6fc14bSjoergpublic:
1688*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1689*4d6fc14bSjoerg  filesystem_error(const string& __what, error_code __ec)
1690*4d6fc14bSjoerg      : system_error(__ec, __what),
1691*4d6fc14bSjoerg        __storage_(make_shared<_Storage>(path(), path())) {
1692*4d6fc14bSjoerg    __create_what(0);
1693*4d6fc14bSjoerg  }
1694*4d6fc14bSjoerg
1695*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1696*4d6fc14bSjoerg  filesystem_error(const string& __what, const path& __p1, error_code __ec)
1697*4d6fc14bSjoerg      : system_error(__ec, __what),
1698*4d6fc14bSjoerg        __storage_(make_shared<_Storage>(__p1, path())) {
1699*4d6fc14bSjoerg    __create_what(1);
1700*4d6fc14bSjoerg  }
1701*4d6fc14bSjoerg
1702*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1703*4d6fc14bSjoerg  filesystem_error(const string& __what, const path& __p1, const path& __p2,
1704*4d6fc14bSjoerg                   error_code __ec)
1705*4d6fc14bSjoerg      : system_error(__ec, __what),
1706*4d6fc14bSjoerg        __storage_(make_shared<_Storage>(__p1, __p2)) {
1707*4d6fc14bSjoerg    __create_what(2);
1708*4d6fc14bSjoerg  }
1709*4d6fc14bSjoerg
1710*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1711*4d6fc14bSjoerg  const path& path1() const noexcept { return __storage_->__p1_; }
1712*4d6fc14bSjoerg
1713*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1714*4d6fc14bSjoerg  const path& path2() const noexcept { return __storage_->__p2_; }
1715*4d6fc14bSjoerg
1716*4d6fc14bSjoerg  filesystem_error(const filesystem_error&) = default;
1717*4d6fc14bSjoerg  ~filesystem_error() override; // key function
1718*4d6fc14bSjoerg
1719*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
1720*4d6fc14bSjoerg  const char* what() const noexcept override {
1721*4d6fc14bSjoerg    return __storage_->__what_.c_str();
1722*4d6fc14bSjoerg  }
1723*4d6fc14bSjoerg
1724*4d6fc14bSjoerg  void __create_what(int __num_paths);
1725*4d6fc14bSjoerg
1726*4d6fc14bSjoergprivate:
1727*4d6fc14bSjoerg  struct _LIBCPP_HIDDEN _Storage {
1728*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1729*4d6fc14bSjoerg    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1730*4d6fc14bSjoerg
1731*4d6fc14bSjoerg    path __p1_;
1732*4d6fc14bSjoerg    path __p2_;
1733*4d6fc14bSjoerg    string __what_;
1734*4d6fc14bSjoerg  };
1735*4d6fc14bSjoerg  shared_ptr<_Storage> __storage_;
1736*4d6fc14bSjoerg};
1737*4d6fc14bSjoerg
1738*4d6fc14bSjoerg_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
1739*4d6fc14bSjoerg
1740*4d6fc14bSjoergtemplate <class... _Args>
1741*4d6fc14bSjoerg_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1742*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1743*4d6fc14bSjoergvoid __throw_filesystem_error(_Args&&... __args) {
1744*4d6fc14bSjoerg  throw filesystem_error(_VSTD::forward<_Args>(__args)...);
1745*4d6fc14bSjoerg}
1746*4d6fc14bSjoerg#else
1747*4d6fc14bSjoergvoid __throw_filesystem_error(_Args&&...) {
1748*4d6fc14bSjoerg  _VSTD::abort();
1749*4d6fc14bSjoerg}
1750*4d6fc14bSjoerg#endif
1751*4d6fc14bSjoerg
1752*4d6fc14bSjoerg// operational functions
1753*4d6fc14bSjoerg
1754*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1755*4d6fc14bSjoergpath __absolute(const path&, error_code* __ec = nullptr);
1756*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1757*4d6fc14bSjoergpath __canonical(const path&, error_code* __ec = nullptr);
1758*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1759*4d6fc14bSjoergvoid __copy(const path& __from, const path& __to, copy_options __opt,
1760*4d6fc14bSjoerg            error_code* __ec = nullptr);
1761*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1762*4d6fc14bSjoergbool __copy_file(const path& __from, const path& __to, copy_options __opt,
1763*4d6fc14bSjoerg                 error_code* __ec = nullptr);
1764*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1765*4d6fc14bSjoergvoid __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1766*4d6fc14bSjoerg                    error_code* __ec = nullptr);
1767*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1768*4d6fc14bSjoergbool __create_directories(const path& p, error_code* ec = nullptr);
1769*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1770*4d6fc14bSjoergbool __create_directory(const path& p, error_code* ec = nullptr);
1771*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1772*4d6fc14bSjoergbool __create_directory(const path& p, const path& attributes,
1773*4d6fc14bSjoerg                        error_code* ec = nullptr);
1774*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1775*4d6fc14bSjoergvoid __create_directory_symlink(const path& __to, const path& __new_symlink,
1776*4d6fc14bSjoerg                                error_code* __ec = nullptr);
1777*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1778*4d6fc14bSjoergvoid __create_hard_link(const path& __to, const path& __new_hard_link,
1779*4d6fc14bSjoerg                        error_code* __ec = nullptr);
1780*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1781*4d6fc14bSjoergvoid __create_symlink(const path& __to, const path& __new_symlink,
1782*4d6fc14bSjoerg                      error_code* __ec = nullptr);
1783*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1784*4d6fc14bSjoergpath __current_path(error_code* __ec = nullptr);
1785*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1786*4d6fc14bSjoergvoid __current_path(const path&, error_code* __ec = nullptr);
1787*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1788*4d6fc14bSjoergbool __equivalent(const path&, const path&, error_code* __ec = nullptr);
1789*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1790*4d6fc14bSjoerguintmax_t __file_size(const path&, error_code* __ec = nullptr);
1791*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1792*4d6fc14bSjoerguintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
1793*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1794*4d6fc14bSjoergbool __fs_is_empty(const path& p, error_code* ec = nullptr);
1795*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1796*4d6fc14bSjoergfile_time_type __last_write_time(const path& p, error_code* ec = nullptr);
1797*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1798*4d6fc14bSjoergvoid __last_write_time(const path& p, file_time_type new_time,
1799*4d6fc14bSjoerg                       error_code* ec = nullptr);
1800*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1801*4d6fc14bSjoergvoid __permissions(const path&, perms, perm_options, error_code* = nullptr);
1802*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1803*4d6fc14bSjoergpath __read_symlink(const path& p, error_code* ec = nullptr);
1804*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1805*4d6fc14bSjoergbool __remove(const path& p, error_code* ec = nullptr);
1806*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1807*4d6fc14bSjoerguintmax_t __remove_all(const path& p, error_code* ec = nullptr);
1808*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1809*4d6fc14bSjoergvoid __rename(const path& from, const path& to, error_code* ec = nullptr);
1810*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1811*4d6fc14bSjoergvoid __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
1812*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1813*4d6fc14bSjoergspace_info __space(const path&, error_code* __ec = nullptr);
1814*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1815*4d6fc14bSjoergfile_status __status(const path&, error_code* __ec = nullptr);
1816*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1817*4d6fc14bSjoergfile_status __symlink_status(const path&, error_code* __ec = nullptr);
1818*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1819*4d6fc14bSjoergpath __system_complete(const path&, error_code* __ec = nullptr);
1820*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1821*4d6fc14bSjoergpath __temp_directory_path(error_code* __ec = nullptr);
1822*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
1823*4d6fc14bSjoergpath __weakly_canonical(path const& __p, error_code* __ec = nullptr);
1824*4d6fc14bSjoerg
1825*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path current_path() {
1826*4d6fc14bSjoerg  return __current_path();
1827*4d6fc14bSjoerg}
1828*4d6fc14bSjoerg
1829*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
1830*4d6fc14bSjoerg  return __current_path(&__ec);
1831*4d6fc14bSjoerg}
1832*4d6fc14bSjoerg
1833*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
1834*4d6fc14bSjoerg  __current_path(__p);
1835*4d6fc14bSjoerg}
1836*4d6fc14bSjoerg
1837*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
1838*4d6fc14bSjoerg                                                   error_code& __ec) noexcept {
1839*4d6fc14bSjoerg  __current_path(__p, &__ec);
1840*4d6fc14bSjoerg}
1841*4d6fc14bSjoerg
1842*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
1843*4d6fc14bSjoerg  return __absolute(__p);
1844*4d6fc14bSjoerg}
1845*4d6fc14bSjoerg
1846*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
1847*4d6fc14bSjoerg                                               error_code& __ec) {
1848*4d6fc14bSjoerg  return __absolute(__p, &__ec);
1849*4d6fc14bSjoerg}
1850*4d6fc14bSjoerg
1851*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
1852*4d6fc14bSjoerg  return __canonical(__p);
1853*4d6fc14bSjoerg}
1854*4d6fc14bSjoerg
1855*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
1856*4d6fc14bSjoerg                                                error_code& __ec) {
1857*4d6fc14bSjoerg  return __canonical(__p, &__ec);
1858*4d6fc14bSjoerg}
1859*4d6fc14bSjoerg
1860*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
1861*4d6fc14bSjoerg                                           const path& __to) {
1862*4d6fc14bSjoerg  __copy(__from, __to, copy_options::none);
1863*4d6fc14bSjoerg}
1864*4d6fc14bSjoerg
1865*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1866*4d6fc14bSjoerg                                           error_code& __ec) {
1867*4d6fc14bSjoerg  __copy(__from, __to, copy_options::none, &__ec);
1868*4d6fc14bSjoerg}
1869*4d6fc14bSjoerg
1870*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1871*4d6fc14bSjoerg                                           copy_options __opt) {
1872*4d6fc14bSjoerg  __copy(__from, __to, __opt);
1873*4d6fc14bSjoerg}
1874*4d6fc14bSjoerg
1875*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1876*4d6fc14bSjoerg                                           copy_options __opt,
1877*4d6fc14bSjoerg                                           error_code& __ec) {
1878*4d6fc14bSjoerg  __copy(__from, __to, __opt, &__ec);
1879*4d6fc14bSjoerg}
1880*4d6fc14bSjoerg
1881*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1882*4d6fc14bSjoerg                                                const path& __to) {
1883*4d6fc14bSjoerg  return __copy_file(__from, __to, copy_options::none);
1884*4d6fc14bSjoerg}
1885*4d6fc14bSjoerg
1886*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
1887*4d6fc14bSjoergcopy_file(const path& __from, const path& __to, error_code& __ec) {
1888*4d6fc14bSjoerg  return __copy_file(__from, __to, copy_options::none, &__ec);
1889*4d6fc14bSjoerg}
1890*4d6fc14bSjoerg
1891*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
1892*4d6fc14bSjoergcopy_file(const path& __from, const path& __to, copy_options __opt) {
1893*4d6fc14bSjoerg  return __copy_file(__from, __to, __opt);
1894*4d6fc14bSjoerg}
1895*4d6fc14bSjoerg
1896*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1897*4d6fc14bSjoerg                                                const path& __to,
1898*4d6fc14bSjoerg                                                copy_options __opt,
1899*4d6fc14bSjoerg                                                error_code& __ec) {
1900*4d6fc14bSjoerg  return __copy_file(__from, __to, __opt, &__ec);
1901*4d6fc14bSjoerg}
1902*4d6fc14bSjoerg
1903*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
1904*4d6fc14bSjoerg                                                   const path& __new) {
1905*4d6fc14bSjoerg  __copy_symlink(__existing, __new);
1906*4d6fc14bSjoerg}
1907*4d6fc14bSjoerg
1908*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
1909*4d6fc14bSjoergcopy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
1910*4d6fc14bSjoerg  __copy_symlink(__ext, __new, &__ec);
1911*4d6fc14bSjoerg}
1912*4d6fc14bSjoerg
1913*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
1914*4d6fc14bSjoerg  return __create_directories(__p);
1915*4d6fc14bSjoerg}
1916*4d6fc14bSjoerg
1917*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
1918*4d6fc14bSjoerg                                                         error_code& __ec) {
1919*4d6fc14bSjoerg  return __create_directories(__p, &__ec);
1920*4d6fc14bSjoerg}
1921*4d6fc14bSjoerg
1922*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
1923*4d6fc14bSjoerg  return __create_directory(__p);
1924*4d6fc14bSjoerg}
1925*4d6fc14bSjoerg
1926*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
1927*4d6fc14bSjoergcreate_directory(const path& __p, error_code& __ec) noexcept {
1928*4d6fc14bSjoerg  return __create_directory(__p, &__ec);
1929*4d6fc14bSjoerg}
1930*4d6fc14bSjoerg
1931*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
1932*4d6fc14bSjoerg                                                       const path& __attrs) {
1933*4d6fc14bSjoerg  return __create_directory(__p, __attrs);
1934*4d6fc14bSjoerg}
1935*4d6fc14bSjoerg
1936*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
1937*4d6fc14bSjoergcreate_directory(const path& __p, const path& __attrs,
1938*4d6fc14bSjoerg                 error_code& __ec) noexcept {
1939*4d6fc14bSjoerg  return __create_directory(__p, __attrs, &__ec);
1940*4d6fc14bSjoerg}
1941*4d6fc14bSjoerg
1942*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
1943*4d6fc14bSjoergcreate_directory_symlink(const path& __to, const path& __new) {
1944*4d6fc14bSjoerg  __create_directory_symlink(__to, __new);
1945*4d6fc14bSjoerg}
1946*4d6fc14bSjoerg
1947*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
1948*4d6fc14bSjoergcreate_directory_symlink(const path& __to, const path& __new,
1949*4d6fc14bSjoerg                         error_code& __ec) noexcept {
1950*4d6fc14bSjoerg  __create_directory_symlink(__to, __new, &__ec);
1951*4d6fc14bSjoerg}
1952*4d6fc14bSjoerg
1953*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
1954*4d6fc14bSjoerg                                                       const path& __new) {
1955*4d6fc14bSjoerg  __create_hard_link(__to, __new);
1956*4d6fc14bSjoerg}
1957*4d6fc14bSjoerg
1958*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
1959*4d6fc14bSjoergcreate_hard_link(const path& __to, const path& __new,
1960*4d6fc14bSjoerg                 error_code& __ec) noexcept {
1961*4d6fc14bSjoerg  __create_hard_link(__to, __new, &__ec);
1962*4d6fc14bSjoerg}
1963*4d6fc14bSjoerg
1964*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
1965*4d6fc14bSjoerg                                                     const path& __new) {
1966*4d6fc14bSjoerg  __create_symlink(__to, __new);
1967*4d6fc14bSjoerg}
1968*4d6fc14bSjoerg
1969*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
1970*4d6fc14bSjoergcreate_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
1971*4d6fc14bSjoerg  return __create_symlink(__to, __new, &__ec);
1972*4d6fc14bSjoerg}
1973*4d6fc14bSjoerg
1974*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
1975*4d6fc14bSjoerg  return __s.type() != file_type::none;
1976*4d6fc14bSjoerg}
1977*4d6fc14bSjoerg
1978*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
1979*4d6fc14bSjoerg  return status_known(__s) && __s.type() != file_type::not_found;
1980*4d6fc14bSjoerg}
1981*4d6fc14bSjoerg
1982*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
1983*4d6fc14bSjoerg  return exists(__status(__p));
1984*4d6fc14bSjoerg}
1985*4d6fc14bSjoerg
1986*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
1987*4d6fc14bSjoerg                                             error_code& __ec) noexcept {
1988*4d6fc14bSjoerg  auto __s = __status(__p, &__ec);
1989*4d6fc14bSjoerg  if (status_known(__s))
1990*4d6fc14bSjoerg    __ec.clear();
1991*4d6fc14bSjoerg  return exists(__s);
1992*4d6fc14bSjoerg}
1993*4d6fc14bSjoerg
1994*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
1995*4d6fc14bSjoerg                                                 const path& __p2) {
1996*4d6fc14bSjoerg  return __equivalent(__p1, __p2);
1997*4d6fc14bSjoerg}
1998*4d6fc14bSjoerg
1999*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2000*4d6fc14bSjoergequivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
2001*4d6fc14bSjoerg  return __equivalent(__p1, __p2, &__ec);
2002*4d6fc14bSjoerg}
2003*4d6fc14bSjoerg
2004*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
2005*4d6fc14bSjoerg  return __file_size(__p);
2006*4d6fc14bSjoerg}
2007*4d6fc14bSjoerg
2008*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t
2009*4d6fc14bSjoergfile_size(const path& __p, error_code& __ec) noexcept {
2010*4d6fc14bSjoerg  return __file_size(__p, &__ec);
2011*4d6fc14bSjoerg}
2012*4d6fc14bSjoerg
2013*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
2014*4d6fc14bSjoerg  return __hard_link_count(__p);
2015*4d6fc14bSjoerg}
2016*4d6fc14bSjoerg
2017*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t
2018*4d6fc14bSjoerghard_link_count(const path& __p, error_code& __ec) noexcept {
2019*4d6fc14bSjoerg  return __hard_link_count(__p, &__ec);
2020*4d6fc14bSjoerg}
2021*4d6fc14bSjoerg
2022*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
2023*4d6fc14bSjoerg  return __s.type() == file_type::block;
2024*4d6fc14bSjoerg}
2025*4d6fc14bSjoerg
2026*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
2027*4d6fc14bSjoerg  return is_block_file(__status(__p));
2028*4d6fc14bSjoerg}
2029*4d6fc14bSjoerg
2030*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
2031*4d6fc14bSjoerg                                                    error_code& __ec) noexcept {
2032*4d6fc14bSjoerg  return is_block_file(__status(__p, &__ec));
2033*4d6fc14bSjoerg}
2034*4d6fc14bSjoerg
2035*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2036*4d6fc14bSjoergis_character_file(file_status __s) noexcept {
2037*4d6fc14bSjoerg  return __s.type() == file_type::character;
2038*4d6fc14bSjoerg}
2039*4d6fc14bSjoerg
2040*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
2041*4d6fc14bSjoerg  return is_character_file(__status(__p));
2042*4d6fc14bSjoerg}
2043*4d6fc14bSjoerg
2044*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2045*4d6fc14bSjoergis_character_file(const path& __p, error_code& __ec) noexcept {
2046*4d6fc14bSjoerg  return is_character_file(__status(__p, &__ec));
2047*4d6fc14bSjoerg}
2048*4d6fc14bSjoerg
2049*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
2050*4d6fc14bSjoerg  return __s.type() == file_type::directory;
2051*4d6fc14bSjoerg}
2052*4d6fc14bSjoerg
2053*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
2054*4d6fc14bSjoerg  return is_directory(__status(__p));
2055*4d6fc14bSjoerg}
2056*4d6fc14bSjoerg
2057*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
2058*4d6fc14bSjoerg                                                   error_code& __ec) noexcept {
2059*4d6fc14bSjoerg  return is_directory(__status(__p, &__ec));
2060*4d6fc14bSjoerg}
2061*4d6fc14bSjoerg
2062*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
2063*4d6fc14bSjoerg  return __fs_is_empty(__p);
2064*4d6fc14bSjoerg}
2065*4d6fc14bSjoerg
2066*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
2067*4d6fc14bSjoerg                                               error_code& __ec) {
2068*4d6fc14bSjoerg  return __fs_is_empty(__p, &__ec);
2069*4d6fc14bSjoerg}
2070*4d6fc14bSjoerg
2071*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
2072*4d6fc14bSjoerg  return __s.type() == file_type::fifo;
2073*4d6fc14bSjoerg}
2074*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
2075*4d6fc14bSjoerg  return is_fifo(__status(__p));
2076*4d6fc14bSjoerg}
2077*4d6fc14bSjoerg
2078*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
2079*4d6fc14bSjoerg                                              error_code& __ec) noexcept {
2080*4d6fc14bSjoerg  return is_fifo(__status(__p, &__ec));
2081*4d6fc14bSjoerg}
2082*4d6fc14bSjoerg
2083*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2084*4d6fc14bSjoergis_regular_file(file_status __s) noexcept {
2085*4d6fc14bSjoerg  return __s.type() == file_type::regular;
2086*4d6fc14bSjoerg}
2087*4d6fc14bSjoerg
2088*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
2089*4d6fc14bSjoerg  return is_regular_file(__status(__p));
2090*4d6fc14bSjoerg}
2091*4d6fc14bSjoerg
2092*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2093*4d6fc14bSjoergis_regular_file(const path& __p, error_code& __ec) noexcept {
2094*4d6fc14bSjoerg  return is_regular_file(__status(__p, &__ec));
2095*4d6fc14bSjoerg}
2096*4d6fc14bSjoerg
2097*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
2098*4d6fc14bSjoerg  return __s.type() == file_type::socket;
2099*4d6fc14bSjoerg}
2100*4d6fc14bSjoerg
2101*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
2102*4d6fc14bSjoerg  return is_socket(__status(__p));
2103*4d6fc14bSjoerg}
2104*4d6fc14bSjoerg
2105*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
2106*4d6fc14bSjoerg                                                error_code& __ec) noexcept {
2107*4d6fc14bSjoerg  return is_socket(__status(__p, &__ec));
2108*4d6fc14bSjoerg}
2109*4d6fc14bSjoerg
2110*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
2111*4d6fc14bSjoerg  return __s.type() == file_type::symlink;
2112*4d6fc14bSjoerg}
2113*4d6fc14bSjoerg
2114*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
2115*4d6fc14bSjoerg  return is_symlink(__symlink_status(__p));
2116*4d6fc14bSjoerg}
2117*4d6fc14bSjoerg
2118*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
2119*4d6fc14bSjoerg                                                 error_code& __ec) noexcept {
2120*4d6fc14bSjoerg  return is_symlink(__symlink_status(__p, &__ec));
2121*4d6fc14bSjoerg}
2122*4d6fc14bSjoerg
2123*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
2124*4d6fc14bSjoerg  return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
2125*4d6fc14bSjoerg         !is_symlink(__s);
2126*4d6fc14bSjoerg}
2127*4d6fc14bSjoerg
2128*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
2129*4d6fc14bSjoerg  return is_other(__status(__p));
2130*4d6fc14bSjoerg}
2131*4d6fc14bSjoerg
2132*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
2133*4d6fc14bSjoerg                                               error_code& __ec) noexcept {
2134*4d6fc14bSjoerg  return is_other(__status(__p, &__ec));
2135*4d6fc14bSjoerg}
2136*4d6fc14bSjoerg
2137*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_time_type
2138*4d6fc14bSjoerglast_write_time(const path& __p) {
2139*4d6fc14bSjoerg  return __last_write_time(__p);
2140*4d6fc14bSjoerg}
2141*4d6fc14bSjoerg
2142*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_time_type
2143*4d6fc14bSjoerglast_write_time(const path& __p, error_code& __ec) noexcept {
2144*4d6fc14bSjoerg  return __last_write_time(__p, &__ec);
2145*4d6fc14bSjoerg}
2146*4d6fc14bSjoerg
2147*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
2148*4d6fc14bSjoerg                                                      file_time_type __t) {
2149*4d6fc14bSjoerg  __last_write_time(__p, __t);
2150*4d6fc14bSjoerg}
2151*4d6fc14bSjoerg
2152*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
2153*4d6fc14bSjoerglast_write_time(const path& __p, file_time_type __t,
2154*4d6fc14bSjoerg                error_code& __ec) noexcept {
2155*4d6fc14bSjoerg  __last_write_time(__p, __t, &__ec);
2156*4d6fc14bSjoerg}
2157*4d6fc14bSjoerg
2158*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
2159*4d6fc14bSjoergpermissions(const path& __p, perms __prms,
2160*4d6fc14bSjoerg            perm_options __opts = perm_options::replace) {
2161*4d6fc14bSjoerg  __permissions(__p, __prms, __opts);
2162*4d6fc14bSjoerg}
2163*4d6fc14bSjoerg
2164*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2165*4d6fc14bSjoerg                                                  error_code& __ec) noexcept {
2166*4d6fc14bSjoerg  __permissions(__p, __prms, perm_options::replace, &__ec);
2167*4d6fc14bSjoerg}
2168*4d6fc14bSjoerg
2169*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2170*4d6fc14bSjoerg                                                  perm_options __opts,
2171*4d6fc14bSjoerg                                                  error_code& __ec) {
2172*4d6fc14bSjoerg  __permissions(__p, __prms, __opts, &__ec);
2173*4d6fc14bSjoerg}
2174*4d6fc14bSjoerg
2175*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2176*4d6fc14bSjoerg                                                const path& __base,
2177*4d6fc14bSjoerg                                                error_code& __ec) {
2178*4d6fc14bSjoerg  path __tmp = __weakly_canonical(__p, &__ec);
2179*4d6fc14bSjoerg  if (__ec)
2180*4d6fc14bSjoerg    return {};
2181*4d6fc14bSjoerg  path __tmp_base = __weakly_canonical(__base, &__ec);
2182*4d6fc14bSjoerg  if (__ec)
2183*4d6fc14bSjoerg    return {};
2184*4d6fc14bSjoerg  return __tmp.lexically_proximate(__tmp_base);
2185*4d6fc14bSjoerg}
2186*4d6fc14bSjoerg
2187*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2188*4d6fc14bSjoerg                                                error_code& __ec) {
2189*4d6fc14bSjoerg  return proximate(__p, current_path(), __ec);
2190*4d6fc14bSjoerg}
2191*4d6fc14bSjoerg
2192*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path
2193*4d6fc14bSjoergproximate(const path& __p, const path& __base = current_path()) {
2194*4d6fc14bSjoerg  return __weakly_canonical(__p).lexically_proximate(
2195*4d6fc14bSjoerg      __weakly_canonical(__base));
2196*4d6fc14bSjoerg}
2197*4d6fc14bSjoerg
2198*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
2199*4d6fc14bSjoerg  return __read_symlink(__p);
2200*4d6fc14bSjoerg}
2201*4d6fc14bSjoerg
2202*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
2203*4d6fc14bSjoerg                                                   error_code& __ec) {
2204*4d6fc14bSjoerg  return __read_symlink(__p, &__ec);
2205*4d6fc14bSjoerg}
2206*4d6fc14bSjoerg
2207*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2208*4d6fc14bSjoerg                                               const path& __base,
2209*4d6fc14bSjoerg                                               error_code& __ec) {
2210*4d6fc14bSjoerg  path __tmp = __weakly_canonical(__p, &__ec);
2211*4d6fc14bSjoerg  if (__ec)
2212*4d6fc14bSjoerg    return path();
2213*4d6fc14bSjoerg  path __tmpbase = __weakly_canonical(__base, &__ec);
2214*4d6fc14bSjoerg  if (__ec)
2215*4d6fc14bSjoerg    return path();
2216*4d6fc14bSjoerg  return __tmp.lexically_relative(__tmpbase);
2217*4d6fc14bSjoerg}
2218*4d6fc14bSjoerg
2219*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2220*4d6fc14bSjoerg                                               error_code& __ec) {
2221*4d6fc14bSjoerg  return relative(__p, current_path(), __ec);
2222*4d6fc14bSjoerg}
2223*4d6fc14bSjoerg
2224*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path
2225*4d6fc14bSjoergrelative(const path& __p, const path& __base = current_path()) {
2226*4d6fc14bSjoerg  return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
2227*4d6fc14bSjoerg}
2228*4d6fc14bSjoerg
2229*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
2230*4d6fc14bSjoerg  return __remove(__p);
2231*4d6fc14bSjoerg}
2232*4d6fc14bSjoerg
2233*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
2234*4d6fc14bSjoerg                                             error_code& __ec) noexcept {
2235*4d6fc14bSjoerg  return __remove(__p, &__ec);
2236*4d6fc14bSjoerg}
2237*4d6fc14bSjoerg
2238*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
2239*4d6fc14bSjoerg  return __remove_all(__p);
2240*4d6fc14bSjoerg}
2241*4d6fc14bSjoerg
2242*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
2243*4d6fc14bSjoerg                                                      error_code& __ec) {
2244*4d6fc14bSjoerg  return __remove_all(__p, &__ec);
2245*4d6fc14bSjoerg}
2246*4d6fc14bSjoerg
2247*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
2248*4d6fc14bSjoerg                                             const path& __to) {
2249*4d6fc14bSjoerg  return __rename(__from, __to);
2250*4d6fc14bSjoerg}
2251*4d6fc14bSjoerg
2252*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
2253*4d6fc14bSjoergrename(const path& __from, const path& __to, error_code& __ec) noexcept {
2254*4d6fc14bSjoerg  return __rename(__from, __to, &__ec);
2255*4d6fc14bSjoerg}
2256*4d6fc14bSjoerg
2257*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
2258*4d6fc14bSjoerg                                                  uintmax_t __ns) {
2259*4d6fc14bSjoerg  return __resize_file(__p, __ns);
2260*4d6fc14bSjoerg}
2261*4d6fc14bSjoerg
2262*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void
2263*4d6fc14bSjoergresize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
2264*4d6fc14bSjoerg  return __resize_file(__p, __ns, &__ec);
2265*4d6fc14bSjoerg}
2266*4d6fc14bSjoerg
2267*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
2268*4d6fc14bSjoerg  return __space(__p);
2269*4d6fc14bSjoerg}
2270*4d6fc14bSjoerg
2271*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
2272*4d6fc14bSjoerg                                                  error_code& __ec) noexcept {
2273*4d6fc14bSjoerg  return __space(__p, &__ec);
2274*4d6fc14bSjoerg}
2275*4d6fc14bSjoerg
2276*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
2277*4d6fc14bSjoerg  return __status(__p);
2278*4d6fc14bSjoerg}
2279*4d6fc14bSjoerg
2280*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
2281*4d6fc14bSjoerg                                                    error_code& __ec) noexcept {
2282*4d6fc14bSjoerg  return __status(__p, &__ec);
2283*4d6fc14bSjoerg}
2284*4d6fc14bSjoerg
2285*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
2286*4d6fc14bSjoerg  return __symlink_status(__p);
2287*4d6fc14bSjoerg}
2288*4d6fc14bSjoerg
2289*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY file_status
2290*4d6fc14bSjoergsymlink_status(const path& __p, error_code& __ec) noexcept {
2291*4d6fc14bSjoerg  return __symlink_status(__p, &__ec);
2292*4d6fc14bSjoerg}
2293*4d6fc14bSjoerg
2294*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
2295*4d6fc14bSjoerg  return __temp_directory_path();
2296*4d6fc14bSjoerg}
2297*4d6fc14bSjoerg
2298*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
2299*4d6fc14bSjoerg  return __temp_directory_path(&__ec);
2300*4d6fc14bSjoerg}
2301*4d6fc14bSjoerg
2302*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
2303*4d6fc14bSjoerg  return __weakly_canonical(__p);
2304*4d6fc14bSjoerg}
2305*4d6fc14bSjoerg
2306*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
2307*4d6fc14bSjoerg                                                       error_code& __ec) {
2308*4d6fc14bSjoerg  return __weakly_canonical(__p, &__ec);
2309*4d6fc14bSjoerg}
2310*4d6fc14bSjoerg
2311*4d6fc14bSjoergclass directory_iterator;
2312*4d6fc14bSjoergclass recursive_directory_iterator;
2313*4d6fc14bSjoergclass _LIBCPP_HIDDEN __dir_stream;
2314*4d6fc14bSjoerg
2315*4d6fc14bSjoergclass directory_entry {
2316*4d6fc14bSjoerg  typedef _VSTD_FS::path _Path;
2317*4d6fc14bSjoerg
2318*4d6fc14bSjoergpublic:
2319*4d6fc14bSjoerg  // constructors and destructors
2320*4d6fc14bSjoerg  directory_entry() noexcept = default;
2321*4d6fc14bSjoerg  directory_entry(directory_entry const&) = default;
2322*4d6fc14bSjoerg  directory_entry(directory_entry&&) noexcept = default;
2323*4d6fc14bSjoerg
2324*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2325*4d6fc14bSjoerg  explicit directory_entry(_Path const& __p) : __p_(__p) {
2326*4d6fc14bSjoerg    error_code __ec;
2327*4d6fc14bSjoerg    __refresh(&__ec);
2328*4d6fc14bSjoerg  }
2329*4d6fc14bSjoerg
2330*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2331*4d6fc14bSjoerg  directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
2332*4d6fc14bSjoerg    __refresh(&__ec);
2333*4d6fc14bSjoerg  }
2334*4d6fc14bSjoerg
2335*4d6fc14bSjoerg  ~directory_entry() {}
2336*4d6fc14bSjoerg
2337*4d6fc14bSjoerg  directory_entry& operator=(directory_entry const&) = default;
2338*4d6fc14bSjoerg  directory_entry& operator=(directory_entry&&) noexcept = default;
2339*4d6fc14bSjoerg
2340*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2341*4d6fc14bSjoerg  void assign(_Path const& __p) {
2342*4d6fc14bSjoerg    __p_ = __p;
2343*4d6fc14bSjoerg    error_code __ec;
2344*4d6fc14bSjoerg    __refresh(&__ec);
2345*4d6fc14bSjoerg  }
2346*4d6fc14bSjoerg
2347*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2348*4d6fc14bSjoerg  void assign(_Path const& __p, error_code& __ec) {
2349*4d6fc14bSjoerg    __p_ = __p;
2350*4d6fc14bSjoerg    __refresh(&__ec);
2351*4d6fc14bSjoerg  }
2352*4d6fc14bSjoerg
2353*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2354*4d6fc14bSjoerg  void replace_filename(_Path const& __p) {
2355*4d6fc14bSjoerg    __p_.replace_filename(__p);
2356*4d6fc14bSjoerg    error_code __ec;
2357*4d6fc14bSjoerg    __refresh(&__ec);
2358*4d6fc14bSjoerg  }
2359*4d6fc14bSjoerg
2360*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2361*4d6fc14bSjoerg  void replace_filename(_Path const& __p, error_code& __ec) {
2362*4d6fc14bSjoerg    __p_ = __p_.parent_path() / __p;
2363*4d6fc14bSjoerg    __refresh(&__ec);
2364*4d6fc14bSjoerg  }
2365*4d6fc14bSjoerg
2366*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2367*4d6fc14bSjoerg  void refresh() { __refresh(); }
2368*4d6fc14bSjoerg
2369*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2370*4d6fc14bSjoerg  void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
2371*4d6fc14bSjoerg
2372*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2373*4d6fc14bSjoerg  _Path const& path() const noexcept { return __p_; }
2374*4d6fc14bSjoerg
2375*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2376*4d6fc14bSjoerg  operator const _Path&() const noexcept { return __p_; }
2377*4d6fc14bSjoerg
2378*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2379*4d6fc14bSjoerg  bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
2380*4d6fc14bSjoerg
2381*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2382*4d6fc14bSjoerg  bool exists(error_code& __ec) const noexcept {
2383*4d6fc14bSjoerg    return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2384*4d6fc14bSjoerg  }
2385*4d6fc14bSjoerg
2386*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2387*4d6fc14bSjoerg  bool is_block_file() const { return __get_ft() == file_type::block; }
2388*4d6fc14bSjoerg
2389*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2390*4d6fc14bSjoerg  bool is_block_file(error_code& __ec) const noexcept {
2391*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::block;
2392*4d6fc14bSjoerg  }
2393*4d6fc14bSjoerg
2394*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2395*4d6fc14bSjoerg  bool is_character_file() const { return __get_ft() == file_type::character; }
2396*4d6fc14bSjoerg
2397*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2398*4d6fc14bSjoerg  bool is_character_file(error_code& __ec) const noexcept {
2399*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::character;
2400*4d6fc14bSjoerg  }
2401*4d6fc14bSjoerg
2402*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2403*4d6fc14bSjoerg  bool is_directory() const { return __get_ft() == file_type::directory; }
2404*4d6fc14bSjoerg
2405*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2406*4d6fc14bSjoerg  bool is_directory(error_code& __ec) const noexcept {
2407*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::directory;
2408*4d6fc14bSjoerg  }
2409*4d6fc14bSjoerg
2410*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2411*4d6fc14bSjoerg  bool is_fifo() const { return __get_ft() == file_type::fifo; }
2412*4d6fc14bSjoerg
2413*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2414*4d6fc14bSjoerg  bool is_fifo(error_code& __ec) const noexcept {
2415*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::fifo;
2416*4d6fc14bSjoerg  }
2417*4d6fc14bSjoerg
2418*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2419*4d6fc14bSjoerg  bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
2420*4d6fc14bSjoerg
2421*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2422*4d6fc14bSjoerg  bool is_other(error_code& __ec) const noexcept {
2423*4d6fc14bSjoerg    return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2424*4d6fc14bSjoerg  }
2425*4d6fc14bSjoerg
2426*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2427*4d6fc14bSjoerg  bool is_regular_file() const { return __get_ft() == file_type::regular; }
2428*4d6fc14bSjoerg
2429*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2430*4d6fc14bSjoerg  bool is_regular_file(error_code& __ec) const noexcept {
2431*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::regular;
2432*4d6fc14bSjoerg  }
2433*4d6fc14bSjoerg
2434*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2435*4d6fc14bSjoerg  bool is_socket() const { return __get_ft() == file_type::socket; }
2436*4d6fc14bSjoerg
2437*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2438*4d6fc14bSjoerg  bool is_socket(error_code& __ec) const noexcept {
2439*4d6fc14bSjoerg    return __get_ft(&__ec) == file_type::socket;
2440*4d6fc14bSjoerg  }
2441*4d6fc14bSjoerg
2442*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2443*4d6fc14bSjoerg  bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
2444*4d6fc14bSjoerg
2445*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2446*4d6fc14bSjoerg  bool is_symlink(error_code& __ec) const noexcept {
2447*4d6fc14bSjoerg    return __get_sym_ft(&__ec) == file_type::symlink;
2448*4d6fc14bSjoerg  }
2449*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2450*4d6fc14bSjoerg  uintmax_t file_size() const { return __get_size(); }
2451*4d6fc14bSjoerg
2452*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2453*4d6fc14bSjoerg  uintmax_t file_size(error_code& __ec) const noexcept {
2454*4d6fc14bSjoerg    return __get_size(&__ec);
2455*4d6fc14bSjoerg  }
2456*4d6fc14bSjoerg
2457*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2458*4d6fc14bSjoerg  uintmax_t hard_link_count() const { return __get_nlink(); }
2459*4d6fc14bSjoerg
2460*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2461*4d6fc14bSjoerg  uintmax_t hard_link_count(error_code& __ec) const noexcept {
2462*4d6fc14bSjoerg    return __get_nlink(&__ec);
2463*4d6fc14bSjoerg  }
2464*4d6fc14bSjoerg
2465*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2466*4d6fc14bSjoerg  file_time_type last_write_time() const { return __get_write_time(); }
2467*4d6fc14bSjoerg
2468*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2469*4d6fc14bSjoerg  file_time_type last_write_time(error_code& __ec) const noexcept {
2470*4d6fc14bSjoerg    return __get_write_time(&__ec);
2471*4d6fc14bSjoerg  }
2472*4d6fc14bSjoerg
2473*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2474*4d6fc14bSjoerg  file_status status() const { return __get_status(); }
2475*4d6fc14bSjoerg
2476*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2477*4d6fc14bSjoerg  file_status status(error_code& __ec) const noexcept {
2478*4d6fc14bSjoerg    return __get_status(&__ec);
2479*4d6fc14bSjoerg  }
2480*4d6fc14bSjoerg
2481*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2482*4d6fc14bSjoerg  file_status symlink_status() const { return __get_symlink_status(); }
2483*4d6fc14bSjoerg
2484*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2485*4d6fc14bSjoerg  file_status symlink_status(error_code& __ec) const noexcept {
2486*4d6fc14bSjoerg    return __get_symlink_status(&__ec);
2487*4d6fc14bSjoerg  }
2488*4d6fc14bSjoerg
2489*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2490*4d6fc14bSjoerg  bool operator<(directory_entry const& __rhs) const noexcept {
2491*4d6fc14bSjoerg    return __p_ < __rhs.__p_;
2492*4d6fc14bSjoerg  }
2493*4d6fc14bSjoerg
2494*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2495*4d6fc14bSjoerg  bool operator==(directory_entry const& __rhs) const noexcept {
2496*4d6fc14bSjoerg    return __p_ == __rhs.__p_;
2497*4d6fc14bSjoerg  }
2498*4d6fc14bSjoerg
2499*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2500*4d6fc14bSjoerg  bool operator!=(directory_entry const& __rhs) const noexcept {
2501*4d6fc14bSjoerg    return __p_ != __rhs.__p_;
2502*4d6fc14bSjoerg  }
2503*4d6fc14bSjoerg
2504*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2505*4d6fc14bSjoerg  bool operator<=(directory_entry const& __rhs) const noexcept {
2506*4d6fc14bSjoerg    return __p_ <= __rhs.__p_;
2507*4d6fc14bSjoerg  }
2508*4d6fc14bSjoerg
2509*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2510*4d6fc14bSjoerg  bool operator>(directory_entry const& __rhs) const noexcept {
2511*4d6fc14bSjoerg    return __p_ > __rhs.__p_;
2512*4d6fc14bSjoerg  }
2513*4d6fc14bSjoerg
2514*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2515*4d6fc14bSjoerg  bool operator>=(directory_entry const& __rhs) const noexcept {
2516*4d6fc14bSjoerg    return __p_ >= __rhs.__p_;
2517*4d6fc14bSjoerg  }
2518*4d6fc14bSjoerg
2519*4d6fc14bSjoergprivate:
2520*4d6fc14bSjoerg  friend class directory_iterator;
2521*4d6fc14bSjoerg  friend class recursive_directory_iterator;
2522*4d6fc14bSjoerg  friend class __dir_stream;
2523*4d6fc14bSjoerg
2524*4d6fc14bSjoerg  enum _CacheType : unsigned char {
2525*4d6fc14bSjoerg    _Empty,
2526*4d6fc14bSjoerg    _IterSymlink,
2527*4d6fc14bSjoerg    _IterNonSymlink,
2528*4d6fc14bSjoerg    _RefreshSymlink,
2529*4d6fc14bSjoerg    _RefreshSymlinkUnresolved,
2530*4d6fc14bSjoerg    _RefreshNonSymlink
2531*4d6fc14bSjoerg  };
2532*4d6fc14bSjoerg
2533*4d6fc14bSjoerg  struct __cached_data {
2534*4d6fc14bSjoerg    uintmax_t __size_;
2535*4d6fc14bSjoerg    uintmax_t __nlink_;
2536*4d6fc14bSjoerg    file_time_type __write_time_;
2537*4d6fc14bSjoerg    perms __sym_perms_;
2538*4d6fc14bSjoerg    perms __non_sym_perms_;
2539*4d6fc14bSjoerg    file_type __type_;
2540*4d6fc14bSjoerg    _CacheType __cache_type_;
2541*4d6fc14bSjoerg
2542*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
2543*4d6fc14bSjoerg    __cached_data() noexcept { __reset(); }
2544*4d6fc14bSjoerg
2545*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
2546*4d6fc14bSjoerg    void __reset() {
2547*4d6fc14bSjoerg      __cache_type_ = _Empty;
2548*4d6fc14bSjoerg      __type_ = file_type::none;
2549*4d6fc14bSjoerg      __sym_perms_ = __non_sym_perms_ = perms::unknown;
2550*4d6fc14bSjoerg      __size_ = __nlink_ = uintmax_t(-1);
2551*4d6fc14bSjoerg      __write_time_ = file_time_type::min();
2552*4d6fc14bSjoerg    }
2553*4d6fc14bSjoerg  };
2554*4d6fc14bSjoerg
2555*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2556*4d6fc14bSjoerg  static __cached_data __create_iter_result(file_type __ft) {
2557*4d6fc14bSjoerg    __cached_data __data;
2558*4d6fc14bSjoerg    __data.__type_ = __ft;
2559*4d6fc14bSjoerg    __data.__cache_type_ = [&]() {
2560*4d6fc14bSjoerg      switch (__ft) {
2561*4d6fc14bSjoerg      case file_type::none:
2562*4d6fc14bSjoerg        return _Empty;
2563*4d6fc14bSjoerg      case file_type::symlink:
2564*4d6fc14bSjoerg        return _IterSymlink;
2565*4d6fc14bSjoerg      default:
2566*4d6fc14bSjoerg        return _IterNonSymlink;
2567*4d6fc14bSjoerg      }
2568*4d6fc14bSjoerg    }();
2569*4d6fc14bSjoerg    return __data;
2570*4d6fc14bSjoerg  }
2571*4d6fc14bSjoerg
2572*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2573*4d6fc14bSjoerg  void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2574*4d6fc14bSjoerg    __p_ = _VSTD::move(__p);
2575*4d6fc14bSjoerg    __data_ = __dt;
2576*4d6fc14bSjoerg  }
2577*4d6fc14bSjoerg
2578*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2579*4d6fc14bSjoerg  error_code __do_refresh() noexcept;
2580*4d6fc14bSjoerg
2581*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2582*4d6fc14bSjoerg  static bool __is_dne_error(error_code const& __ec) {
2583*4d6fc14bSjoerg    if (!__ec)
2584*4d6fc14bSjoerg      return true;
2585*4d6fc14bSjoerg    switch (static_cast<errc>(__ec.value())) {
2586*4d6fc14bSjoerg    case errc::no_such_file_or_directory:
2587*4d6fc14bSjoerg    case errc::not_a_directory:
2588*4d6fc14bSjoerg      return true;
2589*4d6fc14bSjoerg    default:
2590*4d6fc14bSjoerg      return false;
2591*4d6fc14bSjoerg    }
2592*4d6fc14bSjoerg  }
2593*4d6fc14bSjoerg
2594*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2595*4d6fc14bSjoerg  void __handle_error(const char* __msg, error_code* __dest_ec,
2596*4d6fc14bSjoerg                      error_code const& __ec, bool __allow_dne = false) const {
2597*4d6fc14bSjoerg    if (__dest_ec) {
2598*4d6fc14bSjoerg      *__dest_ec = __ec;
2599*4d6fc14bSjoerg      return;
2600*4d6fc14bSjoerg    }
2601*4d6fc14bSjoerg    if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2602*4d6fc14bSjoerg      __throw_filesystem_error(__msg, __p_, __ec);
2603*4d6fc14bSjoerg  }
2604*4d6fc14bSjoerg
2605*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2606*4d6fc14bSjoerg  void __refresh(error_code* __ec = nullptr) {
2607*4d6fc14bSjoerg    __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2608*4d6fc14bSjoerg                   /*allow_dne*/ true);
2609*4d6fc14bSjoerg  }
2610*4d6fc14bSjoerg
2611*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2612*4d6fc14bSjoerg  file_type __get_sym_ft(error_code* __ec = nullptr) const {
2613*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2614*4d6fc14bSjoerg    case _Empty:
2615*4d6fc14bSjoerg      return __symlink_status(__p_, __ec).type();
2616*4d6fc14bSjoerg    case _IterSymlink:
2617*4d6fc14bSjoerg    case _RefreshSymlink:
2618*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2619*4d6fc14bSjoerg      if (__ec)
2620*4d6fc14bSjoerg        __ec->clear();
2621*4d6fc14bSjoerg      return file_type::symlink;
2622*4d6fc14bSjoerg    case _IterNonSymlink:
2623*4d6fc14bSjoerg    case _RefreshNonSymlink:
2624*4d6fc14bSjoerg      file_status __st(__data_.__type_);
2625*4d6fc14bSjoerg      if (__ec && !_VSTD_FS::exists(__st))
2626*4d6fc14bSjoerg        *__ec = make_error_code(errc::no_such_file_or_directory);
2627*4d6fc14bSjoerg      else if (__ec)
2628*4d6fc14bSjoerg        __ec->clear();
2629*4d6fc14bSjoerg      return __data_.__type_;
2630*4d6fc14bSjoerg    }
2631*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2632*4d6fc14bSjoerg  }
2633*4d6fc14bSjoerg
2634*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2635*4d6fc14bSjoerg  file_type __get_ft(error_code* __ec = nullptr) const {
2636*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2637*4d6fc14bSjoerg    case _Empty:
2638*4d6fc14bSjoerg    case _IterSymlink:
2639*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2640*4d6fc14bSjoerg      return __status(__p_, __ec).type();
2641*4d6fc14bSjoerg    case _IterNonSymlink:
2642*4d6fc14bSjoerg    case _RefreshNonSymlink:
2643*4d6fc14bSjoerg    case _RefreshSymlink: {
2644*4d6fc14bSjoerg      file_status __st(__data_.__type_);
2645*4d6fc14bSjoerg      if (__ec && !_VSTD_FS::exists(__st))
2646*4d6fc14bSjoerg        *__ec = make_error_code(errc::no_such_file_or_directory);
2647*4d6fc14bSjoerg      else if (__ec)
2648*4d6fc14bSjoerg        __ec->clear();
2649*4d6fc14bSjoerg      return __data_.__type_;
2650*4d6fc14bSjoerg    }
2651*4d6fc14bSjoerg    }
2652*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2653*4d6fc14bSjoerg  }
2654*4d6fc14bSjoerg
2655*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2656*4d6fc14bSjoerg  file_status __get_status(error_code* __ec = nullptr) const {
2657*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2658*4d6fc14bSjoerg    case _Empty:
2659*4d6fc14bSjoerg    case _IterNonSymlink:
2660*4d6fc14bSjoerg    case _IterSymlink:
2661*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2662*4d6fc14bSjoerg      return __status(__p_, __ec);
2663*4d6fc14bSjoerg    case _RefreshNonSymlink:
2664*4d6fc14bSjoerg    case _RefreshSymlink:
2665*4d6fc14bSjoerg      return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2666*4d6fc14bSjoerg    }
2667*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2668*4d6fc14bSjoerg  }
2669*4d6fc14bSjoerg
2670*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2671*4d6fc14bSjoerg  file_status __get_symlink_status(error_code* __ec = nullptr) const {
2672*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2673*4d6fc14bSjoerg    case _Empty:
2674*4d6fc14bSjoerg    case _IterNonSymlink:
2675*4d6fc14bSjoerg    case _IterSymlink:
2676*4d6fc14bSjoerg      return __symlink_status(__p_, __ec);
2677*4d6fc14bSjoerg    case _RefreshNonSymlink:
2678*4d6fc14bSjoerg      return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2679*4d6fc14bSjoerg    case _RefreshSymlink:
2680*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2681*4d6fc14bSjoerg      return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2682*4d6fc14bSjoerg    }
2683*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2684*4d6fc14bSjoerg  }
2685*4d6fc14bSjoerg
2686*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2687*4d6fc14bSjoerg  uintmax_t __get_size(error_code* __ec = nullptr) const {
2688*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2689*4d6fc14bSjoerg    case _Empty:
2690*4d6fc14bSjoerg    case _IterNonSymlink:
2691*4d6fc14bSjoerg    case _IterSymlink:
2692*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2693*4d6fc14bSjoerg      return _VSTD_FS::__file_size(__p_, __ec);
2694*4d6fc14bSjoerg    case _RefreshSymlink:
2695*4d6fc14bSjoerg    case _RefreshNonSymlink: {
2696*4d6fc14bSjoerg      error_code __m_ec;
2697*4d6fc14bSjoerg      file_status __st(__get_ft(&__m_ec));
2698*4d6fc14bSjoerg      __handle_error("in directory_entry::file_size", __ec, __m_ec);
2699*4d6fc14bSjoerg      if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2700*4d6fc14bSjoerg        errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2701*4d6fc14bSjoerg                                                       : errc::not_supported;
2702*4d6fc14bSjoerg        __handle_error("in directory_entry::file_size", __ec,
2703*4d6fc14bSjoerg                       make_error_code(__err_kind));
2704*4d6fc14bSjoerg      }
2705*4d6fc14bSjoerg      return __data_.__size_;
2706*4d6fc14bSjoerg    }
2707*4d6fc14bSjoerg    }
2708*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2709*4d6fc14bSjoerg  }
2710*4d6fc14bSjoerg
2711*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2712*4d6fc14bSjoerg  uintmax_t __get_nlink(error_code* __ec = nullptr) const {
2713*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2714*4d6fc14bSjoerg    case _Empty:
2715*4d6fc14bSjoerg    case _IterNonSymlink:
2716*4d6fc14bSjoerg    case _IterSymlink:
2717*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2718*4d6fc14bSjoerg      return _VSTD_FS::__hard_link_count(__p_, __ec);
2719*4d6fc14bSjoerg    case _RefreshSymlink:
2720*4d6fc14bSjoerg    case _RefreshNonSymlink: {
2721*4d6fc14bSjoerg      error_code __m_ec;
2722*4d6fc14bSjoerg      (void)__get_ft(&__m_ec);
2723*4d6fc14bSjoerg      __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
2724*4d6fc14bSjoerg      return __data_.__nlink_;
2725*4d6fc14bSjoerg    }
2726*4d6fc14bSjoerg    }
2727*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2728*4d6fc14bSjoerg  }
2729*4d6fc14bSjoerg
2730*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2731*4d6fc14bSjoerg  file_time_type __get_write_time(error_code* __ec = nullptr) const {
2732*4d6fc14bSjoerg    switch (__data_.__cache_type_) {
2733*4d6fc14bSjoerg    case _Empty:
2734*4d6fc14bSjoerg    case _IterNonSymlink:
2735*4d6fc14bSjoerg    case _IterSymlink:
2736*4d6fc14bSjoerg    case _RefreshSymlinkUnresolved:
2737*4d6fc14bSjoerg      return _VSTD_FS::__last_write_time(__p_, __ec);
2738*4d6fc14bSjoerg    case _RefreshSymlink:
2739*4d6fc14bSjoerg    case _RefreshNonSymlink: {
2740*4d6fc14bSjoerg      error_code __m_ec;
2741*4d6fc14bSjoerg      file_status __st(__get_ft(&__m_ec));
2742*4d6fc14bSjoerg      __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
2743*4d6fc14bSjoerg      if (_VSTD_FS::exists(__st) &&
2744*4d6fc14bSjoerg          __data_.__write_time_ == file_time_type::min())
2745*4d6fc14bSjoerg        __handle_error("in directory_entry::last_write_time", __ec,
2746*4d6fc14bSjoerg                       make_error_code(errc::value_too_large));
2747*4d6fc14bSjoerg      return __data_.__write_time_;
2748*4d6fc14bSjoerg    }
2749*4d6fc14bSjoerg    }
2750*4d6fc14bSjoerg    _LIBCPP_UNREACHABLE();
2751*4d6fc14bSjoerg  }
2752*4d6fc14bSjoerg
2753*4d6fc14bSjoergprivate:
2754*4d6fc14bSjoerg  _Path __p_;
2755*4d6fc14bSjoerg  __cached_data __data_;
2756*4d6fc14bSjoerg};
2757*4d6fc14bSjoerg
2758*4d6fc14bSjoergclass __dir_element_proxy {
2759*4d6fc14bSjoergpublic:
2760*4d6fc14bSjoerg  inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
2761*4d6fc14bSjoerg    return _VSTD::move(__elem_);
2762*4d6fc14bSjoerg  }
2763*4d6fc14bSjoerg
2764*4d6fc14bSjoergprivate:
2765*4d6fc14bSjoerg  friend class directory_iterator;
2766*4d6fc14bSjoerg  friend class recursive_directory_iterator;
2767*4d6fc14bSjoerg  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2768*4d6fc14bSjoerg  __dir_element_proxy(__dir_element_proxy&& __o)
2769*4d6fc14bSjoerg      : __elem_(_VSTD::move(__o.__elem_)) {}
2770*4d6fc14bSjoerg  directory_entry __elem_;
2771*4d6fc14bSjoerg};
2772*4d6fc14bSjoerg
2773*4d6fc14bSjoergclass directory_iterator {
2774*4d6fc14bSjoergpublic:
2775*4d6fc14bSjoerg  typedef directory_entry value_type;
2776*4d6fc14bSjoerg  typedef ptrdiff_t difference_type;
2777*4d6fc14bSjoerg  typedef value_type const* pointer;
2778*4d6fc14bSjoerg  typedef value_type const& reference;
2779*4d6fc14bSjoerg  typedef input_iterator_tag iterator_category;
2780*4d6fc14bSjoerg
2781*4d6fc14bSjoergpublic:
2782*4d6fc14bSjoerg  //ctor & dtor
2783*4d6fc14bSjoerg  directory_iterator() noexcept {}
2784*4d6fc14bSjoerg
2785*4d6fc14bSjoerg  explicit directory_iterator(const path& __p)
2786*4d6fc14bSjoerg      : directory_iterator(__p, nullptr) {}
2787*4d6fc14bSjoerg
2788*4d6fc14bSjoerg  directory_iterator(const path& __p, directory_options __opts)
2789*4d6fc14bSjoerg      : directory_iterator(__p, nullptr, __opts) {}
2790*4d6fc14bSjoerg
2791*4d6fc14bSjoerg  directory_iterator(const path& __p, error_code& __ec)
2792*4d6fc14bSjoerg      : directory_iterator(__p, &__ec) {}
2793*4d6fc14bSjoerg
2794*4d6fc14bSjoerg  directory_iterator(const path& __p, directory_options __opts,
2795*4d6fc14bSjoerg                     error_code& __ec)
2796*4d6fc14bSjoerg      : directory_iterator(__p, &__ec, __opts) {}
2797*4d6fc14bSjoerg
2798*4d6fc14bSjoerg  directory_iterator(const directory_iterator&) = default;
2799*4d6fc14bSjoerg  directory_iterator(directory_iterator&&) = default;
2800*4d6fc14bSjoerg  directory_iterator& operator=(const directory_iterator&) = default;
2801*4d6fc14bSjoerg
2802*4d6fc14bSjoerg  directory_iterator& operator=(directory_iterator&& __o) noexcept {
2803*4d6fc14bSjoerg    // non-default implementation provided to support self-move assign.
2804*4d6fc14bSjoerg    if (this != &__o) {
2805*4d6fc14bSjoerg      __imp_ = _VSTD::move(__o.__imp_);
2806*4d6fc14bSjoerg    }
2807*4d6fc14bSjoerg    return *this;
2808*4d6fc14bSjoerg  }
2809*4d6fc14bSjoerg
2810*4d6fc14bSjoerg  ~directory_iterator() = default;
2811*4d6fc14bSjoerg
2812*4d6fc14bSjoerg  const directory_entry& operator*() const {
2813*4d6fc14bSjoerg    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
2814*4d6fc14bSjoerg    return __dereference();
2815*4d6fc14bSjoerg  }
2816*4d6fc14bSjoerg
2817*4d6fc14bSjoerg  const directory_entry* operator->() const { return &**this; }
2818*4d6fc14bSjoerg
2819*4d6fc14bSjoerg  directory_iterator& operator++() { return __increment(); }
2820*4d6fc14bSjoerg
2821*4d6fc14bSjoerg  __dir_element_proxy operator++(int) {
2822*4d6fc14bSjoerg    __dir_element_proxy __p(**this);
2823*4d6fc14bSjoerg    __increment();
2824*4d6fc14bSjoerg    return __p;
2825*4d6fc14bSjoerg  }
2826*4d6fc14bSjoerg
2827*4d6fc14bSjoerg  directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
2828*4d6fc14bSjoerg
2829*4d6fc14bSjoergprivate:
2830*4d6fc14bSjoerg  inline _LIBCPP_INLINE_VISIBILITY friend bool
2831*4d6fc14bSjoerg  operator==(const directory_iterator& __lhs,
2832*4d6fc14bSjoerg             const directory_iterator& __rhs) noexcept;
2833*4d6fc14bSjoerg
2834*4d6fc14bSjoerg  // construct the dir_stream
2835*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2836*4d6fc14bSjoerg  directory_iterator(const path&, error_code*,
2837*4d6fc14bSjoerg                     directory_options = directory_options::none);
2838*4d6fc14bSjoerg
2839*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2840*4d6fc14bSjoerg  directory_iterator& __increment(error_code* __ec = nullptr);
2841*4d6fc14bSjoerg
2842*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2843*4d6fc14bSjoerg  const directory_entry& __dereference() const;
2844*4d6fc14bSjoerg
2845*4d6fc14bSjoergprivate:
2846*4d6fc14bSjoerg  shared_ptr<__dir_stream> __imp_;
2847*4d6fc14bSjoerg};
2848*4d6fc14bSjoerg
2849*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2850*4d6fc14bSjoergoperator==(const directory_iterator& __lhs,
2851*4d6fc14bSjoerg           const directory_iterator& __rhs) noexcept {
2852*4d6fc14bSjoerg  return __lhs.__imp_ == __rhs.__imp_;
2853*4d6fc14bSjoerg}
2854*4d6fc14bSjoerg
2855*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2856*4d6fc14bSjoergoperator!=(const directory_iterator& __lhs,
2857*4d6fc14bSjoerg           const directory_iterator& __rhs) noexcept {
2858*4d6fc14bSjoerg  return !(__lhs == __rhs);
2859*4d6fc14bSjoerg}
2860*4d6fc14bSjoerg
2861*4d6fc14bSjoerg// enable directory_iterator range-based for statements
2862*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY directory_iterator
2863*4d6fc14bSjoergbegin(directory_iterator __iter) noexcept {
2864*4d6fc14bSjoerg  return __iter;
2865*4d6fc14bSjoerg}
2866*4d6fc14bSjoerg
2867*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY directory_iterator
2868*4d6fc14bSjoergend(const directory_iterator&) noexcept {
2869*4d6fc14bSjoerg  return directory_iterator();
2870*4d6fc14bSjoerg}
2871*4d6fc14bSjoerg
2872*4d6fc14bSjoergclass recursive_directory_iterator {
2873*4d6fc14bSjoergpublic:
2874*4d6fc14bSjoerg  using value_type = directory_entry;
2875*4d6fc14bSjoerg  using difference_type = ptrdiff_t;
2876*4d6fc14bSjoerg  using pointer = directory_entry const*;
2877*4d6fc14bSjoerg  using reference = directory_entry const&;
2878*4d6fc14bSjoerg  using iterator_category = input_iterator_tag;
2879*4d6fc14bSjoerg
2880*4d6fc14bSjoergpublic:
2881*4d6fc14bSjoerg  // constructors and destructor
2882*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2883*4d6fc14bSjoerg  recursive_directory_iterator() noexcept : __rec_(false) {}
2884*4d6fc14bSjoerg
2885*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2886*4d6fc14bSjoerg  explicit recursive_directory_iterator(
2887*4d6fc14bSjoerg      const path& __p, directory_options __xoptions = directory_options::none)
2888*4d6fc14bSjoerg      : recursive_directory_iterator(__p, __xoptions, nullptr) {}
2889*4d6fc14bSjoerg
2890*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2891*4d6fc14bSjoerg  recursive_directory_iterator(const path& __p, directory_options __xoptions,
2892*4d6fc14bSjoerg                               error_code& __ec)
2893*4d6fc14bSjoerg      : recursive_directory_iterator(__p, __xoptions, &__ec) {}
2894*4d6fc14bSjoerg
2895*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2896*4d6fc14bSjoerg  recursive_directory_iterator(const path& __p, error_code& __ec)
2897*4d6fc14bSjoerg      : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
2898*4d6fc14bSjoerg
2899*4d6fc14bSjoerg  recursive_directory_iterator(const recursive_directory_iterator&) = default;
2900*4d6fc14bSjoerg  recursive_directory_iterator(recursive_directory_iterator&&) = default;
2901*4d6fc14bSjoerg
2902*4d6fc14bSjoerg  recursive_directory_iterator&
2903*4d6fc14bSjoerg  operator=(const recursive_directory_iterator&) = default;
2904*4d6fc14bSjoerg
2905*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2906*4d6fc14bSjoerg  recursive_directory_iterator&
2907*4d6fc14bSjoerg  operator=(recursive_directory_iterator&& __o) noexcept {
2908*4d6fc14bSjoerg    // non-default implementation provided to support self-move assign.
2909*4d6fc14bSjoerg    if (this != &__o) {
2910*4d6fc14bSjoerg      __imp_ = _VSTD::move(__o.__imp_);
2911*4d6fc14bSjoerg      __rec_ = __o.__rec_;
2912*4d6fc14bSjoerg    }
2913*4d6fc14bSjoerg    return *this;
2914*4d6fc14bSjoerg  }
2915*4d6fc14bSjoerg
2916*4d6fc14bSjoerg  ~recursive_directory_iterator() = default;
2917*4d6fc14bSjoerg
2918*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2919*4d6fc14bSjoerg  const directory_entry& operator*() const { return __dereference(); }
2920*4d6fc14bSjoerg
2921*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2922*4d6fc14bSjoerg  const directory_entry* operator->() const { return &__dereference(); }
2923*4d6fc14bSjoerg
2924*4d6fc14bSjoerg  recursive_directory_iterator& operator++() { return __increment(); }
2925*4d6fc14bSjoerg
2926*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2927*4d6fc14bSjoerg  __dir_element_proxy operator++(int) {
2928*4d6fc14bSjoerg    __dir_element_proxy __p(**this);
2929*4d6fc14bSjoerg    __increment();
2930*4d6fc14bSjoerg    return __p;
2931*4d6fc14bSjoerg  }
2932*4d6fc14bSjoerg
2933*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2934*4d6fc14bSjoerg  recursive_directory_iterator& increment(error_code& __ec) {
2935*4d6fc14bSjoerg    return __increment(&__ec);
2936*4d6fc14bSjoerg  }
2937*4d6fc14bSjoerg
2938*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS directory_options options() const;
2939*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS int depth() const;
2940*4d6fc14bSjoerg
2941*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2942*4d6fc14bSjoerg  void pop() { __pop(); }
2943*4d6fc14bSjoerg
2944*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2945*4d6fc14bSjoerg  void pop(error_code& __ec) { __pop(&__ec); }
2946*4d6fc14bSjoerg
2947*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2948*4d6fc14bSjoerg  bool recursion_pending() const { return __rec_; }
2949*4d6fc14bSjoerg
2950*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
2951*4d6fc14bSjoerg  void disable_recursion_pending() { __rec_ = false; }
2952*4d6fc14bSjoerg
2953*4d6fc14bSjoergprivate:
2954*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2955*4d6fc14bSjoerg  recursive_directory_iterator(const path& __p, directory_options __opt,
2956*4d6fc14bSjoerg                               error_code* __ec);
2957*4d6fc14bSjoerg
2958*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2959*4d6fc14bSjoerg  const directory_entry& __dereference() const;
2960*4d6fc14bSjoerg
2961*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2962*4d6fc14bSjoerg  bool __try_recursion(error_code* __ec);
2963*4d6fc14bSjoerg
2964*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2965*4d6fc14bSjoerg  void __advance(error_code* __ec = nullptr);
2966*4d6fc14bSjoerg
2967*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2968*4d6fc14bSjoerg  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
2969*4d6fc14bSjoerg
2970*4d6fc14bSjoerg  _LIBCPP_FUNC_VIS
2971*4d6fc14bSjoerg  void __pop(error_code* __ec = nullptr);
2972*4d6fc14bSjoerg
2973*4d6fc14bSjoerg  inline _LIBCPP_INLINE_VISIBILITY friend bool
2974*4d6fc14bSjoerg  operator==(const recursive_directory_iterator&,
2975*4d6fc14bSjoerg             const recursive_directory_iterator&) noexcept;
2976*4d6fc14bSjoerg
2977*4d6fc14bSjoerg  struct _LIBCPP_HIDDEN __shared_imp;
2978*4d6fc14bSjoerg  shared_ptr<__shared_imp> __imp_;
2979*4d6fc14bSjoerg  bool __rec_;
2980*4d6fc14bSjoerg}; // class recursive_directory_iterator
2981*4d6fc14bSjoerg
2982*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY bool
2983*4d6fc14bSjoergoperator==(const recursive_directory_iterator& __lhs,
2984*4d6fc14bSjoerg           const recursive_directory_iterator& __rhs) noexcept {
2985*4d6fc14bSjoerg  return __lhs.__imp_ == __rhs.__imp_;
2986*4d6fc14bSjoerg}
2987*4d6fc14bSjoerg
2988*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2989*4d6fc14bSjoerginline bool operator!=(const recursive_directory_iterator& __lhs,
2990*4d6fc14bSjoerg                       const recursive_directory_iterator& __rhs) noexcept {
2991*4d6fc14bSjoerg  return !(__lhs == __rhs);
2992*4d6fc14bSjoerg}
2993*4d6fc14bSjoerg// enable recursive_directory_iterator range-based for statements
2994*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2995*4d6fc14bSjoergbegin(recursive_directory_iterator __iter) noexcept {
2996*4d6fc14bSjoerg  return __iter;
2997*4d6fc14bSjoerg}
2998*4d6fc14bSjoerg
2999*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
3000*4d6fc14bSjoergend(const recursive_directory_iterator&) noexcept {
3001*4d6fc14bSjoerg  return recursive_directory_iterator();
3002*4d6fc14bSjoerg}
3003*4d6fc14bSjoerg
3004*4d6fc14bSjoerg_LIBCPP_AVAILABILITY_FILESYSTEM_POP
3005*4d6fc14bSjoerg
3006*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_FILESYSTEM
3007*4d6fc14bSjoerg
3008*4d6fc14bSjoerg#endif // !_LIBCPP_CXX03_LANG
3009*4d6fc14bSjoerg
3010*4d6fc14bSjoerg_LIBCPP_POP_MACROS
3011*4d6fc14bSjoerg
3012*4d6fc14bSjoerg#endif // _LIBCPP_FILESYSTEM
3013