1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 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/* 970#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 971 // TODO Implement locale conversions. 972 template <class _Source, class = _EnableIfPathable<_Source, void> > 973 path(const _Source& __src, const locale& __loc, format = format::auto_format); 974 template <class _InputIt> 975 path(_InputIt __first, _InputIt _last, const locale& __loc, 976 format = format::auto_format); 977#endif 978*/ 979 980 _LIBCPP_INLINE_VISIBILITY 981 ~path() = default; 982 983 // assignments 984 _LIBCPP_INLINE_VISIBILITY 985 path& operator=(const path& __p) { 986 __pn_ = __p.__pn_; 987 return *this; 988 } 989 990 _LIBCPP_INLINE_VISIBILITY 991 path& operator=(path&& __p) noexcept { 992 __pn_ = _VSTD::move(__p.__pn_); 993 return *this; 994 } 995 996 _LIBCPP_INLINE_VISIBILITY 997 path& operator=(string_type&& __s) noexcept { 998 __pn_ = _VSTD::move(__s); 999 return *this; 1000 } 1001 1002 _LIBCPP_INLINE_VISIBILITY 1003 path& assign(string_type&& __s) noexcept { 1004 __pn_ = _VSTD::move(__s); 1005 return *this; 1006 } 1007 1008 template <class _Source> 1009 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 1010 operator=(const _Source& __src) { 1011 return this->assign(__src); 1012 } 1013 1014 template <class _Source> 1015 _EnableIfPathable<_Source> assign(const _Source& __src) { 1016 __pn_.clear(); 1017 _SourceCVT<_Source>::__append_source(__pn_, __src); 1018 return *this; 1019 } 1020 1021 template <class _InputIt> 1022 path& assign(_InputIt __first, _InputIt __last) { 1023 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 1024 __pn_.clear(); 1025 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 1026 return *this; 1027 } 1028 1029public: 1030 // appends 1031#if defined(_LIBCPP_WIN32API) 1032 path& operator/=(const path& __p) { 1033 auto __p_root_name = __p.__root_name(); 1034 auto __p_root_name_size = __p_root_name.size(); 1035 if (__p.is_absolute() || 1036 (!__p_root_name.empty() && __p_root_name != root_name())) { 1037 __pn_ = __p.__pn_; 1038 return *this; 1039 } 1040 if (__p.has_root_directory()) { 1041 path __root_name_str = root_name(); 1042 __pn_ = __root_name_str.native(); 1043 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 1044 return *this; 1045 } 1046 if (has_filename() || (!has_root_directory() && is_absolute())) 1047 __pn_ += preferred_separator; 1048 __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); 1049 return *this; 1050 } 1051 template <class _Source> 1052 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 1053 operator/=(const _Source& __src) { 1054 return operator/=(path(__src)); 1055 } 1056 1057 template <class _Source> 1058 _EnableIfPathable<_Source> append(const _Source& __src) { 1059 return operator/=(path(__src)); 1060 } 1061 1062 template <class _InputIt> 1063 path& append(_InputIt __first, _InputIt __last) { 1064 return operator/=(path(__first, __last)); 1065 } 1066#else 1067 path& operator/=(const path& __p) { 1068 if (__p.is_absolute()) { 1069 __pn_ = __p.__pn_; 1070 return *this; 1071 } 1072 if (has_filename()) 1073 __pn_ += preferred_separator; 1074 __pn_ += __p.native(); 1075 return *this; 1076 } 1077 1078 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src 1079 // is known at compile time to be "/' since the user almost certainly intended 1080 // to append a separator instead of overwriting the path with "/" 1081 template <class _Source> 1082 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> 1083 operator/=(const _Source& __src) { 1084 return this->append(__src); 1085 } 1086 1087 template <class _Source> 1088 _EnableIfPathable<_Source> append(const _Source& __src) { 1089 using _Traits = __is_pathable<_Source>; 1090 using _CVT = _PathCVT<_SourceChar<_Source> >; 1091 bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src)); 1092 if (__source_is_absolute) 1093 __pn_.clear(); 1094 else if (has_filename()) 1095 __pn_ += preferred_separator; 1096 _CVT::__append_source(__pn_, __src); 1097 return *this; 1098 } 1099 1100 template <class _InputIt> 1101 path& append(_InputIt __first, _InputIt __last) { 1102 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 1103 static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); 1104 using _CVT = _PathCVT<_ItVal>; 1105 if (__first != __last && __is_separator(*__first)) 1106 __pn_.clear(); 1107 else if (has_filename()) 1108 __pn_ += preferred_separator; 1109 _CVT::__append_range(__pn_, __first, __last); 1110 return *this; 1111 } 1112#endif 1113 1114 // concatenation 1115 _LIBCPP_INLINE_VISIBILITY 1116 path& operator+=(const path& __x) { 1117 __pn_ += __x.__pn_; 1118 return *this; 1119 } 1120 1121 _LIBCPP_INLINE_VISIBILITY 1122 path& operator+=(const string_type& __x) { 1123 __pn_ += __x; 1124 return *this; 1125 } 1126 1127 _LIBCPP_INLINE_VISIBILITY 1128 path& operator+=(__string_view __x) { 1129 __pn_ += __x; 1130 return *this; 1131 } 1132 1133 _LIBCPP_INLINE_VISIBILITY 1134 path& operator+=(const value_type* __x) { 1135 __pn_ += __x; 1136 return *this; 1137 } 1138 1139 _LIBCPP_INLINE_VISIBILITY 1140 path& operator+=(value_type __x) { 1141 __pn_ += __x; 1142 return *this; 1143 } 1144 1145 template <class _ECharT> 1146 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type 1147 operator+=(_ECharT __x) { 1148 _PathCVT<_ECharT>::__append_source(__pn_, 1149 basic_string_view<_ECharT>(&__x, 1)); 1150 return *this; 1151 } 1152 1153 template <class _Source> 1154 _EnableIfPathable<_Source> operator+=(const _Source& __x) { 1155 return this->concat(__x); 1156 } 1157 1158 template <class _Source> 1159 _EnableIfPathable<_Source> concat(const _Source& __x) { 1160 _SourceCVT<_Source>::__append_source(__pn_, __x); 1161 return *this; 1162 } 1163 1164 template <class _InputIt> 1165 path& concat(_InputIt __first, _InputIt __last) { 1166 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 1167 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 1168 return *this; 1169 } 1170 1171 // modifiers 1172 _LIBCPP_INLINE_VISIBILITY 1173 void clear() noexcept { __pn_.clear(); } 1174 1175 path& make_preferred() { 1176#if defined(_LIBCPP_WIN32API) 1177 _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); 1178#endif 1179 return *this; 1180 } 1181 1182 _LIBCPP_INLINE_VISIBILITY 1183 path& remove_filename() { 1184 auto __fname = __filename(); 1185 if (!__fname.empty()) 1186 __pn_.erase(__fname.data() - __pn_.data()); 1187 return *this; 1188 } 1189 1190 path& replace_filename(const path& __replacement) { 1191 remove_filename(); 1192 return (*this /= __replacement); 1193 } 1194 1195 path& replace_extension(const path& __replacement = path()); 1196 1197 _LIBCPP_INLINE_VISIBILITY 1198 void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } 1199 1200 // private helper to allow reserving memory in the path 1201 _LIBCPP_INLINE_VISIBILITY 1202 void __reserve(size_t __s) { __pn_.reserve(__s); } 1203 1204 // native format observers 1205 _LIBCPP_INLINE_VISIBILITY 1206 const string_type& native() const noexcept { return __pn_; } 1207 1208 _LIBCPP_INLINE_VISIBILITY 1209 const value_type* c_str() const noexcept { return __pn_.c_str(); } 1210 1211 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } 1212 1213#if defined(_LIBCPP_WIN32API) 1214 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; } 1215 1216 _VSTD::wstring generic_wstring() const { 1217 _VSTD::wstring __s; 1218 __s.resize(__pn_.size()); 1219 _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); 1220 return __s; 1221 } 1222 1223#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 1224 template <class _ECharT, class _Traits = char_traits<_ECharT>, 1225 class _Allocator = allocator<_ECharT> > 1226 basic_string<_ECharT, _Traits, _Allocator> 1227 string(const _Allocator& __a = _Allocator()) const { 1228 using _Str = basic_string<_ECharT, _Traits, _Allocator>; 1229 _Str __s(__a); 1230 __s.reserve(__pn_.size()); 1231 _PathExport<_ECharT>::__append(__s, __pn_); 1232 return __s; 1233 } 1234 1235 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { 1236 return string<char>(); 1237 } 1238 _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const { 1239 using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 1240 __u8_string __s; 1241 __s.reserve(__pn_.size()); 1242 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 1243 return __s; 1244 } 1245 1246 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { 1247 return string<char16_t>(); 1248 } 1249 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { 1250 return string<char32_t>(); 1251 } 1252 1253 // generic format observers 1254 template <class _ECharT, class _Traits = char_traits<_ECharT>, 1255 class _Allocator = allocator<_ECharT> > 1256 basic_string<_ECharT, _Traits, _Allocator> 1257 generic_string(const _Allocator& __a = _Allocator()) const { 1258 using _Str = basic_string<_ECharT, _Traits, _Allocator>; 1259 _Str __s = string<_ECharT, _Traits, _Allocator>(__a); 1260 // Note: This (and generic_u8string below) is slightly suboptimal as 1261 // it iterates twice over the string; once to convert it to the right 1262 // character type, and once to replace path delimiters. 1263 _VSTD::replace(__s.begin(), __s.end(), 1264 static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); 1265 return __s; 1266 } 1267 1268 _VSTD::string generic_string() const { return generic_string<char>(); } 1269 _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); } 1270 _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); } 1271 __u8_string generic_u8string() const { 1272 __u8_string __s = u8string(); 1273 _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); 1274 return __s; 1275 } 1276#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 1277#else /* _LIBCPP_WIN32API */ 1278 1279 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; } 1280#ifndef _LIBCPP_HAS_NO_CHAR8_T 1281 _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 1282#else 1283 _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; } 1284#endif 1285 1286#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 1287 template <class _ECharT, class _Traits = char_traits<_ECharT>, 1288 class _Allocator = allocator<_ECharT> > 1289 basic_string<_ECharT, _Traits, _Allocator> 1290 string(const _Allocator& __a = _Allocator()) const { 1291 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>; 1292 using _Str = basic_string<_ECharT, _Traits, _Allocator>; 1293 _Str __s(__a); 1294 __s.reserve(__pn_.size()); 1295 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 1296 return __s; 1297 } 1298 1299#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1300 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { 1301 return string<wchar_t>(); 1302 } 1303#endif 1304 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { 1305 return string<char16_t>(); 1306 } 1307 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { 1308 return string<char32_t>(); 1309 } 1310#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 1311 1312 // generic format observers 1313 _VSTD::string generic_string() const { return __pn_; } 1314#ifndef _LIBCPP_HAS_NO_CHAR8_T 1315 _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } 1316#else 1317 _VSTD::string generic_u8string() const { return __pn_; } 1318#endif 1319 1320#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 1321 template <class _ECharT, class _Traits = char_traits<_ECharT>, 1322 class _Allocator = allocator<_ECharT> > 1323 basic_string<_ECharT, _Traits, _Allocator> 1324 generic_string(const _Allocator& __a = _Allocator()) const { 1325 return string<_ECharT, _Traits, _Allocator>(__a); 1326 } 1327 1328#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1329 _VSTD::wstring generic_wstring() const { return string<wchar_t>(); } 1330#endif 1331 _VSTD::u16string generic_u16string() const { return string<char16_t>(); } 1332 _VSTD::u32string generic_u32string() const { return string<char32_t>(); } 1333#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ 1334#endif /* !_LIBCPP_WIN32API */ 1335 1336private: 1337 int __compare(__string_view) const; 1338 __string_view __root_name() const; 1339 __string_view __root_directory() const; 1340 __string_view __root_path_raw() const; 1341 __string_view __relative_path() const; 1342 __string_view __parent_path() const; 1343 __string_view __filename() const; 1344 __string_view __stem() const; 1345 __string_view __extension() const; 1346 1347public: 1348 // compare 1349 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept { 1350 return __compare(__p.__pn_); 1351 } 1352 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { 1353 return __compare(__s); 1354 } 1355 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { 1356 return __compare(__s); 1357 } 1358 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { 1359 return __compare(__s); 1360 } 1361 1362 // decomposition 1363 _LIBCPP_INLINE_VISIBILITY path root_name() const { 1364 return string_type(__root_name()); 1365 } 1366 _LIBCPP_INLINE_VISIBILITY path root_directory() const { 1367 return string_type(__root_directory()); 1368 } 1369 _LIBCPP_INLINE_VISIBILITY path root_path() const { 1370#if defined(_LIBCPP_WIN32API) 1371 return string_type(__root_path_raw()); 1372#else 1373 return root_name().append(string_type(__root_directory())); 1374#endif 1375 } 1376 _LIBCPP_INLINE_VISIBILITY path relative_path() const { 1377 return string_type(__relative_path()); 1378 } 1379 _LIBCPP_INLINE_VISIBILITY path parent_path() const { 1380 return string_type(__parent_path()); 1381 } 1382 _LIBCPP_INLINE_VISIBILITY path filename() const { 1383 return string_type(__filename()); 1384 } 1385 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); } 1386 _LIBCPP_INLINE_VISIBILITY path extension() const { 1387 return string_type(__extension()); 1388 } 1389 1390 // query 1391 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool 1392 empty() const noexcept { 1393 return __pn_.empty(); 1394 } 1395 1396 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { 1397 return !__root_name().empty(); 1398 } 1399 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { 1400 return !__root_directory().empty(); 1401 } 1402 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { 1403 return !__root_path_raw().empty(); 1404 } 1405 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { 1406 return !__relative_path().empty(); 1407 } 1408 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { 1409 return !__parent_path().empty(); 1410 } 1411 _LIBCPP_INLINE_VISIBILITY bool has_filename() const { 1412 return !__filename().empty(); 1413 } 1414 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } 1415 _LIBCPP_INLINE_VISIBILITY bool has_extension() const { 1416 return !__extension().empty(); 1417 } 1418 1419 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { 1420#if defined(_LIBCPP_WIN32API) 1421 __string_view __root_name_str = __root_name(); 1422 __string_view __root_dir = __root_directory(); 1423 if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { 1424 // A drive letter with no root directory is relative, e.g. x:example. 1425 return !__root_dir.empty(); 1426 } 1427 // If no root name, it's relative, e.g. \example is relative to the current drive 1428 if (__root_name_str.empty()) 1429 return false; 1430 if (__root_name_str.size() < 3) 1431 return false; 1432 // A server root name, like \\server, is always absolute 1433 if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') 1434 return false; 1435 if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') 1436 return false; 1437 // Seems to be a server root name 1438 return true; 1439#else 1440 return has_root_directory(); 1441#endif 1442 } 1443 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } 1444 1445 // relative paths 1446 path lexically_normal() const; 1447 path lexically_relative(const path& __base) const; 1448 1449 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const { 1450 path __result = this->lexically_relative(__base); 1451 if (__result.native().empty()) 1452 return *this; 1453 return __result; 1454 } 1455 1456 // iterators 1457 class _LIBCPP_TYPE_VIS iterator; 1458 typedef iterator const_iterator; 1459 1460 iterator begin() const; 1461 iterator end() const; 1462 1463#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 1464 template <class _CharT, class _Traits> 1465 _LIBCPP_INLINE_VISIBILITY friend 1466 typename enable_if<is_same<_CharT, value_type>::value && 1467 is_same<_Traits, char_traits<value_type> >::value, 1468 basic_ostream<_CharT, _Traits>&>::type 1469 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1470 __os << _VSTD::__quoted(__p.native()); 1471 return __os; 1472 } 1473 1474 template <class _CharT, class _Traits> 1475 _LIBCPP_INLINE_VISIBILITY friend 1476 typename enable_if<!is_same<_CharT, value_type>::value || 1477 !is_same<_Traits, char_traits<value_type> >::value, 1478 basic_ostream<_CharT, _Traits>&>::type 1479 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1480 __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); 1481 return __os; 1482 } 1483 1484 template <class _CharT, class _Traits> 1485 _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& 1486 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { 1487 basic_string<_CharT, _Traits> __tmp; 1488 __is >> __quoted(__tmp); 1489 __p = __tmp; 1490 return __is; 1491 } 1492#endif // !_LIBCPP_HAS_NO_LOCALIZATION 1493 1494 friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { 1495 return __lhs.compare(__rhs) == 0; 1496 } 1497 friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { 1498 return __lhs.compare(__rhs) != 0; 1499 } 1500 friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { 1501 return __lhs.compare(__rhs) < 0; 1502 } 1503 friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { 1504 return __lhs.compare(__rhs) <= 0; 1505 } 1506 friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { 1507 return __lhs.compare(__rhs) > 0; 1508 } 1509 friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { 1510 return __lhs.compare(__rhs) >= 0; 1511 } 1512 1513 friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, 1514 const path& __rhs) { 1515 path __result(__lhs); 1516 __result /= __rhs; 1517 return __result; 1518 } 1519private: 1520 inline _LIBCPP_INLINE_VISIBILITY path& 1521 __assign_view(__string_view const& __s) noexcept { 1522 __pn_ = string_type(__s); 1523 return *this; 1524 } 1525 string_type __pn_; 1526}; 1527 1528inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { 1529 __lhs.swap(__rhs); 1530} 1531 1532_LIBCPP_FUNC_VIS 1533size_t hash_value(const path& __p) noexcept; 1534 1535template <class _InputIt> 1536_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1537 typename enable_if<__is_pathable<_InputIt>::value, path>::type 1538 u8path(_InputIt __f, _InputIt __l) { 1539 static_assert( 1540#ifndef _LIBCPP_HAS_NO_CHAR8_T 1541 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || 1542#endif 1543 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, 1544 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" 1545 " or 'char8_t'"); 1546#if defined(_LIBCPP_WIN32API) 1547 string __tmp(__f, __l); 1548 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 1549 _VSTD::wstring __w; 1550 __w.reserve(__tmp.size()); 1551 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); 1552 return path(__w); 1553#else 1554 return path(__f, __l); 1555#endif /* !_LIBCPP_WIN32API */ 1556} 1557 1558#if defined(_LIBCPP_WIN32API) 1559template <class _InputIt> 1560_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1561 typename enable_if<__is_pathable<_InputIt>::value, path>::type 1562 u8path(_InputIt __f, _NullSentinel) { 1563 static_assert( 1564#ifndef _LIBCPP_HAS_NO_CHAR8_T 1565 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || 1566#endif 1567 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, 1568 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" 1569 " or 'char8_t'"); 1570 string __tmp; 1571 const char __sentinel = char{}; 1572 for (; *__f != __sentinel; ++__f) 1573 __tmp.push_back(*__f); 1574 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 1575 _VSTD::wstring __w; 1576 __w.reserve(__tmp.size()); 1577 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); 1578 return path(__w); 1579} 1580#endif /* _LIBCPP_WIN32API */ 1581 1582template <class _Source> 1583_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1584 typename enable_if<__is_pathable<_Source>::value, path>::type 1585 u8path(const _Source& __s) { 1586 static_assert( 1587#ifndef _LIBCPP_HAS_NO_CHAR8_T 1588 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value || 1589#endif 1590 is_same<typename __is_pathable<_Source>::__char_type, char>::value, 1591 "u8path(Source const&) requires Source have a character type of type " 1592 "'char' or 'char8_t'"); 1593#if defined(_LIBCPP_WIN32API) 1594 using _Traits = __is_pathable<_Source>; 1595 return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); 1596#else 1597 return path(__s); 1598#endif 1599} 1600 1601class _LIBCPP_TYPE_VIS path::iterator { 1602public: 1603 enum _ParserState : unsigned char { 1604 _Singular, 1605 _BeforeBegin, 1606 _InRootName, 1607 _InRootDir, 1608 _InFilenames, 1609 _InTrailingSep, 1610 _AtEnd 1611 }; 1612 1613public: 1614 typedef bidirectional_iterator_tag iterator_category; 1615 1616 typedef path value_type; 1617 typedef ptrdiff_t difference_type; 1618 typedef const path* pointer; 1619 typedef const path& reference; 1620 1621 typedef void 1622 __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator 1623 1624public: 1625 _LIBCPP_INLINE_VISIBILITY 1626 iterator() 1627 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), 1628 __state_(_Singular) {} 1629 1630 iterator(const iterator&) = default; 1631 ~iterator() = default; 1632 1633 iterator& operator=(const iterator&) = default; 1634 1635 _LIBCPP_INLINE_VISIBILITY 1636 reference operator*() const { return __stashed_elem_; } 1637 1638 _LIBCPP_INLINE_VISIBILITY 1639 pointer operator->() const { return &__stashed_elem_; } 1640 1641 _LIBCPP_INLINE_VISIBILITY 1642 iterator& operator++() { 1643 _LIBCPP_ASSERT(__state_ != _Singular, 1644 "attempting to increment a singular iterator"); 1645 _LIBCPP_ASSERT(__state_ != _AtEnd, 1646 "attempting to increment the end iterator"); 1647 return __increment(); 1648 } 1649 1650 _LIBCPP_INLINE_VISIBILITY 1651 iterator operator++(int) { 1652 iterator __it(*this); 1653 this->operator++(); 1654 return __it; 1655 } 1656 1657 _LIBCPP_INLINE_VISIBILITY 1658 iterator& operator--() { 1659 _LIBCPP_ASSERT(__state_ != _Singular, 1660 "attempting to decrement a singular iterator"); 1661 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), 1662 "attempting to decrement the begin iterator"); 1663 return __decrement(); 1664 } 1665 1666 _LIBCPP_INLINE_VISIBILITY 1667 iterator operator--(int) { 1668 iterator __it(*this); 1669 this->operator--(); 1670 return __it; 1671 } 1672 1673private: 1674 friend class path; 1675 1676 inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, 1677 const iterator&); 1678 1679 iterator& __increment(); 1680 iterator& __decrement(); 1681 1682 path __stashed_elem_; 1683 const path* __path_ptr_; 1684 path::__string_view __entry_; 1685 _ParserState __state_; 1686}; 1687 1688inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, 1689 const path::iterator& __rhs) { 1690 return __lhs.__path_ptr_ == __rhs.__path_ptr_ && 1691 __lhs.__entry_.data() == __rhs.__entry_.data(); 1692} 1693 1694inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, 1695 const path::iterator& __rhs) { 1696 return !(__lhs == __rhs); 1697} 1698 1699// TODO(ldionne): We need to pop the pragma and push it again after 1700// filesystem_error to work around PR41078. 1701_LIBCPP_AVAILABILITY_FILESYSTEM_POP 1702 1703class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { 1704public: 1705 _LIBCPP_INLINE_VISIBILITY 1706 filesystem_error(const string& __what, error_code __ec) 1707 : system_error(__ec, __what), 1708 __storage_(make_shared<_Storage>(path(), path())) { 1709 __create_what(0); 1710 } 1711 1712 _LIBCPP_INLINE_VISIBILITY 1713 filesystem_error(const string& __what, const path& __p1, error_code __ec) 1714 : system_error(__ec, __what), 1715 __storage_(make_shared<_Storage>(__p1, path())) { 1716 __create_what(1); 1717 } 1718 1719 _LIBCPP_INLINE_VISIBILITY 1720 filesystem_error(const string& __what, const path& __p1, const path& __p2, 1721 error_code __ec) 1722 : system_error(__ec, __what), 1723 __storage_(make_shared<_Storage>(__p1, __p2)) { 1724 __create_what(2); 1725 } 1726 1727 _LIBCPP_INLINE_VISIBILITY 1728 const path& path1() const noexcept { return __storage_->__p1_; } 1729 1730 _LIBCPP_INLINE_VISIBILITY 1731 const path& path2() const noexcept { return __storage_->__p2_; } 1732 1733 filesystem_error(const filesystem_error&) = default; 1734 ~filesystem_error() override; // key function 1735 1736 _LIBCPP_INLINE_VISIBILITY 1737 const char* what() const noexcept override { 1738 return __storage_->__what_.c_str(); 1739 } 1740 1741 void __create_what(int __num_paths); 1742 1743private: 1744 struct _LIBCPP_HIDDEN _Storage { 1745 _LIBCPP_INLINE_VISIBILITY 1746 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} 1747 1748 path __p1_; 1749 path __p2_; 1750 string __what_; 1751 }; 1752 shared_ptr<_Storage> __storage_; 1753}; 1754 1755_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 1756 1757template <class... _Args> 1758_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 1759#ifndef _LIBCPP_NO_EXCEPTIONS 1760void __throw_filesystem_error(_Args&&... __args) { 1761 throw filesystem_error(_VSTD::forward<_Args>(__args)...); 1762} 1763#else 1764void __throw_filesystem_error(_Args&&...) { 1765 _VSTD::abort(); 1766} 1767#endif 1768 1769// operational functions 1770 1771_LIBCPP_FUNC_VIS 1772path __absolute(const path&, error_code* __ec = nullptr); 1773_LIBCPP_FUNC_VIS 1774path __canonical(const path&, error_code* __ec = nullptr); 1775_LIBCPP_FUNC_VIS 1776void __copy(const path& __from, const path& __to, copy_options __opt, 1777 error_code* __ec = nullptr); 1778_LIBCPP_FUNC_VIS 1779bool __copy_file(const path& __from, const path& __to, copy_options __opt, 1780 error_code* __ec = nullptr); 1781_LIBCPP_FUNC_VIS 1782void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, 1783 error_code* __ec = nullptr); 1784_LIBCPP_FUNC_VIS 1785bool __create_directories(const path& p, error_code* ec = nullptr); 1786_LIBCPP_FUNC_VIS 1787bool __create_directory(const path& p, error_code* ec = nullptr); 1788_LIBCPP_FUNC_VIS 1789bool __create_directory(const path& p, const path& attributes, 1790 error_code* ec = nullptr); 1791_LIBCPP_FUNC_VIS 1792void __create_directory_symlink(const path& __to, const path& __new_symlink, 1793 error_code* __ec = nullptr); 1794_LIBCPP_FUNC_VIS 1795void __create_hard_link(const path& __to, const path& __new_hard_link, 1796 error_code* __ec = nullptr); 1797_LIBCPP_FUNC_VIS 1798void __create_symlink(const path& __to, const path& __new_symlink, 1799 error_code* __ec = nullptr); 1800_LIBCPP_FUNC_VIS 1801path __current_path(error_code* __ec = nullptr); 1802_LIBCPP_FUNC_VIS 1803void __current_path(const path&, error_code* __ec = nullptr); 1804_LIBCPP_FUNC_VIS 1805bool __equivalent(const path&, const path&, error_code* __ec = nullptr); 1806_LIBCPP_FUNC_VIS 1807uintmax_t __file_size(const path&, error_code* __ec = nullptr); 1808_LIBCPP_FUNC_VIS 1809uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); 1810_LIBCPP_FUNC_VIS 1811bool __fs_is_empty(const path& p, error_code* ec = nullptr); 1812_LIBCPP_FUNC_VIS 1813file_time_type __last_write_time(const path& p, error_code* ec = nullptr); 1814_LIBCPP_FUNC_VIS 1815void __last_write_time(const path& p, file_time_type new_time, 1816 error_code* ec = nullptr); 1817_LIBCPP_FUNC_VIS 1818void __permissions(const path&, perms, perm_options, error_code* = nullptr); 1819_LIBCPP_FUNC_VIS 1820path __read_symlink(const path& p, error_code* ec = nullptr); 1821_LIBCPP_FUNC_VIS 1822bool __remove(const path& p, error_code* ec = nullptr); 1823_LIBCPP_FUNC_VIS 1824uintmax_t __remove_all(const path& p, error_code* ec = nullptr); 1825_LIBCPP_FUNC_VIS 1826void __rename(const path& from, const path& to, error_code* ec = nullptr); 1827_LIBCPP_FUNC_VIS 1828void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); 1829_LIBCPP_FUNC_VIS 1830space_info __space(const path&, error_code* __ec = nullptr); 1831_LIBCPP_FUNC_VIS 1832file_status __status(const path&, error_code* __ec = nullptr); 1833_LIBCPP_FUNC_VIS 1834file_status __symlink_status(const path&, error_code* __ec = nullptr); 1835_LIBCPP_FUNC_VIS 1836path __system_complete(const path&, error_code* __ec = nullptr); 1837_LIBCPP_FUNC_VIS 1838path __temp_directory_path(error_code* __ec = nullptr); 1839_LIBCPP_FUNC_VIS 1840path __weakly_canonical(path const& __p, error_code* __ec = nullptr); 1841 1842inline _LIBCPP_INLINE_VISIBILITY path current_path() { 1843 return __current_path(); 1844} 1845 1846inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { 1847 return __current_path(&__ec); 1848} 1849 1850inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { 1851 __current_path(__p); 1852} 1853 1854inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, 1855 error_code& __ec) noexcept { 1856 __current_path(__p, &__ec); 1857} 1858 1859inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { 1860 return __absolute(__p); 1861} 1862 1863inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, 1864 error_code& __ec) { 1865 return __absolute(__p, &__ec); 1866} 1867 1868inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { 1869 return __canonical(__p); 1870} 1871 1872inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, 1873 error_code& __ec) { 1874 return __canonical(__p, &__ec); 1875} 1876 1877inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, 1878 const path& __to) { 1879 __copy(__from, __to, copy_options::none); 1880} 1881 1882inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1883 error_code& __ec) { 1884 __copy(__from, __to, copy_options::none, &__ec); 1885} 1886 1887inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1888 copy_options __opt) { 1889 __copy(__from, __to, __opt); 1890} 1891 1892inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1893 copy_options __opt, 1894 error_code& __ec) { 1895 __copy(__from, __to, __opt, &__ec); 1896} 1897 1898inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, 1899 const path& __to) { 1900 return __copy_file(__from, __to, copy_options::none); 1901} 1902 1903inline _LIBCPP_INLINE_VISIBILITY bool 1904copy_file(const path& __from, const path& __to, error_code& __ec) { 1905 return __copy_file(__from, __to, copy_options::none, &__ec); 1906} 1907 1908inline _LIBCPP_INLINE_VISIBILITY bool 1909copy_file(const path& __from, const path& __to, copy_options __opt) { 1910 return __copy_file(__from, __to, __opt); 1911} 1912 1913inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, 1914 const path& __to, 1915 copy_options __opt, 1916 error_code& __ec) { 1917 return __copy_file(__from, __to, __opt, &__ec); 1918} 1919 1920inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, 1921 const path& __new) { 1922 __copy_symlink(__existing, __new); 1923} 1924 1925inline _LIBCPP_INLINE_VISIBILITY void 1926copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { 1927 __copy_symlink(__ext, __new, &__ec); 1928} 1929 1930inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { 1931 return __create_directories(__p); 1932} 1933 1934inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, 1935 error_code& __ec) { 1936 return __create_directories(__p, &__ec); 1937} 1938 1939inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { 1940 return __create_directory(__p); 1941} 1942 1943inline _LIBCPP_INLINE_VISIBILITY bool 1944create_directory(const path& __p, error_code& __ec) noexcept { 1945 return __create_directory(__p, &__ec); 1946} 1947 1948inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, 1949 const path& __attrs) { 1950 return __create_directory(__p, __attrs); 1951} 1952 1953inline _LIBCPP_INLINE_VISIBILITY bool 1954create_directory(const path& __p, const path& __attrs, 1955 error_code& __ec) noexcept { 1956 return __create_directory(__p, __attrs, &__ec); 1957} 1958 1959inline _LIBCPP_INLINE_VISIBILITY void 1960create_directory_symlink(const path& __to, const path& __new) { 1961 __create_directory_symlink(__to, __new); 1962} 1963 1964inline _LIBCPP_INLINE_VISIBILITY void 1965create_directory_symlink(const path& __to, const path& __new, 1966 error_code& __ec) noexcept { 1967 __create_directory_symlink(__to, __new, &__ec); 1968} 1969 1970inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, 1971 const path& __new) { 1972 __create_hard_link(__to, __new); 1973} 1974 1975inline _LIBCPP_INLINE_VISIBILITY void 1976create_hard_link(const path& __to, const path& __new, 1977 error_code& __ec) noexcept { 1978 __create_hard_link(__to, __new, &__ec); 1979} 1980 1981inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, 1982 const path& __new) { 1983 __create_symlink(__to, __new); 1984} 1985 1986inline _LIBCPP_INLINE_VISIBILITY void 1987create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { 1988 return __create_symlink(__to, __new, &__ec); 1989} 1990 1991inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { 1992 return __s.type() != file_type::none; 1993} 1994 1995inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { 1996 return status_known(__s) && __s.type() != file_type::not_found; 1997} 1998 1999inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { 2000 return exists(__status(__p)); 2001} 2002 2003inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, 2004 error_code& __ec) noexcept { 2005 auto __s = __status(__p, &__ec); 2006 if (status_known(__s)) 2007 __ec.clear(); 2008 return exists(__s); 2009} 2010 2011inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, 2012 const path& __p2) { 2013 return __equivalent(__p1, __p2); 2014} 2015 2016inline _LIBCPP_INLINE_VISIBILITY bool 2017equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { 2018 return __equivalent(__p1, __p2, &__ec); 2019} 2020 2021inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { 2022 return __file_size(__p); 2023} 2024 2025inline _LIBCPP_INLINE_VISIBILITY uintmax_t 2026file_size(const path& __p, error_code& __ec) noexcept { 2027 return __file_size(__p, &__ec); 2028} 2029 2030inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { 2031 return __hard_link_count(__p); 2032} 2033 2034inline _LIBCPP_INLINE_VISIBILITY uintmax_t 2035hard_link_count(const path& __p, error_code& __ec) noexcept { 2036 return __hard_link_count(__p, &__ec); 2037} 2038 2039inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { 2040 return __s.type() == file_type::block; 2041} 2042 2043inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { 2044 return is_block_file(__status(__p)); 2045} 2046 2047inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, 2048 error_code& __ec) noexcept { 2049 return is_block_file(__status(__p, &__ec)); 2050} 2051 2052inline _LIBCPP_INLINE_VISIBILITY bool 2053is_character_file(file_status __s) noexcept { 2054 return __s.type() == file_type::character; 2055} 2056 2057inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { 2058 return is_character_file(__status(__p)); 2059} 2060 2061inline _LIBCPP_INLINE_VISIBILITY bool 2062is_character_file(const path& __p, error_code& __ec) noexcept { 2063 return is_character_file(__status(__p, &__ec)); 2064} 2065 2066inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { 2067 return __s.type() == file_type::directory; 2068} 2069 2070inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { 2071 return is_directory(__status(__p)); 2072} 2073 2074inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, 2075 error_code& __ec) noexcept { 2076 return is_directory(__status(__p, &__ec)); 2077} 2078 2079inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { 2080 return __fs_is_empty(__p); 2081} 2082 2083inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, 2084 error_code& __ec) { 2085 return __fs_is_empty(__p, &__ec); 2086} 2087 2088inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { 2089 return __s.type() == file_type::fifo; 2090} 2091inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { 2092 return is_fifo(__status(__p)); 2093} 2094 2095inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, 2096 error_code& __ec) noexcept { 2097 return is_fifo(__status(__p, &__ec)); 2098} 2099 2100inline _LIBCPP_INLINE_VISIBILITY bool 2101is_regular_file(file_status __s) noexcept { 2102 return __s.type() == file_type::regular; 2103} 2104 2105inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { 2106 return is_regular_file(__status(__p)); 2107} 2108 2109inline _LIBCPP_INLINE_VISIBILITY bool 2110is_regular_file(const path& __p, error_code& __ec) noexcept { 2111 return is_regular_file(__status(__p, &__ec)); 2112} 2113 2114inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { 2115 return __s.type() == file_type::socket; 2116} 2117 2118inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { 2119 return is_socket(__status(__p)); 2120} 2121 2122inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, 2123 error_code& __ec) noexcept { 2124 return is_socket(__status(__p, &__ec)); 2125} 2126 2127inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { 2128 return __s.type() == file_type::symlink; 2129} 2130 2131inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { 2132 return is_symlink(__symlink_status(__p)); 2133} 2134 2135inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, 2136 error_code& __ec) noexcept { 2137 return is_symlink(__symlink_status(__p, &__ec)); 2138} 2139 2140inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { 2141 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && 2142 !is_symlink(__s); 2143} 2144 2145inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { 2146 return is_other(__status(__p)); 2147} 2148 2149inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, 2150 error_code& __ec) noexcept { 2151 return is_other(__status(__p, &__ec)); 2152} 2153 2154inline _LIBCPP_INLINE_VISIBILITY file_time_type 2155last_write_time(const path& __p) { 2156 return __last_write_time(__p); 2157} 2158 2159inline _LIBCPP_INLINE_VISIBILITY file_time_type 2160last_write_time(const path& __p, error_code& __ec) noexcept { 2161 return __last_write_time(__p, &__ec); 2162} 2163 2164inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, 2165 file_time_type __t) { 2166 __last_write_time(__p, __t); 2167} 2168 2169inline _LIBCPP_INLINE_VISIBILITY void 2170last_write_time(const path& __p, file_time_type __t, 2171 error_code& __ec) noexcept { 2172 __last_write_time(__p, __t, &__ec); 2173} 2174 2175inline _LIBCPP_INLINE_VISIBILITY void 2176permissions(const path& __p, perms __prms, 2177 perm_options __opts = perm_options::replace) { 2178 __permissions(__p, __prms, __opts); 2179} 2180 2181inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, 2182 error_code& __ec) noexcept { 2183 __permissions(__p, __prms, perm_options::replace, &__ec); 2184} 2185 2186inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, 2187 perm_options __opts, 2188 error_code& __ec) { 2189 __permissions(__p, __prms, __opts, &__ec); 2190} 2191 2192inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, 2193 const path& __base, 2194 error_code& __ec) { 2195 path __tmp = __weakly_canonical(__p, &__ec); 2196 if (__ec) 2197 return {}; 2198 path __tmp_base = __weakly_canonical(__base, &__ec); 2199 if (__ec) 2200 return {}; 2201 return __tmp.lexically_proximate(__tmp_base); 2202} 2203 2204inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, 2205 error_code& __ec) { 2206 return proximate(__p, current_path(), __ec); 2207} 2208 2209inline _LIBCPP_INLINE_VISIBILITY path 2210proximate(const path& __p, const path& __base = current_path()) { 2211 return __weakly_canonical(__p).lexically_proximate( 2212 __weakly_canonical(__base)); 2213} 2214 2215inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { 2216 return __read_symlink(__p); 2217} 2218 2219inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, 2220 error_code& __ec) { 2221 return __read_symlink(__p, &__ec); 2222} 2223 2224inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, 2225 const path& __base, 2226 error_code& __ec) { 2227 path __tmp = __weakly_canonical(__p, &__ec); 2228 if (__ec) 2229 return path(); 2230 path __tmpbase = __weakly_canonical(__base, &__ec); 2231 if (__ec) 2232 return path(); 2233 return __tmp.lexically_relative(__tmpbase); 2234} 2235 2236inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, 2237 error_code& __ec) { 2238 return relative(__p, current_path(), __ec); 2239} 2240 2241inline _LIBCPP_INLINE_VISIBILITY path 2242relative(const path& __p, const path& __base = current_path()) { 2243 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); 2244} 2245 2246inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { 2247 return __remove(__p); 2248} 2249 2250inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, 2251 error_code& __ec) noexcept { 2252 return __remove(__p, &__ec); 2253} 2254 2255inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { 2256 return __remove_all(__p); 2257} 2258 2259inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, 2260 error_code& __ec) { 2261 return __remove_all(__p, &__ec); 2262} 2263 2264inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, 2265 const path& __to) { 2266 return __rename(__from, __to); 2267} 2268 2269inline _LIBCPP_INLINE_VISIBILITY void 2270rename(const path& __from, const path& __to, error_code& __ec) noexcept { 2271 return __rename(__from, __to, &__ec); 2272} 2273 2274inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, 2275 uintmax_t __ns) { 2276 return __resize_file(__p, __ns); 2277} 2278 2279inline _LIBCPP_INLINE_VISIBILITY void 2280resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { 2281 return __resize_file(__p, __ns, &__ec); 2282} 2283 2284inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { 2285 return __space(__p); 2286} 2287 2288inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, 2289 error_code& __ec) noexcept { 2290 return __space(__p, &__ec); 2291} 2292 2293inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { 2294 return __status(__p); 2295} 2296 2297inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, 2298 error_code& __ec) noexcept { 2299 return __status(__p, &__ec); 2300} 2301 2302inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { 2303 return __symlink_status(__p); 2304} 2305 2306inline _LIBCPP_INLINE_VISIBILITY file_status 2307symlink_status(const path& __p, error_code& __ec) noexcept { 2308 return __symlink_status(__p, &__ec); 2309} 2310 2311inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { 2312 return __temp_directory_path(); 2313} 2314 2315inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { 2316 return __temp_directory_path(&__ec); 2317} 2318 2319inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { 2320 return __weakly_canonical(__p); 2321} 2322 2323inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, 2324 error_code& __ec) { 2325 return __weakly_canonical(__p, &__ec); 2326} 2327 2328class directory_iterator; 2329class recursive_directory_iterator; 2330class _LIBCPP_HIDDEN __dir_stream; 2331 2332class directory_entry { 2333 typedef _VSTD_FS::path _Path; 2334 2335public: 2336 // constructors and destructors 2337 directory_entry() noexcept = default; 2338 directory_entry(directory_entry const&) = default; 2339 directory_entry(directory_entry&&) noexcept = default; 2340 2341 _LIBCPP_INLINE_VISIBILITY 2342 explicit directory_entry(_Path const& __p) : __p_(__p) { 2343 error_code __ec; 2344 __refresh(&__ec); 2345 } 2346 2347 _LIBCPP_INLINE_VISIBILITY 2348 directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { 2349 __refresh(&__ec); 2350 } 2351 2352 ~directory_entry() {} 2353 2354 directory_entry& operator=(directory_entry const&) = default; 2355 directory_entry& operator=(directory_entry&&) noexcept = default; 2356 2357 _LIBCPP_INLINE_VISIBILITY 2358 void assign(_Path const& __p) { 2359 __p_ = __p; 2360 error_code __ec; 2361 __refresh(&__ec); 2362 } 2363 2364 _LIBCPP_INLINE_VISIBILITY 2365 void assign(_Path const& __p, error_code& __ec) { 2366 __p_ = __p; 2367 __refresh(&__ec); 2368 } 2369 2370 _LIBCPP_INLINE_VISIBILITY 2371 void replace_filename(_Path const& __p) { 2372 __p_.replace_filename(__p); 2373 error_code __ec; 2374 __refresh(&__ec); 2375 } 2376 2377 _LIBCPP_INLINE_VISIBILITY 2378 void replace_filename(_Path const& __p, error_code& __ec) { 2379 __p_ = __p_.parent_path() / __p; 2380 __refresh(&__ec); 2381 } 2382 2383 _LIBCPP_INLINE_VISIBILITY 2384 void refresh() { __refresh(); } 2385 2386 _LIBCPP_INLINE_VISIBILITY 2387 void refresh(error_code& __ec) noexcept { __refresh(&__ec); } 2388 2389 _LIBCPP_INLINE_VISIBILITY 2390 _Path const& path() const noexcept { return __p_; } 2391 2392 _LIBCPP_INLINE_VISIBILITY 2393 operator const _Path&() const noexcept { return __p_; } 2394 2395 _LIBCPP_INLINE_VISIBILITY 2396 bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } 2397 2398 _LIBCPP_INLINE_VISIBILITY 2399 bool exists(error_code& __ec) const noexcept { 2400 return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); 2401 } 2402 2403 _LIBCPP_INLINE_VISIBILITY 2404 bool is_block_file() const { return __get_ft() == file_type::block; } 2405 2406 _LIBCPP_INLINE_VISIBILITY 2407 bool is_block_file(error_code& __ec) const noexcept { 2408 return __get_ft(&__ec) == file_type::block; 2409 } 2410 2411 _LIBCPP_INLINE_VISIBILITY 2412 bool is_character_file() const { return __get_ft() == file_type::character; } 2413 2414 _LIBCPP_INLINE_VISIBILITY 2415 bool is_character_file(error_code& __ec) const noexcept { 2416 return __get_ft(&__ec) == file_type::character; 2417 } 2418 2419 _LIBCPP_INLINE_VISIBILITY 2420 bool is_directory() const { return __get_ft() == file_type::directory; } 2421 2422 _LIBCPP_INLINE_VISIBILITY 2423 bool is_directory(error_code& __ec) const noexcept { 2424 return __get_ft(&__ec) == file_type::directory; 2425 } 2426 2427 _LIBCPP_INLINE_VISIBILITY 2428 bool is_fifo() const { return __get_ft() == file_type::fifo; } 2429 2430 _LIBCPP_INLINE_VISIBILITY 2431 bool is_fifo(error_code& __ec) const noexcept { 2432 return __get_ft(&__ec) == file_type::fifo; 2433 } 2434 2435 _LIBCPP_INLINE_VISIBILITY 2436 bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } 2437 2438 _LIBCPP_INLINE_VISIBILITY 2439 bool is_other(error_code& __ec) const noexcept { 2440 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); 2441 } 2442 2443 _LIBCPP_INLINE_VISIBILITY 2444 bool is_regular_file() const { return __get_ft() == file_type::regular; } 2445 2446 _LIBCPP_INLINE_VISIBILITY 2447 bool is_regular_file(error_code& __ec) const noexcept { 2448 return __get_ft(&__ec) == file_type::regular; 2449 } 2450 2451 _LIBCPP_INLINE_VISIBILITY 2452 bool is_socket() const { return __get_ft() == file_type::socket; } 2453 2454 _LIBCPP_INLINE_VISIBILITY 2455 bool is_socket(error_code& __ec) const noexcept { 2456 return __get_ft(&__ec) == file_type::socket; 2457 } 2458 2459 _LIBCPP_INLINE_VISIBILITY 2460 bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } 2461 2462 _LIBCPP_INLINE_VISIBILITY 2463 bool is_symlink(error_code& __ec) const noexcept { 2464 return __get_sym_ft(&__ec) == file_type::symlink; 2465 } 2466 _LIBCPP_INLINE_VISIBILITY 2467 uintmax_t file_size() const { return __get_size(); } 2468 2469 _LIBCPP_INLINE_VISIBILITY 2470 uintmax_t file_size(error_code& __ec) const noexcept { 2471 return __get_size(&__ec); 2472 } 2473 2474 _LIBCPP_INLINE_VISIBILITY 2475 uintmax_t hard_link_count() const { return __get_nlink(); } 2476 2477 _LIBCPP_INLINE_VISIBILITY 2478 uintmax_t hard_link_count(error_code& __ec) const noexcept { 2479 return __get_nlink(&__ec); 2480 } 2481 2482 _LIBCPP_INLINE_VISIBILITY 2483 file_time_type last_write_time() const { return __get_write_time(); } 2484 2485 _LIBCPP_INLINE_VISIBILITY 2486 file_time_type last_write_time(error_code& __ec) const noexcept { 2487 return __get_write_time(&__ec); 2488 } 2489 2490 _LIBCPP_INLINE_VISIBILITY 2491 file_status status() const { return __get_status(); } 2492 2493 _LIBCPP_INLINE_VISIBILITY 2494 file_status status(error_code& __ec) const noexcept { 2495 return __get_status(&__ec); 2496 } 2497 2498 _LIBCPP_INLINE_VISIBILITY 2499 file_status symlink_status() const { return __get_symlink_status(); } 2500 2501 _LIBCPP_INLINE_VISIBILITY 2502 file_status symlink_status(error_code& __ec) const noexcept { 2503 return __get_symlink_status(&__ec); 2504 } 2505 2506 _LIBCPP_INLINE_VISIBILITY 2507 bool operator<(directory_entry const& __rhs) const noexcept { 2508 return __p_ < __rhs.__p_; 2509 } 2510 2511 _LIBCPP_INLINE_VISIBILITY 2512 bool operator==(directory_entry const& __rhs) const noexcept { 2513 return __p_ == __rhs.__p_; 2514 } 2515 2516 _LIBCPP_INLINE_VISIBILITY 2517 bool operator!=(directory_entry const& __rhs) const noexcept { 2518 return __p_ != __rhs.__p_; 2519 } 2520 2521 _LIBCPP_INLINE_VISIBILITY 2522 bool operator<=(directory_entry const& __rhs) const noexcept { 2523 return __p_ <= __rhs.__p_; 2524 } 2525 2526 _LIBCPP_INLINE_VISIBILITY 2527 bool operator>(directory_entry const& __rhs) const noexcept { 2528 return __p_ > __rhs.__p_; 2529 } 2530 2531 _LIBCPP_INLINE_VISIBILITY 2532 bool operator>=(directory_entry const& __rhs) const noexcept { 2533 return __p_ >= __rhs.__p_; 2534 } 2535 2536private: 2537 friend class directory_iterator; 2538 friend class recursive_directory_iterator; 2539 friend class __dir_stream; 2540 2541 enum _CacheType : unsigned char { 2542 _Empty, 2543 _IterSymlink, 2544 _IterNonSymlink, 2545 _RefreshSymlink, 2546 _RefreshSymlinkUnresolved, 2547 _RefreshNonSymlink 2548 }; 2549 2550 struct __cached_data { 2551 uintmax_t __size_; 2552 uintmax_t __nlink_; 2553 file_time_type __write_time_; 2554 perms __sym_perms_; 2555 perms __non_sym_perms_; 2556 file_type __type_; 2557 _CacheType __cache_type_; 2558 2559 _LIBCPP_INLINE_VISIBILITY 2560 __cached_data() noexcept { __reset(); } 2561 2562 _LIBCPP_INLINE_VISIBILITY 2563 void __reset() { 2564 __cache_type_ = _Empty; 2565 __type_ = file_type::none; 2566 __sym_perms_ = __non_sym_perms_ = perms::unknown; 2567 __size_ = __nlink_ = uintmax_t(-1); 2568 __write_time_ = file_time_type::min(); 2569 } 2570 }; 2571 2572 _LIBCPP_INLINE_VISIBILITY 2573 static __cached_data __create_iter_result(file_type __ft) { 2574 __cached_data __data; 2575 __data.__type_ = __ft; 2576 __data.__cache_type_ = [&]() { 2577 switch (__ft) { 2578 case file_type::none: 2579 return _Empty; 2580 case file_type::symlink: 2581 return _IterSymlink; 2582 default: 2583 return _IterNonSymlink; 2584 } 2585 }(); 2586 return __data; 2587 } 2588 2589 _LIBCPP_INLINE_VISIBILITY 2590 void __assign_iter_entry(_Path&& __p, __cached_data __dt) { 2591 __p_ = _VSTD::move(__p); 2592 __data_ = __dt; 2593 } 2594 2595 _LIBCPP_FUNC_VIS 2596 error_code __do_refresh() noexcept; 2597 2598 _LIBCPP_INLINE_VISIBILITY 2599 static bool __is_dne_error(error_code const& __ec) { 2600 if (!__ec) 2601 return true; 2602 switch (static_cast<errc>(__ec.value())) { 2603 case errc::no_such_file_or_directory: 2604 case errc::not_a_directory: 2605 return true; 2606 default: 2607 return false; 2608 } 2609 } 2610 2611 _LIBCPP_INLINE_VISIBILITY 2612 void __handle_error(const char* __msg, error_code* __dest_ec, 2613 error_code const& __ec, bool __allow_dne = false) const { 2614 if (__dest_ec) { 2615 *__dest_ec = __ec; 2616 return; 2617 } 2618 if (__ec && (!__allow_dne || !__is_dne_error(__ec))) 2619 __throw_filesystem_error(__msg, __p_, __ec); 2620 } 2621 2622 _LIBCPP_INLINE_VISIBILITY 2623 void __refresh(error_code* __ec = nullptr) { 2624 __handle_error("in directory_entry::refresh", __ec, __do_refresh(), 2625 /*allow_dne*/ true); 2626 } 2627 2628 _LIBCPP_INLINE_VISIBILITY 2629 file_type __get_sym_ft(error_code* __ec = nullptr) const { 2630 switch (__data_.__cache_type_) { 2631 case _Empty: 2632 return __symlink_status(__p_, __ec).type(); 2633 case _IterSymlink: 2634 case _RefreshSymlink: 2635 case _RefreshSymlinkUnresolved: 2636 if (__ec) 2637 __ec->clear(); 2638 return file_type::symlink; 2639 case _IterNonSymlink: 2640 case _RefreshNonSymlink: 2641 file_status __st(__data_.__type_); 2642 if (__ec && !_VSTD_FS::exists(__st)) 2643 *__ec = make_error_code(errc::no_such_file_or_directory); 2644 else if (__ec) 2645 __ec->clear(); 2646 return __data_.__type_; 2647 } 2648 _LIBCPP_UNREACHABLE(); 2649 } 2650 2651 _LIBCPP_INLINE_VISIBILITY 2652 file_type __get_ft(error_code* __ec = nullptr) const { 2653 switch (__data_.__cache_type_) { 2654 case _Empty: 2655 case _IterSymlink: 2656 case _RefreshSymlinkUnresolved: 2657 return __status(__p_, __ec).type(); 2658 case _IterNonSymlink: 2659 case _RefreshNonSymlink: 2660 case _RefreshSymlink: { 2661 file_status __st(__data_.__type_); 2662 if (__ec && !_VSTD_FS::exists(__st)) 2663 *__ec = make_error_code(errc::no_such_file_or_directory); 2664 else if (__ec) 2665 __ec->clear(); 2666 return __data_.__type_; 2667 } 2668 } 2669 _LIBCPP_UNREACHABLE(); 2670 } 2671 2672 _LIBCPP_INLINE_VISIBILITY 2673 file_status __get_status(error_code* __ec = nullptr) const { 2674 switch (__data_.__cache_type_) { 2675 case _Empty: 2676 case _IterNonSymlink: 2677 case _IterSymlink: 2678 case _RefreshSymlinkUnresolved: 2679 return __status(__p_, __ec); 2680 case _RefreshNonSymlink: 2681 case _RefreshSymlink: 2682 return file_status(__get_ft(__ec), __data_.__non_sym_perms_); 2683 } 2684 _LIBCPP_UNREACHABLE(); 2685 } 2686 2687 _LIBCPP_INLINE_VISIBILITY 2688 file_status __get_symlink_status(error_code* __ec = nullptr) const { 2689 switch (__data_.__cache_type_) { 2690 case _Empty: 2691 case _IterNonSymlink: 2692 case _IterSymlink: 2693 return __symlink_status(__p_, __ec); 2694 case _RefreshNonSymlink: 2695 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); 2696 case _RefreshSymlink: 2697 case _RefreshSymlinkUnresolved: 2698 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); 2699 } 2700 _LIBCPP_UNREACHABLE(); 2701 } 2702 2703 _LIBCPP_INLINE_VISIBILITY 2704 uintmax_t __get_size(error_code* __ec = nullptr) const { 2705 switch (__data_.__cache_type_) { 2706 case _Empty: 2707 case _IterNonSymlink: 2708 case _IterSymlink: 2709 case _RefreshSymlinkUnresolved: 2710 return _VSTD_FS::__file_size(__p_, __ec); 2711 case _RefreshSymlink: 2712 case _RefreshNonSymlink: { 2713 error_code __m_ec; 2714 file_status __st(__get_ft(&__m_ec)); 2715 __handle_error("in directory_entry::file_size", __ec, __m_ec); 2716 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { 2717 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory 2718 : errc::not_supported; 2719 __handle_error("in directory_entry::file_size", __ec, 2720 make_error_code(__err_kind)); 2721 } 2722 return __data_.__size_; 2723 } 2724 } 2725 _LIBCPP_UNREACHABLE(); 2726 } 2727 2728 _LIBCPP_INLINE_VISIBILITY 2729 uintmax_t __get_nlink(error_code* __ec = nullptr) const { 2730 switch (__data_.__cache_type_) { 2731 case _Empty: 2732 case _IterNonSymlink: 2733 case _IterSymlink: 2734 case _RefreshSymlinkUnresolved: 2735 return _VSTD_FS::__hard_link_count(__p_, __ec); 2736 case _RefreshSymlink: 2737 case _RefreshNonSymlink: { 2738 error_code __m_ec; 2739 (void)__get_ft(&__m_ec); 2740 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); 2741 return __data_.__nlink_; 2742 } 2743 } 2744 _LIBCPP_UNREACHABLE(); 2745 } 2746 2747 _LIBCPP_INLINE_VISIBILITY 2748 file_time_type __get_write_time(error_code* __ec = nullptr) const { 2749 switch (__data_.__cache_type_) { 2750 case _Empty: 2751 case _IterNonSymlink: 2752 case _IterSymlink: 2753 case _RefreshSymlinkUnresolved: 2754 return _VSTD_FS::__last_write_time(__p_, __ec); 2755 case _RefreshSymlink: 2756 case _RefreshNonSymlink: { 2757 error_code __m_ec; 2758 file_status __st(__get_ft(&__m_ec)); 2759 __handle_error("in directory_entry::last_write_time", __ec, __m_ec); 2760 if (_VSTD_FS::exists(__st) && 2761 __data_.__write_time_ == file_time_type::min()) 2762 __handle_error("in directory_entry::last_write_time", __ec, 2763 make_error_code(errc::value_too_large)); 2764 return __data_.__write_time_; 2765 } 2766 } 2767 _LIBCPP_UNREACHABLE(); 2768 } 2769 2770private: 2771 _Path __p_; 2772 __cached_data __data_; 2773}; 2774 2775class __dir_element_proxy { 2776public: 2777 inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { 2778 return _VSTD::move(__elem_); 2779 } 2780 2781private: 2782 friend class directory_iterator; 2783 friend class recursive_directory_iterator; 2784 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} 2785 __dir_element_proxy(__dir_element_proxy&& __o) 2786 : __elem_(_VSTD::move(__o.__elem_)) {} 2787 directory_entry __elem_; 2788}; 2789 2790class directory_iterator { 2791public: 2792 typedef directory_entry value_type; 2793 typedef ptrdiff_t difference_type; 2794 typedef value_type const* pointer; 2795 typedef value_type const& reference; 2796 typedef input_iterator_tag iterator_category; 2797 2798public: 2799 //ctor & dtor 2800 directory_iterator() noexcept {} 2801 2802 explicit directory_iterator(const path& __p) 2803 : directory_iterator(__p, nullptr) {} 2804 2805 directory_iterator(const path& __p, directory_options __opts) 2806 : directory_iterator(__p, nullptr, __opts) {} 2807 2808 directory_iterator(const path& __p, error_code& __ec) 2809 : directory_iterator(__p, &__ec) {} 2810 2811 directory_iterator(const path& __p, directory_options __opts, 2812 error_code& __ec) 2813 : directory_iterator(__p, &__ec, __opts) {} 2814 2815 directory_iterator(const directory_iterator&) = default; 2816 directory_iterator(directory_iterator&&) = default; 2817 directory_iterator& operator=(const directory_iterator&) = default; 2818 2819 directory_iterator& operator=(directory_iterator&& __o) noexcept { 2820 // non-default implementation provided to support self-move assign. 2821 if (this != &__o) { 2822 __imp_ = _VSTD::move(__o.__imp_); 2823 } 2824 return *this; 2825 } 2826 2827 ~directory_iterator() = default; 2828 2829 const directory_entry& operator*() const { 2830 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); 2831 return __dereference(); 2832 } 2833 2834 const directory_entry* operator->() const { return &**this; } 2835 2836 directory_iterator& operator++() { return __increment(); } 2837 2838 __dir_element_proxy operator++(int) { 2839 __dir_element_proxy __p(**this); 2840 __increment(); 2841 return __p; 2842 } 2843 2844 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } 2845 2846private: 2847 inline _LIBCPP_INLINE_VISIBILITY friend bool 2848 operator==(const directory_iterator& __lhs, 2849 const directory_iterator& __rhs) noexcept; 2850 2851 // construct the dir_stream 2852 _LIBCPP_FUNC_VIS 2853 directory_iterator(const path&, error_code*, 2854 directory_options = directory_options::none); 2855 2856 _LIBCPP_FUNC_VIS 2857 directory_iterator& __increment(error_code* __ec = nullptr); 2858 2859 _LIBCPP_FUNC_VIS 2860 const directory_entry& __dereference() const; 2861 2862private: 2863 shared_ptr<__dir_stream> __imp_; 2864}; 2865 2866inline _LIBCPP_INLINE_VISIBILITY bool 2867operator==(const directory_iterator& __lhs, 2868 const directory_iterator& __rhs) noexcept { 2869 return __lhs.__imp_ == __rhs.__imp_; 2870} 2871 2872inline _LIBCPP_INLINE_VISIBILITY bool 2873operator!=(const directory_iterator& __lhs, 2874 const directory_iterator& __rhs) noexcept { 2875 return !(__lhs == __rhs); 2876} 2877 2878// enable directory_iterator range-based for statements 2879inline _LIBCPP_INLINE_VISIBILITY directory_iterator 2880begin(directory_iterator __iter) noexcept { 2881 return __iter; 2882} 2883 2884inline _LIBCPP_INLINE_VISIBILITY directory_iterator 2885end(directory_iterator) noexcept { 2886 return directory_iterator(); 2887} 2888 2889class recursive_directory_iterator { 2890public: 2891 using value_type = directory_entry; 2892 using difference_type = ptrdiff_t; 2893 using pointer = directory_entry const*; 2894 using reference = directory_entry const&; 2895 using iterator_category = input_iterator_tag; 2896 2897public: 2898 // constructors and destructor 2899 _LIBCPP_INLINE_VISIBILITY 2900 recursive_directory_iterator() noexcept : __rec_(false) {} 2901 2902 _LIBCPP_INLINE_VISIBILITY 2903 explicit recursive_directory_iterator( 2904 const path& __p, directory_options __xoptions = directory_options::none) 2905 : recursive_directory_iterator(__p, __xoptions, nullptr) {} 2906 2907 _LIBCPP_INLINE_VISIBILITY 2908 recursive_directory_iterator(const path& __p, directory_options __xoptions, 2909 error_code& __ec) 2910 : recursive_directory_iterator(__p, __xoptions, &__ec) {} 2911 2912 _LIBCPP_INLINE_VISIBILITY 2913 recursive_directory_iterator(const path& __p, error_code& __ec) 2914 : recursive_directory_iterator(__p, directory_options::none, &__ec) {} 2915 2916 recursive_directory_iterator(const recursive_directory_iterator&) = default; 2917 recursive_directory_iterator(recursive_directory_iterator&&) = default; 2918 2919 recursive_directory_iterator& 2920 operator=(const recursive_directory_iterator&) = default; 2921 2922 _LIBCPP_INLINE_VISIBILITY 2923 recursive_directory_iterator& 2924 operator=(recursive_directory_iterator&& __o) noexcept { 2925 // non-default implementation provided to support self-move assign. 2926 if (this != &__o) { 2927 __imp_ = _VSTD::move(__o.__imp_); 2928 __rec_ = __o.__rec_; 2929 } 2930 return *this; 2931 } 2932 2933 ~recursive_directory_iterator() = default; 2934 2935 _LIBCPP_INLINE_VISIBILITY 2936 const directory_entry& operator*() const { return __dereference(); } 2937 2938 _LIBCPP_INLINE_VISIBILITY 2939 const directory_entry* operator->() const { return &__dereference(); } 2940 2941 recursive_directory_iterator& operator++() { return __increment(); } 2942 2943 _LIBCPP_INLINE_VISIBILITY 2944 __dir_element_proxy operator++(int) { 2945 __dir_element_proxy __p(**this); 2946 __increment(); 2947 return __p; 2948 } 2949 2950 _LIBCPP_INLINE_VISIBILITY 2951 recursive_directory_iterator& increment(error_code& __ec) { 2952 return __increment(&__ec); 2953 } 2954 2955 _LIBCPP_FUNC_VIS directory_options options() const; 2956 _LIBCPP_FUNC_VIS int depth() const; 2957 2958 _LIBCPP_INLINE_VISIBILITY 2959 void pop() { __pop(); } 2960 2961 _LIBCPP_INLINE_VISIBILITY 2962 void pop(error_code& __ec) { __pop(&__ec); } 2963 2964 _LIBCPP_INLINE_VISIBILITY 2965 bool recursion_pending() const { return __rec_; } 2966 2967 _LIBCPP_INLINE_VISIBILITY 2968 void disable_recursion_pending() { __rec_ = false; } 2969 2970private: 2971 _LIBCPP_FUNC_VIS 2972 recursive_directory_iterator(const path& __p, directory_options __opt, 2973 error_code* __ec); 2974 2975 _LIBCPP_FUNC_VIS 2976 const directory_entry& __dereference() const; 2977 2978 _LIBCPP_FUNC_VIS 2979 bool __try_recursion(error_code* __ec); 2980 2981 _LIBCPP_FUNC_VIS 2982 void __advance(error_code* __ec = nullptr); 2983 2984 _LIBCPP_FUNC_VIS 2985 recursive_directory_iterator& __increment(error_code* __ec = nullptr); 2986 2987 _LIBCPP_FUNC_VIS 2988 void __pop(error_code* __ec = nullptr); 2989 2990 inline _LIBCPP_INLINE_VISIBILITY friend bool 2991 operator==(const recursive_directory_iterator&, 2992 const recursive_directory_iterator&) noexcept; 2993 2994 struct _LIBCPP_HIDDEN __shared_imp; 2995 shared_ptr<__shared_imp> __imp_; 2996 bool __rec_; 2997}; // class recursive_directory_iterator 2998 2999inline _LIBCPP_INLINE_VISIBILITY bool 3000operator==(const recursive_directory_iterator& __lhs, 3001 const recursive_directory_iterator& __rhs) noexcept { 3002 return __lhs.__imp_ == __rhs.__imp_; 3003} 3004 3005_LIBCPP_INLINE_VISIBILITY 3006inline bool operator!=(const recursive_directory_iterator& __lhs, 3007 const recursive_directory_iterator& __rhs) noexcept { 3008 return !(__lhs == __rhs); 3009} 3010// enable recursive_directory_iterator range-based for statements 3011inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator 3012begin(recursive_directory_iterator __iter) noexcept { 3013 return __iter; 3014} 3015 3016inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator 3017end(recursive_directory_iterator) noexcept { 3018 return recursive_directory_iterator(); 3019} 3020 3021_LIBCPP_AVAILABILITY_FILESYSTEM_POP 3022 3023_LIBCPP_END_NAMESPACE_FILESYSTEM 3024 3025#if !defined(_LIBCPP_HAS_NO_RANGES) 3026template <> 3027inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; 3028template <> 3029inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; 3030 3031template <> 3032inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; 3033template <> 3034inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; 3035#endif 3036 3037#endif // !_LIBCPP_CXX03_LANG 3038 3039_LIBCPP_POP_MACROS 3040 3041#endif // _LIBCPP_FILESYSTEM 3042