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