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