1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 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 10#ifndef _LIBCPP_FILESYSTEM 11#define _LIBCPP_FILESYSTEM 12 13/* 14 filesystem synopsis 15 16 namespace std::filesystem { 17 18 // `class path` from http://eel.is/c++draft/fs.class.path.general#6 19 class path { 20 public: 21 using value_type = see below; 22 using string_type = basic_string<value_type>; 23 static constexpr value_type preferred_separator = see below; 24 25 enum format; 26 27 path() noexcept; 28 path(const path& p); 29 path(path&& p) noexcept; 30 path(string_type&& source, format fmt = auto_format); 31 template<class Source> 32 path(const Source& source, format fmt = auto_format); 33 template<class InputIterator> 34 path(InputIterator first, InputIterator last, format fmt = auto_format); 35 template<class Source> 36 path(const Source& source, const locale& loc, format fmt = auto_format); 37 template<class InputIterator> 38 path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); 39 ~path(); 40 41 path& operator=(const path& p); 42 path& operator=(path&& p) noexcept; 43 path& operator=(string_type&& source); 44 path& assign(string_type&& source); 45 template<class Source> 46 path& operator=(const Source& source); 47 template<class Source> 48 path& assign(const Source& source); 49 template<class InputIterator> 50 path& assign(InputIterator first, InputIterator last); 51 52 path& operator/=(const path& p); 53 template<class Source> 54 path& operator/=(const Source& source); 55 template<class Source> 56 path& append(const Source& source); 57 template<class InputIterator> 58 path& append(InputIterator first, InputIterator last); 59 60 path& operator+=(const path& x); 61 path& operator+=(const string_type& x); 62 path& operator+=(basic_string_view<value_type> x); 63 path& operator+=(const value_type* x); 64 path& operator+=(value_type x); 65 template<class Source> 66 path& operator+=(const Source& x); 67 template<class EcharT> 68 path& operator+=(EcharT x); 69 template<class Source> 70 path& concat(const Source& x); 71 template<class InputIterator> 72 path& concat(InputIterator first, InputIterator last); 73 74 void clear() noexcept; 75 path& make_preferred(); 76 path& remove_filename(); 77 path& replace_filename(const path& replacement); 78 path& replace_extension(const path& replacement = path()); 79 void swap(path& rhs) noexcept; 80 81 friend bool operator==(const path& lhs, const path& rhs) noexcept; 82 friend bool operator!=(const path& lhs, const path& rhs) noexcept; // removed in C++20 83 friend bool operator< (const path& lhs, const path& rhs) noexcept; // removed in C++20 84 friend bool operator<=(const path& lhs, const path& rhs) noexcept; // removed in C++20 85 friend bool operator> (const path& lhs, const path& rhs) noexcept; // removed in C++20 86 friend bool operator>=(const path& lhs, const path& rhs) noexcept; // removed in C++20 87 friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; // C++20 88 89 friend path operator/(const path& lhs, const path& rhs); 90 91 const string_type& native() const noexcept; 92 const value_type* c_str() const noexcept; 93 operator string_type() const; 94 95 template<class EcharT, class traits = char_traits<EcharT>, 96 class Allocator = allocator<EcharT>> 97 basic_string<EcharT, traits, Allocator> 98 string(const Allocator& a = Allocator()) const; 99 std::string string() const; 100 std::wstring wstring() const; 101 std::u8string u8string() const; 102 std::u16string u16string() const; 103 std::u32string u32string() const; 104 105 template<class EcharT, class traits = char_traits<EcharT>, 106 class Allocator = allocator<EcharT>> 107 basic_string<EcharT, traits, Allocator> 108 generic_string(const Allocator& a = Allocator()) const; 109 std::string generic_string() const; 110 std::wstring generic_wstring() const; 111 std::u8string generic_u8string() const; 112 std::u16string generic_u16string() const; 113 std::u32string generic_u32string() const; 114 115 int compare(const path& p) const noexcept; 116 int compare(const string_type& s) const; 117 int compare(basic_string_view<value_type> s) const; 118 int compare(const value_type* s) const; 119 120 path root_name() const; 121 path root_directory() const; 122 path root_path() const; 123 path relative_path() const; 124 path parent_path() const; 125 path filename() const; 126 path stem() const; 127 path extension() const; 128 129 [[nodiscard]] bool empty() const noexcept; 130 bool has_root_name() const; 131 bool has_root_directory() const; 132 bool has_root_path() const; 133 bool has_relative_path() const; 134 bool has_parent_path() const; 135 bool has_filename() const; 136 bool has_stem() const; 137 bool has_extension() const; 138 bool is_absolute() const; 139 bool is_relative() const; 140 141 path lexically_normal() const; 142 path lexically_relative(const path& base) const; 143 path lexically_proximate(const path& base) const; 144 145 class iterator; 146 using const_iterator = iterator; 147 148 iterator begin() const; 149 iterator end() const; 150 151 template<class charT, class traits> 152 friend basic_ostream<charT, traits>& 153 operator<<(basic_ostream<charT, traits>& os, const path& p); 154 template<class charT, class traits> 155 friend basic_istream<charT, traits>& 156 operator>>(basic_istream<charT, traits>& is, path& p); 157 }; 158 159 void swap(path& lhs, path& rhs) noexcept; 160 size_t hash_value(const path& p) noexcept; 161 162 // [fs.path.hash], hash support 163 template<> struct hash<filesystem::path>; 164 165 template <class Source> 166 path u8path(const Source& source); 167 template <class InputIterator> 168 path u8path(InputIterator first, InputIterator last); 169 170 class filesystem_error; 171 172 class directory_entry { 173 public: 174 directory_entry() noexcept = default; 175 directory_entry(const directory_entry&) = default; 176 directory_entry(directory_entry&&) noexcept = default; 177 explicit directory_entry(const filesystem::path& p); 178 directory_entry(const filesystem::path& p, error_code& ec); 179 ~directory_entry(); 180 181 directory_entry& operator=(const directory_entry&) = default; 182 directory_entry& operator=(directory_entry&&) noexcept = default; 183 184 void assign(const filesystem::path& p); 185 void assign(const filesystem::path& p, error_code& ec); 186 void replace_filename(const filesystem::path& p); 187 void replace_filename(const filesystem::path& p, error_code& ec); 188 void refresh(); 189 void refresh(error_code& ec) noexcept; 190 191 const filesystem::path& path() const noexcept; 192 operator const filesystem::path&() const noexcept; 193 bool exists() const; 194 bool exists(error_code& ec) const noexcept; 195 bool is_block_file() const; 196 bool is_block_file(error_code& ec) const noexcept; 197 bool is_character_file() const; 198 bool is_character_file(error_code& ec) const noexcept; 199 bool is_directory() const; 200 bool is_directory(error_code& ec) const noexcept; 201 bool is_fifo() const; 202 bool is_fifo(error_code& ec) const noexcept; 203 bool is_other() const; 204 bool is_other(error_code& ec) const noexcept; 205 bool is_regular_file() const; 206 bool is_regular_file(error_code& ec) const noexcept; 207 bool is_socket() const; 208 bool is_socket(error_code& ec) const noexcept; 209 bool is_symlink() const; 210 bool is_symlink(error_code& ec) const noexcept; 211 uintmax_t file_size() const; 212 uintmax_t file_size(error_code& ec) const noexcept; 213 uintmax_t hard_link_count() const; 214 uintmax_t hard_link_count(error_code& ec) const noexcept; 215 file_time_type last_write_time() const; 216 file_time_type last_write_time(error_code& ec) const noexcept; 217 file_status status() const; 218 file_status status(error_code& ec) const noexcept; 219 file_status symlink_status() const; 220 file_status symlink_status(error_code& ec) const noexcept; 221 222 bool operator==(const directory_entry& rhs) const noexcept; 223 bool operator!=(const directory_entry& rhs) const noexcept; // removed in C++20 224 bool operator< (const directory_entry& rhs) const noexcept; // removed in C++20 225 bool operator<=(const directory_entry& rhs) const noexcept; // removed in C++20 226 bool operator> (const directory_entry& rhs) const noexcept; // removed in C++20 227 bool operator>=(const directory_entry& rhs) const noexcept; // removed in C++20 228 strong_ordering operator<=>(const directory_entry& rhs) const noexcept; // since C++20 229 230 template<class charT, class traits> 231 friend basic_ostream<charT, traits>& 232 operator<<(basic_ostream<charT, traits>& os, const directory_entry& d); 233 234 private: 235 filesystem::path pathobject; // exposition only 236 friend class directory_iterator; // exposition only 237 }; 238 239 class directory_iterator { 240 public: 241 using iterator_category = input_iterator_tag; 242 using value_type = directory_entry; 243 using difference_type = ptrdiff_t; 244 using pointer = const directory_entry*; 245 using reference = const directory_entry&; 246 247 // [fs.dir.itr.members], member functions 248 directory_iterator() noexcept; 249 explicit directory_iterator(const path& p); 250 directory_iterator(const path& p, directory_options options); 251 directory_iterator(const path& p, error_code& ec); 252 directory_iterator(const path& p, directory_options options, 253 error_code& ec); 254 directory_iterator(const directory_iterator& rhs); 255 directory_iterator(directory_iterator&& rhs) noexcept; 256 ~directory_iterator(); 257 258 directory_iterator& operator=(const directory_iterator& rhs); 259 directory_iterator& operator=(directory_iterator&& rhs) noexcept; 260 261 const directory_entry& operator*() const; 262 const directory_entry* operator->() const; 263 directory_iterator& operator++(); 264 directory_iterator& increment(error_code& ec); 265 266 bool operator==(default_sentinel_t) const noexcept { // since C++20 267 return *this == directory_iterator(); 268 } 269 270 // other members as required by [input.iterators], input iterators 271 }; 272 273 // enable directory_iterator range-based for statements 274 directory_iterator begin(directory_iterator iter) noexcept; 275 directory_iterator end(directory_iterator) noexcept; 276 277class recursive_directory_iterator { 278 public: 279 using iterator_category = input_iterator_tag; 280 using value_type = directory_entry; 281 using difference_type = ptrdiff_t; 282 using pointer = const directory_entry*; 283 using reference = const directory_entry&; 284 285 // [fs.rec.dir.itr.members], constructors and destructor 286 recursive_directory_iterator() noexcept; 287 explicit recursive_directory_iterator(const path& p); 288 recursive_directory_iterator(const path& p, directory_options options); 289 recursive_directory_iterator(const path& p, directory_options options, 290 error_code& ec); 291 recursive_directory_iterator(const path& p, error_code& ec); 292 recursive_directory_iterator(const recursive_directory_iterator& rhs); 293 recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; 294 ~recursive_directory_iterator(); 295 296 // [fs.rec.dir.itr.members], observers 297 directory_options options() const; 298 int depth() const; 299 bool recursion_pending() const; 300 301 const directory_entry& operator*() const; 302 const directory_entry* operator->() const; 303 304 // [fs.rec.dir.itr.members], modifiers 305 recursive_directory_iterator& 306 operator=(const recursive_directory_iterator& rhs); 307 recursive_directory_iterator& 308 operator=(recursive_directory_iterator&& rhs) noexcept; 309 310 recursive_directory_iterator& operator++(); 311 recursive_directory_iterator& increment(error_code& ec); 312 313 void pop(); 314 void pop(error_code& ec); 315 void disable_recursion_pending(); 316 317 bool operator==(default_sentinel_t) const noexcept { // since C++20 318 return *this == recursive_directory_iterator(); 319 } 320 321 // other members as required by [input.iterators], input iterators 322 }; 323 324 // enable recursive_directory_iterator range-based for statements 325 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; 326 recursive_directory_iterator end(recursive_directory_iterator) noexcept; 327 328 class file_status { 329 public: 330 // [fs.file.status.cons], constructors and destructor 331 file_status() noexcept : file_status(file_type::none) {} 332 explicit file_status(file_type ft, 333 perms prms = perms::unknown) noexcept; 334 file_status(const file_status&) noexcept = default; 335 file_status(file_status&&) noexcept = default; 336 ~file_status(); 337 338 // assignments 339 file_status& operator=(const file_status&) noexcept = default; 340 file_status& operator=(file_status&&) noexcept = default; 341 342 // [fs.file.status.mods], modifiers 343 void type(file_type ft) noexcept; 344 void permissions(perms prms) noexcept; 345 346 // [fs.file.status.obs], observers 347 file_type type() const noexcept; 348 perms permissions() const noexcept; 349 350 friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept 351 { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } // C++20 352 }; 353 354 struct space_info 355 { 356 uintmax_t capacity; 357 uintmax_t free; 358 uintmax_t available; 359 360 friend bool operator==(const space_info&, const space_info&) = default; // C++20 361 }; 362 363 enum class file_type; 364 enum class perms; 365 enum class perm_options; 366 enum class copy_options; 367 enum class directory_options; 368 369 typedef chrono::time_point<trivial-clock> file_time_type; 370 371 // operational functions 372 373 path absolute(const path& p); 374 path absolute(const path& p, error_code &ec); 375 376 path canonical(const path& p); 377 path canonical(const path& p, error_code& ec); 378 379 void copy(const path& from, const path& to); 380 void copy(const path& from, const path& to, error_code& ec); 381 void copy(const path& from, const path& to, copy_options options); 382 void copy(const path& from, const path& to, copy_options options, 383 error_code& ec); 384 385 bool copy_file(const path& from, const path& to); 386 bool copy_file(const path& from, const path& to, error_code& ec); 387 bool copy_file(const path& from, const path& to, copy_options option); 388 bool copy_file(const path& from, const path& to, copy_options option, 389 error_code& ec); 390 391 void copy_symlink(const path& existing_symlink, const path& new_symlink); 392 void copy_symlink(const path& existing_symlink, const path& new_symlink, 393 error_code& ec) noexcept; 394 395 bool create_directories(const path& p); 396 bool create_directories(const path& p, error_code& ec); 397 398 bool create_directory(const path& p); 399 bool create_directory(const path& p, error_code& ec) noexcept; 400 401 bool create_directory(const path& p, const path& attributes); 402 bool create_directory(const path& p, const path& attributes, 403 error_code& ec) noexcept; 404 405 void create_directory_symlink(const path& to, const path& new_symlink); 406 void create_directory_symlink(const path& to, const path& new_symlink, 407 error_code& ec) noexcept; 408 409 void create_hard_link(const path& to, const path& new_hard_link); 410 void create_hard_link(const path& to, const path& new_hard_link, 411 error_code& ec) noexcept; 412 413 void create_symlink(const path& to, const path& new_symlink); 414 void create_symlink(const path& to, const path& new_symlink, 415 error_code& ec) noexcept; 416 417 path current_path(); 418 path current_path(error_code& ec); 419 void current_path(const path& p); 420 void current_path(const path& p, error_code& ec) noexcept; 421 422 bool exists(file_status s) noexcept; 423 bool exists(const path& p); 424 bool exists(const path& p, error_code& ec) noexcept; 425 426 bool equivalent(const path& p1, const path& p2); 427 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; 428 429 uintmax_t file_size(const path& p); 430 uintmax_t file_size(const path& p, error_code& ec) noexcept; 431 432 uintmax_t hard_link_count(const path& p); 433 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; 434 435 bool is_block_file(file_status s) noexcept; 436 bool is_block_file(const path& p); 437 bool is_block_file(const path& p, error_code& ec) noexcept; 438 439 bool is_character_file(file_status s) noexcept; 440 bool is_character_file(const path& p); 441 bool is_character_file(const path& p, error_code& ec) noexcept; 442 443 bool is_directory(file_status s) noexcept; 444 bool is_directory(const path& p); 445 bool is_directory(const path& p, error_code& ec) noexcept; 446 447 bool is_empty(const path& p); 448 bool is_empty(const path& p, error_code& ec) noexcept; 449 450 bool is_fifo(file_status s) noexcept; 451 bool is_fifo(const path& p); 452 bool is_fifo(const path& p, error_code& ec) noexcept; 453 454 bool is_other(file_status s) noexcept; 455 bool is_other(const path& p); 456 bool is_other(const path& p, error_code& ec) noexcept; 457 458 bool is_regular_file(file_status s) noexcept; 459 bool is_regular_file(const path& p); 460 bool is_regular_file(const path& p, error_code& ec) noexcept; 461 462 bool is_socket(file_status s) noexcept; 463 bool is_socket(const path& p); 464 bool is_socket(const path& p, error_code& ec) noexcept; 465 466 bool is_symlink(file_status s) noexcept; 467 bool is_symlink(const path& p); 468 bool is_symlink(const path& p, error_code& ec) noexcept; 469 470 file_time_type last_write_time(const path& p); 471 file_time_type last_write_time(const path& p, error_code& ec) noexcept; 472 void last_write_time(const path& p, file_time_type new_time); 473 void last_write_time(const path& p, file_time_type new_time, 474 error_code& ec) noexcept; 475 476 void permissions(const path& p, perms prms, 477 perm_options opts=perm_options::replace); 478 void permissions(const path& p, perms prms, error_code& ec) noexcept; 479 void permissions(const path& p, perms prms, perm_options opts, 480 error_code& ec); 481 482 path proximate(const path& p, error_code& ec); 483 path proximate(const path& p, const path& base = current_path()); 484 path proximate(const path& p, const path& base, error_code &ec); 485 486 path read_symlink(const path& p); 487 path read_symlink(const path& p, error_code& ec); 488 489 path relative(const path& p, error_code& ec); 490 path relative(const path& p, const path& base=current_path()); 491 path relative(const path& p, const path& base, error_code& ec); 492 493 bool remove(const path& p); 494 bool remove(const path& p, error_code& ec) noexcept; 495 496 uintmax_t remove_all(const path& p); 497 uintmax_t remove_all(const path& p, error_code& ec); 498 499 void rename(const path& from, const path& to); 500 void rename(const path& from, const path& to, error_code& ec) noexcept; 501 502 void resize_file(const path& p, uintmax_t size); 503 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; 504 505 space_info space(const path& p); 506 space_info space(const path& p, error_code& ec) noexcept; 507 508 file_status status(const path& p); 509 file_status status(const path& p, error_code& ec) noexcept; 510 511 bool status_known(file_status s) noexcept; 512 513 file_status symlink_status(const path& p); 514 file_status symlink_status(const path& p, error_code& ec) noexcept; 515 516 path temp_directory_path(); 517 path temp_directory_path(error_code& ec); 518 519 path weakly_canonical(path const& p); 520 path weakly_canonical(path const& p, error_code& ec); 521 522} // namespace std::filesystem 523 524template <> 525inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true; 526template <> 527inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true; 528 529template <> 530inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true; 531template <> 532inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true; 533 534*/ 535 536#include <__assert> // all public C++ headers provide the assertion handler 537#include <__config> 538#include <__filesystem/copy_options.h> 539#include <__filesystem/directory_entry.h> 540#include <__filesystem/directory_iterator.h> 541#include <__filesystem/directory_options.h> 542#include <__filesystem/file_status.h> 543#include <__filesystem/file_time_type.h> 544#include <__filesystem/file_type.h> 545#include <__filesystem/filesystem_error.h> 546#include <__filesystem/operations.h> 547#include <__filesystem/path.h> 548#include <__filesystem/path_iterator.h> 549#include <__filesystem/perm_options.h> 550#include <__filesystem/perms.h> 551#include <__filesystem/recursive_directory_iterator.h> 552#include <__filesystem/space_info.h> 553#include <__filesystem/u8path.h> 554#include <version> 555 556// standard-mandated includes 557 558// [fs.filesystem.syn] 559#include <compare> 560 561#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 562# pragma GCC system_header 563#endif 564 565#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 566# include <concepts> 567# include <cstdlib> 568# include <iosfwd> 569# include <new> 570# include <system_error> 571#endif 572 573#endif // _LIBCPP_FILESYSTEM 574