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