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 241 // enable directory_iterator range-based for statements 242 directory_iterator begin(directory_iterator iter) noexcept; 243 directory_iterator end(directory_iterator) noexcept; 244 245 class recursive_directory_iterator; 246 247 // enable recursive_directory_iterator range-based for statements 248 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; 249 recursive_directory_iterator end(recursive_directory_iterator) noexcept; 250 251 class file_status; 252 253 struct space_info 254 { 255 uintmax_t capacity; 256 uintmax_t free; 257 uintmax_t available; 258 259 friend bool operator==(const space_info&, const space_info&) = default; // C++20 260 }; 261 262 enum class file_type; 263 enum class perms; 264 enum class perm_options; 265 enum class copy_options; 266 enum class directory_options; 267 268 typedef chrono::time_point<trivial-clock> file_time_type; 269 270 // operational functions 271 272 path absolute(const path& p); 273 path absolute(const path& p, error_code &ec); 274 275 path canonical(const path& p); 276 path canonical(const path& p, error_code& ec); 277 278 void copy(const path& from, const path& to); 279 void copy(const path& from, const path& to, error_code& ec); 280 void copy(const path& from, const path& to, copy_options options); 281 void copy(const path& from, const path& to, copy_options options, 282 error_code& ec); 283 284 bool copy_file(const path& from, const path& to); 285 bool copy_file(const path& from, const path& to, error_code& ec); 286 bool copy_file(const path& from, const path& to, copy_options option); 287 bool copy_file(const path& from, const path& to, copy_options option, 288 error_code& ec); 289 290 void copy_symlink(const path& existing_symlink, const path& new_symlink); 291 void copy_symlink(const path& existing_symlink, const path& new_symlink, 292 error_code& ec) noexcept; 293 294 bool create_directories(const path& p); 295 bool create_directories(const path& p, error_code& ec); 296 297 bool create_directory(const path& p); 298 bool create_directory(const path& p, error_code& ec) noexcept; 299 300 bool create_directory(const path& p, const path& attributes); 301 bool create_directory(const path& p, const path& attributes, 302 error_code& ec) noexcept; 303 304 void create_directory_symlink(const path& to, const path& new_symlink); 305 void create_directory_symlink(const path& to, const path& new_symlink, 306 error_code& ec) noexcept; 307 308 void create_hard_link(const path& to, const path& new_hard_link); 309 void create_hard_link(const path& to, const path& new_hard_link, 310 error_code& ec) noexcept; 311 312 void create_symlink(const path& to, const path& new_symlink); 313 void create_symlink(const path& to, const path& new_symlink, 314 error_code& ec) noexcept; 315 316 path current_path(); 317 path current_path(error_code& ec); 318 void current_path(const path& p); 319 void current_path(const path& p, error_code& ec) noexcept; 320 321 bool exists(file_status s) noexcept; 322 bool exists(const path& p); 323 bool exists(const path& p, error_code& ec) noexcept; 324 325 bool equivalent(const path& p1, const path& p2); 326 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; 327 328 uintmax_t file_size(const path& p); 329 uintmax_t file_size(const path& p, error_code& ec) noexcept; 330 331 uintmax_t hard_link_count(const path& p); 332 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; 333 334 bool is_block_file(file_status s) noexcept; 335 bool is_block_file(const path& p); 336 bool is_block_file(const path& p, error_code& ec) noexcept; 337 338 bool is_character_file(file_status s) noexcept; 339 bool is_character_file(const path& p); 340 bool is_character_file(const path& p, error_code& ec) noexcept; 341 342 bool is_directory(file_status s) noexcept; 343 bool is_directory(const path& p); 344 bool is_directory(const path& p, error_code& ec) noexcept; 345 346 bool is_empty(const path& p); 347 bool is_empty(const path& p, error_code& ec) noexcept; 348 349 bool is_fifo(file_status s) noexcept; 350 bool is_fifo(const path& p); 351 bool is_fifo(const path& p, error_code& ec) noexcept; 352 353 bool is_other(file_status s) noexcept; 354 bool is_other(const path& p); 355 bool is_other(const path& p, error_code& ec) noexcept; 356 357 bool is_regular_file(file_status s) noexcept; 358 bool is_regular_file(const path& p); 359 bool is_regular_file(const path& p, error_code& ec) noexcept; 360 361 bool is_socket(file_status s) noexcept; 362 bool is_socket(const path& p); 363 bool is_socket(const path& p, error_code& ec) noexcept; 364 365 bool is_symlink(file_status s) noexcept; 366 bool is_symlink(const path& p); 367 bool is_symlink(const path& p, error_code& ec) noexcept; 368 369 file_time_type last_write_time(const path& p); 370 file_time_type last_write_time(const path& p, error_code& ec) noexcept; 371 void last_write_time(const path& p, file_time_type new_time); 372 void last_write_time(const path& p, file_time_type new_time, 373 error_code& ec) noexcept; 374 375 void permissions(const path& p, perms prms, 376 perm_options opts=perm_options::replace); 377 void permissions(const path& p, perms prms, error_code& ec) noexcept; 378 void permissions(const path& p, perms prms, perm_options opts, 379 error_code& ec); 380 381 path proximate(const path& p, error_code& ec); 382 path proximate(const path& p, const path& base = current_path()); 383 path proximate(const path& p, const path& base, error_code &ec); 384 385 path read_symlink(const path& p); 386 path read_symlink(const path& p, error_code& ec); 387 388 path relative(const path& p, error_code& ec); 389 path relative(const path& p, const path& base=current_path()); 390 path relative(const path& p, const path& base, error_code& ec); 391 392 bool remove(const path& p); 393 bool remove(const path& p, error_code& ec) noexcept; 394 395 uintmax_t remove_all(const path& p); 396 uintmax_t remove_all(const path& p, error_code& ec); 397 398 void rename(const path& from, const path& to); 399 void rename(const path& from, const path& to, error_code& ec) noexcept; 400 401 void resize_file(const path& p, uintmax_t size); 402 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; 403 404 space_info space(const path& p); 405 space_info space(const path& p, error_code& ec) noexcept; 406 407 file_status status(const path& p); 408 file_status status(const path& p, error_code& ec) noexcept; 409 410 bool status_known(file_status s) noexcept; 411 412 file_status symlink_status(const path& p); 413 file_status symlink_status(const path& p, error_code& ec) noexcept; 414 415 path temp_directory_path(); 416 path temp_directory_path(error_code& ec); 417 418 path weakly_canonical(path const& p); 419 path weakly_canonical(path const& p, error_code& ec); 420 421} // namespace std::filesystem 422 423template <> 424inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true; 425template <> 426inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true; 427 428template <> 429inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true; 430template <> 431inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true; 432 433*/ 434 435#include <__assert> // all public C++ headers provide the assertion handler 436#include <__config> 437#include <__filesystem/copy_options.h> 438#include <__filesystem/directory_entry.h> 439#include <__filesystem/directory_iterator.h> 440#include <__filesystem/directory_options.h> 441#include <__filesystem/file_status.h> 442#include <__filesystem/file_time_type.h> 443#include <__filesystem/file_type.h> 444#include <__filesystem/filesystem_error.h> 445#include <__filesystem/operations.h> 446#include <__filesystem/path.h> 447#include <__filesystem/path_iterator.h> 448#include <__filesystem/perm_options.h> 449#include <__filesystem/perms.h> 450#include <__filesystem/recursive_directory_iterator.h> 451#include <__filesystem/space_info.h> 452#include <__filesystem/u8path.h> 453#include <version> 454 455// standard-mandated includes 456 457// [fs.filesystem.syn] 458#include <compare> 459 460#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) 461# error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem." 462#endif 463 464#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 465# pragma GCC system_header 466#endif 467 468#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 469# include <concepts> 470# include <cstdlib> 471# include <system_error> 472#endif 473 474#endif // _LIBCPP_FILESYSTEM 475