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