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