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