2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_FILESYSTEM
11 #define _LIBCPP_FILESYSTEM
16 namespace std::filesystem {
18 // `class path` from http://eel.is/c++draft/fs.class.path.general#6
21 using value_type = see below;
22 using string_type = basic_string<value_type>;
23 static constexpr value_type preferred_separator = see below;
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);
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);
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);
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);
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;
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
89 friend path operator/(const path& lhs, const path& rhs);
91 const string_type& native() const noexcept;
92 const value_type* c_str() const noexcept;
93 operator string_type() const;
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;
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;
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;
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;
127 path extension() const;
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;
141 path lexically_normal() const;
142 path lexically_relative(const path& base) const;
143 path lexically_proximate(const path& base) const;
146 using const_iterator = iterator;
148 iterator begin() const;
149 iterator end() const;
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);
159 void swap(path& lhs, path& rhs) noexcept;
160 size_t hash_value(const path& p) noexcept;
162 // [fs.path.hash], hash support
163 template<> struct hash<filesystem::path>;
165 template <class Source>
166 path u8path(const Source& source);
167 template <class InputIterator>
168 path u8path(InputIterator first, InputIterator last);
170 class filesystem_error;
172 class directory_entry {
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);
181 directory_entry& operator=(const directory_entry&) = default;
182 directory_entry& operator=(directory_entry&&) noexcept = default;
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);
189 void refresh(error_code& ec) noexcept;
191 const filesystem::path& path() const noexcept;
192 operator const filesystem::path&() const noexcept;
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;
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
230 template<class charT, class traits>
231 friend basic_ostream<charT, traits>&
232 operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
235 filesystem::path pathobject; // exposition only
236 friend class directory_iterator; // exposition only
239 class directory_iterator {
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&;
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,
254 directory_iterator(const directory_iterator& rhs);
255 directory_iterator(directory_iterator&& rhs) noexcept;
256 ~directory_iterator();
258 directory_iterator& operator=(const directory_iterator& rhs);
259 directory_iterator& operator=(directory_iterator&& rhs) noexcept;
261 const directory_entry& operator*() const;
262 const directory_entry* operator->() const;
263 directory_iterator& operator++();
264 directory_iterator& increment(error_code& ec);
266 bool operator==(default_sentinel_t) const noexcept { // since C++20
267 return *this == directory_iterator();
270 // other members as required by [input.iterators], input iterators
273 // enable directory_iterator range-based for statements
274 directory_iterator begin(directory_iterator iter) noexcept;
275 directory_iterator end(directory_iterator) noexcept;
277 class recursive_directory_iterator {
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&;
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,
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();
296 // [fs.rec.dir.itr.members], observers
297 directory_options options() const;
299 bool recursion_pending() const;
301 const directory_entry& operator*() const;
302 const directory_entry* operator->() const;
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;
310 recursive_directory_iterator& operator++();
311 recursive_directory_iterator& increment(error_code& ec);
314 void pop(error_code& ec);
315 void disable_recursion_pending();
317 bool operator==(default_sentinel_t) const noexcept { // since C++20
318 return *this == recursive_directory_iterator();
321 // other members as required by [input.iterators], input iterators
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;
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;
339 file_status& operator=(const file_status&) noexcept = default;
340 file_status& operator=(file_status&&) noexcept = default;
342 // [fs.file.status.mods], modifiers
343 void type(file_type ft) noexcept;
344 void permissions(perms prms) noexcept;
346 // [fs.file.status.obs], observers
347 file_type type() const noexcept;
348 perms permissions() const noexcept;
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
360 friend bool operator==(const space_info&, const space_info&) = default; // C++20
363 enum class file_type;
365 enum class perm_options;
366 enum class copy_options;
367 enum class directory_options;
369 typedef chrono::time_point<trivial-clock> file_time_type;
371 // operational functions
373 path absolute(const path& p);
374 path absolute(const path& p, error_code &ec);
376 path canonical(const path& p);
377 path canonical(const path& p, error_code& ec);
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,
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,
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;
395 bool create_directories(const path& p);
396 bool create_directories(const path& p, error_code& ec);
398 bool create_directory(const path& p);
399 bool create_directory(const path& p, error_code& ec) noexcept;
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;
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;
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;
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;
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;
422 bool exists(file_status s) noexcept;
423 bool exists(const path& p);
424 bool exists(const path& p, error_code& ec) noexcept;
426 bool equivalent(const path& p1, const path& p2);
427 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
429 uintmax_t file_size(const path& p);
430 uintmax_t file_size(const path& p, error_code& ec) noexcept;
432 uintmax_t hard_link_count(const path& p);
433 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
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;
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;
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;
447 bool is_empty(const path& p);
448 bool is_empty(const path& p, error_code& ec) noexcept;
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;
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;
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;
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;
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;
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;
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,
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);
486 path read_symlink(const path& p);
487 path read_symlink(const path& p, error_code& ec);
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);
493 bool remove(const path& p);
494 bool remove(const path& p, error_code& ec) noexcept;
496 uintmax_t remove_all(const path& p);
497 uintmax_t remove_all(const path& p, error_code& ec);
499 void rename(const path& from, const path& to);
500 void rename(const path& from, const path& to, error_code& ec) noexcept;
502 void resize_file(const path& p, uintmax_t size);
503 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
505 space_info space(const path& p);
506 space_info space(const path& p, error_code& ec) noexcept;
508 file_status status(const path& p);
509 file_status status(const path& p, error_code& ec) noexcept;
511 bool status_known(file_status s) noexcept;
513 file_status symlink_status(const path& p);
514 file_status symlink_status(const path& p, error_code& ec) noexcept;
516 path temp_directory_path();
517 path temp_directory_path(error_code& ec);
519 path weakly_canonical(path const& p);
520 path weakly_canonical(path const& p, error_code& ec);
522 } // namespace std::filesystem
525 inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
527 inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
530 inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true;
532 inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
536 #include <__cxx03/__config>
538 #if _LIBCPP_STD_VER >= 17
539 # include <__cxx03/__filesystem/copy_options.h>
540 # include <__cxx03/__filesystem/directory_entry.h>
541 # include <__cxx03/__filesystem/directory_iterator.h>
542 # include <__cxx03/__filesystem/directory_options.h>
543 # include <__cxx03/__filesystem/file_status.h>
544 # include <__cxx03/__filesystem/file_time_type.h>
545 # include <__cxx03/__filesystem/file_type.h>
546 # include <__cxx03/__filesystem/filesystem_error.h>
547 # include <__cxx03/__filesystem/operations.h>
548 # include <__cxx03/__filesystem/path.h>
549 # include <__cxx03/__filesystem/path_iterator.h>
550 # include <__cxx03/__filesystem/perm_options.h>
551 # include <__cxx03/__filesystem/perms.h>
552 # include <__cxx03/__filesystem/recursive_directory_iterator.h>
553 # include <__cxx03/__filesystem/space_info.h>
554 # include <__cxx03/__filesystem/u8path.h>
557 #include <__cxx03/version>
559 // standard-mandated includes
561 // [fs.filesystem.syn]
562 #include <__cxx03/compare>
564 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
565 # pragma GCC system_header
568 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
569 # include <__cxx03/concepts>
570 # include <__cxx03/cstdlib>
571 # include <__cxx03/cstring>
572 # include <__cxx03/iosfwd>
573 # include <__cxx03/new>
574 # include <__cxx03/system_error>
577 #endif // _LIBCPP_FILESYSTEM