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