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