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