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