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