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