2 //===--------------------------- filesystem -------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_FILESYSTEM
11 #define _LIBCPP_FILESYSTEM
15 namespace std { namespace filesystem {
19 void swap(path& lhs, path& rhs) noexcept;
20 size_t hash_value(const path& p) noexcept;
22 bool operator==(const path& lhs, const path& rhs) noexcept;
23 bool operator!=(const path& lhs, const path& rhs) noexcept;
24 bool operator< (const path& lhs, const path& rhs) noexcept;
25 bool operator<=(const path& lhs, const path& rhs) noexcept;
26 bool operator> (const path& lhs, const path& rhs) noexcept;
27 bool operator>=(const path& lhs, const path& rhs) noexcept;
29 path operator/ (const path& lhs, const path& rhs);
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);
36 template <class charT, class traits>
37 friend basic_istream<charT, traits>&
38 operator>>(basic_istream<charT, traits>& is, path& p);
40 template <class Source>
41 path u8path(const Source& source);
42 template <class InputIterator>
43 path u8path(InputIterator first, InputIterator last);
45 class filesystem_error;
46 class directory_entry;
48 class directory_iterator;
50 // enable directory_iterator range-based for statements
51 directory_iterator begin(directory_iterator iter) noexcept;
52 directory_iterator end(const directory_iterator&) noexcept;
54 class recursive_directory_iterator;
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;
71 enum class perm_options;
72 enum class copy_options;
73 enum class directory_options;
75 typedef chrono::time_point<trivial-clock> file_time_type;
77 // operational functions
79 path absolute(const path& p);
80 path absolute(const path& p, error_code &ec);
82 path canonical(const path& p);
83 path canonical(const path& p, error_code& ec);
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,
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,
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;
101 bool create_directories(const path& p);
102 bool create_directories(const path& p, error_code& ec);
104 bool create_directory(const path& p);
105 bool create_directory(const path& p, error_code& ec) noexcept;
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;
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;
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;
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;
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;
128 bool exists(file_status s) noexcept;
129 bool exists(const path& p);
130 bool exists(const path& p, error_code& ec) noexcept;
132 bool equivalent(const path& p1, const path& p2);
133 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
135 uintmax_t file_size(const path& p);
136 uintmax_t file_size(const path& p, error_code& ec) noexcept;
138 uintmax_t hard_link_count(const path& p);
139 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
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;
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;
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;
153 bool is_empty(const path& p);
154 bool is_empty(const path& p, error_code& ec) noexcept;
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;
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;
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;
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;
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;
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;
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,
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);
192 path read_symlink(const path& p);
193 path read_symlink(const path& p, error_code& ec);
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);
199 bool remove(const path& p);
200 bool remove(const path& p, error_code& ec) noexcept;
202 uintmax_t remove_all(const path& p);
203 uintmax_t remove_all(const path& p, error_code& ec);
205 void rename(const path& from, const path& to);
206 void rename(const path& from, const path& to, error_code& ec) noexcept;
208 void resize_file(const path& p, uintmax_t size);
209 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
211 space_info space(const path& p);
212 space_info space(const path& p, error_code& ec) noexcept;
214 file_status status(const path& p);
215 file_status status(const path& p, error_code& ec) noexcept;
217 bool status_known(file_status s) noexcept;
219 file_status symlink_status(const path& p);
220 file_status symlink_status(const path& p, error_code& ec) noexcept;
222 path temp_directory_path();
223 path temp_directory_path(error_code& ec);
225 path weakly_canonical(path const& p);
226 path weakly_canonical(path const& p, error_code& ec);
229 } } // namespaces std::filesystem
243 #include <system_error>
245 #include <iomanip> // for quoted
246 #include <string_view>
250 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
251 #pragma GCC system_header
255 #include <__undef_macros>
257 #ifndef _LIBCPP_CXX03_LANG
259 #if _LIBCPP_STD_VER >= 17
260 #define __cpp_lib_filesystem 201703
263 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
265 struct _FilesystemClock {
266 #if !defined(_LIBCPP_HAS_NO_INT128)
267 typedef __int128_t rep;
270 typedef long long rep;
274 typedef chrono::duration<rep, period> duration;
275 typedef chrono::time_point<_FilesystemClock> time_point;
277 static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
279 _LIBCPP_FUNC_VIS static time_point now() noexcept;
281 _LIBCPP_INLINE_VISIBILITY
282 static time_t to_time_t(const time_point& __t) noexcept {
283 typedef chrono::duration<rep> __secs;
285 chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
288 _LIBCPP_INLINE_VISIBILITY
289 static time_point from_time_t(time_t __t) noexcept {
290 typedef chrono::duration<rep> __secs;
291 return time_point(__secs(__t));
295 typedef chrono::time_point<_FilesystemClock> file_time_type;
297 struct _LIBCPP_TYPE_VIS space_info {
303 enum class _LIBCPP_ENUM_VIS file_type : signed char {
316 enum class _LIBCPP_ENUM_VIS perms : unsigned {
343 _LIBCPP_INLINE_VISIBILITY
344 inline constexpr perms operator&(perms _LHS, perms _RHS) {
345 return static_cast<perms>(static_cast<unsigned>(_LHS) &
346 static_cast<unsigned>(_RHS));
349 _LIBCPP_INLINE_VISIBILITY
350 inline constexpr perms operator|(perms _LHS, perms _RHS) {
351 return static_cast<perms>(static_cast<unsigned>(_LHS) |
352 static_cast<unsigned>(_RHS));
355 _LIBCPP_INLINE_VISIBILITY
356 inline constexpr perms operator^(perms _LHS, perms _RHS) {
357 return static_cast<perms>(static_cast<unsigned>(_LHS) ^
358 static_cast<unsigned>(_RHS));
361 _LIBCPP_INLINE_VISIBILITY
362 inline constexpr perms operator~(perms _LHS) {
363 return static_cast<perms>(~static_cast<unsigned>(_LHS));
366 _LIBCPP_INLINE_VISIBILITY
367 inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
369 _LIBCPP_INLINE_VISIBILITY
370 inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
372 _LIBCPP_INLINE_VISIBILITY
373 inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
375 enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
382 _LIBCPP_INLINE_VISIBILITY
383 inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
384 return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
385 static_cast<unsigned>(_RHS));
388 _LIBCPP_INLINE_VISIBILITY
389 inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
390 return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
391 static_cast<unsigned>(_RHS));
394 _LIBCPP_INLINE_VISIBILITY
395 inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
396 return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
397 static_cast<unsigned>(_RHS));
400 _LIBCPP_INLINE_VISIBILITY
401 inline constexpr perm_options operator~(perm_options _LHS) {
402 return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
405 _LIBCPP_INLINE_VISIBILITY
406 inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
407 return _LHS = _LHS & _RHS;
410 _LIBCPP_INLINE_VISIBILITY
411 inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
412 return _LHS = _LHS | _RHS;
415 _LIBCPP_INLINE_VISIBILITY
416 inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
417 return _LHS = _LHS ^ _RHS;
420 enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
423 overwrite_existing = 2,
428 directories_only = 64,
429 create_symlinks = 128,
430 create_hard_links = 256,
431 __in_recursive_copy = 512,
434 _LIBCPP_INLINE_VISIBILITY
435 inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
436 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
437 static_cast<unsigned short>(_RHS));
440 _LIBCPP_INLINE_VISIBILITY
441 inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
442 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
443 static_cast<unsigned short>(_RHS));
446 _LIBCPP_INLINE_VISIBILITY
447 inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
448 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
449 static_cast<unsigned short>(_RHS));
452 _LIBCPP_INLINE_VISIBILITY
453 inline constexpr copy_options operator~(copy_options _LHS) {
454 return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
457 _LIBCPP_INLINE_VISIBILITY
458 inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
459 return _LHS = _LHS & _RHS;
462 _LIBCPP_INLINE_VISIBILITY
463 inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
464 return _LHS = _LHS | _RHS;
467 _LIBCPP_INLINE_VISIBILITY
468 inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
469 return _LHS = _LHS ^ _RHS;
472 enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
474 follow_directory_symlink = 1,
475 skip_permission_denied = 2
478 _LIBCPP_INLINE_VISIBILITY
479 inline constexpr directory_options operator&(directory_options _LHS,
480 directory_options _RHS) {
481 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
482 static_cast<unsigned char>(_RHS));
485 _LIBCPP_INLINE_VISIBILITY
486 inline constexpr directory_options operator|(directory_options _LHS,
487 directory_options _RHS) {
488 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
489 static_cast<unsigned char>(_RHS));
492 _LIBCPP_INLINE_VISIBILITY
493 inline constexpr directory_options operator^(directory_options _LHS,
494 directory_options _RHS) {
495 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
496 static_cast<unsigned char>(_RHS));
499 _LIBCPP_INLINE_VISIBILITY
500 inline constexpr directory_options operator~(directory_options _LHS) {
501 return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
504 _LIBCPP_INLINE_VISIBILITY
505 inline directory_options& operator&=(directory_options& _LHS,
506 directory_options _RHS) {
507 return _LHS = _LHS & _RHS;
510 _LIBCPP_INLINE_VISIBILITY
511 inline directory_options& operator|=(directory_options& _LHS,
512 directory_options _RHS) {
513 return _LHS = _LHS | _RHS;
516 _LIBCPP_INLINE_VISIBILITY
517 inline directory_options& operator^=(directory_options& _LHS,
518 directory_options _RHS) {
519 return _LHS = _LHS ^ _RHS;
522 class _LIBCPP_TYPE_VIS file_status {
525 _LIBCPP_INLINE_VISIBILITY
526 file_status() noexcept : file_status(file_type::none) {}
527 _LIBCPP_INLINE_VISIBILITY
528 explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
532 file_status(const file_status&) noexcept = default;
533 file_status(file_status&&) noexcept = default;
535 _LIBCPP_INLINE_VISIBILITY
538 file_status& operator=(const file_status&) noexcept = default;
539 file_status& operator=(file_status&&) noexcept = default;
542 _LIBCPP_INLINE_VISIBILITY
543 file_type type() const noexcept { return __ft_; }
545 _LIBCPP_INLINE_VISIBILITY
546 perms permissions() const noexcept { return __prms_; }
549 _LIBCPP_INLINE_VISIBILITY
550 void type(file_type __ft) noexcept { __ft_ = __ft; }
552 _LIBCPP_INLINE_VISIBILITY
553 void permissions(perms __p) noexcept { __prms_ = __p; }
560 class _LIBCPP_TYPE_VIS directory_entry;
563 struct __can_convert_char {
564 static const bool value = false;
567 struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
569 struct __can_convert_char<char> {
570 static const bool value = true;
571 using __char_type = char;
574 struct __can_convert_char<wchar_t> {
575 static const bool value = true;
576 using __char_type = wchar_t;
579 struct __can_convert_char<char16_t> {
580 static const bool value = true;
581 using __char_type = char16_t;
584 struct __can_convert_char<char32_t> {
585 static const bool value = true;
586 using __char_type = char32_t;
589 template <class _ECharT>
590 typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
591 __is_separator(_ECharT __e) {
592 return __e == _ECharT('/');
595 struct _NullSentinal {};
600 template <class _Tp, class = void>
601 struct __is_pathable_string : public false_type {};
603 template <class _ECharT, class _Traits, class _Alloc>
604 struct __is_pathable_string<
605 basic_string<_ECharT, _Traits, _Alloc>,
606 _Void<typename __can_convert_char<_ECharT>::__char_type> >
607 : public __can_convert_char<_ECharT> {
608 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
609 using _Base = __can_convert_char<_ECharT>;
610 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
611 static _ECharT const* __range_end(_Str const& __s) {
612 return __s.data() + __s.length();
614 static _ECharT __first_or_null(_Str const& __s) {
615 return __s.empty() ? _ECharT{} : __s[0];
619 template <class _ECharT, class _Traits>
620 struct __is_pathable_string<
621 basic_string_view<_ECharT, _Traits>,
622 _Void<typename __can_convert_char<_ECharT>::__char_type> >
623 : public __can_convert_char<_ECharT> {
624 using _Str = basic_string_view<_ECharT, _Traits>;
625 using _Base = __can_convert_char<_ECharT>;
626 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
627 static _ECharT const* __range_end(_Str const& __s) {
628 return __s.data() + __s.length();
630 static _ECharT __first_or_null(_Str const& __s) {
631 return __s.empty() ? _ECharT{} : __s[0];
635 template <class _Source, class _DS = typename decay<_Source>::type,
636 class _UnqualPtrType =
637 typename remove_const<typename remove_pointer<_DS>::type>::type,
638 bool _IsCharPtr = is_pointer<_DS>::value&&
639 __can_convert_char<_UnqualPtrType>::value>
640 struct __is_pathable_char_array : false_type {};
642 template <class _Source, class _ECharT, class _UPtr>
643 struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
644 : __can_convert_char<typename remove_const<_ECharT>::type> {
645 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
647 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
648 static _ECharT const* __range_end(const _ECharT* __b) {
649 using _Iter = const _ECharT*;
650 const _ECharT __sentinal = _ECharT{};
652 for (; *__e != __sentinal; ++__e)
657 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
660 template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value,
662 struct __is_pathable_iter : false_type {};
664 template <class _Iter>
665 struct __is_pathable_iter<
667 _Void<typename __can_convert_char<
668 typename iterator_traits<_Iter>::value_type>::__char_type> >
669 : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
670 using _ECharT = typename iterator_traits<_Iter>::value_type;
671 using _Base = __can_convert_char<_ECharT>;
673 static _Iter __range_begin(_Iter __b) { return __b; }
674 static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
676 static _ECharT __first_or_null(_Iter __b) { return *__b; }
679 template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
680 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
681 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
682 struct __is_pathable : false_type {
683 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
687 struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
690 struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
694 struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
696 template <class _ECharT>
698 static_assert(__can_convert_char<_ECharT>::value,
699 "Char type not convertible");
701 typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
703 static void __append_range(string& __dest, _ECharT const* __b,
704 _ECharT const* __e) {
705 _Narrower()(back_inserter(__dest), __b, __e);
708 template <class _Iter>
709 static void __append_range(string& __dest, _Iter __b, _Iter __e) {
710 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
713 basic_string<_ECharT> __tmp(__b, __e);
714 _Narrower()(back_inserter(__dest), __tmp.data(),
715 __tmp.data() + __tmp.length());
718 template <class _Iter>
719 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
720 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
721 const _ECharT __sentinal = _ECharT{};
722 if (*__b == __sentinal)
724 basic_string<_ECharT> __tmp;
725 for (; *__b != __sentinal; ++__b)
726 __tmp.push_back(*__b);
727 _Narrower()(back_inserter(__dest), __tmp.data(),
728 __tmp.data() + __tmp.length());
731 template <class _Source>
732 static void __append_source(string& __dest, _Source const& __s) {
733 using _Traits = __is_pathable<_Source>;
734 __append_range(__dest, _Traits::__range_begin(__s),
735 _Traits::__range_end(__s));
740 struct _PathCVT<char> {
742 template <class _Iter>
743 static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type
744 __append_range(string& __dest, _Iter __b, _Iter __e) {
745 for (; __b != __e; ++__b)
746 __dest.push_back(*__b);
749 template <class _Iter>
750 static typename enable_if<__is_forward_iterator<_Iter>::value>::type
751 __append_range(string& __dest, _Iter __b, _Iter __e) {
752 __dest.__append_forward_unsafe(__b, __e);
755 template <class _Iter>
756 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
757 const char __sentinal = char{};
758 for (; *__b != __sentinal; ++__b)
759 __dest.push_back(*__b);
762 template <class _Source>
763 static void __append_source(string& __dest, _Source const& __s) {
764 using _Traits = __is_pathable<_Source>;
765 __append_range(__dest, _Traits::__range_begin(__s),
766 _Traits::__range_end(__s));
770 class _LIBCPP_TYPE_VIS path {
771 template <class _SourceOrIter, class _Tp = path&>
772 using _EnableIfPathable =
773 typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
776 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
779 using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
782 typedef char value_type;
783 typedef basic_string<value_type> string_type;
784 typedef _VSTD::string_view __string_view;
785 static constexpr value_type preferred_separator = '/';
787 enum class _LIBCPP_ENUM_VIS format : unsigned char {
793 // constructors and destructor
794 _LIBCPP_INLINE_VISIBILITY path() noexcept {}
795 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
796 _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
797 : __pn_(_VSTD::move(__p.__pn_)) {}
799 _LIBCPP_INLINE_VISIBILITY
800 path(string_type&& __s, format = format::auto_format) noexcept
801 : __pn_(_VSTD::move(__s)) {}
803 template <class _Source, class = _EnableIfPathable<_Source, void> >
804 path(const _Source& __src, format = format::auto_format) {
805 _SourceCVT<_Source>::__append_source(__pn_, __src);
808 template <class _InputIt>
809 path(_InputIt __first, _InputIt __last, format = format::auto_format) {
810 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
811 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
814 // TODO Implement locale conversions.
815 template <class _Source, class = _EnableIfPathable<_Source, void> >
816 path(const _Source& __src, const locale& __loc, format = format::auto_format);
817 template <class _InputIt>
818 path(_InputIt __first, _InputIt _last, const locale& __loc,
819 format = format::auto_format);
821 _LIBCPP_INLINE_VISIBILITY
825 _LIBCPP_INLINE_VISIBILITY
826 path& operator=(const path& __p) {
831 _LIBCPP_INLINE_VISIBILITY
832 path& operator=(path&& __p) noexcept {
833 __pn_ = _VSTD::move(__p.__pn_);
837 template <class = void>
838 _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
839 __pn_ = _VSTD::move(__s);
843 _LIBCPP_INLINE_VISIBILITY
844 path& assign(string_type&& __s) noexcept {
845 __pn_ = _VSTD::move(__s);
849 template <class _Source>
850 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
851 operator=(const _Source& __src) {
852 return this->assign(__src);
855 template <class _Source>
856 _EnableIfPathable<_Source> assign(const _Source& __src) {
858 _SourceCVT<_Source>::__append_source(__pn_, __src);
862 template <class _InputIt>
863 path& assign(_InputIt __first, _InputIt __last) {
864 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
866 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
871 template <class _ECharT>
872 static bool __source_is_absolute(_ECharT __first_or_null) {
873 return __is_separator(__first_or_null);
878 path& operator/=(const path& __p) {
879 if (__p.is_absolute()) {
884 __pn_ += preferred_separator;
885 __pn_ += __p.native();
889 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
890 // is known at compile time to be "/' since the user almost certainly intended
891 // to append a separator instead of overwriting the path with "/"
892 template <class _Source>
893 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
894 operator/=(const _Source& __src) {
895 return this->append(__src);
898 template <class _Source>
899 _EnableIfPathable<_Source> append(const _Source& __src) {
900 using _Traits = __is_pathable<_Source>;
901 using _CVT = _PathCVT<_SourceChar<_Source> >;
902 if (__source_is_absolute(_Traits::__first_or_null(__src)))
904 else if (has_filename())
905 __pn_ += preferred_separator;
906 _CVT::__append_source(__pn_, __src);
910 template <class _InputIt>
911 path& append(_InputIt __first, _InputIt __last) {
912 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
913 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
914 using _CVT = _PathCVT<_ItVal>;
915 if (__first != __last && __source_is_absolute(*__first))
917 else if (has_filename())
918 __pn_ += preferred_separator;
919 _CVT::__append_range(__pn_, __first, __last);
924 _LIBCPP_INLINE_VISIBILITY
925 path& operator+=(const path& __x) {
930 _LIBCPP_INLINE_VISIBILITY
931 path& operator+=(const string_type& __x) {
936 _LIBCPP_INLINE_VISIBILITY
937 path& operator+=(__string_view __x) {
942 _LIBCPP_INLINE_VISIBILITY
943 path& operator+=(const value_type* __x) {
948 _LIBCPP_INLINE_VISIBILITY
949 path& operator+=(value_type __x) {
954 template <class _ECharT>
955 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
956 operator+=(_ECharT __x) {
957 basic_string<_ECharT> __tmp;
959 _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
963 template <class _Source>
964 _EnableIfPathable<_Source> operator+=(const _Source& __x) {
965 return this->concat(__x);
968 template <class _Source>
969 _EnableIfPathable<_Source> concat(const _Source& __x) {
970 _SourceCVT<_Source>::__append_source(__pn_, __x);
974 template <class _InputIt>
975 path& concat(_InputIt __first, _InputIt __last) {
976 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
977 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
982 _LIBCPP_INLINE_VISIBILITY
983 void clear() noexcept { __pn_.clear(); }
985 path& make_preferred() { return *this; }
987 _LIBCPP_INLINE_VISIBILITY
988 path& remove_filename() {
989 auto __fname = __filename();
990 if (!__fname.empty())
991 __pn_.erase(__fname.data() - __pn_.data());
995 path& replace_filename(const path& __replacement) {
997 return (*this /= __replacement);
1000 path& replace_extension(const path& __replacement = path());
1002 _LIBCPP_INLINE_VISIBILITY
1003 void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
1005 // private helper to allow reserving memory in the path
1006 _LIBCPP_INLINE_VISIBILITY
1007 void __reserve(size_t __s) { __pn_.reserve(__s); }
1009 // native format observers
1010 _LIBCPP_INLINE_VISIBILITY
1011 const string_type& native() const noexcept { return __pn_; }
1013 _LIBCPP_INLINE_VISIBILITY
1014 const value_type* c_str() const noexcept { return __pn_.c_str(); }
1016 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
1018 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1019 class _Allocator = allocator<_ECharT> >
1020 basic_string<_ECharT, _Traits, _Allocator>
1021 string(const _Allocator& __a = _Allocator()) const {
1022 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
1023 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1025 __s.reserve(__pn_.size());
1026 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1030 _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
1031 _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const {
1032 return string<wchar_t>();
1034 _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
1035 _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const {
1036 return string<char16_t>();
1038 _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const {
1039 return string<char32_t>();
1042 // generic format observers
1043 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1044 class _Allocator = allocator<_ECharT> >
1045 basic_string<_ECharT, _Traits, _Allocator>
1046 generic_string(const _Allocator& __a = _Allocator()) const {
1047 return string<_ECharT, _Traits, _Allocator>(__a);
1050 std::string generic_string() const { return __pn_; }
1051 std::wstring generic_wstring() const { return string<wchar_t>(); }
1052 std::string generic_u8string() const { return __pn_; }
1053 std::u16string generic_u16string() const { return string<char16_t>(); }
1054 std::u32string generic_u32string() const { return string<char32_t>(); }
1057 int __compare(__string_view) const;
1058 __string_view __root_name() const;
1059 __string_view __root_directory() const;
1060 __string_view __root_path_raw() const;
1061 __string_view __relative_path() const;
1062 __string_view __parent_path() const;
1063 __string_view __filename() const;
1064 __string_view __stem() const;
1065 __string_view __extension() const;
1069 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
1070 return __compare(__p.__pn_);
1072 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
1073 return __compare(__s);
1075 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
1076 return __compare(__s);
1078 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
1079 return __compare(__s);
1083 _LIBCPP_INLINE_VISIBILITY path root_name() const {
1084 return string_type(__root_name());
1086 _LIBCPP_INLINE_VISIBILITY path root_directory() const {
1087 return string_type(__root_directory());
1089 _LIBCPP_INLINE_VISIBILITY path root_path() const {
1090 return root_name().append(string_type(__root_directory()));
1092 _LIBCPP_INLINE_VISIBILITY path relative_path() const {
1093 return string_type(__relative_path());
1095 _LIBCPP_INLINE_VISIBILITY path parent_path() const {
1096 return string_type(__parent_path());
1098 _LIBCPP_INLINE_VISIBILITY path filename() const {
1099 return string_type(__filename());
1101 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
1102 _LIBCPP_INLINE_VISIBILITY path extension() const {
1103 return string_type(__extension());
1107 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
1108 empty() const noexcept {
1109 return __pn_.empty();
1112 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
1113 return !__root_name().empty();
1115 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
1116 return !__root_directory().empty();
1118 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
1119 return !__root_path_raw().empty();
1121 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
1122 return !__relative_path().empty();
1124 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
1125 return !__parent_path().empty();
1127 _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
1128 return !__filename().empty();
1130 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1131 _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
1132 return !__extension().empty();
1135 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1136 return has_root_directory();
1138 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1141 path lexically_normal() const;
1142 path lexically_relative(const path& __base) const;
1144 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1145 path __result = this->lexically_relative(__base);
1146 if (__result.native().empty())
1152 class _LIBCPP_TYPE_VIS iterator;
1153 typedef iterator const_iterator;
1155 iterator begin() const;
1156 iterator end() const;
1158 template <class _CharT, class _Traits>
1159 _LIBCPP_INLINE_VISIBILITY friend
1160 typename enable_if<is_same<_CharT, char>::value &&
1161 is_same<_Traits, char_traits<char> >::value,
1162 basic_ostream<_CharT, _Traits>&>::type
1163 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1164 __os << std::__quoted(__p.native());
1168 template <class _CharT, class _Traits>
1169 _LIBCPP_INLINE_VISIBILITY friend
1170 typename enable_if<!is_same<_CharT, char>::value ||
1171 !is_same<_Traits, char_traits<char> >::value,
1172 basic_ostream<_CharT, _Traits>&>::type
1173 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1174 __os << std::__quoted(__p.string<_CharT, _Traits>());
1178 template <class _CharT, class _Traits>
1179 _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
1180 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
1181 basic_string<_CharT, _Traits> __tmp;
1182 __is >> __quoted(__tmp);
1188 inline _LIBCPP_INLINE_VISIBILITY path&
1189 __assign_view(__string_view const& __s) noexcept {
1190 __pn_ = string_type(__s);
1196 inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
1201 size_t hash_value(const path& __p) noexcept;
1203 inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs,
1204 const path& __rhs) noexcept {
1205 return __lhs.compare(__rhs) == 0;
1208 inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs,
1209 const path& __rhs) noexcept {
1210 return __lhs.compare(__rhs) != 0;
1213 inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs,
1214 const path& __rhs) noexcept {
1215 return __lhs.compare(__rhs) < 0;
1218 inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs,
1219 const path& __rhs) noexcept {
1220 return __lhs.compare(__rhs) <= 0;
1223 inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs,
1224 const path& __rhs) noexcept {
1225 return __lhs.compare(__rhs) > 0;
1228 inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs,
1229 const path& __rhs) noexcept {
1230 return __lhs.compare(__rhs) >= 0;
1233 inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1234 const path& __rhs) {
1235 path __result(__lhs);
1240 template <class _Source>
1241 _LIBCPP_INLINE_VISIBILITY
1242 typename enable_if<__is_pathable<_Source>::value, path>::type
1243 u8path(const _Source& __s) {
1245 is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1246 "u8path(Source const&) requires Source have a character type of type "
1251 template <class _InputIt>
1252 _LIBCPP_INLINE_VISIBILITY
1253 typename enable_if<__is_pathable<_InputIt>::value, path>::type
1254 u8path(_InputIt __f, _InputIt __l) {
1256 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1257 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
1258 return path(__f, __l);
1261 class _LIBCPP_TYPE_VIS path::iterator {
1263 enum _ParserState : unsigned char {
1274 typedef bidirectional_iterator_tag iterator_category;
1276 typedef path value_type;
1277 typedef std::ptrdiff_t difference_type;
1278 typedef const path* pointer;
1279 typedef const path& reference;
1282 __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1285 _LIBCPP_INLINE_VISIBILITY
1287 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
1288 __state_(_Singular) {}
1290 iterator(const iterator&) = default;
1291 ~iterator() = default;
1293 iterator& operator=(const iterator&) = default;
1295 _LIBCPP_INLINE_VISIBILITY
1296 reference operator*() const { return __stashed_elem_; }
1298 _LIBCPP_INLINE_VISIBILITY
1299 pointer operator->() const { return &__stashed_elem_; }
1301 _LIBCPP_INLINE_VISIBILITY
1302 iterator& operator++() {
1303 _LIBCPP_ASSERT(__state_ != _Singular,
1304 "attempting to increment a singular iterator");
1305 _LIBCPP_ASSERT(__state_ != _AtEnd,
1306 "attempting to increment the end iterator");
1307 return __increment();
1310 _LIBCPP_INLINE_VISIBILITY
1311 iterator operator++(int) {
1312 iterator __it(*this);
1317 _LIBCPP_INLINE_VISIBILITY
1318 iterator& operator--() {
1319 _LIBCPP_ASSERT(__state_ != _Singular,
1320 "attempting to decrement a singular iterator");
1321 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1322 "attempting to decrement the begin iterator");
1323 return __decrement();
1326 _LIBCPP_INLINE_VISIBILITY
1327 iterator operator--(int) {
1328 iterator __it(*this);
1336 inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
1339 iterator& __increment();
1340 iterator& __decrement();
1342 path __stashed_elem_;
1343 const path* __path_ptr_;
1344 path::__string_view __entry_;
1345 _ParserState __state_;
1348 inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
1349 const path::iterator& __rhs) {
1350 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1351 __lhs.__entry_.data() == __rhs.__entry_.data();
1354 inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
1355 const path::iterator& __rhs) {
1356 return !(__lhs == __rhs);
1359 class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
1361 _LIBCPP_INLINE_VISIBILITY
1362 filesystem_error(const string& __what, error_code __ec)
1363 : system_error(__ec, __what),
1364 __storage_(make_shared<_Storage>(path(), path())) {
1368 _LIBCPP_INLINE_VISIBILITY
1369 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1370 : system_error(__ec, __what),
1371 __storage_(make_shared<_Storage>(__p1, path())) {
1375 _LIBCPP_INLINE_VISIBILITY
1376 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1378 : system_error(__ec, __what),
1379 __storage_(make_shared<_Storage>(__p1, __p2)) {
1383 _LIBCPP_INLINE_VISIBILITY
1384 const path& path1() const noexcept { return __storage_->__p1_; }
1386 _LIBCPP_INLINE_VISIBILITY
1387 const path& path2() const noexcept { return __storage_->__p2_; }
1389 ~filesystem_error() override; // key function
1391 _LIBCPP_INLINE_VISIBILITY
1392 const char* what() const noexcept override {
1393 return __storage_->__what_.c_str();
1397 void __create_what(int __num_paths);
1401 _LIBCPP_INLINE_VISIBILITY
1402 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1408 shared_ptr<_Storage> __storage_;
1411 template <class... _Args>
1412 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1413 #ifndef _LIBCPP_NO_EXCEPTIONS
1415 __throw_filesystem_error(_Args&&... __args) {
1416 throw filesystem_error(std::forward<_Args>(__args)...);
1420 __throw_filesystem_error(_Args&&...) {
1425 // operational functions
1428 path __absolute(const path&, error_code* __ec = nullptr);
1430 path __canonical(const path&, error_code* __ec = nullptr);
1432 void __copy(const path& __from, const path& __to, copy_options __opt,
1433 error_code* __ec = nullptr);
1435 bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1436 error_code* __ec = nullptr);
1438 void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1439 error_code* __ec = nullptr);
1441 bool __create_directories(const path& p, error_code* ec = nullptr);
1443 bool __create_directory(const path& p, error_code* ec = nullptr);
1445 bool __create_directory(const path& p, const path& attributes,
1446 error_code* ec = nullptr);
1448 void __create_directory_symlink(const path& __to, const path& __new_symlink,
1449 error_code* __ec = nullptr);
1451 void __create_hard_link(const path& __to, const path& __new_hard_link,
1452 error_code* __ec = nullptr);
1454 void __create_symlink(const path& __to, const path& __new_symlink,
1455 error_code* __ec = nullptr);
1457 path __current_path(error_code* __ec = nullptr);
1459 void __current_path(const path&, error_code* __ec = nullptr);
1461 bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
1463 uintmax_t __file_size(const path&, error_code* __ec = nullptr);
1465 uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
1467 bool __fs_is_empty(const path& p, error_code* ec = nullptr);
1469 file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
1471 void __last_write_time(const path& p, file_time_type new_time,
1472 error_code* ec = nullptr);
1474 void __permissions(const path&, perms, perm_options, error_code* = nullptr);
1476 path __read_symlink(const path& p, error_code* ec = nullptr);
1478 bool __remove(const path& p, error_code* ec = nullptr);
1480 uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
1482 void __rename(const path& from, const path& to, error_code* ec = nullptr);
1484 void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
1486 space_info __space(const path&, error_code* __ec = nullptr);
1488 file_status __status(const path&, error_code* __ec = nullptr);
1490 file_status __symlink_status(const path&, error_code* __ec = nullptr);
1492 path __system_complete(const path&, error_code* __ec = nullptr);
1494 path __temp_directory_path(error_code* __ec = nullptr);
1496 path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
1498 inline _LIBCPP_INLINE_VISIBILITY path current_path() {
1499 return __current_path();
1502 inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
1503 return __current_path(&__ec);
1506 inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
1507 __current_path(__p);
1510 inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
1511 error_code& __ec) noexcept {
1512 __current_path(__p, &__ec);
1515 inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
1516 return __absolute(__p);
1519 inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
1521 return __absolute(__p, &__ec);
1524 inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
1525 return __canonical(__p);
1528 inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
1530 return __canonical(__p, &__ec);
1533 inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
1535 __copy(__from, __to, copy_options::none);
1538 inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1540 __copy(__from, __to, copy_options::none, &__ec);
1543 inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1544 copy_options __opt) {
1545 __copy(__from, __to, __opt);
1548 inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1551 __copy(__from, __to, __opt, &__ec);
1554 inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1556 return __copy_file(__from, __to, copy_options::none);
1559 inline _LIBCPP_INLINE_VISIBILITY bool
1560 copy_file(const path& __from, const path& __to, error_code& __ec) {
1561 return __copy_file(__from, __to, copy_options::none, &__ec);
1564 inline _LIBCPP_INLINE_VISIBILITY bool
1565 copy_file(const path& __from, const path& __to, copy_options __opt) {
1566 return __copy_file(__from, __to, __opt);
1569 inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1573 return __copy_file(__from, __to, __opt, &__ec);
1576 inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
1577 const path& __new) {
1578 __copy_symlink(__existing, __new);
1581 inline _LIBCPP_INLINE_VISIBILITY void
1582 copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
1583 __copy_symlink(__ext, __new, &__ec);
1586 inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
1587 return __create_directories(__p);
1590 inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
1592 return __create_directories(__p, &__ec);
1595 inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
1596 return __create_directory(__p);
1599 inline _LIBCPP_INLINE_VISIBILITY bool
1600 create_directory(const path& __p, error_code& __ec) noexcept {
1601 return __create_directory(__p, &__ec);
1604 inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
1605 const path& __attrs) {
1606 return __create_directory(__p, __attrs);
1609 inline _LIBCPP_INLINE_VISIBILITY bool
1610 create_directory(const path& __p, const path& __attrs,
1611 error_code& __ec) noexcept {
1612 return __create_directory(__p, __attrs, &__ec);
1615 inline _LIBCPP_INLINE_VISIBILITY void
1616 create_directory_symlink(const path& __to, const path& __new) {
1617 __create_directory_symlink(__to, __new);
1620 inline _LIBCPP_INLINE_VISIBILITY void
1621 create_directory_symlink(const path& __to, const path& __new,
1622 error_code& __ec) noexcept {
1623 __create_directory_symlink(__to, __new, &__ec);
1626 inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
1627 const path& __new) {
1628 __create_hard_link(__to, __new);
1631 inline _LIBCPP_INLINE_VISIBILITY void
1632 create_hard_link(const path& __to, const path& __new,
1633 error_code& __ec) noexcept {
1634 __create_hard_link(__to, __new, &__ec);
1637 inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
1638 const path& __new) {
1639 __create_symlink(__to, __new);
1642 inline _LIBCPP_INLINE_VISIBILITY void
1643 create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
1644 return __create_symlink(__to, __new, &__ec);
1647 inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
1648 return __s.type() != file_type::none;
1651 inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
1652 return status_known(__s) && __s.type() != file_type::not_found;
1655 inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
1656 return exists(__status(__p));
1659 inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
1660 error_code& __ec) noexcept {
1661 auto __s = __status(__p, &__ec);
1662 if (status_known(__s))
1667 inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
1669 return __equivalent(__p1, __p2);
1672 inline _LIBCPP_INLINE_VISIBILITY bool
1673 equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
1674 return __equivalent(__p1, __p2, &__ec);
1677 inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
1678 return __file_size(__p);
1681 inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1682 file_size(const path& __p, error_code& __ec) noexcept {
1683 return __file_size(__p, &__ec);
1686 inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
1687 return __hard_link_count(__p);
1690 inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1691 hard_link_count(const path& __p, error_code& __ec) noexcept {
1692 return __hard_link_count(__p, &__ec);
1695 inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
1696 return __s.type() == file_type::block;
1699 inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
1700 return is_block_file(__status(__p));
1703 inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
1704 error_code& __ec) noexcept {
1705 return is_block_file(__status(__p, &__ec));
1708 inline _LIBCPP_INLINE_VISIBILITY bool
1709 is_character_file(file_status __s) noexcept {
1710 return __s.type() == file_type::character;
1713 inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
1714 return is_character_file(__status(__p));
1717 inline _LIBCPP_INLINE_VISIBILITY bool
1718 is_character_file(const path& __p, error_code& __ec) noexcept {
1719 return is_character_file(__status(__p, &__ec));
1722 inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
1723 return __s.type() == file_type::directory;
1726 inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
1727 return is_directory(__status(__p));
1730 inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
1731 error_code& __ec) noexcept {
1732 return is_directory(__status(__p, &__ec));
1735 inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
1736 return __fs_is_empty(__p);
1739 inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
1741 return __fs_is_empty(__p, &__ec);
1744 inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
1745 return __s.type() == file_type::fifo;
1747 inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
1748 return is_fifo(__status(__p));
1751 inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
1752 error_code& __ec) noexcept {
1753 return is_fifo(__status(__p, &__ec));
1756 inline _LIBCPP_INLINE_VISIBILITY bool
1757 is_regular_file(file_status __s) noexcept {
1758 return __s.type() == file_type::regular;
1761 inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
1762 return is_regular_file(__status(__p));
1765 inline _LIBCPP_INLINE_VISIBILITY bool
1766 is_regular_file(const path& __p, error_code& __ec) noexcept {
1767 return is_regular_file(__status(__p, &__ec));
1770 inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
1771 return __s.type() == file_type::socket;
1774 inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
1775 return is_socket(__status(__p));
1778 inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
1779 error_code& __ec) noexcept {
1780 return is_socket(__status(__p, &__ec));
1783 inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
1784 return __s.type() == file_type::symlink;
1787 inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
1788 return is_symlink(__symlink_status(__p));
1791 inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
1792 error_code& __ec) noexcept {
1793 return is_symlink(__symlink_status(__p, &__ec));
1796 inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
1797 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
1801 inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
1802 return is_other(__status(__p));
1805 inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
1806 error_code& __ec) noexcept {
1807 return is_other(__status(__p, &__ec));
1810 inline _LIBCPP_INLINE_VISIBILITY file_time_type
1811 last_write_time(const path& __p) {
1812 return __last_write_time(__p);
1815 inline _LIBCPP_INLINE_VISIBILITY file_time_type
1816 last_write_time(const path& __p, error_code& __ec) noexcept {
1817 return __last_write_time(__p, &__ec);
1820 inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
1821 file_time_type __t) {
1822 __last_write_time(__p, __t);
1825 inline _LIBCPP_INLINE_VISIBILITY void
1826 last_write_time(const path& __p, file_time_type __t,
1827 error_code& __ec) noexcept {
1828 __last_write_time(__p, __t, &__ec);
1831 inline _LIBCPP_INLINE_VISIBILITY void
1832 permissions(const path& __p, perms __prms,
1833 perm_options __opts = perm_options::replace) {
1834 __permissions(__p, __prms, __opts);
1837 inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
1838 error_code& __ec) noexcept {
1839 __permissions(__p, __prms, perm_options::replace, &__ec);
1842 inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
1843 perm_options __opts,
1845 __permissions(__p, __prms, __opts, &__ec);
1848 inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
1851 path __tmp = __weakly_canonical(__p, &__ec);
1854 path __tmp_base = __weakly_canonical(__base, &__ec);
1857 return __tmp.lexically_proximate(__tmp_base);
1860 inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
1862 return proximate(__p, current_path(), __ec);
1865 inline _LIBCPP_INLINE_VISIBILITY path
1866 proximate(const path& __p, const path& __base = current_path()) {
1867 return __weakly_canonical(__p).lexically_proximate(
1868 __weakly_canonical(__base));
1871 inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
1872 return __read_symlink(__p);
1875 inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
1877 return __read_symlink(__p, &__ec);
1880 inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
1883 path __tmp = __weakly_canonical(__p, &__ec);
1886 path __tmpbase = __weakly_canonical(__base, &__ec);
1889 return __tmp.lexically_relative(__tmpbase);
1892 inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
1894 return relative(__p, current_path(), __ec);
1897 inline _LIBCPP_INLINE_VISIBILITY path
1898 relative(const path& __p, const path& __base = current_path()) {
1899 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
1902 inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
1903 return __remove(__p);
1906 inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
1907 error_code& __ec) noexcept {
1908 return __remove(__p, &__ec);
1911 inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
1912 return __remove_all(__p);
1915 inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
1917 return __remove_all(__p, &__ec);
1920 inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
1922 return __rename(__from, __to);
1925 inline _LIBCPP_INLINE_VISIBILITY void
1926 rename(const path& __from, const path& __to, error_code& __ec) noexcept {
1927 return __rename(__from, __to, &__ec);
1930 inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
1932 return __resize_file(__p, __ns);
1935 inline _LIBCPP_INLINE_VISIBILITY void
1936 resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
1937 return __resize_file(__p, __ns, &__ec);
1940 inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
1941 return __space(__p);
1944 inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
1945 error_code& __ec) noexcept {
1946 return __space(__p, &__ec);
1949 inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
1950 return __status(__p);
1953 inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
1954 error_code& __ec) noexcept {
1955 return __status(__p, &__ec);
1958 inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
1959 return __symlink_status(__p);
1962 inline _LIBCPP_INLINE_VISIBILITY file_status
1963 symlink_status(const path& __p, error_code& __ec) noexcept {
1964 return __symlink_status(__p, &__ec);
1967 inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
1968 return __temp_directory_path();
1971 inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
1972 return __temp_directory_path(&__ec);
1975 inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
1976 return __weakly_canonical(__p);
1979 inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
1981 return __weakly_canonical(__p, &__ec);
1984 class directory_iterator;
1985 class recursive_directory_iterator;
1988 class directory_entry {
1989 typedef _VSTD_FS::path _Path;
1992 // constructors and destructors
1993 directory_entry() noexcept = default;
1994 directory_entry(directory_entry const&) = default;
1995 directory_entry(directory_entry&&) noexcept = default;
1997 _LIBCPP_INLINE_VISIBILITY
1998 explicit directory_entry(_Path const& __p) : __p_(__p) {
2003 _LIBCPP_INLINE_VISIBILITY
2004 directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
2008 ~directory_entry() {}
2010 directory_entry& operator=(directory_entry const&) = default;
2011 directory_entry& operator=(directory_entry&&) noexcept = default;
2013 _LIBCPP_INLINE_VISIBILITY
2014 void assign(_Path const& __p) {
2020 _LIBCPP_INLINE_VISIBILITY
2021 void assign(_Path const& __p, error_code& __ec) {
2026 _LIBCPP_INLINE_VISIBILITY
2027 void replace_filename(_Path const& __p) {
2028 __p_.replace_filename(__p);
2033 _LIBCPP_INLINE_VISIBILITY
2034 void replace_filename(_Path const& __p, error_code& __ec) {
2035 __p_ = __p_.parent_path() / __p;
2039 _LIBCPP_INLINE_VISIBILITY
2040 void refresh() { __refresh(); }
2042 _LIBCPP_INLINE_VISIBILITY
2043 void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
2045 _LIBCPP_INLINE_VISIBILITY
2046 _Path const& path() const noexcept { return __p_; }
2048 _LIBCPP_INLINE_VISIBILITY
2049 operator const _Path&() const noexcept { return __p_; }
2051 _LIBCPP_INLINE_VISIBILITY
2052 bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
2054 _LIBCPP_INLINE_VISIBILITY
2055 bool exists(error_code& __ec) const noexcept {
2056 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2059 _LIBCPP_INLINE_VISIBILITY
2060 bool is_block_file() const { return __get_ft() == file_type::block; }
2062 _LIBCPP_INLINE_VISIBILITY
2063 bool is_block_file(error_code& __ec) const noexcept {
2064 return __get_ft(&__ec) == file_type::block;
2067 _LIBCPP_INLINE_VISIBILITY
2068 bool is_character_file() const { return __get_ft() == file_type::character; }
2070 _LIBCPP_INLINE_VISIBILITY
2071 bool is_character_file(error_code& __ec) const noexcept {
2072 return __get_ft(&__ec) == file_type::character;
2075 _LIBCPP_INLINE_VISIBILITY
2076 bool is_directory() const { return __get_ft() == file_type::directory; }
2078 _LIBCPP_INLINE_VISIBILITY
2079 bool is_directory(error_code& __ec) const noexcept {
2080 return __get_ft(&__ec) == file_type::directory;
2083 _LIBCPP_INLINE_VISIBILITY
2084 bool is_fifo() const { return __get_ft() == file_type::fifo; }
2086 _LIBCPP_INLINE_VISIBILITY
2087 bool is_fifo(error_code& __ec) const noexcept {
2088 return __get_ft(&__ec) == file_type::fifo;
2091 _LIBCPP_INLINE_VISIBILITY
2092 bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
2094 _LIBCPP_INLINE_VISIBILITY
2095 bool is_other(error_code& __ec) const noexcept {
2096 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2099 _LIBCPP_INLINE_VISIBILITY
2100 bool is_regular_file() const { return __get_ft() == file_type::regular; }
2102 _LIBCPP_INLINE_VISIBILITY
2103 bool is_regular_file(error_code& __ec) const noexcept {
2104 return __get_ft(&__ec) == file_type::regular;
2107 _LIBCPP_INLINE_VISIBILITY
2108 bool is_socket() const { return __get_ft() == file_type::socket; }
2110 _LIBCPP_INLINE_VISIBILITY
2111 bool is_socket(error_code& __ec) const noexcept {
2112 return __get_ft(&__ec) == file_type::socket;
2115 _LIBCPP_INLINE_VISIBILITY
2116 bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
2118 _LIBCPP_INLINE_VISIBILITY
2119 bool is_symlink(error_code& __ec) const noexcept {
2120 return __get_sym_ft(&__ec) == file_type::symlink;
2122 _LIBCPP_INLINE_VISIBILITY
2123 uintmax_t file_size() const { return __get_size(); }
2125 _LIBCPP_INLINE_VISIBILITY
2126 uintmax_t file_size(error_code& __ec) const noexcept {
2127 return __get_size(&__ec);
2130 _LIBCPP_INLINE_VISIBILITY
2131 uintmax_t hard_link_count() const { return __get_nlink(); }
2133 _LIBCPP_INLINE_VISIBILITY
2134 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2135 return __get_nlink(&__ec);
2138 _LIBCPP_INLINE_VISIBILITY
2139 file_time_type last_write_time() const { return __get_write_time(); }
2141 _LIBCPP_INLINE_VISIBILITY
2142 file_time_type last_write_time(error_code& __ec) const noexcept {
2143 return __get_write_time(&__ec);
2146 _LIBCPP_INLINE_VISIBILITY
2147 file_status status() const { return __get_status(); }
2149 _LIBCPP_INLINE_VISIBILITY
2150 file_status status(error_code& __ec) const noexcept {
2151 return __get_status(&__ec);
2154 _LIBCPP_INLINE_VISIBILITY
2155 file_status symlink_status() const { return __get_symlink_status(); }
2157 _LIBCPP_INLINE_VISIBILITY
2158 file_status symlink_status(error_code& __ec) const noexcept {
2159 return __get_symlink_status(&__ec);
2162 _LIBCPP_INLINE_VISIBILITY
2163 bool operator<(directory_entry const& __rhs) const noexcept {
2164 return __p_ < __rhs.__p_;
2167 _LIBCPP_INLINE_VISIBILITY
2168 bool operator==(directory_entry const& __rhs) const noexcept {
2169 return __p_ == __rhs.__p_;
2172 _LIBCPP_INLINE_VISIBILITY
2173 bool operator!=(directory_entry const& __rhs) const noexcept {
2174 return __p_ != __rhs.__p_;
2177 _LIBCPP_INLINE_VISIBILITY
2178 bool operator<=(directory_entry const& __rhs) const noexcept {
2179 return __p_ <= __rhs.__p_;
2182 _LIBCPP_INLINE_VISIBILITY
2183 bool operator>(directory_entry const& __rhs) const noexcept {
2184 return __p_ > __rhs.__p_;
2187 _LIBCPP_INLINE_VISIBILITY
2188 bool operator>=(directory_entry const& __rhs) const noexcept {
2189 return __p_ >= __rhs.__p_;
2193 friend class directory_iterator;
2194 friend class recursive_directory_iterator;
2195 friend class __dir_stream;
2197 enum _CacheType : unsigned char {
2202 _RefreshSymlinkUnresolved,
2206 struct __cached_data {
2209 file_time_type __write_time_;
2211 perms __non_sym_perms_;
2213 _CacheType __cache_type_;
2215 _LIBCPP_INLINE_VISIBILITY
2216 __cached_data() noexcept { __reset(); }
2218 _LIBCPP_INLINE_VISIBILITY
2220 __cache_type_ = _Empty;
2221 __type_ = file_type::none;
2222 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2223 __size_ = __nlink_ = uintmax_t(-1);
2224 __write_time_ = file_time_type::min();
2228 _LIBCPP_INLINE_VISIBILITY
2229 static __cached_data __create_iter_result(file_type __ft) {
2230 __cached_data __data;
2231 __data.__type_ = __ft;
2232 __data.__cache_type_ = [&]() {
2234 case file_type::none:
2236 case file_type::symlink:
2237 return _IterSymlink;
2239 return _IterNonSymlink;
2245 _LIBCPP_INLINE_VISIBILITY
2246 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2247 __p_ = std::move(__p);
2252 error_code __do_refresh() noexcept;
2254 _LIBCPP_INLINE_VISIBILITY
2255 static bool __is_dne_error(error_code const& __ec) {
2258 switch (static_cast<errc>(__ec.value())) {
2259 case errc::no_such_file_or_directory:
2260 case errc::not_a_directory:
2267 _LIBCPP_INLINE_VISIBILITY
2268 void __handle_error(const char* __msg, error_code* __dest_ec,
2269 error_code const& __ec, bool __allow_dne = false) const {
2274 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2275 __throw_filesystem_error(__msg, __p_, __ec);
2278 _LIBCPP_INLINE_VISIBILITY
2279 void __refresh(error_code* __ec = nullptr) {
2280 __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2281 /*allow_dne*/ true);
2284 _LIBCPP_INLINE_VISIBILITY
2285 file_type __get_sym_ft(error_code* __ec = nullptr) const {
2286 switch (__data_.__cache_type_) {
2288 return __symlink_status(__p_, __ec).type();
2290 case _RefreshSymlink:
2291 case _RefreshSymlinkUnresolved:
2294 return file_type::symlink;
2295 case _IterNonSymlink:
2296 case _RefreshNonSymlink:
2297 file_status __st(__data_.__type_);
2298 if (__ec && !_VSTD_FS::exists(__st))
2299 *__ec = make_error_code(errc::no_such_file_or_directory);
2302 return __data_.__type_;
2304 _LIBCPP_UNREACHABLE();
2307 _LIBCPP_INLINE_VISIBILITY
2308 file_type __get_ft(error_code* __ec = nullptr) const {
2309 switch (__data_.__cache_type_) {
2312 case _RefreshSymlinkUnresolved:
2313 return __status(__p_, __ec).type();
2314 case _IterNonSymlink:
2315 case _RefreshNonSymlink:
2316 case _RefreshSymlink: {
2317 file_status __st(__data_.__type_);
2318 if (__ec && !_VSTD_FS::exists(__st))
2319 *__ec = make_error_code(errc::no_such_file_or_directory);
2322 return __data_.__type_;
2325 _LIBCPP_UNREACHABLE();
2328 _LIBCPP_INLINE_VISIBILITY
2329 file_status __get_status(error_code* __ec = nullptr) const {
2330 switch (__data_.__cache_type_) {
2332 case _IterNonSymlink:
2334 case _RefreshSymlinkUnresolved:
2335 return __status(__p_, __ec);
2336 case _RefreshNonSymlink:
2337 case _RefreshSymlink:
2338 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2340 _LIBCPP_UNREACHABLE();
2343 _LIBCPP_INLINE_VISIBILITY
2344 file_status __get_symlink_status(error_code* __ec = nullptr) const {
2345 switch (__data_.__cache_type_) {
2347 case _IterNonSymlink:
2349 return __symlink_status(__p_, __ec);
2350 case _RefreshNonSymlink:
2351 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2352 case _RefreshSymlink:
2353 case _RefreshSymlinkUnresolved:
2354 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2356 _LIBCPP_UNREACHABLE();
2359 _LIBCPP_INLINE_VISIBILITY
2360 uintmax_t __get_size(error_code* __ec = nullptr) const {
2361 switch (__data_.__cache_type_) {
2363 case _IterNonSymlink:
2365 case _RefreshSymlinkUnresolved:
2366 return _VSTD_FS::__file_size(__p_, __ec);
2367 case _RefreshSymlink:
2368 case _RefreshNonSymlink: {
2370 file_status __st(__get_ft(&__m_ec));
2371 __handle_error("in directory_entry::file_size", __ec, __m_ec);
2372 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2373 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2374 : errc::not_supported;
2375 __handle_error("in directory_entry::file_size", __ec,
2376 make_error_code(__err_kind));
2378 return __data_.__size_;
2381 _LIBCPP_UNREACHABLE();
2384 _LIBCPP_INLINE_VISIBILITY
2385 uintmax_t __get_nlink(error_code* __ec = nullptr) const {
2386 switch (__data_.__cache_type_) {
2388 case _IterNonSymlink:
2390 case _RefreshSymlinkUnresolved:
2391 return _VSTD_FS::__hard_link_count(__p_, __ec);
2392 case _RefreshSymlink:
2393 case _RefreshNonSymlink: {
2395 (void)__get_ft(&__m_ec);
2396 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
2397 return __data_.__nlink_;
2400 _LIBCPP_UNREACHABLE();
2403 _LIBCPP_INLINE_VISIBILITY
2404 file_time_type __get_write_time(error_code* __ec = nullptr) const {
2405 switch (__data_.__cache_type_) {
2407 case _IterNonSymlink:
2409 case _RefreshSymlinkUnresolved:
2410 return _VSTD_FS::__last_write_time(__p_, __ec);
2411 case _RefreshSymlink:
2412 case _RefreshNonSymlink: {
2414 file_status __st(__get_ft(&__m_ec));
2415 __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
2416 if (_VSTD_FS::exists(__st) &&
2417 __data_.__write_time_ == file_time_type::min())
2418 __handle_error("in directory_entry::last_write_time", __ec,
2419 make_error_code(errc::value_too_large));
2420 return __data_.__write_time_;
2423 _LIBCPP_UNREACHABLE();
2428 __cached_data __data_;
2431 class __dir_element_proxy {
2433 inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
2434 return _VSTD::move(__elem_);
2438 friend class directory_iterator;
2439 friend class recursive_directory_iterator;
2440 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2441 __dir_element_proxy(__dir_element_proxy&& __o)
2442 : __elem_(_VSTD::move(__o.__elem_)) {}
2443 directory_entry __elem_;
2446 class directory_iterator {
2448 typedef directory_entry value_type;
2449 typedef ptrdiff_t difference_type;
2450 typedef value_type const* pointer;
2451 typedef value_type const& reference;
2452 typedef input_iterator_tag iterator_category;
2456 directory_iterator() noexcept {}
2458 explicit directory_iterator(const path& __p)
2459 : directory_iterator(__p, nullptr) {}
2461 directory_iterator(const path& __p, directory_options __opts)
2462 : directory_iterator(__p, nullptr, __opts) {}
2464 directory_iterator(const path& __p, error_code& __ec)
2465 : directory_iterator(__p, &__ec) {}
2467 directory_iterator(const path& __p, directory_options __opts,
2469 : directory_iterator(__p, &__ec, __opts) {}
2471 directory_iterator(const directory_iterator&) = default;
2472 directory_iterator(directory_iterator&&) = default;
2473 directory_iterator& operator=(const directory_iterator&) = default;
2475 directory_iterator& operator=(directory_iterator&& __o) noexcept {
2476 // non-default implementation provided to support self-move assign.
2478 __imp_ = _VSTD::move(__o.__imp_);
2483 ~directory_iterator() = default;
2485 const directory_entry& operator*() const {
2486 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
2487 return __dereference();
2490 const directory_entry* operator->() const { return &**this; }
2492 directory_iterator& operator++() { return __increment(); }
2494 __dir_element_proxy operator++(int) {
2495 __dir_element_proxy __p(**this);
2500 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
2503 inline _LIBCPP_INLINE_VISIBILITY friend bool
2504 operator==(const directory_iterator& __lhs,
2505 const directory_iterator& __rhs) noexcept;
2507 // construct the dir_stream
2509 directory_iterator(const path&, error_code*,
2510 directory_options = directory_options::none);
2513 directory_iterator& __increment(error_code* __ec = nullptr);
2516 const directory_entry& __dereference() const;
2519 shared_ptr<__dir_stream> __imp_;
2522 inline _LIBCPP_INLINE_VISIBILITY bool
2523 operator==(const directory_iterator& __lhs,
2524 const directory_iterator& __rhs) noexcept {
2525 return __lhs.__imp_ == __rhs.__imp_;
2528 inline _LIBCPP_INLINE_VISIBILITY bool
2529 operator!=(const directory_iterator& __lhs,
2530 const directory_iterator& __rhs) noexcept {
2531 return !(__lhs == __rhs);
2534 // enable directory_iterator range-based for statements
2535 inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2536 begin(directory_iterator __iter) noexcept {
2540 inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2541 end(const directory_iterator&) noexcept {
2542 return directory_iterator();
2545 class recursive_directory_iterator {
2547 using value_type = directory_entry;
2548 using difference_type = std::ptrdiff_t;
2549 using pointer = directory_entry const*;
2550 using reference = directory_entry const&;
2551 using iterator_category = std::input_iterator_tag;
2554 // constructors and destructor
2555 _LIBCPP_INLINE_VISIBILITY
2556 recursive_directory_iterator() noexcept : __rec_(false) {}
2558 _LIBCPP_INLINE_VISIBILITY
2559 explicit recursive_directory_iterator(
2560 const path& __p, directory_options __xoptions = directory_options::none)
2561 : recursive_directory_iterator(__p, __xoptions, nullptr) {}
2563 _LIBCPP_INLINE_VISIBILITY
2564 recursive_directory_iterator(const path& __p, directory_options __xoptions,
2566 : recursive_directory_iterator(__p, __xoptions, &__ec) {}
2568 _LIBCPP_INLINE_VISIBILITY
2569 recursive_directory_iterator(const path& __p, error_code& __ec)
2570 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
2572 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2573 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2575 recursive_directory_iterator&
2576 operator=(const recursive_directory_iterator&) = default;
2578 _LIBCPP_INLINE_VISIBILITY
2579 recursive_directory_iterator&
2580 operator=(recursive_directory_iterator&& __o) noexcept {
2581 // non-default implementation provided to support self-move assign.
2583 __imp_ = _VSTD::move(__o.__imp_);
2584 __rec_ = __o.__rec_;
2589 ~recursive_directory_iterator() = default;
2591 _LIBCPP_INLINE_VISIBILITY
2592 const directory_entry& operator*() const { return __dereference(); }
2594 _LIBCPP_INLINE_VISIBILITY
2595 const directory_entry* operator->() const { return &__dereference(); }
2597 recursive_directory_iterator& operator++() { return __increment(); }
2599 _LIBCPP_INLINE_VISIBILITY
2600 __dir_element_proxy operator++(int) {
2601 __dir_element_proxy __p(**this);
2606 _LIBCPP_INLINE_VISIBILITY
2607 recursive_directory_iterator& increment(error_code& __ec) {
2608 return __increment(&__ec);
2611 _LIBCPP_FUNC_VIS directory_options options() const;
2612 _LIBCPP_FUNC_VIS int depth() const;
2614 _LIBCPP_INLINE_VISIBILITY
2615 void pop() { __pop(); }
2617 _LIBCPP_INLINE_VISIBILITY
2618 void pop(error_code& __ec) { __pop(&__ec); }
2620 _LIBCPP_INLINE_VISIBILITY
2621 bool recursion_pending() const { return __rec_; }
2623 _LIBCPP_INLINE_VISIBILITY
2624 void disable_recursion_pending() { __rec_ = false; }
2627 recursive_directory_iterator(const path& __p, directory_options __opt,
2631 const directory_entry& __dereference() const;
2634 bool __try_recursion(error_code* __ec);
2637 void __advance(error_code* __ec = nullptr);
2640 recursive_directory_iterator& __increment(error_code* __ec = nullptr);
2643 void __pop(error_code* __ec = nullptr);
2645 inline _LIBCPP_INLINE_VISIBILITY friend bool
2646 operator==(const recursive_directory_iterator&,
2647 const recursive_directory_iterator&) noexcept;
2649 struct __shared_imp;
2650 shared_ptr<__shared_imp> __imp_;
2652 }; // class recursive_directory_iterator
2654 inline _LIBCPP_INLINE_VISIBILITY bool
2655 operator==(const recursive_directory_iterator& __lhs,
2656 const recursive_directory_iterator& __rhs) noexcept {
2657 return __lhs.__imp_ == __rhs.__imp_;
2660 _LIBCPP_INLINE_VISIBILITY
2661 inline bool operator!=(const recursive_directory_iterator& __lhs,
2662 const recursive_directory_iterator& __rhs) noexcept {
2663 return !(__lhs == __rhs);
2665 // enable recursive_directory_iterator range-based for statements
2666 inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2667 begin(recursive_directory_iterator __iter) noexcept {
2671 inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2672 end(const recursive_directory_iterator&) noexcept {
2673 return recursive_directory_iterator();
2676 _LIBCPP_END_NAMESPACE_FILESYSTEM
2678 #endif // !_LIBCPP_CXX03_LANG
2682 #endif // _LIBCPP_FILESYSTEM