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