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