filesystem 22 KB

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