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