blob: 7efa4ed2b39fd3a9b8e63a70b0a1b6800395a814 [file] [log] [blame]
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001// -*- C++ -*-
Louis Dionne9bd93882021-11-17 16:25:01 -05002//===----------------------------------------------------------------------===//
Eric Fiselier02cea5e2018-07-27 03:07:09 +00003//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// 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
Eric Fiselier02cea5e2018-07-27 03:07:09 +00007//
8//===----------------------------------------------------------------------===//
Louis Dionne35fb2512022-11-25 10:25:10 -05009
Eric Fiselier02cea5e2018-07-27 03:07:09 +000010#ifndef _LIBCPP_FILESYSTEM
11#define _LIBCPP_FILESYSTEM
Louis Dionneb4fce352022-03-25 12:55:36 -040012
Eric Fiselier02cea5e2018-07-27 03:07:09 +000013/*
14 filesystem synopsis
15
Joe Loser9d1c0d42021-10-14 11:53:43 -040016 namespace std::filesystem {
Eric Fiselier02cea5e2018-07-27 03:07:09 +000017
Adrian Vogelsgesang25763c02022-07-31 15:21:01 -070018 // `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 };
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000158
159 void swap(path& lhs, path& rhs) noexcept;
160 size_t hash_value(const path& p) noexcept;
161
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000162 template <class Source>
163 path u8path(const Source& source);
164 template <class InputIterator>
165 path u8path(InputIterator first, InputIterator last);
166
167 class filesystem_error;
Adrian Vogelsgesang91de62b2022-07-31 15:57:10 -0700168
169 class directory_entry {
170 public:
171 directory_entry() noexcept = default;
172 directory_entry(const directory_entry&) = default;
173 directory_entry(directory_entry&&) noexcept = default;
174 explicit directory_entry(const filesystem::path& p);
175 directory_entry(const filesystem::path& p, error_code& ec);
176 ~directory_entry();
177
178 directory_entry& operator=(const directory_entry&) = default;
179 directory_entry& operator=(directory_entry&&) noexcept = default;
180
181 void assign(const filesystem::path& p);
182 void assign(const filesystem::path& p, error_code& ec);
183 void replace_filename(const filesystem::path& p);
184 void replace_filename(const filesystem::path& p, error_code& ec);
185 void refresh();
186 void refresh(error_code& ec) noexcept;
187
188 const filesystem::path& path() const noexcept;
189 operator const filesystem::path&() const noexcept;
190 bool exists() const;
191 bool exists(error_code& ec) const noexcept;
192 bool is_block_file() const;
193 bool is_block_file(error_code& ec) const noexcept;
194 bool is_character_file() const;
195 bool is_character_file(error_code& ec) const noexcept;
196 bool is_directory() const;
197 bool is_directory(error_code& ec) const noexcept;
198 bool is_fifo() const;
199 bool is_fifo(error_code& ec) const noexcept;
200 bool is_other() const;
201 bool is_other(error_code& ec) const noexcept;
202 bool is_regular_file() const;
203 bool is_regular_file(error_code& ec) const noexcept;
204 bool is_socket() const;
205 bool is_socket(error_code& ec) const noexcept;
206 bool is_symlink() const;
207 bool is_symlink(error_code& ec) const noexcept;
208 uintmax_t file_size() const;
209 uintmax_t file_size(error_code& ec) const noexcept;
210 uintmax_t hard_link_count() const;
211 uintmax_t hard_link_count(error_code& ec) const noexcept;
212 file_time_type last_write_time() const;
213 file_time_type last_write_time(error_code& ec) const noexcept;
214 file_status status() const;
215 file_status status(error_code& ec) const noexcept;
216 file_status symlink_status() const;
217 file_status symlink_status(error_code& ec) const noexcept;
218
219 bool operator==(const directory_entry& rhs) const noexcept;
220 bool operator!=(const directory_entry& rhs) const noexcept; // removed in C++20
221 bool operator< (const directory_entry& rhs) const noexcept; // removed in C++20
222 bool operator<=(const directory_entry& rhs) const noexcept; // removed in C++20
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 strong_ordering operator<=>(const directory_entry& rhs) const noexcept; // since C++20
226
227 template<class charT, class traits>
228 friend basic_ostream<charT, traits>&
229 operator<<(basic_ostream<charT, traits>& os, const directory_entry& d);
230
231 private:
232 filesystem::path pathobject; // exposition only
233 friend class directory_iterator; // exposition only
234 };
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000235
236 class directory_iterator;
237
238 // enable directory_iterator range-based for statements
239 directory_iterator begin(directory_iterator iter) noexcept;
Joe Loser9d1c0d42021-10-14 11:53:43 -0400240 directory_iterator end(directory_iterator) noexcept;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000241
242 class recursive_directory_iterator;
243
244 // enable recursive_directory_iterator range-based for statements
245 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
Joe Loser9d1c0d42021-10-14 11:53:43 -0400246 recursive_directory_iterator end(recursive_directory_iterator) noexcept;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000247
248 class file_status;
249
250 struct space_info
251 {
252 uintmax_t capacity;
253 uintmax_t free;
254 uintmax_t available;
Adrian Vogelsgesangfe1bc752022-07-31 16:12:42 -0700255
256 friend bool operator==(const space_info&, const space_info&) = default; // C++20
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000257 };
258
259 enum class file_type;
260 enum class perms;
261 enum class perm_options;
262 enum class copy_options;
263 enum class directory_options;
264
265 typedef chrono::time_point<trivial-clock> file_time_type;
266
267 // operational functions
268
269 path absolute(const path& p);
270 path absolute(const path& p, error_code &ec);
271
272 path canonical(const path& p);
273 path canonical(const path& p, error_code& ec);
274
275 void copy(const path& from, const path& to);
276 void copy(const path& from, const path& to, error_code& ec);
277 void copy(const path& from, const path& to, copy_options options);
278 void copy(const path& from, const path& to, copy_options options,
279 error_code& ec);
280
281 bool copy_file(const path& from, const path& to);
282 bool copy_file(const path& from, const path& to, error_code& ec);
283 bool copy_file(const path& from, const path& to, copy_options option);
284 bool copy_file(const path& from, const path& to, copy_options option,
285 error_code& ec);
286
287 void copy_symlink(const path& existing_symlink, const path& new_symlink);
288 void copy_symlink(const path& existing_symlink, const path& new_symlink,
289 error_code& ec) noexcept;
290
291 bool create_directories(const path& p);
292 bool create_directories(const path& p, error_code& ec);
293
294 bool create_directory(const path& p);
295 bool create_directory(const path& p, error_code& ec) noexcept;
296
297 bool create_directory(const path& p, const path& attributes);
298 bool create_directory(const path& p, const path& attributes,
299 error_code& ec) noexcept;
300
301 void create_directory_symlink(const path& to, const path& new_symlink);
302 void create_directory_symlink(const path& to, const path& new_symlink,
303 error_code& ec) noexcept;
304
305 void create_hard_link(const path& to, const path& new_hard_link);
306 void create_hard_link(const path& to, const path& new_hard_link,
307 error_code& ec) noexcept;
308
309 void create_symlink(const path& to, const path& new_symlink);
310 void create_symlink(const path& to, const path& new_symlink,
311 error_code& ec) noexcept;
312
313 path current_path();
314 path current_path(error_code& ec);
315 void current_path(const path& p);
316 void current_path(const path& p, error_code& ec) noexcept;
317
318 bool exists(file_status s) noexcept;
319 bool exists(const path& p);
320 bool exists(const path& p, error_code& ec) noexcept;
321
322 bool equivalent(const path& p1, const path& p2);
323 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
324
325 uintmax_t file_size(const path& p);
326 uintmax_t file_size(const path& p, error_code& ec) noexcept;
327
328 uintmax_t hard_link_count(const path& p);
329 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
330
331 bool is_block_file(file_status s) noexcept;
332 bool is_block_file(const path& p);
333 bool is_block_file(const path& p, error_code& ec) noexcept;
334
335 bool is_character_file(file_status s) noexcept;
336 bool is_character_file(const path& p);
337 bool is_character_file(const path& p, error_code& ec) noexcept;
338
339 bool is_directory(file_status s) noexcept;
340 bool is_directory(const path& p);
341 bool is_directory(const path& p, error_code& ec) noexcept;
342
343 bool is_empty(const path& p);
344 bool is_empty(const path& p, error_code& ec) noexcept;
345
346 bool is_fifo(file_status s) noexcept;
347 bool is_fifo(const path& p);
348 bool is_fifo(const path& p, error_code& ec) noexcept;
349
350 bool is_other(file_status s) noexcept;
351 bool is_other(const path& p);
352 bool is_other(const path& p, error_code& ec) noexcept;
353
354 bool is_regular_file(file_status s) noexcept;
355 bool is_regular_file(const path& p);
356 bool is_regular_file(const path& p, error_code& ec) noexcept;
357
358 bool is_socket(file_status s) noexcept;
359 bool is_socket(const path& p);
360 bool is_socket(const path& p, error_code& ec) noexcept;
361
362 bool is_symlink(file_status s) noexcept;
363 bool is_symlink(const path& p);
364 bool is_symlink(const path& p, error_code& ec) noexcept;
365
366 file_time_type last_write_time(const path& p);
367 file_time_type last_write_time(const path& p, error_code& ec) noexcept;
368 void last_write_time(const path& p, file_time_type new_time);
369 void last_write_time(const path& p, file_time_type new_time,
370 error_code& ec) noexcept;
371
372 void permissions(const path& p, perms prms,
373 perm_options opts=perm_options::replace);
374 void permissions(const path& p, perms prms, error_code& ec) noexcept;
375 void permissions(const path& p, perms prms, perm_options opts,
376 error_code& ec);
377
378 path proximate(const path& p, error_code& ec);
379 path proximate(const path& p, const path& base = current_path());
380 path proximate(const path& p, const path& base, error_code &ec);
381
382 path read_symlink(const path& p);
383 path read_symlink(const path& p, error_code& ec);
384
385 path relative(const path& p, error_code& ec);
386 path relative(const path& p, const path& base=current_path());
387 path relative(const path& p, const path& base, error_code& ec);
388
389 bool remove(const path& p);
390 bool remove(const path& p, error_code& ec) noexcept;
391
392 uintmax_t remove_all(const path& p);
393 uintmax_t remove_all(const path& p, error_code& ec);
394
395 void rename(const path& from, const path& to);
396 void rename(const path& from, const path& to, error_code& ec) noexcept;
397
398 void resize_file(const path& p, uintmax_t size);
399 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
400
401 space_info space(const path& p);
402 space_info space(const path& p, error_code& ec) noexcept;
403
404 file_status status(const path& p);
405 file_status status(const path& p, error_code& ec) noexcept;
406
407 bool status_known(file_status s) noexcept;
408
409 file_status symlink_status(const path& p);
410 file_status symlink_status(const path& p, error_code& ec) noexcept;
411
412 path temp_directory_path();
413 path temp_directory_path(error_code& ec);
414
415 path weakly_canonical(path const& p);
416 path weakly_canonical(path const& p, error_code& ec);
417
Joe Loser9d1c0d42021-10-14 11:53:43 -0400418} // namespace std::filesystem
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000419
Joe Loser9d1c0d42021-10-14 11:53:43 -0400420template <>
421inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
422template <>
423inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
424
425template <>
426inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true;
427template <>
428inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000429
430*/
431
Louis Dionneb4fce352022-03-25 12:55:36 -0400432#include <__assert> // all public C++ headers provide the assertion handler
Nikolas Klauser0d7bb8b2021-12-23 11:55:38 +0100433#include <__config>
Nikolas Klauserd2ef1062021-12-23 12:21:00 +0100434#include <__filesystem/copy_options.h>
435#include <__filesystem/directory_entry.h>
436#include <__filesystem/directory_iterator.h>
437#include <__filesystem/directory_options.h>
438#include <__filesystem/file_status.h>
439#include <__filesystem/file_time_type.h>
440#include <__filesystem/file_type.h>
441#include <__filesystem/filesystem_error.h>
442#include <__filesystem/operations.h>
Nikolas Klauserd2ef1062021-12-23 12:21:00 +0100443#include <__filesystem/path.h>
Arthur O'Dwyer65077c02022-01-07 09:45:05 -0500444#include <__filesystem/path_iterator.h>
Nikolas Klauserd2ef1062021-12-23 12:21:00 +0100445#include <__filesystem/perm_options.h>
446#include <__filesystem/perms.h>
447#include <__filesystem/recursive_directory_iterator.h>
448#include <__filesystem/space_info.h>
449#include <__filesystem/u8path.h>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000450#include <version>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000451
Nikolas Klausera0e0edb2022-06-16 22:43:46 +0200452// standard-mandated includes
Nikolas Klauser71619e72022-09-22 18:05:08 +0200453
454// [fs.filesystem.syn]
Nikolas Klausera0e0edb2022-06-16 22:43:46 +0200455#include <compare>
456
Louis Dionnedb84e122021-01-18 12:18:18 -0500457#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
Louis Dionne685c4702022-05-18 13:17:14 -0400458# error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem."
Louis Dionnedb84e122021-01-18 12:18:18 -0500459#endif
460
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000461#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Arthur O'Dwyer6eeaa002022-02-01 20:16:40 -0500462# pragma GCC system_header
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000463#endif
464
Nikolas Klauser1e4ae5d2022-11-02 20:27:42 +0100465#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
466# include <concepts>
467#endif
468
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000469#endif // _LIBCPP_FILESYSTEM