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