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