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