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