1 // -*- C++ -*- 2 //===--------------------------- filesystem -------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 #ifndef _LIBCPP_EXPERIMENTAL_FILESYSTEM 11 #define _LIBCPP_EXPERIMENTAL_FILESYSTEM 12 /* 13 filesystem synopsis 14 15 namespace std { namespace experimental { namespace filesystem { inline namespace v1 { 16 17 class path; 18 19 void swap(path& lhs, path& rhs) _NOEXCEPT; 20 size_t hash_value(const path& p) _NOEXCEPT; 21 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 bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT; 28 29 path operator/ (const path& lhs, const path& rhs); 30 31 // fs.path.io operators are friends of path. 32 template <class charT, class traits> 33 friend basic_ostream<charT, traits>& 34 operator<<(basic_ostream<charT, traits>& os, const path& p); 35 36 template <class charT, class traits> 37 friend basic_istream<charT, traits>& 38 operator>>(basic_istream<charT, traits>& is, path& p); 39 40 template <class Source> 41 path u8path(const Source& source); 42 template <class InputIterator> 43 path u8path(InputIterator first, InputIterator last); 44 45 class filesystem_error; 46 class directory_entry; 47 48 class directory_iterator; 49 50 // enable directory_iterator range-based for statements 51 directory_iterator begin(directory_iterator iter) noexcept; 52 directory_iterator end(const directory_iterator&) noexcept; 53 54 class recursive_directory_iterator; 55 56 // enable recursive_directory_iterator range-based for statements 57 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; 58 recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; 59 60 class file_status; 61 62 struct space_info 63 { 64 uintmax_t capacity; 65 uintmax_t free; 66 uintmax_t available; 67 }; 68 69 enum class file_type; 70 enum class perms; 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, const path& base=current_path()); 79 80 path canonical(const path& p, const path& base = current_path()); 81 path canonical(const path& p, error_code& ec); 82 path canonical(const path& p, const path& base, 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 void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT; 183 184 path read_symlink(const path& p); 185 path read_symlink(const path& p, error_code& ec); 186 187 bool remove(const path& p); 188 bool remove(const path& p, error_code& ec) _NOEXCEPT; 189 190 uintmax_t remove_all(const path& p); 191 uintmax_t remove_all(const path& p, error_code& ec); 192 193 void rename(const path& from, const path& to); 194 void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT; 195 196 void resize_file(const path& p, uintmax_t size); 197 void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT; 198 199 space_info space(const path& p); 200 space_info space(const path& p, error_code& ec) _NOEXCEPT; 201 202 file_status status(const path& p); 203 file_status status(const path& p, error_code& ec) _NOEXCEPT; 204 205 bool status_known(file_status s) _NOEXCEPT; 206 207 file_status symlink_status(const path& p); 208 file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT; 209 210 path system_complete(const path& p); 211 path system_complete(const path& p, error_code& ec); 212 213 path temp_directory_path(); 214 path temp_directory_path(error_code& ec); 215 216 } } } } // namespaces std::experimental::filesystem::v1 217 218 */ 219 220 #include <experimental/__config> 221 #include <cstddef> 222 #include <chrono> 223 #include <iterator> 224 #include <iosfwd> 225 #include <locale> 226 #include <memory> 227 #include <stack> 228 #include <string> 229 #include <system_error> 230 #include <utility> 231 #include <iomanip> // for quoted 232 #include <string_view> 233 234 #include <__debug> 235 236 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 237 #pragma GCC system_header 238 #endif 239 240 #define __cpp_lib_experimental_filesystem 201406 241 242 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM 243 244 typedef chrono::time_point<std::chrono::system_clock> file_time_type; 245 246 struct _LIBCPP_TYPE_VIS space_info 247 { 248 uintmax_t capacity; 249 uintmax_t free; 250 uintmax_t available; 251 }; 252 253 enum class _LIBCPP_ENUM_VIS file_type : signed char 254 { 255 none = 0, 256 not_found = -1, 257 regular = 1, 258 directory = 2, 259 symlink = 3, 260 block = 4, 261 character = 5, 262 fifo = 6, 263 socket = 7, 264 unknown = 8 265 }; 266 267 enum class _LIBCPP_ENUM_VIS perms : unsigned 268 { 269 none = 0, 270 271 owner_read = 0400, 272 owner_write = 0200, 273 owner_exec = 0100, 274 owner_all = 0700, 275 276 group_read = 040, 277 group_write = 020, 278 group_exec = 010, 279 group_all = 070, 280 281 others_read = 04, 282 others_write = 02, 283 others_exec = 01, 284 others_all = 07, 285 286 all = 0777, 287 288 set_uid = 04000, 289 set_gid = 02000, 290 sticky_bit = 01000, 291 mask = 07777, 292 unknown = 0xFFFF, 293 294 add_perms = 0x10000, 295 remove_perms = 0x20000, 296 symlink_nofollow = 0x40000 297 }; 298 299 _LIBCPP_INLINE_VISIBILITY 300 inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS) 301 { return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); } 302 303 _LIBCPP_INLINE_VISIBILITY 304 inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS) 305 { return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); } 306 307 _LIBCPP_INLINE_VISIBILITY 308 inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS) 309 { return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); } 310 311 _LIBCPP_INLINE_VISIBILITY 312 inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS) 313 { return static_cast<perms>(~static_cast<unsigned>(_LHS)); } 314 315 _LIBCPP_INLINE_VISIBILITY 316 inline perms& operator&=(perms& _LHS, perms _RHS) 317 { return _LHS = _LHS & _RHS; } 318 319 _LIBCPP_INLINE_VISIBILITY 320 inline perms& operator|=(perms& _LHS, perms _RHS) 321 { return _LHS = _LHS | _RHS; } 322 323 _LIBCPP_INLINE_VISIBILITY 324 inline perms& operator^=(perms& _LHS, perms _RHS) 325 { return _LHS = _LHS ^ _RHS; } 326 327 enum class _LIBCPP_ENUM_VIS copy_options : unsigned short 328 { 329 none = 0, 330 skip_existing = 1, 331 overwrite_existing = 2, 332 update_existing = 4, 333 recursive = 8, 334 copy_symlinks = 16, 335 skip_symlinks = 32, 336 directories_only = 64, 337 create_symlinks = 128, 338 create_hard_links = 256, 339 __in_recursive_copy = 512, 340 }; 341 342 _LIBCPP_INLINE_VISIBILITY 343 inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS) 344 { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); } 345 346 _LIBCPP_INLINE_VISIBILITY 347 inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS) 348 { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); } 349 350 _LIBCPP_INLINE_VISIBILITY 351 inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS) 352 { return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); } 353 354 _LIBCPP_INLINE_VISIBILITY 355 inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS) 356 { return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); } 357 358 _LIBCPP_INLINE_VISIBILITY 359 inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) 360 { return _LHS = _LHS & _RHS; } 361 362 _LIBCPP_INLINE_VISIBILITY 363 inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) 364 { return _LHS = _LHS | _RHS; } 365 366 _LIBCPP_INLINE_VISIBILITY 367 inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) 368 { return _LHS = _LHS ^ _RHS; } 369 370 371 enum class _LIBCPP_ENUM_VIS directory_options : unsigned char 372 { 373 none = 0, 374 follow_directory_symlink = 1, 375 skip_permission_denied = 2 376 }; 377 378 _LIBCPP_INLINE_VISIBILITY 379 inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS) 380 { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); } 381 382 _LIBCPP_INLINE_VISIBILITY 383 inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS) 384 { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); } 385 386 _LIBCPP_INLINE_VISIBILITY 387 inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS) 388 { return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); } 389 390 _LIBCPP_INLINE_VISIBILITY 391 inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS) 392 { return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); } 393 394 _LIBCPP_INLINE_VISIBILITY 395 inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS) 396 { return _LHS = _LHS & _RHS; } 397 398 _LIBCPP_INLINE_VISIBILITY 399 inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS) 400 { return _LHS = _LHS | _RHS; } 401 402 _LIBCPP_INLINE_VISIBILITY 403 inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS) 404 { return _LHS = _LHS ^ _RHS; } 405 406 407 class _LIBCPP_TYPE_VIS file_status 408 { 409 public: 410 // constructors 411 _LIBCPP_INLINE_VISIBILITY 412 file_status() _NOEXCEPT : file_status(file_type::none) {} 413 _LIBCPP_INLINE_VISIBILITY 414 explicit file_status(file_type __ft, 415 perms __prms = perms::unknown) _NOEXCEPT 416 : __ft_(__ft), __prms_(__prms) 417 {} 418 419 file_status(const file_status&) _NOEXCEPT = default; 420 file_status(file_status&&) _NOEXCEPT = default; 421 422 _LIBCPP_INLINE_VISIBILITY 423 ~file_status() {} 424 425 file_status& operator=(const file_status&) _NOEXCEPT = default; 426 file_status& operator=(file_status&&) _NOEXCEPT = default; 427 428 // observers 429 _LIBCPP_ALWAYS_INLINE 430 file_type type() const _NOEXCEPT { 431 return __ft_; 432 } 433 434 _LIBCPP_ALWAYS_INLINE 435 perms permissions() const _NOEXCEPT { 436 return __prms_; 437 } 438 439 // modifiers 440 _LIBCPP_ALWAYS_INLINE 441 void type(file_type __ft) _NOEXCEPT { 442 __ft_ = __ft; 443 } 444 445 _LIBCPP_ALWAYS_INLINE 446 void permissions(perms __p) _NOEXCEPT { 447 __prms_ = __p; 448 } 449 private: 450 file_type __ft_; 451 perms __prms_; 452 }; 453 454 class _LIBCPP_TYPE_VIS directory_entry; 455 456 template <class _Tp> struct __can_convert_char { 457 static const bool value = false; 458 }; 459 template <class _Tp> struct __can_convert_char<const _Tp> 460 : public __can_convert_char<_Tp> { 461 }; 462 template <> struct __can_convert_char<char> { 463 static const bool value = true; 464 using __char_type = char; 465 }; 466 template <> struct __can_convert_char<wchar_t> { 467 static const bool value = true; 468 using __char_type = wchar_t; 469 }; 470 template <> struct __can_convert_char<char16_t> { 471 static const bool value = true; 472 using __char_type = char16_t; 473 }; 474 template <> struct __can_convert_char<char32_t> { 475 static const bool value = true; 476 using __char_type = char32_t; 477 }; 478 479 template <class _ECharT> 480 typename enable_if<__can_convert_char<_ECharT>::value, bool>::type 481 __is_separator(_ECharT __e) { 482 return __e == _ECharT('/'); 483 }; 484 485 struct _NullSentinal {}; 486 487 template <class _Tp> 488 using _Void = void; 489 490 template <class _Tp, class = void> 491 struct __is_pathable_string : public false_type {}; 492 493 template <class _ECharT, class _Traits, class _Alloc> 494 struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>, 495 _Void<typename __can_convert_char<_ECharT>::__char_type>> 496 : public __can_convert_char<_ECharT> 497 { 498 using _Str = basic_string<_ECharT, _Traits, _Alloc>; 499 using _Base = __can_convert_char<_ECharT>; 500 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 501 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } 502 static _ECharT __first_or_null(_Str const& __s) { 503 return __s.empty() ? _ECharT{} : __s[0]; 504 } 505 }; 506 507 508 template <class _ECharT, class _Traits> 509 struct __is_pathable_string<basic_string_view<_ECharT, _Traits>, 510 _Void<typename __can_convert_char<_ECharT>::__char_type>> 511 : public __can_convert_char<_ECharT> 512 { 513 using _Str = basic_string_view<_ECharT, _Traits>; 514 using _Base = __can_convert_char<_ECharT>; 515 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } 516 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } 517 static _ECharT __first_or_null(_Str const& __s) { 518 return __s.empty() ? _ECharT{} : __s[0]; 519 } 520 }; 521 522 template <class _Source, 523 class _DS = typename decay<_Source>::type, 524 class _UnqualPtrType = typename remove_const< 525 typename remove_pointer<_DS>::type>::type, 526 bool _IsCharPtr = is_pointer<_DS>::value && 527 __can_convert_char<_UnqualPtrType>::value 528 > 529 struct __is_pathable_char_array : false_type {}; 530 531 template <class _Source, class _ECharT, class _UPtr> 532 struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> 533 : __can_convert_char<typename remove_const<_ECharT>::type> 534 { 535 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; 536 537 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } 538 static _ECharT const* __range_end(const _ECharT* __b) 539 { 540 using _Iter = const _ECharT*; 541 const _ECharT __sentinal = _ECharT{}; 542 _Iter __e = __b; 543 for (; *__e != __sentinal; ++__e) 544 ; 545 return __e; 546 } 547 548 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } 549 }; 550 551 template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void> 552 struct __is_pathable_iter : false_type {}; 553 554 template <class _Iter> 555 struct __is_pathable_iter<_Iter, true, 556 _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>> 557 : __can_convert_char<typename iterator_traits<_Iter>::value_type> 558 { 559 using _ECharT = typename iterator_traits<_Iter>::value_type; 560 using _Base = __can_convert_char<_ECharT>; 561 562 static _Iter __range_begin(_Iter __b) { return __b; } 563 static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } 564 565 static _ECharT __first_or_null(_Iter __b) { return *__b; } 566 }; 567 568 template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, 569 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, 570 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value 571 > 572 struct __is_pathable : false_type { 573 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); 574 }; 575 576 template <class _Tp> 577 struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; 578 579 580 template <class _Tp> 581 struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; 582 583 584 template <class _Tp> 585 struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; 586 587 588 template <class _ECharT> 589 struct _PathCVT { 590 static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); 591 592 typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower; 593 594 static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) { 595 _Narrower()(back_inserter(__dest), __b, __e); 596 } 597 598 template <class _Iter> 599 static void __append_range(string& __dest, _Iter __b, _Iter __e) { 600 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 601 if (__b == __e) return; 602 basic_string<_ECharT> __tmp(__b, __e); 603 _Narrower()(back_inserter(__dest), __tmp.data(), 604 __tmp.data() + __tmp.length()); 605 } 606 607 template <class _Iter> 608 static void __append_range(string& __dest, _Iter __b, _NullSentinal) { 609 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); 610 const _ECharT __sentinal = _ECharT{}; 611 if (*__b == __sentinal) return; 612 basic_string<_ECharT> __tmp; 613 for (; *__b != __sentinal; ++__b) 614 __tmp.push_back(*__b); 615 _Narrower()(back_inserter(__dest), __tmp.data(), 616 __tmp.data() + __tmp.length()); 617 } 618 619 template <class _Source> 620 static void __append_source(string& __dest, _Source const& __s) 621 { 622 using _Traits = __is_pathable<_Source>; 623 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); 624 } 625 }; 626 627 template <> 628 struct _PathCVT<char> { 629 630 template <class _Iter> 631 static typename enable_if< 632 __is_exactly_input_iterator<_Iter>::value 633 >::type __append_range(string& __dest, _Iter __b, _Iter __e) { 634 for (; __b != __e; ++__b) 635 __dest.push_back(*__b); 636 } 637 638 template <class _Iter> 639 static typename enable_if< 640 __is_forward_iterator<_Iter>::value 641 >::type __append_range(string& __dest, _Iter __b, _Iter __e) { 642 __dest.__append_forward_unsafe(__b, __e); 643 } 644 645 template <class _Iter> 646 static void __append_range(string& __dest, _Iter __b, _NullSentinal) { 647 const char __sentinal = char{}; 648 for (; *__b != __sentinal; ++__b) 649 __dest.push_back(*__b); 650 } 651 652 template <class _Source> 653 static void __append_source(string& __dest, _Source const& __s) 654 { 655 using _Traits = __is_pathable<_Source>; 656 __append_range(__dest, _Traits::__range_begin(__s), 657 _Traits::__range_end(__s)); 658 } 659 }; 660 661 662 class _LIBCPP_TYPE_VIS path 663 { 664 template <class _SourceOrIter, class _Tp = path&> 665 using _EnableIfPathable = typename 666 enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; 667 668 template <class _Tp> 669 using _SourceChar = typename __is_pathable<_Tp>::__char_type; 670 671 template <class _Tp> 672 using _SourceCVT = _PathCVT<_SourceChar<_Tp>>; 673 674 public: 675 typedef char value_type; 676 typedef basic_string<value_type> string_type; 677 typedef _VSTD::string_view __string_view; 678 static _LIBCPP_CONSTEXPR value_type preferred_separator = '/'; 679 680 // constructors and destructor 681 _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {} 682 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {} 683 _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {} 684 685 _LIBCPP_INLINE_VISIBILITY 686 path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {} 687 688 template < 689 class _Source, 690 class = _EnableIfPathable<_Source, void> 691 > 692 path(const _Source& __src) { 693 _SourceCVT<_Source>::__append_source(__pn_, __src); 694 } 695 696 template <class _InputIt> 697 path(_InputIt __first, _InputIt __last) { 698 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 699 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 700 } 701 702 // TODO Implement locale conversions. 703 template <class _Source, 704 class = _EnableIfPathable<_Source, void> 705 > 706 path(const _Source& __src, const locale& __loc); 707 template <class _InputIt> 708 path(_InputIt __first, _InputIt _last, const locale& __loc); 709 710 _LIBCPP_INLINE_VISIBILITY 711 ~path() = default; 712 713 // assignments 714 _LIBCPP_INLINE_VISIBILITY 715 path& operator=(const path& __p) { 716 __pn_ = __p.__pn_; 717 return *this; 718 } 719 720 _LIBCPP_INLINE_VISIBILITY 721 path& operator=(path&& __p) _NOEXCEPT { 722 __pn_ = _VSTD::move(__p.__pn_); 723 return *this; 724 } 725 726 template <class = void> 727 _LIBCPP_INLINE_VISIBILITY 728 path& operator=(string_type&& __s) _NOEXCEPT { 729 __pn_ = _VSTD::move(__s); 730 return *this; 731 } 732 733 _LIBCPP_INLINE_VISIBILITY 734 path& assign(string_type&& __s) _NOEXCEPT { 735 __pn_ = _VSTD::move(__s); 736 return *this; 737 } 738 739 template <class _Source> 740 _LIBCPP_INLINE_VISIBILITY 741 _EnableIfPathable<_Source> 742 operator=(const _Source& __src) 743 { return this->assign(__src); } 744 745 746 template <class _Source> 747 _EnableIfPathable<_Source> 748 assign(const _Source& __src) { 749 __pn_.clear(); 750 _SourceCVT<_Source>::__append_source(__pn_, __src); 751 return *this; 752 } 753 754 template <class _InputIt> 755 path& assign(_InputIt __first, _InputIt __last) { 756 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 757 __pn_.clear(); 758 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 759 return *this; 760 } 761 762 private: 763 template <class _ECharT> 764 void __append_sep_if_needed(_ECharT __first_or_null) { 765 const _ECharT __null_val = {}; 766 bool __append_sep = !empty() && 767 !__is_separator(__pn_.back()) && 768 __first_or_null != __null_val && // non-empty 769 !__is_separator(__first_or_null); 770 if (__append_sep) 771 __pn_ += preferred_separator; 772 } 773 774 public: 775 // appends 776 path& operator/=(const path& __p) { 777 _LIBCPP_ASSERT(!__p.has_root_name(), 778 "cannot append to a path with a root name"); 779 __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]); 780 __pn_ += __p.native(); 781 return *this; 782 } 783 784 template <class _Source> 785 _LIBCPP_INLINE_VISIBILITY 786 _EnableIfPathable<_Source> 787 operator/=(const _Source& __src) { 788 return this->append(__src); 789 } 790 791 template <class _Source> 792 _EnableIfPathable<_Source> 793 append(const _Source& __src) { 794 using _Traits = __is_pathable<_Source>; 795 using _CVT = _PathCVT<_SourceChar<_Source>>; 796 __append_sep_if_needed(_Traits::__first_or_null(__src)); 797 _CVT::__append_source(__pn_, __src); 798 return *this; 799 } 800 801 template <class _InputIt> 802 path& append(_InputIt __first, _InputIt __last) { 803 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 804 static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); 805 using _CVT = _PathCVT<_ItVal>; 806 if (__first != __last) { 807 __append_sep_if_needed(*__first); 808 _CVT::__append_range(__pn_, __first, __last); 809 } 810 return *this; 811 } 812 813 // concatenation 814 _LIBCPP_INLINE_VISIBILITY 815 path& operator+=(const path& __x) { 816 __pn_ += __x.__pn_; 817 return *this; 818 } 819 820 _LIBCPP_INLINE_VISIBILITY 821 path& operator+=(const string_type& __x) { 822 __pn_ += __x; 823 return *this; 824 } 825 826 _LIBCPP_INLINE_VISIBILITY 827 path& operator+=(__string_view __x) { 828 __pn_ += __x; 829 return *this; 830 } 831 832 _LIBCPP_INLINE_VISIBILITY 833 path& operator+=(const value_type* __x) { 834 __pn_ += __x; 835 return *this; 836 } 837 838 _LIBCPP_INLINE_VISIBILITY 839 path& operator+=(value_type __x) { 840 __pn_ += __x; 841 return *this; 842 } 843 844 template <class _ECharT> 845 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type 846 operator+=(_ECharT __x) 847 { 848 basic_string<_ECharT> __tmp; 849 __tmp += __x; 850 _PathCVT<_ECharT>::__append_source(__pn_, __tmp); 851 return *this; 852 } 853 854 template <class _Source> 855 _EnableIfPathable<_Source> 856 operator+=(const _Source& __x) { 857 return this->concat(__x); 858 } 859 860 template <class _Source> 861 _EnableIfPathable<_Source> 862 concat(const _Source& __x) { 863 _SourceCVT<_Source>::__append_source(__pn_, __x); 864 return *this; 865 } 866 867 template <class _InputIt> 868 path& concat(_InputIt __first, _InputIt __last) { 869 typedef typename iterator_traits<_InputIt>::value_type _ItVal; 870 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); 871 return *this; 872 } 873 874 // modifiers 875 _LIBCPP_INLINE_VISIBILITY 876 void clear() _NOEXCEPT { 877 __pn_.clear(); 878 } 879 880 path& make_preferred() { return *this; } 881 882 _LIBCPP_INLINE_VISIBILITY 883 path& remove_filename() { 884 if (__pn_.size() == __root_path_raw().size()) 885 clear(); 886 else 887 __pn_ = __parent_path(); 888 return *this; 889 } 890 891 path& replace_filename(const path& __replacement) { 892 remove_filename(); 893 return (*this /= __replacement); 894 } 895 896 path& replace_extension(const path& __replacement = path()); 897 898 _LIBCPP_INLINE_VISIBILITY 899 void swap(path& __rhs) _NOEXCEPT { 900 __pn_.swap(__rhs.__pn_); 901 } 902 903 // native format observers 904 _LIBCPP_INLINE_VISIBILITY 905 const string_type& native() const _NOEXCEPT { 906 return __pn_; 907 } 908 909 _LIBCPP_INLINE_VISIBILITY 910 const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); } 911 912 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } 913 914 template <class _ECharT, class _Traits = char_traits<_ECharT>, 915 class _Allocator = allocator<_ECharT> > 916 basic_string<_ECharT, _Traits, _Allocator> 917 string(const _Allocator& __a = _Allocator()) const { 918 using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>; 919 using _Str = basic_string<_ECharT, _Traits, _Allocator>; 920 _Str __s(__a); 921 __s.reserve(__pn_.size()); 922 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); 923 return __s; 924 } 925 926 _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } 927 _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); } 928 _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } 929 _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); } 930 _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); } 931 932 // generic format observers 933 template <class _ECharT, class _Traits = char_traits<_ECharT>, 934 class _Allocator = allocator<_ECharT> 935 > 936 basic_string<_ECharT, _Traits, _Allocator> 937 generic_string(const _Allocator& __a = _Allocator()) const { 938 return string<_ECharT, _Traits, _Allocator>(__a); 939 } 940 941 std::string generic_string() const { return __pn_; } 942 std::wstring generic_wstring() const { return string<wchar_t>(); } 943 std::string generic_u8string() const { return __pn_; } 944 std::u16string generic_u16string() const { return string<char16_t>(); } 945 std::u32string generic_u32string() const { return string<char32_t>(); } 946 947 private: 948 int __compare(__string_view) const; 949 __string_view __root_name() const; 950 __string_view __root_directory() const; 951 __string_view __root_path_raw() const; 952 __string_view __relative_path() const; 953 __string_view __parent_path() const; 954 __string_view __filename() const; 955 __string_view __stem() const; 956 __string_view __extension() const; 957 958 public: 959 // compare 960 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);} 961 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); } 962 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); } 963 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); } 964 965 // decomposition 966 _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); } 967 _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); } 968 _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); } 969 _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); } 970 _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); } 971 _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); } 972 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());} 973 _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); } 974 975 // query 976 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 977 bool empty() const _NOEXCEPT { return __pn_.empty(); } 978 979 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); } 980 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); } 981 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); } 982 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); } 983 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); } 984 _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); } 985 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } 986 _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); } 987 988 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); } 989 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } 990 991 // iterators 992 class _LIBCPP_TYPE_VIS iterator; 993 typedef iterator const_iterator; 994 995 iterator begin() const; 996 iterator end() const; 997 998 999 template <class _CharT, class _Traits> 1000 _LIBCPP_INLINE_VISIBILITY 1001 friend typename enable_if<is_same<_CharT, char>::value && 1002 is_same<_Traits, char_traits<char>>::value, 1003 basic_ostream<_CharT, _Traits>& 1004 >::type 1005 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1006 __os << std::__quoted(__p.native()); 1007 return __os; 1008 } 1009 1010 template <class _CharT, class _Traits> 1011 _LIBCPP_INLINE_VISIBILITY 1012 friend typename enable_if<!is_same<_CharT, char>::value || 1013 !is_same<_Traits, char_traits<char>>::value, 1014 basic_ostream<_CharT, _Traits>& 1015 >::type 1016 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { 1017 __os << std::__quoted(__p.string<_CharT, _Traits>()); 1018 return __os; 1019 } 1020 1021 template <class _CharT, class _Traits> 1022 _LIBCPP_INLINE_VISIBILITY 1023 friend basic_istream<_CharT, _Traits>& 1024 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) 1025 { 1026 basic_string<_CharT, _Traits> __tmp; 1027 __is >> __quoted(__tmp); 1028 __p = __tmp; 1029 return __is; 1030 } 1031 1032 private: 1033 inline _LIBCPP_INLINE_VISIBILITY 1034 path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; } 1035 string_type __pn_; 1036 }; 1037 1038 inline _LIBCPP_ALWAYS_INLINE 1039 void swap(path& __lhs, path& __rhs) _NOEXCEPT { 1040 __lhs.swap(__rhs); 1041 } 1042 1043 _LIBCPP_FUNC_VIS 1044 size_t hash_value(const path& __p) _NOEXCEPT; 1045 1046 inline _LIBCPP_INLINE_VISIBILITY 1047 bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT 1048 { return __lhs.compare(__rhs) == 0; } 1049 1050 inline _LIBCPP_INLINE_VISIBILITY 1051 bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT 1052 { return __lhs.compare(__rhs) != 0; } 1053 1054 inline _LIBCPP_INLINE_VISIBILITY 1055 bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT 1056 { return __lhs.compare(__rhs) < 0; } 1057 1058 inline _LIBCPP_INLINE_VISIBILITY 1059 bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT 1060 { return __lhs.compare(__rhs) <= 0; } 1061 1062 inline _LIBCPP_INLINE_VISIBILITY 1063 bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT 1064 { return __lhs.compare(__rhs) > 0; } 1065 1066 inline _LIBCPP_INLINE_VISIBILITY 1067 bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT 1068 { return __lhs.compare(__rhs) >= 0; } 1069 1070 inline _LIBCPP_INLINE_VISIBILITY 1071 path operator/(const path& __lhs, const path& __rhs) { 1072 return path(__lhs) /= __rhs; 1073 } 1074 1075 template <class _Source> 1076 _LIBCPP_INLINE_VISIBILITY 1077 typename enable_if<__is_pathable<_Source>::value, path>::type 1078 u8path(const _Source& __s){ 1079 static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value, 1080 "u8path(Source const&) requires Source have a character type of type 'char'"); 1081 return path(__s); 1082 } 1083 1084 template <class _InputIt> 1085 _LIBCPP_INLINE_VISIBILITY 1086 typename enable_if<__is_pathable<_InputIt>::value, path>::type 1087 u8path(_InputIt __f, _InputIt __l) { 1088 static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, 1089 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); 1090 return path(__f, __l); 1091 } 1092 1093 class _LIBCPP_TYPE_VIS path::iterator 1094 { 1095 public: 1096 typedef bidirectional_iterator_tag iterator_category; 1097 1098 typedef path value_type; 1099 typedef std::ptrdiff_t difference_type; 1100 typedef const path* pointer; 1101 typedef const path& reference; 1102 1103 typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator 1104 public: 1105 _LIBCPP_INLINE_VISIBILITY 1106 iterator() : __stashed_elem_(), __path_ptr_(nullptr), 1107 __entry_(), __state_(__singular) {} 1108 1109 iterator(const iterator&) = default; 1110 ~iterator() = default; 1111 1112 iterator& operator=(const iterator&) = default; 1113 1114 _LIBCPP_INLINE_VISIBILITY 1115 reference operator*() const { 1116 return __stashed_elem_; 1117 } 1118 1119 _LIBCPP_INLINE_VISIBILITY 1120 pointer operator->() const { 1121 return &__stashed_elem_; 1122 } 1123 1124 _LIBCPP_INLINE_VISIBILITY 1125 iterator& operator++() { 1126 _LIBCPP_ASSERT(__state_ != __singular, 1127 "attempting to increment a singular iterator"); 1128 _LIBCPP_ASSERT(__state_ != __at_end, 1129 "attempting to increment the end iterator"); 1130 return __increment(); 1131 } 1132 1133 _LIBCPP_INLINE_VISIBILITY 1134 iterator operator++(int) { 1135 iterator __it(*this); 1136 this->operator++(); 1137 return __it; 1138 } 1139 1140 _LIBCPP_INLINE_VISIBILITY 1141 iterator& operator--() { 1142 _LIBCPP_ASSERT(__state_ != __singular, 1143 "attempting to decrement a singular iterator"); 1144 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), 1145 "attempting to decrement the begin iterator"); 1146 return __decrement(); 1147 } 1148 1149 _LIBCPP_INLINE_VISIBILITY 1150 iterator operator--(int) { 1151 iterator __it(*this); 1152 this->operator--(); 1153 return __it; 1154 } 1155 1156 private: 1157 friend class path; 1158 1159 static constexpr unsigned char __singular = 0; 1160 static constexpr unsigned char __at_end = 6; 1161 1162 inline _LIBCPP_INLINE_VISIBILITY 1163 friend bool operator==(const iterator&, const iterator&); 1164 1165 iterator& __increment(); 1166 iterator& __decrement(); 1167 1168 path __stashed_elem_; 1169 const path* __path_ptr_; 1170 path::__string_view __entry_; 1171 unsigned char __state_; 1172 }; 1173 1174 inline _LIBCPP_INLINE_VISIBILITY 1175 bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { 1176 return __lhs.__path_ptr_ == __rhs.__path_ptr_ && 1177 __lhs.__entry_.data() == __rhs.__entry_.data(); 1178 } 1179 1180 inline _LIBCPP_INLINE_VISIBILITY 1181 bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { 1182 return !(__lhs == __rhs); 1183 } 1184 1185 class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error 1186 { 1187 public: 1188 _LIBCPP_INLINE_VISIBILITY 1189 filesystem_error(const string& __what, error_code __ec) 1190 : system_error(__ec, __what), 1191 __paths_(make_shared<_Storage>(path(), path())) 1192 {} 1193 1194 _LIBCPP_INLINE_VISIBILITY 1195 filesystem_error(const string& __what, const path& __p1, error_code __ec) 1196 : system_error(__ec, __what), 1197 __paths_(make_shared<_Storage>(__p1, path())) 1198 {} 1199 1200 _LIBCPP_INLINE_VISIBILITY 1201 filesystem_error(const string& __what, const path& __p1, const path& __p2, 1202 error_code __ec) 1203 : system_error(__ec, __what), 1204 __paths_(make_shared<_Storage>(__p1, __p2)) 1205 {} 1206 1207 _LIBCPP_INLINE_VISIBILITY 1208 const path& path1() const _NOEXCEPT { 1209 return __paths_->first; 1210 } 1211 1212 _LIBCPP_INLINE_VISIBILITY 1213 const path& path2() const _NOEXCEPT { 1214 return __paths_->second; 1215 } 1216 1217 ~filesystem_error() override; // key function 1218 1219 // TODO(ericwf): Create a custom error message. 1220 //const char* what() const _NOEXCEPT; 1221 1222 private: 1223 typedef pair<path, path> _Storage; 1224 shared_ptr<_Storage> __paths_; 1225 }; 1226 1227 template <class... _Args> 1228 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE 1229 #ifndef _LIBCPP_NO_EXCEPTIONS 1230 void __throw_filesystem_error(_Args && ...__args) 1231 { 1232 throw filesystem_error(std::forward<_Args>(__args)...); 1233 } 1234 #else 1235 void __throw_filesystem_error(_Args&&...) 1236 { 1237 _VSTD::abort(); 1238 } 1239 #endif 1240 1241 1242 // operational functions 1243 1244 _LIBCPP_FUNC_VIS 1245 path __canonical(const path&, const path&, error_code *__ec=nullptr); 1246 _LIBCPP_FUNC_VIS 1247 void __copy(const path& __from, const path& __to, copy_options __opt, 1248 error_code *__ec=nullptr); 1249 _LIBCPP_FUNC_VIS 1250 bool __copy_file(const path& __from, const path& __to, copy_options __opt, 1251 error_code *__ec=nullptr); 1252 _LIBCPP_FUNC_VIS 1253 void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, 1254 error_code *__ec=nullptr); 1255 _LIBCPP_FUNC_VIS 1256 bool __create_directories(const path& p, error_code *ec=nullptr); 1257 _LIBCPP_FUNC_VIS 1258 bool __create_directory(const path& p, error_code *ec=nullptr); 1259 _LIBCPP_FUNC_VIS 1260 bool __create_directory(const path& p, const path & attributes, 1261 error_code *ec=nullptr); 1262 _LIBCPP_FUNC_VIS 1263 void __create_directory_symlink(const path& __to, const path& __new_symlink, 1264 error_code *__ec=nullptr); 1265 _LIBCPP_FUNC_VIS 1266 void __create_hard_link(const path& __to, const path& __new_hard_link, 1267 error_code *__ec=nullptr); 1268 _LIBCPP_FUNC_VIS 1269 void __create_symlink(const path& __to, const path& __new_symlink, 1270 error_code *__ec=nullptr); 1271 _LIBCPP_FUNC_VIS 1272 path __current_path(error_code *__ec=nullptr); 1273 _LIBCPP_FUNC_VIS 1274 void __current_path(const path&, error_code *__ec=nullptr); 1275 _LIBCPP_FUNC_VIS 1276 bool __equivalent(const path&, const path&, error_code *__ec=nullptr); 1277 _LIBCPP_FUNC_VIS 1278 uintmax_t __file_size(const path&, error_code *__ec=nullptr); 1279 _LIBCPP_FUNC_VIS 1280 uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr); 1281 _LIBCPP_FUNC_VIS 1282 bool __fs_is_empty(const path& p, error_code *ec=nullptr); 1283 _LIBCPP_FUNC_VIS 1284 file_time_type __last_write_time(const path& p, error_code *ec=nullptr); 1285 _LIBCPP_FUNC_VIS 1286 void __last_write_time(const path& p, file_time_type new_time, 1287 error_code *ec=nullptr); 1288 _LIBCPP_FUNC_VIS 1289 void __permissions(const path& p, perms prms, error_code *ec=nullptr); 1290 _LIBCPP_FUNC_VIS 1291 path __read_symlink(const path& p, error_code *ec=nullptr); 1292 _LIBCPP_FUNC_VIS 1293 bool __remove(const path& p, error_code *ec=nullptr); 1294 _LIBCPP_FUNC_VIS 1295 uintmax_t __remove_all(const path& p, error_code *ec=nullptr); 1296 _LIBCPP_FUNC_VIS 1297 void __rename(const path& from, const path& to, error_code *ec=nullptr); 1298 _LIBCPP_FUNC_VIS 1299 void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr); 1300 _LIBCPP_FUNC_VIS 1301 space_info __space(const path&, error_code *__ec=nullptr); 1302 _LIBCPP_FUNC_VIS 1303 file_status __status(const path&, error_code *__ec=nullptr); 1304 _LIBCPP_FUNC_VIS 1305 file_status __symlink_status(const path&, error_code *__ec=nullptr); 1306 _LIBCPP_FUNC_VIS 1307 path __system_complete(const path&, error_code *__ec=nullptr); 1308 _LIBCPP_FUNC_VIS 1309 path __temp_directory_path(error_code *__ec=nullptr); 1310 1311 inline _LIBCPP_INLINE_VISIBILITY 1312 path current_path() { 1313 return __current_path(); 1314 } 1315 1316 inline _LIBCPP_INLINE_VISIBILITY 1317 path current_path(error_code& __ec) { 1318 return __current_path(&__ec); 1319 } 1320 1321 inline _LIBCPP_INLINE_VISIBILITY 1322 void current_path(const path& __p) { 1323 __current_path(__p); 1324 } 1325 1326 inline _LIBCPP_INLINE_VISIBILITY 1327 void current_path(const path& __p, error_code& __ec) _NOEXCEPT { 1328 __current_path(__p, &__ec); 1329 } 1330 1331 _LIBCPP_FUNC_VIS 1332 path absolute(const path&, const path& __p2 = current_path()); 1333 1334 inline _LIBCPP_INLINE_VISIBILITY 1335 path canonical(const path& __p, const path& __base = current_path()) { 1336 return __canonical(__p, __base); 1337 } 1338 1339 inline _LIBCPP_INLINE_VISIBILITY 1340 path canonical(const path& __p, error_code& __ec) { 1341 path __base = __current_path(&__ec); 1342 if (__ec) return {}; 1343 return __canonical(__p, __base, &__ec); 1344 } 1345 1346 inline _LIBCPP_INLINE_VISIBILITY 1347 path canonical(const path& __p, const path& __base, error_code& __ec) { 1348 return __canonical(__p, __base, &__ec); 1349 } 1350 1351 inline _LIBCPP_INLINE_VISIBILITY 1352 void copy(const path& __from, const path& __to) { 1353 __copy(__from, __to, copy_options::none); 1354 } 1355 1356 inline _LIBCPP_INLINE_VISIBILITY 1357 void copy(const path& __from, const path& __to, error_code& __ec) { 1358 __copy(__from, __to, copy_options::none, &__ec); 1359 } 1360 1361 inline _LIBCPP_INLINE_VISIBILITY 1362 void copy(const path& __from, const path& __to, copy_options __opt) { 1363 __copy(__from, __to, __opt); 1364 } 1365 1366 inline _LIBCPP_INLINE_VISIBILITY 1367 void copy(const path& __from, const path& __to, 1368 copy_options __opt, error_code& __ec) { 1369 __copy(__from, __to, __opt, &__ec); 1370 } 1371 1372 inline _LIBCPP_INLINE_VISIBILITY 1373 bool copy_file(const path& __from, const path& __to) { 1374 return __copy_file(__from, __to, copy_options::none); 1375 } 1376 1377 inline _LIBCPP_INLINE_VISIBILITY 1378 bool copy_file(const path& __from, const path& __to, error_code& __ec) { 1379 return __copy_file(__from, __to, copy_options::none, &__ec); 1380 } 1381 1382 inline _LIBCPP_INLINE_VISIBILITY 1383 bool copy_file(const path& __from, const path& __to, copy_options __opt) { 1384 return __copy_file(__from, __to, __opt); 1385 } 1386 1387 inline _LIBCPP_INLINE_VISIBILITY 1388 bool copy_file(const path& __from, const path& __to, 1389 copy_options __opt, error_code& __ec){ 1390 return __copy_file(__from, __to, __opt, &__ec); 1391 } 1392 1393 inline _LIBCPP_INLINE_VISIBILITY 1394 void copy_symlink(const path& __existing, const path& __new) { 1395 __copy_symlink(__existing, __new); 1396 } 1397 1398 inline _LIBCPP_INLINE_VISIBILITY 1399 void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT { 1400 __copy_symlink(__ext, __new, &__ec); 1401 } 1402 1403 inline _LIBCPP_INLINE_VISIBILITY 1404 bool create_directories(const path& __p) { 1405 return __create_directories(__p); 1406 } 1407 1408 inline _LIBCPP_INLINE_VISIBILITY 1409 bool create_directories(const path& __p, error_code& __ec) { 1410 return __create_directories(__p, &__ec); 1411 } 1412 1413 inline _LIBCPP_INLINE_VISIBILITY 1414 bool create_directory(const path& __p) { 1415 return __create_directory(__p); 1416 } 1417 1418 inline _LIBCPP_INLINE_VISIBILITY 1419 bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT { 1420 return __create_directory(__p, &__ec); 1421 } 1422 1423 inline _LIBCPP_INLINE_VISIBILITY 1424 bool create_directory(const path& __p, const path& __attrs) { 1425 return __create_directory(__p, __attrs); 1426 } 1427 1428 inline _LIBCPP_INLINE_VISIBILITY 1429 bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT { 1430 return __create_directory(__p, __attrs, &__ec); 1431 } 1432 1433 inline _LIBCPP_INLINE_VISIBILITY 1434 void create_directory_symlink(const path& __to, const path& __new) { 1435 __create_directory_symlink(__to, __new); 1436 } 1437 1438 inline _LIBCPP_INLINE_VISIBILITY 1439 void create_directory_symlink(const path& __to, const path& __new, 1440 error_code& __ec) _NOEXCEPT { 1441 __create_directory_symlink(__to, __new, &__ec); 1442 } 1443 1444 inline _LIBCPP_INLINE_VISIBILITY 1445 void create_hard_link(const path& __to, const path& __new) { 1446 __create_hard_link(__to, __new); 1447 } 1448 1449 inline _LIBCPP_INLINE_VISIBILITY 1450 void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { 1451 __create_hard_link(__to, __new, &__ec); 1452 } 1453 1454 inline _LIBCPP_INLINE_VISIBILITY 1455 void create_symlink(const path& __to, const path& __new) { 1456 __create_symlink(__to, __new); 1457 } 1458 1459 inline _LIBCPP_INLINE_VISIBILITY 1460 void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { 1461 return __create_symlink(__to, __new, &__ec); 1462 } 1463 1464 inline _LIBCPP_INLINE_VISIBILITY 1465 bool status_known(file_status __s) _NOEXCEPT { 1466 return __s.type() != file_type::none; 1467 } 1468 1469 inline _LIBCPP_INLINE_VISIBILITY 1470 bool exists(file_status __s) _NOEXCEPT { 1471 return status_known(__s) && __s.type() != file_type::not_found; 1472 } 1473 1474 inline _LIBCPP_INLINE_VISIBILITY 1475 bool exists(const path& __p) { 1476 return exists(__status(__p)); 1477 } 1478 1479 inline _LIBCPP_INLINE_VISIBILITY 1480 bool exists(const path& __p, error_code& __ec) _NOEXCEPT { 1481 auto __s = __status(__p, &__ec); 1482 if (status_known(__s)) __ec.clear(); 1483 return exists(__s); 1484 } 1485 1486 inline _LIBCPP_INLINE_VISIBILITY 1487 bool equivalent(const path& __p1, const path& __p2) { 1488 return __equivalent(__p1, __p2); 1489 } 1490 1491 inline _LIBCPP_INLINE_VISIBILITY 1492 bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT { 1493 return __equivalent(__p1, __p2, &__ec); 1494 } 1495 1496 inline _LIBCPP_INLINE_VISIBILITY 1497 uintmax_t file_size(const path& __p) { 1498 return __file_size(__p); 1499 } 1500 1501 inline _LIBCPP_INLINE_VISIBILITY 1502 uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT { 1503 return __file_size(__p, &__ec); 1504 } 1505 1506 inline _LIBCPP_INLINE_VISIBILITY 1507 uintmax_t hard_link_count(const path& __p) { 1508 return __hard_link_count(__p); 1509 } 1510 1511 inline _LIBCPP_INLINE_VISIBILITY 1512 uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT { 1513 return __hard_link_count(__p, &__ec); 1514 } 1515 1516 inline _LIBCPP_INLINE_VISIBILITY 1517 bool is_block_file(file_status __s) _NOEXCEPT { 1518 return __s.type() == file_type::block; 1519 } 1520 1521 inline _LIBCPP_INLINE_VISIBILITY 1522 bool is_block_file(const path& __p) { 1523 return is_block_file(__status(__p)); 1524 } 1525 1526 inline _LIBCPP_INLINE_VISIBILITY 1527 bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT { 1528 return is_block_file(__status(__p, &__ec)); 1529 } 1530 1531 inline _LIBCPP_INLINE_VISIBILITY 1532 bool is_character_file(file_status __s) _NOEXCEPT { 1533 return __s.type() == file_type::character; 1534 } 1535 1536 inline _LIBCPP_INLINE_VISIBILITY 1537 bool is_character_file(const path& __p) { 1538 return is_character_file(__status(__p)); 1539 } 1540 1541 inline _LIBCPP_INLINE_VISIBILITY 1542 bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT { 1543 return is_character_file(__status(__p, &__ec)); 1544 } 1545 1546 inline _LIBCPP_INLINE_VISIBILITY 1547 bool is_directory(file_status __s) _NOEXCEPT { 1548 return __s.type() == file_type::directory; 1549 } 1550 1551 inline _LIBCPP_INLINE_VISIBILITY 1552 bool is_directory(const path& __p) { 1553 return is_directory(__status(__p)); 1554 } 1555 1556 inline _LIBCPP_INLINE_VISIBILITY 1557 bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT { 1558 return is_directory(__status(__p, &__ec)); 1559 } 1560 1561 inline _LIBCPP_INLINE_VISIBILITY 1562 bool is_empty(const path& __p) { 1563 return __fs_is_empty(__p); 1564 } 1565 1566 inline _LIBCPP_INLINE_VISIBILITY 1567 bool is_empty(const path& __p, error_code& __ec) { 1568 return __fs_is_empty(__p, &__ec); 1569 } 1570 1571 inline _LIBCPP_INLINE_VISIBILITY 1572 bool is_fifo(file_status __s) _NOEXCEPT { 1573 return __s.type() == file_type::fifo; 1574 } 1575 inline _LIBCPP_INLINE_VISIBILITY 1576 bool is_fifo(const path& __p) { 1577 return is_fifo(__status(__p)); 1578 } 1579 1580 inline _LIBCPP_INLINE_VISIBILITY 1581 bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT { 1582 return is_fifo(__status(__p, &__ec)); 1583 } 1584 1585 inline _LIBCPP_INLINE_VISIBILITY 1586 bool is_regular_file(file_status __s) _NOEXCEPT { 1587 return __s.type() == file_type::regular; 1588 } 1589 1590 inline _LIBCPP_INLINE_VISIBILITY 1591 bool is_regular_file(const path& __p) { 1592 return is_regular_file(__status(__p)); 1593 } 1594 1595 inline _LIBCPP_INLINE_VISIBILITY 1596 bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT { 1597 return is_regular_file(__status(__p, &__ec)); 1598 } 1599 1600 inline _LIBCPP_INLINE_VISIBILITY 1601 bool is_socket(file_status __s) _NOEXCEPT { 1602 return __s.type() == file_type::socket; 1603 } 1604 1605 inline _LIBCPP_INLINE_VISIBILITY 1606 bool is_socket(const path& __p) { 1607 return is_socket(__status(__p)); 1608 } 1609 1610 inline _LIBCPP_INLINE_VISIBILITY 1611 bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT { 1612 return is_socket(__status(__p, &__ec)); 1613 } 1614 1615 inline _LIBCPP_INLINE_VISIBILITY 1616 bool is_symlink(file_status __s) _NOEXCEPT { 1617 return __s.type() == file_type::symlink; 1618 } 1619 1620 inline _LIBCPP_INLINE_VISIBILITY 1621 bool is_symlink(const path& __p) { 1622 return is_symlink(__symlink_status(__p)); 1623 } 1624 1625 inline _LIBCPP_INLINE_VISIBILITY 1626 bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT { 1627 return is_symlink(__symlink_status(__p, &__ec)); 1628 } 1629 1630 inline _LIBCPP_INLINE_VISIBILITY 1631 bool is_other(file_status __s) _NOEXCEPT { 1632 return exists(__s) 1633 && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); 1634 } 1635 1636 inline _LIBCPP_INLINE_VISIBILITY 1637 bool is_other(const path& __p) { 1638 return is_other(__status(__p)); 1639 } 1640 1641 inline _LIBCPP_INLINE_VISIBILITY 1642 bool is_other(const path& __p, error_code& __ec) _NOEXCEPT { 1643 return is_other(__status(__p, &__ec)); 1644 } 1645 1646 inline _LIBCPP_INLINE_VISIBILITY 1647 file_time_type last_write_time(const path& __p) { 1648 return __last_write_time(__p); 1649 } 1650 1651 inline _LIBCPP_INLINE_VISIBILITY 1652 file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT { 1653 return __last_write_time(__p, &__ec); 1654 } 1655 1656 inline _LIBCPP_INLINE_VISIBILITY 1657 void last_write_time(const path& __p, file_time_type __t) { 1658 __last_write_time(__p, __t); 1659 } 1660 1661 inline _LIBCPP_INLINE_VISIBILITY 1662 void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT { 1663 __last_write_time(__p, __t, &__ec); 1664 } 1665 1666 inline _LIBCPP_INLINE_VISIBILITY 1667 void permissions(const path& __p, perms __prms) { 1668 __permissions(__p, __prms); 1669 } 1670 1671 inline _LIBCPP_INLINE_VISIBILITY 1672 void permissions(const path& __p, perms __prms, error_code& __ec) { 1673 __permissions(__p, __prms, &__ec); 1674 } 1675 1676 inline _LIBCPP_INLINE_VISIBILITY 1677 path read_symlink(const path& __p) { 1678 return __read_symlink(__p); 1679 } 1680 1681 inline _LIBCPP_INLINE_VISIBILITY 1682 path read_symlink(const path& __p, error_code& __ec) { 1683 return __read_symlink(__p, &__ec); 1684 } 1685 1686 inline _LIBCPP_INLINE_VISIBILITY 1687 bool remove(const path& __p) { 1688 return __remove(__p); 1689 } 1690 1691 inline _LIBCPP_INLINE_VISIBILITY 1692 bool remove(const path& __p, error_code& __ec) _NOEXCEPT { 1693 return __remove(__p, &__ec); 1694 } 1695 1696 inline _LIBCPP_INLINE_VISIBILITY 1697 uintmax_t remove_all(const path& __p) { 1698 return __remove_all(__p); 1699 } 1700 1701 inline _LIBCPP_INLINE_VISIBILITY 1702 uintmax_t remove_all(const path& __p, error_code& __ec) { 1703 return __remove_all(__p, &__ec); 1704 } 1705 1706 inline _LIBCPP_INLINE_VISIBILITY 1707 void rename(const path& __from, const path& __to) { 1708 return __rename(__from, __to); 1709 } 1710 1711 inline _LIBCPP_INLINE_VISIBILITY 1712 void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { 1713 return __rename(__from, __to, &__ec); 1714 } 1715 1716 inline _LIBCPP_INLINE_VISIBILITY 1717 void resize_file(const path& __p, uintmax_t __ns) { 1718 return __resize_file(__p, __ns); 1719 } 1720 1721 inline _LIBCPP_INLINE_VISIBILITY 1722 void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT { 1723 return __resize_file(__p, __ns, &__ec); 1724 } 1725 1726 inline _LIBCPP_INLINE_VISIBILITY 1727 space_info space(const path& __p) { 1728 return __space(__p); 1729 } 1730 1731 inline _LIBCPP_INLINE_VISIBILITY 1732 space_info space(const path& __p, error_code& __ec) _NOEXCEPT { 1733 return __space(__p, &__ec); 1734 } 1735 1736 inline _LIBCPP_INLINE_VISIBILITY 1737 file_status status(const path& __p) { 1738 return __status(__p); 1739 } 1740 1741 inline _LIBCPP_INLINE_VISIBILITY 1742 file_status status(const path& __p, error_code& __ec) _NOEXCEPT { 1743 return __status(__p, &__ec); 1744 } 1745 1746 inline _LIBCPP_INLINE_VISIBILITY 1747 file_status symlink_status(const path& __p) { 1748 return __symlink_status(__p); 1749 } 1750 1751 inline _LIBCPP_INLINE_VISIBILITY 1752 file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT { 1753 return __symlink_status(__p, &__ec); 1754 } 1755 1756 inline _LIBCPP_INLINE_VISIBILITY 1757 path system_complete(const path& __p) { 1758 return __system_complete(__p); 1759 } 1760 1761 inline _LIBCPP_INLINE_VISIBILITY 1762 path system_complete(const path& __p, error_code& __ec) { 1763 return __system_complete(__p, &__ec); 1764 } 1765 1766 inline _LIBCPP_INLINE_VISIBILITY 1767 path temp_directory_path() { 1768 return __temp_directory_path(); 1769 } 1770 1771 inline _LIBCPP_INLINE_VISIBILITY 1772 path temp_directory_path(error_code& __ec) { 1773 return __temp_directory_path(&__ec); 1774 } 1775 1776 1777 class directory_entry 1778 { 1779 typedef _VSTD_FS::path _Path; 1780 1781 public: 1782 // constructors and destructors 1783 directory_entry() _NOEXCEPT = default; 1784 directory_entry(directory_entry const&) = default; 1785 directory_entry(directory_entry&&) _NOEXCEPT = default; 1786 1787 _LIBCPP_INLINE_VISIBILITY 1788 explicit directory_entry(_Path const& __p) : __p_(__p) {} 1789 1790 ~directory_entry() {} 1791 1792 directory_entry& operator=(directory_entry const&) = default; 1793 directory_entry& operator=(directory_entry&&) _NOEXCEPT = default; 1794 1795 _LIBCPP_INLINE_VISIBILITY 1796 void assign(_Path const& __p) { 1797 __p_ = __p; 1798 } 1799 1800 _LIBCPP_INLINE_VISIBILITY 1801 void replace_filename(_Path const& __p) { 1802 __p_ = __p_.parent_path() / __p; 1803 } 1804 1805 _LIBCPP_INLINE_VISIBILITY 1806 _Path const& path() const _NOEXCEPT { 1807 return __p_; 1808 } 1809 1810 _LIBCPP_INLINE_VISIBILITY 1811 operator const _Path&() const _NOEXCEPT { 1812 return __p_; 1813 } 1814 1815 _LIBCPP_INLINE_VISIBILITY 1816 file_status status() const { 1817 return _VSTD_FS::status(__p_); 1818 } 1819 1820 _LIBCPP_INLINE_VISIBILITY 1821 file_status status(error_code& __ec) const _NOEXCEPT { 1822 return _VSTD_FS::status(__p_, __ec); 1823 } 1824 1825 _LIBCPP_INLINE_VISIBILITY 1826 file_status symlink_status() const { 1827 return _VSTD_FS::symlink_status(__p_); 1828 } 1829 1830 _LIBCPP_INLINE_VISIBILITY 1831 file_status symlink_status(error_code& __ec) const _NOEXCEPT { 1832 return _VSTD_FS::symlink_status(__p_, __ec); 1833 } 1834 1835 _LIBCPP_INLINE_VISIBILITY 1836 bool operator< (directory_entry const& __rhs) const _NOEXCEPT { 1837 return __p_ < __rhs.__p_; 1838 } 1839 1840 _LIBCPP_INLINE_VISIBILITY 1841 bool operator==(directory_entry const& __rhs) const _NOEXCEPT { 1842 return __p_ == __rhs.__p_; 1843 } 1844 1845 _LIBCPP_INLINE_VISIBILITY 1846 bool operator!=(directory_entry const& __rhs) const _NOEXCEPT { 1847 return __p_ != __rhs.__p_; 1848 } 1849 1850 _LIBCPP_INLINE_VISIBILITY 1851 bool operator<=(directory_entry const& __rhs) const _NOEXCEPT { 1852 return __p_ <= __rhs.__p_; 1853 } 1854 1855 _LIBCPP_INLINE_VISIBILITY 1856 bool operator> (directory_entry const& __rhs) const _NOEXCEPT { 1857 return __p_ > __rhs.__p_; 1858 } 1859 1860 _LIBCPP_INLINE_VISIBILITY 1861 bool operator>=(directory_entry const& __rhs) const _NOEXCEPT { 1862 return __p_ >= __rhs.__p_; 1863 } 1864 private: 1865 _Path __p_; 1866 }; 1867 1868 1869 class directory_iterator; 1870 class recursive_directory_iterator; 1871 class __dir_stream; 1872 1873 class __dir_element_proxy { 1874 public: 1875 1876 inline _LIBCPP_INLINE_VISIBILITY 1877 directory_entry operator*() { return _VSTD::move(__elem_); } 1878 1879 private: 1880 friend class directory_iterator; 1881 friend class recursive_directory_iterator; 1882 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} 1883 __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {} 1884 directory_entry __elem_; 1885 }; 1886 1887 class directory_iterator 1888 { 1889 public: 1890 typedef directory_entry value_type; 1891 typedef ptrdiff_t difference_type; 1892 typedef value_type const* pointer; 1893 typedef value_type const& reference; 1894 typedef input_iterator_tag iterator_category; 1895 1896 public: 1897 //ctor & dtor 1898 directory_iterator() _NOEXCEPT 1899 { } 1900 1901 explicit directory_iterator(const path& __p) 1902 : directory_iterator(__p, nullptr) 1903 { } 1904 1905 directory_iterator(const path& __p, directory_options __opts) 1906 : directory_iterator(__p, nullptr, __opts) 1907 { } 1908 1909 directory_iterator(const path& __p, error_code& __ec) 1910 : directory_iterator(__p, &__ec) 1911 { } 1912 1913 directory_iterator(const path& __p, directory_options __opts, 1914 error_code& __ec) 1915 : directory_iterator(__p, &__ec, __opts) 1916 { } 1917 1918 directory_iterator(const directory_iterator&) = default; 1919 directory_iterator(directory_iterator&&) = default; 1920 directory_iterator& operator=(const directory_iterator&) = default; 1921 1922 directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT { 1923 // non-default implementation provided to support self-move assign. 1924 if (this != &__o) { 1925 __imp_ = _VSTD::move(__o.__imp_); 1926 } 1927 return *this; 1928 } 1929 1930 ~directory_iterator() = default; 1931 1932 const directory_entry& operator*() const { 1933 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); 1934 return __dereference(); 1935 } 1936 1937 const directory_entry* operator->() const 1938 { return &**this; } 1939 1940 directory_iterator& operator++() 1941 { return __increment(); } 1942 1943 __dir_element_proxy operator++(int) { 1944 __dir_element_proxy __p(**this); 1945 __increment(); 1946 return __p; 1947 } 1948 1949 directory_iterator& increment(error_code& __ec) 1950 { return __increment(&__ec); } 1951 1952 private: 1953 inline _LIBCPP_INLINE_VISIBILITY 1954 friend bool operator==(const directory_iterator& __lhs, 1955 const directory_iterator& __rhs) _NOEXCEPT; 1956 1957 // construct the dir_stream 1958 _LIBCPP_FUNC_VIS 1959 directory_iterator(const path&, error_code *, 1960 directory_options = directory_options::none); 1961 1962 _LIBCPP_FUNC_VIS 1963 directory_iterator& __increment(error_code * __ec = nullptr); 1964 1965 _LIBCPP_FUNC_VIS 1966 const directory_entry& __dereference() const; 1967 1968 private: 1969 shared_ptr<__dir_stream> __imp_; 1970 }; 1971 1972 1973 inline _LIBCPP_INLINE_VISIBILITY 1974 bool operator==(const directory_iterator& __lhs, 1975 const directory_iterator& __rhs) _NOEXCEPT { 1976 return __lhs.__imp_ == __rhs.__imp_; 1977 } 1978 1979 inline _LIBCPP_INLINE_VISIBILITY 1980 bool operator!=(const directory_iterator& __lhs, 1981 const directory_iterator& __rhs) _NOEXCEPT { 1982 return !(__lhs == __rhs); 1983 } 1984 1985 // enable directory_iterator range-based for statements 1986 inline _LIBCPP_INLINE_VISIBILITY 1987 directory_iterator begin(directory_iterator __iter) _NOEXCEPT { 1988 return __iter; 1989 } 1990 1991 inline _LIBCPP_INLINE_VISIBILITY 1992 directory_iterator end(const directory_iterator&) _NOEXCEPT { 1993 return directory_iterator(); 1994 } 1995 1996 class recursive_directory_iterator { 1997 public: 1998 using value_type = directory_entry; 1999 using difference_type = std::ptrdiff_t; 2000 using pointer = directory_entry const *; 2001 using reference = directory_entry const &; 2002 using iterator_category = std::input_iterator_tag; 2003 2004 public: 2005 // constructors and destructor 2006 _LIBCPP_INLINE_VISIBILITY 2007 recursive_directory_iterator() _NOEXCEPT 2008 : __rec_(false) 2009 {} 2010 2011 _LIBCPP_INLINE_VISIBILITY 2012 explicit recursive_directory_iterator(const path& __p, 2013 directory_options __xoptions = directory_options::none) 2014 : recursive_directory_iterator(__p, __xoptions, nullptr) 2015 { } 2016 2017 _LIBCPP_INLINE_VISIBILITY 2018 recursive_directory_iterator(const path& __p, 2019 directory_options __xoptions, error_code& __ec) 2020 : recursive_directory_iterator(__p, __xoptions, &__ec) 2021 { } 2022 2023 _LIBCPP_INLINE_VISIBILITY 2024 recursive_directory_iterator(const path& __p, error_code& __ec) 2025 : recursive_directory_iterator(__p, directory_options::none, &__ec) 2026 { } 2027 2028 recursive_directory_iterator(const recursive_directory_iterator&) = default; 2029 recursive_directory_iterator(recursive_directory_iterator&&) = default; 2030 2031 recursive_directory_iterator & 2032 operator=(const recursive_directory_iterator&) = default; 2033 2034 _LIBCPP_INLINE_VISIBILITY 2035 recursive_directory_iterator & 2036 operator=(recursive_directory_iterator&& __o) noexcept { 2037 // non-default implementation provided to support self-move assign. 2038 if (this != &__o) { 2039 __imp_ = _VSTD::move(__o.__imp_); 2040 __rec_ = __o.__rec_; 2041 } 2042 return *this; 2043 } 2044 2045 ~recursive_directory_iterator() = default; 2046 2047 _LIBCPP_INLINE_VISIBILITY 2048 const directory_entry& operator*() const 2049 { return __dereference(); } 2050 2051 _LIBCPP_INLINE_VISIBILITY 2052 const directory_entry* operator->() const 2053 { return &__dereference(); } 2054 2055 recursive_directory_iterator& operator++() 2056 { return __increment(); } 2057 2058 _LIBCPP_INLINE_VISIBILITY 2059 __dir_element_proxy operator++(int) { 2060 __dir_element_proxy __p(**this); 2061 __increment(); 2062 return __p; 2063 } 2064 2065 _LIBCPP_INLINE_VISIBILITY 2066 recursive_directory_iterator& increment(error_code& __ec) 2067 { return __increment(&__ec); } 2068 2069 _LIBCPP_FUNC_VIS directory_options options() const; 2070 _LIBCPP_FUNC_VIS int depth() const; 2071 2072 _LIBCPP_INLINE_VISIBILITY 2073 void pop() { __pop(); } 2074 2075 _LIBCPP_INLINE_VISIBILITY 2076 void pop(error_code& __ec) 2077 { __pop(&__ec); } 2078 2079 _LIBCPP_INLINE_VISIBILITY 2080 bool recursion_pending() const 2081 { return __rec_; } 2082 2083 _LIBCPP_INLINE_VISIBILITY 2084 void disable_recursion_pending() 2085 { __rec_ = false; } 2086 2087 private: 2088 recursive_directory_iterator(const path& __p, directory_options __opt, 2089 error_code *__ec); 2090 2091 _LIBCPP_FUNC_VIS 2092 const directory_entry& __dereference() const; 2093 2094 _LIBCPP_FUNC_VIS 2095 bool __try_recursion(error_code* __ec); 2096 2097 _LIBCPP_FUNC_VIS 2098 void __advance(error_code* __ec=nullptr); 2099 2100 _LIBCPP_FUNC_VIS 2101 recursive_directory_iterator& __increment(error_code *__ec=nullptr); 2102 2103 _LIBCPP_FUNC_VIS 2104 void __pop(error_code* __ec=nullptr); 2105 2106 inline _LIBCPP_INLINE_VISIBILITY 2107 friend bool operator==(const recursive_directory_iterator&, 2108 const recursive_directory_iterator&) _NOEXCEPT; 2109 2110 struct __shared_imp; 2111 shared_ptr<__shared_imp> __imp_; 2112 bool __rec_; 2113 }; // class recursive_directory_iterator 2114 2115 2116 inline _LIBCPP_INLINE_VISIBILITY 2117 bool operator==(const recursive_directory_iterator& __lhs, 2118 const recursive_directory_iterator& __rhs) _NOEXCEPT 2119 { 2120 return __lhs.__imp_ == __rhs.__imp_; 2121 } 2122 2123 _LIBCPP_INLINE_VISIBILITY 2124 inline bool operator!=(const recursive_directory_iterator& __lhs, 2125 const recursive_directory_iterator& __rhs) _NOEXCEPT 2126 { 2127 return !(__lhs == __rhs); 2128 } 2129 // enable recursive_directory_iterator range-based for statements 2130 inline _LIBCPP_INLINE_VISIBILITY 2131 recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT { 2132 return __iter; 2133 } 2134 2135 inline _LIBCPP_INLINE_VISIBILITY 2136 recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT { 2137 return recursive_directory_iterator(); 2138 } 2139 2140 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM 2141 2142 #endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM 2143