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