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