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 _LIBCPP_INLINE_VISIBILITY 977 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#if defined(_LIBCPP_WIN32API) 1345 __string_view __root_name_str = __root_name(); 1346 __string_view __root_dir = __root_directory(); 1347 if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { 1348 // A drive letter with no root directory is relative, e.g. x:example. 1349 return !__root_dir.empty(); 1350 } 1351 // If no root name, it's relative, e.g. \example is relative to the current drive 1352 if (__root_name_str.empty()) 1353 return false; 1354 if (__root_name_str.size() < 3) 1355 return false; 1356 // A server root name, like \\server, is always absolute 1357 if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') 1358 return false; 1359 if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') 1360 return false; 1361 // Seems to be a server root name 1362 return true; 1363#else 1364 return has_root_directory(); 1365#endif 1366 } 1367 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } 1368 1369 // relative paths 1370 path lexically_normal() const; 1371 path lexically_relative(const path& __base) const; 1372 1373 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const { 1374 path __result = this->lexically_relative(__base); 1375 if (__result.native().empty()) 1376 return *this; 1377 return __result; 1378 } 1379 1380 // iterators 1381 class _LIBCPP_TYPE_VIS iterator; 1382 typedef iterator const_iterator; 1383 1384 iterator begin() const; 1385 iterator end() const; 1386 1387#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 1388 template <class _CharT, class _Traits> 1389 _LIBCPP_INLINE_VISIBILITY friend 1390 typename enable_if<is_same<_CharT, value_type>::value && 1391 is_same<_Traits, char_traits<value_type> >::value, 1392 basic_ostream<_CharT, _Traits>&>::type 1393 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1394 __os << _VSTD::__quoted(__p.native()); 1395 return __os; 1396 } 1397 1398 template <class _CharT, class _Traits> 1399 _LIBCPP_INLINE_VISIBILITY friend 1400 typename enable_if<!is_same<_CharT, value_type>::value || 1401 !is_same<_Traits, char_traits<value_type> >::value, 1402 basic_ostream<_CharT, _Traits>&>::type 1403 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1404 __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); 1405 return __os; 1406 } 1407 1408 template <class _CharT, class _Traits> 1409 _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& 1410 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { 1411 basic_string<_CharT, _Traits> __tmp; 1412 __is >> __quoted(__tmp); 1413 __p = __tmp; 1414 return __is; 1415 } 1416#endif // !_LIBCPP_HAS_NO_LOCALIZATION 1417 1418 friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { 1419 return __lhs.compare(__rhs) == 0; 1420 } 1421 friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { 1422 return __lhs.compare(__rhs) != 0; 1423 } 1424 friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { 1425 return __lhs.compare(__rhs) < 0; 1426 } 1427 friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { 1428 return __lhs.compare(__rhs) <= 0; 1429 } 1430 friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { 1431 return __lhs.compare(__rhs) > 0; 1432 } 1433 friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { 1434 return __lhs.compare(__rhs) >= 0; 1435 } 1436 1437 friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, 1438 const path& __rhs) { 1439 path __result(__lhs); 1440 __result /= __rhs; 1441 return __result; 1442 } 1443private: 1444 inline _LIBCPP_INLINE_VISIBILITY path& 1445 __assign_view(__string_view const& __s) noexcept { 1446 __pn_ = string_type(__s); 1447 return *this; 1448 } 1449 string_type __pn_; 1450}; 1451 1452inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { 1453 __lhs.swap(__rhs); 1454} 1455 1456_LIBCPP_FUNC_VIS 1457size_t hash_value(const path& __p) noexcept; 1458 1459template <class _InputIt> 1460_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1461 typename enable_if<__is_pathable<_InputIt>::value, path>::type 1462 u8path(_InputIt __f, _InputIt __l) { 1463 static_assert( 1464#ifndef _LIBCPP_NO_HAS_CHAR8_T 1465 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || 1466#endif 1467 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, 1468 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" 1469 " or 'char8_t'"); 1470#if defined(_LIBCPP_WIN32API) 1471 string __tmp(__f, __l); 1472 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 1473 _VSTD::wstring __w; 1474 __w.reserve(__tmp.size()); 1475 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); 1476 return path(__w); 1477#else 1478 return path(__f, __l); 1479#endif /* !_LIBCPP_WIN32API */ 1480} 1481 1482#if defined(_LIBCPP_WIN32API) 1483template <class _InputIt> 1484_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1485 typename enable_if<__is_pathable<_InputIt>::value, path>::type 1486 u8path(_InputIt __f, _NullSentinel) { 1487 static_assert( 1488#ifndef _LIBCPP_NO_HAS_CHAR8_T 1489 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || 1490#endif 1491 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, 1492 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" 1493 " or 'char8_t'"); 1494 string __tmp; 1495 const char __sentinel = char{}; 1496 for (; *__f != __sentinel; ++__f) 1497 __tmp.push_back(*__f); 1498 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; 1499 _VSTD::wstring __w; 1500 __w.reserve(__tmp.size()); 1501 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); 1502 return path(__w); 1503} 1504#endif /* _LIBCPP_WIN32API */ 1505 1506template <class _Source> 1507_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T 1508 typename enable_if<__is_pathable<_Source>::value, path>::type 1509 u8path(const _Source& __s) { 1510 static_assert( 1511#ifndef _LIBCPP_NO_HAS_CHAR8_T 1512 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value || 1513#endif 1514 is_same<typename __is_pathable<_Source>::__char_type, char>::value, 1515 "u8path(Source const&) requires Source have a character type of type " 1516 "'char' or 'char8_t'"); 1517#if defined(_LIBCPP_WIN32API) 1518 using _Traits = __is_pathable<_Source>; 1519 return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); 1520#else 1521 return path(__s); 1522#endif 1523} 1524 1525class _LIBCPP_TYPE_VIS path::iterator { 1526public: 1527 enum _ParserState : unsigned char { 1528 _Singular, 1529 _BeforeBegin, 1530 _InRootName, 1531 _InRootDir, 1532 _InFilenames, 1533 _InTrailingSep, 1534 _AtEnd 1535 }; 1536 1537public: 1538 typedef bidirectional_iterator_tag iterator_category; 1539 1540 typedef path value_type; 1541 typedef ptrdiff_t difference_type; 1542 typedef const path* pointer; 1543 typedef const path& reference; 1544 1545 typedef void 1546 __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator 1547 1548public: 1549 _LIBCPP_INLINE_VISIBILITY 1550 iterator() 1551 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), 1552 __state_(_Singular) {} 1553 1554 iterator(const iterator&) = default; 1555 ~iterator() = default; 1556 1557 iterator& operator=(const iterator&) = default; 1558 1559 _LIBCPP_INLINE_VISIBILITY 1560 reference operator*() const { return __stashed_elem_; } 1561 1562 _LIBCPP_INLINE_VISIBILITY 1563 pointer operator->() const { return &__stashed_elem_; } 1564 1565 _LIBCPP_INLINE_VISIBILITY 1566 iterator& operator++() { 1567 _LIBCPP_ASSERT(__state_ != _Singular, 1568 "attempting to increment a singular iterator"); 1569 _LIBCPP_ASSERT(__state_ != _AtEnd, 1570 "attempting to increment the end iterator"); 1571 return __increment(); 1572 } 1573 1574 _LIBCPP_INLINE_VISIBILITY 1575 iterator operator++(int) { 1576 iterator __it(*this); 1577 this->operator++(); 1578 return __it; 1579 } 1580 1581 _LIBCPP_INLINE_VISIBILITY 1582 iterator& operator--() { 1583 _LIBCPP_ASSERT(__state_ != _Singular, 1584 "attempting to decrement a singular iterator"); 1585 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), 1586 "attempting to decrement the begin iterator"); 1587 return __decrement(); 1588 } 1589 1590 _LIBCPP_INLINE_VISIBILITY 1591 iterator operator--(int) { 1592 iterator __it(*this); 1593 this->operator--(); 1594 return __it; 1595 } 1596 1597private: 1598 friend class path; 1599 1600 inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, 1601 const iterator&); 1602 1603 iterator& __increment(); 1604 iterator& __decrement(); 1605 1606 path __stashed_elem_; 1607 const path* __path_ptr_; 1608 path::__string_view __entry_; 1609 _ParserState __state_; 1610}; 1611 1612inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, 1613 const path::iterator& __rhs) { 1614 return __lhs.__path_ptr_ == __rhs.__path_ptr_ && 1615 __lhs.__entry_.data() == __rhs.__entry_.data(); 1616} 1617 1618inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, 1619 const path::iterator& __rhs) { 1620 return !(__lhs == __rhs); 1621} 1622 1623// TODO(ldionne): We need to pop the pragma and push it again after 1624// filesystem_error to work around PR41078. 1625_LIBCPP_AVAILABILITY_FILESYSTEM_POP 1626 1627class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { 1628public: 1629 _LIBCPP_INLINE_VISIBILITY 1630 filesystem_error(const string& __what, error_code __ec) 1631 : system_error(__ec, __what), 1632 __storage_(make_shared<_Storage>(path(), path())) { 1633 __create_what(0); 1634 } 1635 1636 _LIBCPP_INLINE_VISIBILITY 1637 filesystem_error(const string& __what, const path& __p1, error_code __ec) 1638 : system_error(__ec, __what), 1639 __storage_(make_shared<_Storage>(__p1, path())) { 1640 __create_what(1); 1641 } 1642 1643 _LIBCPP_INLINE_VISIBILITY 1644 filesystem_error(const string& __what, const path& __p1, const path& __p2, 1645 error_code __ec) 1646 : system_error(__ec, __what), 1647 __storage_(make_shared<_Storage>(__p1, __p2)) { 1648 __create_what(2); 1649 } 1650 1651 _LIBCPP_INLINE_VISIBILITY 1652 const path& path1() const noexcept { return __storage_->__p1_; } 1653 1654 _LIBCPP_INLINE_VISIBILITY 1655 const path& path2() const noexcept { return __storage_->__p2_; } 1656 1657 filesystem_error(const filesystem_error&) = default; 1658 ~filesystem_error() override; // key function 1659 1660 _LIBCPP_INLINE_VISIBILITY 1661 const char* what() const noexcept override { 1662 return __storage_->__what_.c_str(); 1663 } 1664 1665 void __create_what(int __num_paths); 1666 1667private: 1668 struct _LIBCPP_HIDDEN _Storage { 1669 _LIBCPP_INLINE_VISIBILITY 1670 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} 1671 1672 path __p1_; 1673 path __p2_; 1674 string __what_; 1675 }; 1676 shared_ptr<_Storage> __storage_; 1677}; 1678 1679_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 1680 1681template <class... _Args> 1682_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 1683#ifndef _LIBCPP_NO_EXCEPTIONS 1684void __throw_filesystem_error(_Args&&... __args) { 1685 throw filesystem_error(_VSTD::forward<_Args>(__args)...); 1686} 1687#else 1688void __throw_filesystem_error(_Args&&...) { 1689 _VSTD::abort(); 1690} 1691#endif 1692 1693// operational functions 1694 1695_LIBCPP_FUNC_VIS 1696path __absolute(const path&, error_code* __ec = nullptr); 1697_LIBCPP_FUNC_VIS 1698path __canonical(const path&, error_code* __ec = nullptr); 1699_LIBCPP_FUNC_VIS 1700void __copy(const path& __from, const path& __to, copy_options __opt, 1701 error_code* __ec = nullptr); 1702_LIBCPP_FUNC_VIS 1703bool __copy_file(const path& __from, const path& __to, copy_options __opt, 1704 error_code* __ec = nullptr); 1705_LIBCPP_FUNC_VIS 1706void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, 1707 error_code* __ec = nullptr); 1708_LIBCPP_FUNC_VIS 1709bool __create_directories(const path& p, error_code* ec = nullptr); 1710_LIBCPP_FUNC_VIS 1711bool __create_directory(const path& p, error_code* ec = nullptr); 1712_LIBCPP_FUNC_VIS 1713bool __create_directory(const path& p, const path& attributes, 1714 error_code* ec = nullptr); 1715_LIBCPP_FUNC_VIS 1716void __create_directory_symlink(const path& __to, const path& __new_symlink, 1717 error_code* __ec = nullptr); 1718_LIBCPP_FUNC_VIS 1719void __create_hard_link(const path& __to, const path& __new_hard_link, 1720 error_code* __ec = nullptr); 1721_LIBCPP_FUNC_VIS 1722void __create_symlink(const path& __to, const path& __new_symlink, 1723 error_code* __ec = nullptr); 1724_LIBCPP_FUNC_VIS 1725path __current_path(error_code* __ec = nullptr); 1726_LIBCPP_FUNC_VIS 1727void __current_path(const path&, error_code* __ec = nullptr); 1728_LIBCPP_FUNC_VIS 1729bool __equivalent(const path&, const path&, error_code* __ec = nullptr); 1730_LIBCPP_FUNC_VIS 1731uintmax_t __file_size(const path&, error_code* __ec = nullptr); 1732_LIBCPP_FUNC_VIS 1733uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); 1734_LIBCPP_FUNC_VIS 1735bool __fs_is_empty(const path& p, error_code* ec = nullptr); 1736_LIBCPP_FUNC_VIS 1737file_time_type __last_write_time(const path& p, error_code* ec = nullptr); 1738_LIBCPP_FUNC_VIS 1739void __last_write_time(const path& p, file_time_type new_time, 1740 error_code* ec = nullptr); 1741_LIBCPP_FUNC_VIS 1742void __permissions(const path&, perms, perm_options, error_code* = nullptr); 1743_LIBCPP_FUNC_VIS 1744path __read_symlink(const path& p, error_code* ec = nullptr); 1745_LIBCPP_FUNC_VIS 1746bool __remove(const path& p, error_code* ec = nullptr); 1747_LIBCPP_FUNC_VIS 1748uintmax_t __remove_all(const path& p, error_code* ec = nullptr); 1749_LIBCPP_FUNC_VIS 1750void __rename(const path& from, const path& to, error_code* ec = nullptr); 1751_LIBCPP_FUNC_VIS 1752void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); 1753_LIBCPP_FUNC_VIS 1754space_info __space(const path&, error_code* __ec = nullptr); 1755_LIBCPP_FUNC_VIS 1756file_status __status(const path&, error_code* __ec = nullptr); 1757_LIBCPP_FUNC_VIS 1758file_status __symlink_status(const path&, error_code* __ec = nullptr); 1759_LIBCPP_FUNC_VIS 1760path __system_complete(const path&, error_code* __ec = nullptr); 1761_LIBCPP_FUNC_VIS 1762path __temp_directory_path(error_code* __ec = nullptr); 1763_LIBCPP_FUNC_VIS 1764path __weakly_canonical(path const& __p, error_code* __ec = nullptr); 1765 1766inline _LIBCPP_INLINE_VISIBILITY path current_path() { 1767 return __current_path(); 1768} 1769 1770inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { 1771 return __current_path(&__ec); 1772} 1773 1774inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { 1775 __current_path(__p); 1776} 1777 1778inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, 1779 error_code& __ec) noexcept { 1780 __current_path(__p, &__ec); 1781} 1782 1783inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { 1784 return __absolute(__p); 1785} 1786 1787inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, 1788 error_code& __ec) { 1789 return __absolute(__p, &__ec); 1790} 1791 1792inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { 1793 return __canonical(__p); 1794} 1795 1796inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, 1797 error_code& __ec) { 1798 return __canonical(__p, &__ec); 1799} 1800 1801inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, 1802 const path& __to) { 1803 __copy(__from, __to, copy_options::none); 1804} 1805 1806inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1807 error_code& __ec) { 1808 __copy(__from, __to, copy_options::none, &__ec); 1809} 1810 1811inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1812 copy_options __opt) { 1813 __copy(__from, __to, __opt); 1814} 1815 1816inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, 1817 copy_options __opt, 1818 error_code& __ec) { 1819 __copy(__from, __to, __opt, &__ec); 1820} 1821 1822inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, 1823 const path& __to) { 1824 return __copy_file(__from, __to, copy_options::none); 1825} 1826 1827inline _LIBCPP_INLINE_VISIBILITY bool 1828copy_file(const path& __from, const path& __to, error_code& __ec) { 1829 return __copy_file(__from, __to, copy_options::none, &__ec); 1830} 1831 1832inline _LIBCPP_INLINE_VISIBILITY bool 1833copy_file(const path& __from, const path& __to, copy_options __opt) { 1834 return __copy_file(__from, __to, __opt); 1835} 1836 1837inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, 1838 const path& __to, 1839 copy_options __opt, 1840 error_code& __ec) { 1841 return __copy_file(__from, __to, __opt, &__ec); 1842} 1843 1844inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, 1845 const path& __new) { 1846 __copy_symlink(__existing, __new); 1847} 1848 1849inline _LIBCPP_INLINE_VISIBILITY void 1850copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { 1851 __copy_symlink(__ext, __new, &__ec); 1852} 1853 1854inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { 1855 return __create_directories(__p); 1856} 1857 1858inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, 1859 error_code& __ec) { 1860 return __create_directories(__p, &__ec); 1861} 1862 1863inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { 1864 return __create_directory(__p); 1865} 1866 1867inline _LIBCPP_INLINE_VISIBILITY bool 1868create_directory(const path& __p, error_code& __ec) noexcept { 1869 return __create_directory(__p, &__ec); 1870} 1871 1872inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, 1873 const path& __attrs) { 1874 return __create_directory(__p, __attrs); 1875} 1876 1877inline _LIBCPP_INLINE_VISIBILITY bool 1878create_directory(const path& __p, const path& __attrs, 1879 error_code& __ec) noexcept { 1880 return __create_directory(__p, __attrs, &__ec); 1881} 1882 1883inline _LIBCPP_INLINE_VISIBILITY void 1884create_directory_symlink(const path& __to, const path& __new) { 1885 __create_directory_symlink(__to, __new); 1886} 1887 1888inline _LIBCPP_INLINE_VISIBILITY void 1889create_directory_symlink(const path& __to, const path& __new, 1890 error_code& __ec) noexcept { 1891 __create_directory_symlink(__to, __new, &__ec); 1892} 1893 1894inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, 1895 const path& __new) { 1896 __create_hard_link(__to, __new); 1897} 1898 1899inline _LIBCPP_INLINE_VISIBILITY void 1900create_hard_link(const path& __to, const path& __new, 1901 error_code& __ec) noexcept { 1902 __create_hard_link(__to, __new, &__ec); 1903} 1904 1905inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, 1906 const path& __new) { 1907 __create_symlink(__to, __new); 1908} 1909 1910inline _LIBCPP_INLINE_VISIBILITY void 1911create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { 1912 return __create_symlink(__to, __new, &__ec); 1913} 1914 1915inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { 1916 return __s.type() != file_type::none; 1917} 1918 1919inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { 1920 return status_known(__s) && __s.type() != file_type::not_found; 1921} 1922 1923inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { 1924 return exists(__status(__p)); 1925} 1926 1927inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, 1928 error_code& __ec) noexcept { 1929 auto __s = __status(__p, &__ec); 1930 if (status_known(__s)) 1931 __ec.clear(); 1932 return exists(__s); 1933} 1934 1935inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, 1936 const path& __p2) { 1937 return __equivalent(__p1, __p2); 1938} 1939 1940inline _LIBCPP_INLINE_VISIBILITY bool 1941equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { 1942 return __equivalent(__p1, __p2, &__ec); 1943} 1944 1945inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { 1946 return __file_size(__p); 1947} 1948 1949inline _LIBCPP_INLINE_VISIBILITY uintmax_t 1950file_size(const path& __p, error_code& __ec) noexcept { 1951 return __file_size(__p, &__ec); 1952} 1953 1954inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { 1955 return __hard_link_count(__p); 1956} 1957 1958inline _LIBCPP_INLINE_VISIBILITY uintmax_t 1959hard_link_count(const path& __p, error_code& __ec) noexcept { 1960 return __hard_link_count(__p, &__ec); 1961} 1962 1963inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { 1964 return __s.type() == file_type::block; 1965} 1966 1967inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { 1968 return is_block_file(__status(__p)); 1969} 1970 1971inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, 1972 error_code& __ec) noexcept { 1973 return is_block_file(__status(__p, &__ec)); 1974} 1975 1976inline _LIBCPP_INLINE_VISIBILITY bool 1977is_character_file(file_status __s) noexcept { 1978 return __s.type() == file_type::character; 1979} 1980 1981inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { 1982 return is_character_file(__status(__p)); 1983} 1984 1985inline _LIBCPP_INLINE_VISIBILITY bool 1986is_character_file(const path& __p, error_code& __ec) noexcept { 1987 return is_character_file(__status(__p, &__ec)); 1988} 1989 1990inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { 1991 return __s.type() == file_type::directory; 1992} 1993 1994inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { 1995 return is_directory(__status(__p)); 1996} 1997 1998inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, 1999 error_code& __ec) noexcept { 2000 return is_directory(__status(__p, &__ec)); 2001} 2002 2003inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { 2004 return __fs_is_empty(__p); 2005} 2006 2007inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, 2008 error_code& __ec) { 2009 return __fs_is_empty(__p, &__ec); 2010} 2011 2012inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { 2013 return __s.type() == file_type::fifo; 2014} 2015inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { 2016 return is_fifo(__status(__p)); 2017} 2018 2019inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, 2020 error_code& __ec) noexcept { 2021 return is_fifo(__status(__p, &__ec)); 2022} 2023 2024inline _LIBCPP_INLINE_VISIBILITY bool 2025is_regular_file(file_status __s) noexcept { 2026 return __s.type() == file_type::regular; 2027} 2028 2029inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { 2030 return is_regular_file(__status(__p)); 2031} 2032 2033inline _LIBCPP_INLINE_VISIBILITY bool 2034is_regular_file(const path& __p, error_code& __ec) noexcept { 2035 return is_regular_file(__status(__p, &__ec)); 2036} 2037 2038inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { 2039 return __s.type() == file_type::socket; 2040} 2041 2042inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { 2043 return is_socket(__status(__p)); 2044} 2045 2046inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, 2047 error_code& __ec) noexcept { 2048 return is_socket(__status(__p, &__ec)); 2049} 2050 2051inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { 2052 return __s.type() == file_type::symlink; 2053} 2054 2055inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { 2056 return is_symlink(__symlink_status(__p)); 2057} 2058 2059inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, 2060 error_code& __ec) noexcept { 2061 return is_symlink(__symlink_status(__p, &__ec)); 2062} 2063 2064inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { 2065 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && 2066 !is_symlink(__s); 2067} 2068 2069inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { 2070 return is_other(__status(__p)); 2071} 2072 2073inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, 2074 error_code& __ec) noexcept { 2075 return is_other(__status(__p, &__ec)); 2076} 2077 2078inline _LIBCPP_INLINE_VISIBILITY file_time_type 2079last_write_time(const path& __p) { 2080 return __last_write_time(__p); 2081} 2082 2083inline _LIBCPP_INLINE_VISIBILITY file_time_type 2084last_write_time(const path& __p, error_code& __ec) noexcept { 2085 return __last_write_time(__p, &__ec); 2086} 2087 2088inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, 2089 file_time_type __t) { 2090 __last_write_time(__p, __t); 2091} 2092 2093inline _LIBCPP_INLINE_VISIBILITY void 2094last_write_time(const path& __p, file_time_type __t, 2095 error_code& __ec) noexcept { 2096 __last_write_time(__p, __t, &__ec); 2097} 2098 2099inline _LIBCPP_INLINE_VISIBILITY void 2100permissions(const path& __p, perms __prms, 2101 perm_options __opts = perm_options::replace) { 2102 __permissions(__p, __prms, __opts); 2103} 2104 2105inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, 2106 error_code& __ec) noexcept { 2107 __permissions(__p, __prms, perm_options::replace, &__ec); 2108} 2109 2110inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, 2111 perm_options __opts, 2112 error_code& __ec) { 2113 __permissions(__p, __prms, __opts, &__ec); 2114} 2115 2116inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, 2117 const path& __base, 2118 error_code& __ec) { 2119 path __tmp = __weakly_canonical(__p, &__ec); 2120 if (__ec) 2121 return {}; 2122 path __tmp_base = __weakly_canonical(__base, &__ec); 2123 if (__ec) 2124 return {}; 2125 return __tmp.lexically_proximate(__tmp_base); 2126} 2127 2128inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, 2129 error_code& __ec) { 2130 return proximate(__p, current_path(), __ec); 2131} 2132 2133inline _LIBCPP_INLINE_VISIBILITY path 2134proximate(const path& __p, const path& __base = current_path()) { 2135 return __weakly_canonical(__p).lexically_proximate( 2136 __weakly_canonical(__base)); 2137} 2138 2139inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { 2140 return __read_symlink(__p); 2141} 2142 2143inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, 2144 error_code& __ec) { 2145 return __read_symlink(__p, &__ec); 2146} 2147 2148inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, 2149 const path& __base, 2150 error_code& __ec) { 2151 path __tmp = __weakly_canonical(__p, &__ec); 2152 if (__ec) 2153 return path(); 2154 path __tmpbase = __weakly_canonical(__base, &__ec); 2155 if (__ec) 2156 return path(); 2157 return __tmp.lexically_relative(__tmpbase); 2158} 2159 2160inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, 2161 error_code& __ec) { 2162 return relative(__p, current_path(), __ec); 2163} 2164 2165inline _LIBCPP_INLINE_VISIBILITY path 2166relative(const path& __p, const path& __base = current_path()) { 2167 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); 2168} 2169 2170inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { 2171 return __remove(__p); 2172} 2173 2174inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, 2175 error_code& __ec) noexcept { 2176 return __remove(__p, &__ec); 2177} 2178 2179inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { 2180 return __remove_all(__p); 2181} 2182 2183inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, 2184 error_code& __ec) { 2185 return __remove_all(__p, &__ec); 2186} 2187 2188inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, 2189 const path& __to) { 2190 return __rename(__from, __to); 2191} 2192 2193inline _LIBCPP_INLINE_VISIBILITY void 2194rename(const path& __from, const path& __to, error_code& __ec) noexcept { 2195 return __rename(__from, __to, &__ec); 2196} 2197 2198inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, 2199 uintmax_t __ns) { 2200 return __resize_file(__p, __ns); 2201} 2202 2203inline _LIBCPP_INLINE_VISIBILITY void 2204resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { 2205 return __resize_file(__p, __ns, &__ec); 2206} 2207 2208inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { 2209 return __space(__p); 2210} 2211 2212inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, 2213 error_code& __ec) noexcept { 2214 return __space(__p, &__ec); 2215} 2216 2217inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { 2218 return __status(__p); 2219} 2220 2221inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, 2222 error_code& __ec) noexcept { 2223 return __status(__p, &__ec); 2224} 2225 2226inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { 2227 return __symlink_status(__p); 2228} 2229 2230inline _LIBCPP_INLINE_VISIBILITY file_status 2231symlink_status(const path& __p, error_code& __ec) noexcept { 2232 return __symlink_status(__p, &__ec); 2233} 2234 2235inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { 2236 return __temp_directory_path(); 2237} 2238 2239inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { 2240 return __temp_directory_path(&__ec); 2241} 2242 2243inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { 2244 return __weakly_canonical(__p); 2245} 2246 2247inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, 2248 error_code& __ec) { 2249 return __weakly_canonical(__p, &__ec); 2250} 2251 2252class directory_iterator; 2253class recursive_directory_iterator; 2254class _LIBCPP_HIDDEN __dir_stream; 2255 2256class directory_entry { 2257 typedef _VSTD_FS::path _Path; 2258 2259public: 2260 // constructors and destructors 2261 directory_entry() noexcept = default; 2262 directory_entry(directory_entry const&) = default; 2263 directory_entry(directory_entry&&) noexcept = default; 2264 2265 _LIBCPP_INLINE_VISIBILITY 2266 explicit directory_entry(_Path const& __p) : __p_(__p) { 2267 error_code __ec; 2268 __refresh(&__ec); 2269 } 2270 2271 _LIBCPP_INLINE_VISIBILITY 2272 directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { 2273 __refresh(&__ec); 2274 } 2275 2276 ~directory_entry() {} 2277 2278 directory_entry& operator=(directory_entry const&) = default; 2279 directory_entry& operator=(directory_entry&&) noexcept = default; 2280 2281 _LIBCPP_INLINE_VISIBILITY 2282 void assign(_Path const& __p) { 2283 __p_ = __p; 2284 error_code __ec; 2285 __refresh(&__ec); 2286 } 2287 2288 _LIBCPP_INLINE_VISIBILITY 2289 void assign(_Path const& __p, error_code& __ec) { 2290 __p_ = __p; 2291 __refresh(&__ec); 2292 } 2293 2294 _LIBCPP_INLINE_VISIBILITY 2295 void replace_filename(_Path const& __p) { 2296 __p_.replace_filename(__p); 2297 error_code __ec; 2298 __refresh(&__ec); 2299 } 2300 2301 _LIBCPP_INLINE_VISIBILITY 2302 void replace_filename(_Path const& __p, error_code& __ec) { 2303 __p_ = __p_.parent_path() / __p; 2304 __refresh(&__ec); 2305 } 2306 2307 _LIBCPP_INLINE_VISIBILITY 2308 void refresh() { __refresh(); } 2309 2310 _LIBCPP_INLINE_VISIBILITY 2311 void refresh(error_code& __ec) noexcept { __refresh(&__ec); } 2312 2313 _LIBCPP_INLINE_VISIBILITY 2314 _Path const& path() const noexcept { return __p_; } 2315 2316 _LIBCPP_INLINE_VISIBILITY 2317 operator const _Path&() const noexcept { return __p_; } 2318 2319 _LIBCPP_INLINE_VISIBILITY 2320 bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } 2321 2322 _LIBCPP_INLINE_VISIBILITY 2323 bool exists(error_code& __ec) const noexcept { 2324 return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); 2325 } 2326 2327 _LIBCPP_INLINE_VISIBILITY 2328 bool is_block_file() const { return __get_ft() == file_type::block; } 2329 2330 _LIBCPP_INLINE_VISIBILITY 2331 bool is_block_file(error_code& __ec) const noexcept { 2332 return __get_ft(&__ec) == file_type::block; 2333 } 2334 2335 _LIBCPP_INLINE_VISIBILITY 2336 bool is_character_file() const { return __get_ft() == file_type::character; } 2337 2338 _LIBCPP_INLINE_VISIBILITY 2339 bool is_character_file(error_code& __ec) const noexcept { 2340 return __get_ft(&__ec) == file_type::character; 2341 } 2342 2343 _LIBCPP_INLINE_VISIBILITY 2344 bool is_directory() const { return __get_ft() == file_type::directory; } 2345 2346 _LIBCPP_INLINE_VISIBILITY 2347 bool is_directory(error_code& __ec) const noexcept { 2348 return __get_ft(&__ec) == file_type::directory; 2349 } 2350 2351 _LIBCPP_INLINE_VISIBILITY 2352 bool is_fifo() const { return __get_ft() == file_type::fifo; } 2353 2354 _LIBCPP_INLINE_VISIBILITY 2355 bool is_fifo(error_code& __ec) const noexcept { 2356 return __get_ft(&__ec) == file_type::fifo; 2357 } 2358 2359 _LIBCPP_INLINE_VISIBILITY 2360 bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } 2361 2362 _LIBCPP_INLINE_VISIBILITY 2363 bool is_other(error_code& __ec) const noexcept { 2364 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); 2365 } 2366 2367 _LIBCPP_INLINE_VISIBILITY 2368 bool is_regular_file() const { return __get_ft() == file_type::regular; } 2369 2370 _LIBCPP_INLINE_VISIBILITY 2371 bool is_regular_file(error_code& __ec) const noexcept { 2372 return __get_ft(&__ec) == file_type::regular; 2373 } 2374 2375 _LIBCPP_INLINE_VISIBILITY 2376 bool is_socket() const { return __get_ft() == file_type::socket; } 2377 2378 _LIBCPP_INLINE_VISIBILITY 2379 bool is_socket(error_code& __ec) const noexcept { 2380 return __get_ft(&__ec) == file_type::socket; 2381 } 2382 2383 _LIBCPP_INLINE_VISIBILITY 2384 bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } 2385 2386 _LIBCPP_INLINE_VISIBILITY 2387 bool is_symlink(error_code& __ec) const noexcept { 2388 return __get_sym_ft(&__ec) == file_type::symlink; 2389 } 2390 _LIBCPP_INLINE_VISIBILITY 2391 uintmax_t file_size() const { return __get_size(); } 2392 2393 _LIBCPP_INLINE_VISIBILITY 2394 uintmax_t file_size(error_code& __ec) const noexcept { 2395 return __get_size(&__ec); 2396 } 2397 2398 _LIBCPP_INLINE_VISIBILITY 2399 uintmax_t hard_link_count() const { return __get_nlink(); } 2400 2401 _LIBCPP_INLINE_VISIBILITY 2402 uintmax_t hard_link_count(error_code& __ec) const noexcept { 2403 return __get_nlink(&__ec); 2404 } 2405 2406 _LIBCPP_INLINE_VISIBILITY 2407 file_time_type last_write_time() const { return __get_write_time(); } 2408 2409 _LIBCPP_INLINE_VISIBILITY 2410 file_time_type last_write_time(error_code& __ec) const noexcept { 2411 return __get_write_time(&__ec); 2412 } 2413 2414 _LIBCPP_INLINE_VISIBILITY 2415 file_status status() const { return __get_status(); } 2416 2417 _LIBCPP_INLINE_VISIBILITY 2418 file_status status(error_code& __ec) const noexcept { 2419 return __get_status(&__ec); 2420 } 2421 2422 _LIBCPP_INLINE_VISIBILITY 2423 file_status symlink_status() const { return __get_symlink_status(); } 2424 2425 _LIBCPP_INLINE_VISIBILITY 2426 file_status symlink_status(error_code& __ec) const noexcept { 2427 return __get_symlink_status(&__ec); 2428 } 2429 2430 _LIBCPP_INLINE_VISIBILITY 2431 bool operator<(directory_entry const& __rhs) const noexcept { 2432 return __p_ < __rhs.__p_; 2433 } 2434 2435 _LIBCPP_INLINE_VISIBILITY 2436 bool operator==(directory_entry const& __rhs) const noexcept { 2437 return __p_ == __rhs.__p_; 2438 } 2439 2440 _LIBCPP_INLINE_VISIBILITY 2441 bool operator!=(directory_entry const& __rhs) const noexcept { 2442 return __p_ != __rhs.__p_; 2443 } 2444 2445 _LIBCPP_INLINE_VISIBILITY 2446 bool operator<=(directory_entry const& __rhs) const noexcept { 2447 return __p_ <= __rhs.__p_; 2448 } 2449 2450 _LIBCPP_INLINE_VISIBILITY 2451 bool operator>(directory_entry const& __rhs) const noexcept { 2452 return __p_ > __rhs.__p_; 2453 } 2454 2455 _LIBCPP_INLINE_VISIBILITY 2456 bool operator>=(directory_entry const& __rhs) const noexcept { 2457 return __p_ >= __rhs.__p_; 2458 } 2459 2460private: 2461 friend class directory_iterator; 2462 friend class recursive_directory_iterator; 2463 friend class __dir_stream; 2464 2465 enum _CacheType : unsigned char { 2466 _Empty, 2467 _IterSymlink, 2468 _IterNonSymlink, 2469 _RefreshSymlink, 2470 _RefreshSymlinkUnresolved, 2471 _RefreshNonSymlink 2472 }; 2473 2474 struct __cached_data { 2475 uintmax_t __size_; 2476 uintmax_t __nlink_; 2477 file_time_type __write_time_; 2478 perms __sym_perms_; 2479 perms __non_sym_perms_; 2480 file_type __type_; 2481 _CacheType __cache_type_; 2482 2483 _LIBCPP_INLINE_VISIBILITY 2484 __cached_data() noexcept { __reset(); } 2485 2486 _LIBCPP_INLINE_VISIBILITY 2487 void __reset() { 2488 __cache_type_ = _Empty; 2489 __type_ = file_type::none; 2490 __sym_perms_ = __non_sym_perms_ = perms::unknown; 2491 __size_ = __nlink_ = uintmax_t(-1); 2492 __write_time_ = file_time_type::min(); 2493 } 2494 }; 2495 2496 _LIBCPP_INLINE_VISIBILITY 2497 static __cached_data __create_iter_result(file_type __ft) { 2498 __cached_data __data; 2499 __data.__type_ = __ft; 2500 __data.__cache_type_ = [&]() { 2501 switch (__ft) { 2502 case file_type::none: 2503 return _Empty; 2504 case file_type::symlink: 2505 return _IterSymlink; 2506 default: 2507 return _IterNonSymlink; 2508 } 2509 }(); 2510 return __data; 2511 } 2512 2513 _LIBCPP_INLINE_VISIBILITY 2514 void __assign_iter_entry(_Path&& __p, __cached_data __dt) { 2515 __p_ = _VSTD::move(__p); 2516 __data_ = __dt; 2517 } 2518 2519 _LIBCPP_FUNC_VIS 2520 error_code __do_refresh() noexcept; 2521 2522 _LIBCPP_INLINE_VISIBILITY 2523 static bool __is_dne_error(error_code const& __ec) { 2524 if (!__ec) 2525 return true; 2526 switch (static_cast<errc>(__ec.value())) { 2527 case errc::no_such_file_or_directory: 2528 case errc::not_a_directory: 2529 return true; 2530 default: 2531 return false; 2532 } 2533 } 2534 2535 _LIBCPP_INLINE_VISIBILITY 2536 void __handle_error(const char* __msg, error_code* __dest_ec, 2537 error_code const& __ec, bool __allow_dne = false) const { 2538 if (__dest_ec) { 2539 *__dest_ec = __ec; 2540 return; 2541 } 2542 if (__ec && (!__allow_dne || !__is_dne_error(__ec))) 2543 __throw_filesystem_error(__msg, __p_, __ec); 2544 } 2545 2546 _LIBCPP_INLINE_VISIBILITY 2547 void __refresh(error_code* __ec = nullptr) { 2548 __handle_error("in directory_entry::refresh", __ec, __do_refresh(), 2549 /*allow_dne*/ true); 2550 } 2551 2552 _LIBCPP_INLINE_VISIBILITY 2553 file_type __get_sym_ft(error_code* __ec = nullptr) const { 2554 switch (__data_.__cache_type_) { 2555 case _Empty: 2556 return __symlink_status(__p_, __ec).type(); 2557 case _IterSymlink: 2558 case _RefreshSymlink: 2559 case _RefreshSymlinkUnresolved: 2560 if (__ec) 2561 __ec->clear(); 2562 return file_type::symlink; 2563 case _IterNonSymlink: 2564 case _RefreshNonSymlink: 2565 file_status __st(__data_.__type_); 2566 if (__ec && !_VSTD_FS::exists(__st)) 2567 *__ec = make_error_code(errc::no_such_file_or_directory); 2568 else if (__ec) 2569 __ec->clear(); 2570 return __data_.__type_; 2571 } 2572 _LIBCPP_UNREACHABLE(); 2573 } 2574 2575 _LIBCPP_INLINE_VISIBILITY 2576 file_type __get_ft(error_code* __ec = nullptr) const { 2577 switch (__data_.__cache_type_) { 2578 case _Empty: 2579 case _IterSymlink: 2580 case _RefreshSymlinkUnresolved: 2581 return __status(__p_, __ec).type(); 2582 case _IterNonSymlink: 2583 case _RefreshNonSymlink: 2584 case _RefreshSymlink: { 2585 file_status __st(__data_.__type_); 2586 if (__ec && !_VSTD_FS::exists(__st)) 2587 *__ec = make_error_code(errc::no_such_file_or_directory); 2588 else if (__ec) 2589 __ec->clear(); 2590 return __data_.__type_; 2591 } 2592 } 2593 _LIBCPP_UNREACHABLE(); 2594 } 2595 2596 _LIBCPP_INLINE_VISIBILITY 2597 file_status __get_status(error_code* __ec = nullptr) const { 2598 switch (__data_.__cache_type_) { 2599 case _Empty: 2600 case _IterNonSymlink: 2601 case _IterSymlink: 2602 case _RefreshSymlinkUnresolved: 2603 return __status(__p_, __ec); 2604 case _RefreshNonSymlink: 2605 case _RefreshSymlink: 2606 return file_status(__get_ft(__ec), __data_.__non_sym_perms_); 2607 } 2608 _LIBCPP_UNREACHABLE(); 2609 } 2610 2611 _LIBCPP_INLINE_VISIBILITY 2612 file_status __get_symlink_status(error_code* __ec = nullptr) const { 2613 switch (__data_.__cache_type_) { 2614 case _Empty: 2615 case _IterNonSymlink: 2616 case _IterSymlink: 2617 return __symlink_status(__p_, __ec); 2618 case _RefreshNonSymlink: 2619 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); 2620 case _RefreshSymlink: 2621 case _RefreshSymlinkUnresolved: 2622 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); 2623 } 2624 _LIBCPP_UNREACHABLE(); 2625 } 2626 2627 _LIBCPP_INLINE_VISIBILITY 2628 uintmax_t __get_size(error_code* __ec = nullptr) const { 2629 switch (__data_.__cache_type_) { 2630 case _Empty: 2631 case _IterNonSymlink: 2632 case _IterSymlink: 2633 case _RefreshSymlinkUnresolved: 2634 return _VSTD_FS::__file_size(__p_, __ec); 2635 case _RefreshSymlink: 2636 case _RefreshNonSymlink: { 2637 error_code __m_ec; 2638 file_status __st(__get_ft(&__m_ec)); 2639 __handle_error("in directory_entry::file_size", __ec, __m_ec); 2640 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { 2641 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory 2642 : errc::not_supported; 2643 __handle_error("in directory_entry::file_size", __ec, 2644 make_error_code(__err_kind)); 2645 } 2646 return __data_.__size_; 2647 } 2648 } 2649 _LIBCPP_UNREACHABLE(); 2650 } 2651 2652 _LIBCPP_INLINE_VISIBILITY 2653 uintmax_t __get_nlink(error_code* __ec = nullptr) const { 2654 switch (__data_.__cache_type_) { 2655 case _Empty: 2656 case _IterNonSymlink: 2657 case _IterSymlink: 2658 case _RefreshSymlinkUnresolved: 2659 return _VSTD_FS::__hard_link_count(__p_, __ec); 2660 case _RefreshSymlink: 2661 case _RefreshNonSymlink: { 2662 error_code __m_ec; 2663 (void)__get_ft(&__m_ec); 2664 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); 2665 return __data_.__nlink_; 2666 } 2667 } 2668 _LIBCPP_UNREACHABLE(); 2669 } 2670 2671 _LIBCPP_INLINE_VISIBILITY 2672 file_time_type __get_write_time(error_code* __ec = nullptr) const { 2673 switch (__data_.__cache_type_) { 2674 case _Empty: 2675 case _IterNonSymlink: 2676 case _IterSymlink: 2677 case _RefreshSymlinkUnresolved: 2678 return _VSTD_FS::__last_write_time(__p_, __ec); 2679 case _RefreshSymlink: 2680 case _RefreshNonSymlink: { 2681 error_code __m_ec; 2682 file_status __st(__get_ft(&__m_ec)); 2683 __handle_error("in directory_entry::last_write_time", __ec, __m_ec); 2684 if (_VSTD_FS::exists(__st) && 2685 __data_.__write_time_ == file_time_type::min()) 2686 __handle_error("in directory_entry::last_write_time", __ec, 2687 make_error_code(errc::value_too_large)); 2688 return __data_.__write_time_; 2689 } 2690 } 2691 _LIBCPP_UNREACHABLE(); 2692 } 2693 2694private: 2695 _Path __p_; 2696 __cached_data __data_; 2697}; 2698 2699class __dir_element_proxy { 2700public: 2701 inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { 2702 return _VSTD::move(__elem_); 2703 } 2704 2705private: 2706 friend class directory_iterator; 2707 friend class recursive_directory_iterator; 2708 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} 2709 __dir_element_proxy(__dir_element_proxy&& __o) 2710 : __elem_(_VSTD::move(__o.__elem_)) {} 2711 directory_entry __elem_; 2712}; 2713 2714class directory_iterator { 2715public: 2716 typedef directory_entry value_type; 2717 typedef ptrdiff_t difference_type; 2718 typedef value_type const* pointer; 2719 typedef value_type const& reference; 2720 typedef input_iterator_tag iterator_category; 2721 2722public: 2723 //ctor & dtor 2724 directory_iterator() noexcept {} 2725 2726 explicit directory_iterator(const path& __p) 2727 : directory_iterator(__p, nullptr) {} 2728 2729 directory_iterator(const path& __p, directory_options __opts) 2730 : directory_iterator(__p, nullptr, __opts) {} 2731 2732 directory_iterator(const path& __p, error_code& __ec) 2733 : directory_iterator(__p, &__ec) {} 2734 2735 directory_iterator(const path& __p, directory_options __opts, 2736 error_code& __ec) 2737 : directory_iterator(__p, &__ec, __opts) {} 2738 2739 directory_iterator(const directory_iterator&) = default; 2740 directory_iterator(directory_iterator&&) = default; 2741 directory_iterator& operator=(const directory_iterator&) = default; 2742 2743 directory_iterator& operator=(directory_iterator&& __o) noexcept { 2744 // non-default implementation provided to support self-move assign. 2745 if (this != &__o) { 2746 __imp_ = _VSTD::move(__o.__imp_); 2747 } 2748 return *this; 2749 } 2750 2751 ~directory_iterator() = default; 2752 2753 const directory_entry& operator*() const { 2754 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); 2755 return __dereference(); 2756 } 2757 2758 const directory_entry* operator->() const { return &**this; } 2759 2760 directory_iterator& operator++() { return __increment(); } 2761 2762 __dir_element_proxy operator++(int) { 2763 __dir_element_proxy __p(**this); 2764 __increment(); 2765 return __p; 2766 } 2767 2768 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } 2769 2770private: 2771 inline _LIBCPP_INLINE_VISIBILITY friend bool 2772 operator==(const directory_iterator& __lhs, 2773 const directory_iterator& __rhs) noexcept; 2774 2775 // construct the dir_stream 2776 _LIBCPP_FUNC_VIS 2777 directory_iterator(const path&, error_code*, 2778 directory_options = directory_options::none); 2779 2780 _LIBCPP_FUNC_VIS 2781 directory_iterator& __increment(error_code* __ec = nullptr); 2782 2783 _LIBCPP_FUNC_VIS 2784 const directory_entry& __dereference() const; 2785 2786private: 2787 shared_ptr<__dir_stream> __imp_; 2788}; 2789 2790inline _LIBCPP_INLINE_VISIBILITY bool 2791operator==(const directory_iterator& __lhs, 2792 const directory_iterator& __rhs) noexcept { 2793 return __lhs.__imp_ == __rhs.__imp_; 2794} 2795 2796inline _LIBCPP_INLINE_VISIBILITY bool 2797operator!=(const directory_iterator& __lhs, 2798 const directory_iterator& __rhs) noexcept { 2799 return !(__lhs == __rhs); 2800} 2801 2802// enable directory_iterator range-based for statements 2803inline _LIBCPP_INLINE_VISIBILITY directory_iterator 2804begin(directory_iterator __iter) noexcept { 2805 return __iter; 2806} 2807 2808inline _LIBCPP_INLINE_VISIBILITY directory_iterator 2809end(const directory_iterator&) noexcept { 2810 return directory_iterator(); 2811} 2812 2813class recursive_directory_iterator { 2814public: 2815 using value_type = directory_entry; 2816 using difference_type = ptrdiff_t; 2817 using pointer = directory_entry const*; 2818 using reference = directory_entry const&; 2819 using iterator_category = input_iterator_tag; 2820 2821public: 2822 // constructors and destructor 2823 _LIBCPP_INLINE_VISIBILITY 2824 recursive_directory_iterator() noexcept : __rec_(false) {} 2825 2826 _LIBCPP_INLINE_VISIBILITY 2827 explicit recursive_directory_iterator( 2828 const path& __p, directory_options __xoptions = directory_options::none) 2829 : recursive_directory_iterator(__p, __xoptions, nullptr) {} 2830 2831 _LIBCPP_INLINE_VISIBILITY 2832 recursive_directory_iterator(const path& __p, directory_options __xoptions, 2833 error_code& __ec) 2834 : recursive_directory_iterator(__p, __xoptions, &__ec) {} 2835 2836 _LIBCPP_INLINE_VISIBILITY 2837 recursive_directory_iterator(const path& __p, error_code& __ec) 2838 : recursive_directory_iterator(__p, directory_options::none, &__ec) {} 2839 2840 recursive_directory_iterator(const recursive_directory_iterator&) = default; 2841 recursive_directory_iterator(recursive_directory_iterator&&) = default; 2842 2843 recursive_directory_iterator& 2844 operator=(const recursive_directory_iterator&) = default; 2845 2846 _LIBCPP_INLINE_VISIBILITY 2847 recursive_directory_iterator& 2848 operator=(recursive_directory_iterator&& __o) noexcept { 2849 // non-default implementation provided to support self-move assign. 2850 if (this != &__o) { 2851 __imp_ = _VSTD::move(__o.__imp_); 2852 __rec_ = __o.__rec_; 2853 } 2854 return *this; 2855 } 2856 2857 ~recursive_directory_iterator() = default; 2858 2859 _LIBCPP_INLINE_VISIBILITY 2860 const directory_entry& operator*() const { return __dereference(); } 2861 2862 _LIBCPP_INLINE_VISIBILITY 2863 const directory_entry* operator->() const { return &__dereference(); } 2864 2865 recursive_directory_iterator& operator++() { return __increment(); } 2866 2867 _LIBCPP_INLINE_VISIBILITY 2868 __dir_element_proxy operator++(int) { 2869 __dir_element_proxy __p(**this); 2870 __increment(); 2871 return __p; 2872 } 2873 2874 _LIBCPP_INLINE_VISIBILITY 2875 recursive_directory_iterator& increment(error_code& __ec) { 2876 return __increment(&__ec); 2877 } 2878 2879 _LIBCPP_FUNC_VIS directory_options options() const; 2880 _LIBCPP_FUNC_VIS int depth() const; 2881 2882 _LIBCPP_INLINE_VISIBILITY 2883 void pop() { __pop(); } 2884 2885 _LIBCPP_INLINE_VISIBILITY 2886 void pop(error_code& __ec) { __pop(&__ec); } 2887 2888 _LIBCPP_INLINE_VISIBILITY 2889 bool recursion_pending() const { return __rec_; } 2890 2891 _LIBCPP_INLINE_VISIBILITY 2892 void disable_recursion_pending() { __rec_ = false; } 2893 2894private: 2895 _LIBCPP_FUNC_VIS 2896 recursive_directory_iterator(const path& __p, directory_options __opt, 2897 error_code* __ec); 2898 2899 _LIBCPP_FUNC_VIS 2900 const directory_entry& __dereference() const; 2901 2902 _LIBCPP_FUNC_VIS 2903 bool __try_recursion(error_code* __ec); 2904 2905 _LIBCPP_FUNC_VIS 2906 void __advance(error_code* __ec = nullptr); 2907 2908 _LIBCPP_FUNC_VIS 2909 recursive_directory_iterator& __increment(error_code* __ec = nullptr); 2910 2911 _LIBCPP_FUNC_VIS 2912 void __pop(error_code* __ec = nullptr); 2913 2914 inline _LIBCPP_INLINE_VISIBILITY friend bool 2915 operator==(const recursive_directory_iterator&, 2916 const recursive_directory_iterator&) noexcept; 2917 2918 struct _LIBCPP_HIDDEN __shared_imp; 2919 shared_ptr<__shared_imp> __imp_; 2920 bool __rec_; 2921}; // class recursive_directory_iterator 2922 2923inline _LIBCPP_INLINE_VISIBILITY bool 2924operator==(const recursive_directory_iterator& __lhs, 2925 const recursive_directory_iterator& __rhs) noexcept { 2926 return __lhs.__imp_ == __rhs.__imp_; 2927} 2928 2929_LIBCPP_INLINE_VISIBILITY 2930inline bool operator!=(const recursive_directory_iterator& __lhs, 2931 const recursive_directory_iterator& __rhs) noexcept { 2932 return !(__lhs == __rhs); 2933} 2934// enable recursive_directory_iterator range-based for statements 2935inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator 2936begin(recursive_directory_iterator __iter) noexcept { 2937 return __iter; 2938} 2939 2940inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator 2941end(const recursive_directory_iterator&) noexcept { 2942 return recursive_directory_iterator(); 2943} 2944 2945_LIBCPP_AVAILABILITY_FILESYSTEM_POP 2946 2947_LIBCPP_END_NAMESPACE_FILESYSTEM 2948 2949#endif // !_LIBCPP_CXX03_LANG 2950 2951_LIBCPP_POP_MACROS 2952 2953#endif // _LIBCPP_FILESYSTEM 2954