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