blob: 1f6d1ab4d962430284130536ed5e6fc2d0a5674c [file] [log] [blame]
Eric Fiselier435db152016-06-17 19:46:40 +00001// -*- C++ -*-
2//===--------------------------- filesystem -------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10#ifndef _LIBCPP_EXPERIMENTAL_FILESYSTEM
11#define _LIBCPP_EXPERIMENTAL_FILESYSTEM
12/*
13 filesystem synopsis
14
15 namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
16
17 class path;
18
19 void swap(path& lhs, path& rhs) _NOEXCEPT;
20 size_t hash_value(const path& p) _NOEXCEPT;
21
22 bool operator==(const path& lhs, const path& rhs) _NOEXCEPT;
23 bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT;
24 bool operator< (const path& lhs, const path& rhs) _NOEXCEPT;
25 bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT;
26 bool operator> (const path& lhs, const path& rhs) _NOEXCEPT;
27 bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT;
28
29 path operator/ (const path& lhs, const path& rhs);
30
Eric Fiselier2cd75272018-02-04 03:10:53 +000031 // fs.path.io operators are friends of path.
Eric Fiselier435db152016-06-17 19:46:40 +000032 template <class charT, class traits>
Eric Fiselier2cd75272018-02-04 03:10:53 +000033 friend basic_ostream<charT, traits>&
Eric Fiselier435db152016-06-17 19:46:40 +000034 operator<<(basic_ostream<charT, traits>& os, const path& p);
35
36 template <class charT, class traits>
Eric Fiselier2cd75272018-02-04 03:10:53 +000037 friend basic_istream<charT, traits>&
Eric Fiselier435db152016-06-17 19:46:40 +000038 operator>>(basic_istream<charT, traits>& is, path& p);
39
40 template <class Source>
41 path u8path(const Source& source);
42 template <class InputIterator>
43 path u8path(InputIterator first, InputIterator last);
44
45 class filesystem_error;
46 class directory_entry;
47
48 class directory_iterator;
49
50 // enable directory_iterator range-based for statements
51 directory_iterator begin(directory_iterator iter) noexcept;
52 directory_iterator end(const directory_iterator&) noexcept;
53
54 class recursive_directory_iterator;
55
56 // enable recursive_directory_iterator range-based for statements
57 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
58 recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
59
60 class file_status;
61
62 struct space_info
63 {
64 uintmax_t capacity;
65 uintmax_t free;
66 uintmax_t available;
67 };
68
69 enum class file_type;
70 enum class perms;
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +000071 enum class perm_options;
Eric Fiselier435db152016-06-17 19:46:40 +000072 enum class copy_options;
73 enum class directory_options;
74
75 typedef chrono::time_point<trivial-clock> file_time_type;
76
77 // operational functions
78
Eric Fiselier91a182b2018-04-02 23:03:41 +000079 path absolute(const path& p);
80 path absolute(const path& p, error_code &ec);
Eric Fiselier435db152016-06-17 19:46:40 +000081
Eric Fiselier91a182b2018-04-02 23:03:41 +000082 path canonical(const path& p);
Eric Fiselier435db152016-06-17 19:46:40 +000083 path canonical(const path& p, error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +000084
85 void copy(const path& from, const path& to);
Eric Fiselierd56d5322017-10-30 18:59:59 +000086 void copy(const path& from, const path& to, error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +000087 void copy(const path& from, const path& to, copy_options options);
88 void copy(const path& from, const path& to, copy_options options,
Eric Fiselierd56d5322017-10-30 18:59:59 +000089 error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +000090
91 bool copy_file(const path& from, const path& to);
Eric Fiseliere1164812018-02-04 07:35:36 +000092 bool copy_file(const path& from, const path& to, error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +000093 bool copy_file(const path& from, const path& to, copy_options option);
94 bool copy_file(const path& from, const path& to, copy_options option,
Eric Fiseliere1164812018-02-04 07:35:36 +000095 error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +000096
97 void copy_symlink(const path& existing_symlink, const path& new_symlink);
98 void copy_symlink(const path& existing_symlink, const path& new_symlink,
99 error_code& ec) _NOEXCEPT;
100
101 bool create_directories(const path& p);
Eric Fiseliere1164812018-02-04 07:35:36 +0000102 bool create_directories(const path& p, error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +0000103
104 bool create_directory(const path& p);
105 bool create_directory(const path& p, error_code& ec) _NOEXCEPT;
106
107 bool create_directory(const path& p, const path& attributes);
108 bool create_directory(const path& p, const path& attributes,
109 error_code& ec) _NOEXCEPT;
110
111 void create_directory_symlink(const path& to, const path& new_symlink);
112 void create_directory_symlink(const path& to, const path& new_symlink,
113 error_code& ec) _NOEXCEPT;
114
115 void create_hard_link(const path& to, const path& new_hard_link);
116 void create_hard_link(const path& to, const path& new_hard_link,
117 error_code& ec) _NOEXCEPT;
118
119 void create_symlink(const path& to, const path& new_symlink);
120 void create_symlink(const path& to, const path& new_symlink,
121 error_code& ec) _NOEXCEPT;
122
123 path current_path();
124 path current_path(error_code& ec);
125 void current_path(const path& p);
126 void current_path(const path& p, error_code& ec) _NOEXCEPT;
127
128 bool exists(file_status s) _NOEXCEPT;
129 bool exists(const path& p);
130 bool exists(const path& p, error_code& ec) _NOEXCEPT;
131
132 bool equivalent(const path& p1, const path& p2);
133 bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT;
134
135 uintmax_t file_size(const path& p);
136 uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT;
137
138 uintmax_t hard_link_count(const path& p);
139 uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT;
140
141 bool is_block_file(file_status s) _NOEXCEPT;
142 bool is_block_file(const path& p);
143 bool is_block_file(const path& p, error_code& ec) _NOEXCEPT;
144
145 bool is_character_file(file_status s) _NOEXCEPT;
146 bool is_character_file(const path& p);
147 bool is_character_file(const path& p, error_code& ec) _NOEXCEPT;
148
149 bool is_directory(file_status s) _NOEXCEPT;
150 bool is_directory(const path& p);
151 bool is_directory(const path& p, error_code& ec) _NOEXCEPT;
152
153 bool is_empty(const path& p);
154 bool is_empty(const path& p, error_code& ec) _NOEXCEPT;
155
156 bool is_fifo(file_status s) _NOEXCEPT;
157 bool is_fifo(const path& p);
158 bool is_fifo(const path& p, error_code& ec) _NOEXCEPT;
159
160 bool is_other(file_status s) _NOEXCEPT;
161 bool is_other(const path& p);
162 bool is_other(const path& p, error_code& ec) _NOEXCEPT;
163
164 bool is_regular_file(file_status s) _NOEXCEPT;
165 bool is_regular_file(const path& p);
166 bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT;
167
168 bool is_socket(file_status s) _NOEXCEPT;
169 bool is_socket(const path& p);
170 bool is_socket(const path& p, error_code& ec) _NOEXCEPT;
171
172 bool is_symlink(file_status s) _NOEXCEPT;
173 bool is_symlink(const path& p);
174 bool is_symlink(const path& p, error_code& ec) _NOEXCEPT;
175
176 file_time_type last_write_time(const path& p);
177 file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT;
178 void last_write_time(const path& p, file_time_type new_time);
179 void last_write_time(const path& p, file_time_type new_time,
180 error_code& ec) _NOEXCEPT;
181
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +0000182 void permissions(const path& p, perms prms,
183 perm_options opts=perm_options::replace);
184 void permissions(const path& p, perms prms, error_code& ec) noexcept;
185 void permissions(const path& p, perms prms, perm_options opts,
186 error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +0000187
Eric Fiselier91a182b2018-04-02 23:03:41 +0000188 path proximate(const path& p, error_code& ec);
189 path proximate(const path& p, const path& base = current_path());
190 path proximate(const path& p, const path& base, error_code &ec);
191
Eric Fiselier435db152016-06-17 19:46:40 +0000192 path read_symlink(const path& p);
193 path read_symlink(const path& p, error_code& ec);
194
Eric Fiselier91a182b2018-04-02 23:03:41 +0000195 path relative(const path& p, error_code& ec);
196 path relative(const path& p, const path& base=current_path());
197 path relative(const path& p, const path& base, error_code& ec);
198
Eric Fiselier435db152016-06-17 19:46:40 +0000199 bool remove(const path& p);
200 bool remove(const path& p, error_code& ec) _NOEXCEPT;
201
202 uintmax_t remove_all(const path& p);
Eric Fiseliere1164812018-02-04 07:35:36 +0000203 uintmax_t remove_all(const path& p, error_code& ec);
Eric Fiselier435db152016-06-17 19:46:40 +0000204
205 void rename(const path& from, const path& to);
206 void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
207
208 void resize_file(const path& p, uintmax_t size);
209 void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT;
210
211 space_info space(const path& p);
212 space_info space(const path& p, error_code& ec) _NOEXCEPT;
213
214 file_status status(const path& p);
215 file_status status(const path& p, error_code& ec) _NOEXCEPT;
216
217 bool status_known(file_status s) _NOEXCEPT;
218
219 file_status symlink_status(const path& p);
220 file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
221
Eric Fiselier435db152016-06-17 19:46:40 +0000222 path temp_directory_path();
223 path temp_directory_path(error_code& ec);
224
Eric Fiselier91a182b2018-04-02 23:03:41 +0000225 path weakly_canonical(path const& p);
226 path weakly_canonical(path const& p, error_code& ec);
227
228
Eric Fiselier435db152016-06-17 19:46:40 +0000229} } } } // namespaces std::experimental::filesystem::v1
230
231*/
232
233#include <experimental/__config>
234#include <cstddef>
Eric Fiselierb3b129c2018-07-20 01:44:33 +0000235#include <cstdlib>
Eric Fiselier435db152016-06-17 19:46:40 +0000236#include <chrono>
237#include <iterator>
238#include <iosfwd>
239#include <locale>
240#include <memory>
241#include <stack>
242#include <string>
243#include <system_error>
244#include <utility>
245#include <iomanip> // for quoted
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000246#include <string_view>
Eric Fiselier435db152016-06-17 19:46:40 +0000247
248#include <__debug>
249
250#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
251#pragma GCC system_header
252#endif
253
Eric Fiselier3ad58be2018-07-20 01:51:48 +0000254_LIBCPP_PUSH_MACROS
255#include <__undef_macros>
256
Eric Fiselier435db152016-06-17 19:46:40 +0000257#define __cpp_lib_experimental_filesystem 201406
258
259_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
260
261typedef chrono::time_point<std::chrono::system_clock> file_time_type;
262
263struct _LIBCPP_TYPE_VIS space_info
264{
265 uintmax_t capacity;
266 uintmax_t free;
267 uintmax_t available;
268};
269
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000270enum class _LIBCPP_ENUM_VIS file_type : signed char
Eric Fiselier435db152016-06-17 19:46:40 +0000271{
272 none = 0,
273 not_found = -1,
274 regular = 1,
275 directory = 2,
276 symlink = 3,
277 block = 4,
278 character = 5,
279 fifo = 6,
280 socket = 7,
281 unknown = 8
282};
283
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000284enum class _LIBCPP_ENUM_VIS perms : unsigned
Eric Fiselier435db152016-06-17 19:46:40 +0000285{
286 none = 0,
287
288 owner_read = 0400,
289 owner_write = 0200,
290 owner_exec = 0100,
291 owner_all = 0700,
292
293 group_read = 040,
294 group_write = 020,
295 group_exec = 010,
296 group_all = 070,
297
298 others_read = 04,
299 others_write = 02,
300 others_exec = 01,
301 others_all = 07,
302
303 all = 0777,
304
305 set_uid = 04000,
306 set_gid = 02000,
307 sticky_bit = 01000,
308 mask = 07777,
309 unknown = 0xFFFF,
Eric Fiselier435db152016-06-17 19:46:40 +0000310};
311
312_LIBCPP_INLINE_VISIBILITY
313inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
314{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
315
316_LIBCPP_INLINE_VISIBILITY
317inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
318{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
319
320_LIBCPP_INLINE_VISIBILITY
321inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
322{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
323
324_LIBCPP_INLINE_VISIBILITY
325inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
326{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
327
328_LIBCPP_INLINE_VISIBILITY
329inline perms& operator&=(perms& _LHS, perms _RHS)
330{ return _LHS = _LHS & _RHS; }
331
332_LIBCPP_INLINE_VISIBILITY
333inline perms& operator|=(perms& _LHS, perms _RHS)
334{ return _LHS = _LHS | _RHS; }
335
336_LIBCPP_INLINE_VISIBILITY
337inline perms& operator^=(perms& _LHS, perms _RHS)
338{ return _LHS = _LHS ^ _RHS; }
339
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +0000340enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
341 replace = 1,
342 add = 2,
343 remove = 4,
344 nofollow = 8
345};
346
347_LIBCPP_INLINE_VISIBILITY
348inline _LIBCPP_CONSTEXPR perm_options operator&(perm_options _LHS, perm_options _RHS)
349{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
350
351_LIBCPP_INLINE_VISIBILITY
352inline _LIBCPP_CONSTEXPR perm_options operator|(perm_options _LHS, perm_options _RHS)
353{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
354
355_LIBCPP_INLINE_VISIBILITY
356inline _LIBCPP_CONSTEXPR perm_options operator^(perm_options _LHS, perm_options _RHS)
357{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
358
359_LIBCPP_INLINE_VISIBILITY
360inline _LIBCPP_CONSTEXPR perm_options operator~(perm_options _LHS)
361{ return static_cast<perm_options>(~static_cast<unsigned>(_LHS)); }
362
363_LIBCPP_INLINE_VISIBILITY
364inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS)
365{ return _LHS = _LHS & _RHS; }
366
367_LIBCPP_INLINE_VISIBILITY
368inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS)
369{ return _LHS = _LHS | _RHS; }
370
371_LIBCPP_INLINE_VISIBILITY
372inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS)
373{ return _LHS = _LHS ^ _RHS; }
374
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000375enum class _LIBCPP_ENUM_VIS copy_options : unsigned short
Eric Fiselier435db152016-06-17 19:46:40 +0000376{
377 none = 0,
378 skip_existing = 1,
379 overwrite_existing = 2,
380 update_existing = 4,
381 recursive = 8,
382 copy_symlinks = 16,
383 skip_symlinks = 32,
384 directories_only = 64,
385 create_symlinks = 128,
386 create_hard_links = 256,
387 __in_recursive_copy = 512,
388};
389
390_LIBCPP_INLINE_VISIBILITY
391inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
392{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
393
394_LIBCPP_INLINE_VISIBILITY
395inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
396{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
397
398_LIBCPP_INLINE_VISIBILITY
399inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
400{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
401
402_LIBCPP_INLINE_VISIBILITY
403inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
404{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
405
406_LIBCPP_INLINE_VISIBILITY
407inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
408{ return _LHS = _LHS & _RHS; }
409
410_LIBCPP_INLINE_VISIBILITY
411inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
412{ return _LHS = _LHS | _RHS; }
413
414_LIBCPP_INLINE_VISIBILITY
415inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
416{ return _LHS = _LHS ^ _RHS; }
417
418
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000419enum class _LIBCPP_ENUM_VIS directory_options : unsigned char
Eric Fiselier435db152016-06-17 19:46:40 +0000420{
421 none = 0,
422 follow_directory_symlink = 1,
423 skip_permission_denied = 2
424};
425
426_LIBCPP_INLINE_VISIBILITY
427inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
428{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
429
430_LIBCPP_INLINE_VISIBILITY
431inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
432{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
433
434_LIBCPP_INLINE_VISIBILITY
435inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
436{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
437
438_LIBCPP_INLINE_VISIBILITY
439inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
440{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
441
442_LIBCPP_INLINE_VISIBILITY
443inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
444{ return _LHS = _LHS & _RHS; }
445
446_LIBCPP_INLINE_VISIBILITY
447inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
448{ return _LHS = _LHS | _RHS; }
449
450_LIBCPP_INLINE_VISIBILITY
451inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
452{ return _LHS = _LHS ^ _RHS; }
453
454
455class _LIBCPP_TYPE_VIS file_status
456{
457public:
458 // constructors
459 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6afd7e82017-03-06 21:02:06 +0000460 file_status() _NOEXCEPT : file_status(file_type::none) {}
461 _LIBCPP_INLINE_VISIBILITY
462 explicit file_status(file_type __ft,
463 perms __prms = perms::unknown) _NOEXCEPT
Eric Fiselier435db152016-06-17 19:46:40 +0000464 : __ft_(__ft), __prms_(__prms)
465 {}
466
467 file_status(const file_status&) _NOEXCEPT = default;
468 file_status(file_status&&) _NOEXCEPT = default;
469
470 _LIBCPP_INLINE_VISIBILITY
471 ~file_status() {}
472
473 file_status& operator=(const file_status&) _NOEXCEPT = default;
474 file_status& operator=(file_status&&) _NOEXCEPT = default;
475
476 // observers
Louis Dionne16fe2952018-07-11 23:14:33 +0000477 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000478 file_type type() const _NOEXCEPT {
479 return __ft_;
480 }
481
Louis Dionne16fe2952018-07-11 23:14:33 +0000482 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000483 perms permissions() const _NOEXCEPT {
484 return __prms_;
485 }
486
487 // modifiers
Louis Dionne16fe2952018-07-11 23:14:33 +0000488 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000489 void type(file_type __ft) _NOEXCEPT {
490 __ft_ = __ft;
491 }
492
Louis Dionne16fe2952018-07-11 23:14:33 +0000493 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000494 void permissions(perms __p) _NOEXCEPT {
495 __prms_ = __p;
496 }
497private:
498 file_type __ft_;
499 perms __prms_;
500};
501
502class _LIBCPP_TYPE_VIS directory_entry;
503
504template <class _Tp> struct __can_convert_char {
505 static const bool value = false;
506};
Eric Fiselierc355aa32016-08-28 21:26:01 +0000507template <class _Tp> struct __can_convert_char<const _Tp>
508 : public __can_convert_char<_Tp> {
509};
Eric Fiselier435db152016-06-17 19:46:40 +0000510template <> struct __can_convert_char<char> {
511 static const bool value = true;
512 using __char_type = char;
513};
514template <> struct __can_convert_char<wchar_t> {
515 static const bool value = true;
516 using __char_type = wchar_t;
517};
518template <> struct __can_convert_char<char16_t> {
519 static const bool value = true;
520 using __char_type = char16_t;
521};
522template <> struct __can_convert_char<char32_t> {
523 static const bool value = true;
524 using __char_type = char32_t;
525};
526
527template <class _ECharT>
528typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
529__is_separator(_ECharT __e) {
530 return __e == _ECharT('/');
531};
532
533struct _NullSentinal {};
534
535template <class _Tp>
536using _Void = void;
537
538template <class _Tp, class = void>
539struct __is_pathable_string : public false_type {};
540
541template <class _ECharT, class _Traits, class _Alloc>
542struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
543 _Void<typename __can_convert_char<_ECharT>::__char_type>>
544: public __can_convert_char<_ECharT>
545{
546 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
547 using _Base = __can_convert_char<_ECharT>;
548 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
549 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
550 static _ECharT __first_or_null(_Str const& __s) {
551 return __s.empty() ? _ECharT{} : __s[0];
552 }
553};
554
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000555
556template <class _ECharT, class _Traits>
557struct __is_pathable_string<basic_string_view<_ECharT, _Traits>,
558 _Void<typename __can_convert_char<_ECharT>::__char_type>>
559: public __can_convert_char<_ECharT>
560{
561 using _Str = basic_string_view<_ECharT, _Traits>;
562 using _Base = __can_convert_char<_ECharT>;
563 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
564 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
565 static _ECharT __first_or_null(_Str const& __s) {
566 return __s.empty() ? _ECharT{} : __s[0];
567 }
568};
569
Eric Fiselier435db152016-06-17 19:46:40 +0000570template <class _Source,
571 class _DS = typename decay<_Source>::type,
572 class _UnqualPtrType = typename remove_const<
573 typename remove_pointer<_DS>::type>::type,
574 bool _IsCharPtr = is_pointer<_DS>::value &&
575 __can_convert_char<_UnqualPtrType>::value
576 >
577struct __is_pathable_char_array : false_type {};
578
579template <class _Source, class _ECharT, class _UPtr>
580struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
581 : __can_convert_char<typename remove_const<_ECharT>::type>
582{
583 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
584
585 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
586 static _ECharT const* __range_end(const _ECharT* __b)
587 {
588 using _Iter = const _ECharT*;
589 const _ECharT __sentinal = _ECharT{};
590 _Iter __e = __b;
591 for (; *__e != __sentinal; ++__e)
592 ;
593 return __e;
594 }
595
596 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
597};
598
599template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
600struct __is_pathable_iter : false_type {};
601
602template <class _Iter>
603struct __is_pathable_iter<_Iter, true,
604 _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
605 : __can_convert_char<typename iterator_traits<_Iter>::value_type>
606{
607 using _ECharT = typename iterator_traits<_Iter>::value_type;
608 using _Base = __can_convert_char<_ECharT>;
609
610 static _Iter __range_begin(_Iter __b) { return __b; }
611 static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
612
613 static _ECharT __first_or_null(_Iter __b) { return *__b; }
614};
615
616template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
617 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
618 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
619 >
620struct __is_pathable : false_type {
621 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
622};
623
624template <class _Tp>
625struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
626
627
628template <class _Tp>
629struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
630
631
632template <class _Tp>
633struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
634
635
636template <class _ECharT>
637struct _PathCVT {
638 static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
639
640 typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
641
642 static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) {
643 _Narrower()(back_inserter(__dest), __b, __e);
644 }
645
646 template <class _Iter>
647 static void __append_range(string& __dest, _Iter __b, _Iter __e) {
648 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
649 if (__b == __e) return;
650 basic_string<_ECharT> __tmp(__b, __e);
651 _Narrower()(back_inserter(__dest), __tmp.data(),
652 __tmp.data() + __tmp.length());
653 }
654
655 template <class _Iter>
656 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
657 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
658 const _ECharT __sentinal = _ECharT{};
659 if (*__b == __sentinal) return;
660 basic_string<_ECharT> __tmp;
661 for (; *__b != __sentinal; ++__b)
662 __tmp.push_back(*__b);
663 _Narrower()(back_inserter(__dest), __tmp.data(),
664 __tmp.data() + __tmp.length());
665 }
666
667 template <class _Source>
668 static void __append_source(string& __dest, _Source const& __s)
669 {
670 using _Traits = __is_pathable<_Source>;
671 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
672 }
673};
674
675template <>
676struct _PathCVT<char> {
Eric Fiselier70027d62016-10-30 23:53:50 +0000677
Eric Fiselier435db152016-06-17 19:46:40 +0000678 template <class _Iter>
Eric Fiselierdb7ee8f2016-10-31 02:46:25 +0000679 static typename enable_if<
680 __is_exactly_input_iterator<_Iter>::value
681 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
682 for (; __b != __e; ++__b)
683 __dest.push_back(*__b);
684 }
685
686 template <class _Iter>
687 static typename enable_if<
688 __is_forward_iterator<_Iter>::value
689 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
690 __dest.__append_forward_unsafe(__b, __e);
Eric Fiselier435db152016-06-17 19:46:40 +0000691 }
692
693 template <class _Iter>
694 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
695 const char __sentinal = char{};
696 for (; *__b != __sentinal; ++__b)
697 __dest.push_back(*__b);
698 }
699
700 template <class _Source>
701 static void __append_source(string& __dest, _Source const& __s)
702 {
703 using _Traits = __is_pathable<_Source>;
Eric Fiselier70027d62016-10-30 23:53:50 +0000704 __append_range(__dest, _Traits::__range_begin(__s),
705 _Traits::__range_end(__s));
Eric Fiselier435db152016-06-17 19:46:40 +0000706 }
707};
708
709
710class _LIBCPP_TYPE_VIS path
711{
712 template <class _SourceOrIter, class _Tp = path&>
713 using _EnableIfPathable = typename
714 enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
715
716 template <class _Tp>
717 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
718
719 template <class _Tp>
720 using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
721
722public:
723 typedef char value_type;
724 typedef basic_string<value_type> string_type;
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000725 typedef _VSTD::string_view __string_view;
Eric Fiselier435db152016-06-17 19:46:40 +0000726 static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
727
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000728 enum class _LIBCPP_ENUM_VIS format : unsigned char {
729 auto_format,
730 native_format,
731 generic_format
732 };
733
Eric Fiselier435db152016-06-17 19:46:40 +0000734 // constructors and destructor
735 _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
736 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
737 _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
738
739 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000740 path(string_type&& __s, format = format::auto_format) _NOEXCEPT
741 : __pn_(_VSTD::move(__s)) {}
Eric Fiselier435db152016-06-17 19:46:40 +0000742
743 template <
744 class _Source,
745 class = _EnableIfPathable<_Source, void>
746 >
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000747 path(const _Source& __src, format = format::auto_format) {
Eric Fiselier435db152016-06-17 19:46:40 +0000748 _SourceCVT<_Source>::__append_source(__pn_, __src);
749 }
750
751 template <class _InputIt>
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000752 path(_InputIt __first, _InputIt __last, format = format::auto_format) {
Eric Fiselier435db152016-06-17 19:46:40 +0000753 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
754 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
755 }
756
757 // TODO Implement locale conversions.
758 template <class _Source,
759 class = _EnableIfPathable<_Source, void>
760 >
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000761 path(const _Source& __src, const locale& __loc,
762 format = format::auto_format);
Eric Fiselier435db152016-06-17 19:46:40 +0000763 template <class _InputIt>
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000764 path(_InputIt __first, _InputIt _last, const locale& __loc,
765 format = format::auto_format);
Eric Fiselier435db152016-06-17 19:46:40 +0000766
767 _LIBCPP_INLINE_VISIBILITY
768 ~path() = default;
769
770 // assignments
771 _LIBCPP_INLINE_VISIBILITY
772 path& operator=(const path& __p) {
773 __pn_ = __p.__pn_;
774 return *this;
775 }
776
777 _LIBCPP_INLINE_VISIBILITY
778 path& operator=(path&& __p) _NOEXCEPT {
779 __pn_ = _VSTD::move(__p.__pn_);
780 return *this;
781 }
782
Eric Fiselier8beffc82017-01-18 05:48:55 +0000783 template <class = void>
Eric Fiselier435db152016-06-17 19:46:40 +0000784 _LIBCPP_INLINE_VISIBILITY
785 path& operator=(string_type&& __s) _NOEXCEPT {
786 __pn_ = _VSTD::move(__s);
787 return *this;
788 }
789
790 _LIBCPP_INLINE_VISIBILITY
791 path& assign(string_type&& __s) _NOEXCEPT {
792 __pn_ = _VSTD::move(__s);
793 return *this;
794 }
795
796 template <class _Source>
797 _LIBCPP_INLINE_VISIBILITY
798 _EnableIfPathable<_Source>
799 operator=(const _Source& __src)
800 { return this->assign(__src); }
801
802
803 template <class _Source>
804 _EnableIfPathable<_Source>
805 assign(const _Source& __src) {
806 __pn_.clear();
807 _SourceCVT<_Source>::__append_source(__pn_, __src);
808 return *this;
809 }
810
811 template <class _InputIt>
812 path& assign(_InputIt __first, _InputIt __last) {
813 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
814 __pn_.clear();
815 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
816 return *this;
817 }
818
819private:
820 template <class _ECharT>
Eric Fiselier91a182b2018-04-02 23:03:41 +0000821 static bool __source_is_absolute(_ECharT __first_or_null) {
822 return __is_separator(__first_or_null);
Eric Fiselier435db152016-06-17 19:46:40 +0000823 }
824
825public:
826 // appends
827 path& operator/=(const path& __p) {
Eric Fiselier91a182b2018-04-02 23:03:41 +0000828 if (__p.is_absolute()) {
829 __pn_ = __p.__pn_;
830 return *this;
831 }
832 if (has_filename())
833 __pn_ += preferred_separator;
Eric Fiselier435db152016-06-17 19:46:40 +0000834 __pn_ += __p.native();
835 return *this;
836 }
837
Eric Fiselier91a182b2018-04-02 23:03:41 +0000838 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
839 // is known at compile time to be "/' since the user almost certainly intended
840 // to append a separator instead of overwriting the path with "/"
Eric Fiselier435db152016-06-17 19:46:40 +0000841 template <class _Source>
842 _LIBCPP_INLINE_VISIBILITY
843 _EnableIfPathable<_Source>
844 operator/=(const _Source& __src) {
845 return this->append(__src);
846 }
847
848 template <class _Source>
849 _EnableIfPathable<_Source>
850 append(const _Source& __src) {
851 using _Traits = __is_pathable<_Source>;
852 using _CVT = _PathCVT<_SourceChar<_Source>>;
Eric Fiselier91a182b2018-04-02 23:03:41 +0000853 if (__source_is_absolute(_Traits::__first_or_null(__src)))
854 __pn_.clear();
855 else if (has_filename())
856 __pn_ += preferred_separator;
Eric Fiselier435db152016-06-17 19:46:40 +0000857 _CVT::__append_source(__pn_, __src);
858 return *this;
859 }
860
861 template <class _InputIt>
862 path& append(_InputIt __first, _InputIt __last) {
863 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
864 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
865 using _CVT = _PathCVT<_ItVal>;
Eric Fiselier91a182b2018-04-02 23:03:41 +0000866 if (__first != __last && __source_is_absolute(*__first))
867 __pn_.clear();
868 else if (has_filename())
869 __pn_ += preferred_separator;
870 _CVT::__append_range(__pn_, __first, __last);
Eric Fiselier435db152016-06-17 19:46:40 +0000871 return *this;
872 }
873
874 // concatenation
875 _LIBCPP_INLINE_VISIBILITY
876 path& operator+=(const path& __x) {
877 __pn_ += __x.__pn_;
878 return *this;
879 }
880
881 _LIBCPP_INLINE_VISIBILITY
882 path& operator+=(const string_type& __x) {
883 __pn_ += __x;
884 return *this;
885 }
886
887 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000888 path& operator+=(__string_view __x) {
889 __pn_ += __x;
890 return *this;
891 }
892
893 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000894 path& operator+=(const value_type* __x) {
895 __pn_ += __x;
896 return *this;
897 }
898
899 _LIBCPP_INLINE_VISIBILITY
900 path& operator+=(value_type __x) {
901 __pn_ += __x;
902 return *this;
903 }
904
Eric Fiselier435db152016-06-17 19:46:40 +0000905 template <class _ECharT>
906 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
907 operator+=(_ECharT __x)
908 {
909 basic_string<_ECharT> __tmp;
910 __tmp += __x;
911 _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
912 return *this;
913 }
914
915 template <class _Source>
916 _EnableIfPathable<_Source>
917 operator+=(const _Source& __x) {
918 return this->concat(__x);
919 }
920
921 template <class _Source>
922 _EnableIfPathable<_Source>
923 concat(const _Source& __x) {
924 _SourceCVT<_Source>::__append_source(__pn_, __x);
925 return *this;
926 }
927
928 template <class _InputIt>
929 path& concat(_InputIt __first, _InputIt __last) {
930 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
931 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
932 return *this;
933 }
934
935 // modifiers
936 _LIBCPP_INLINE_VISIBILITY
937 void clear() _NOEXCEPT {
938 __pn_.clear();
939 }
940
941 path& make_preferred() { return *this; }
Eric Fiselierf08063a2016-10-15 22:37:42 +0000942
943 _LIBCPP_INLINE_VISIBILITY
944 path& remove_filename() {
Eric Fiselier91a182b2018-04-02 23:03:41 +0000945 auto __fname = __filename();
946 if (!__fname.empty())
947 __pn_.erase(__fname.data() - __pn_.data());
Eric Fiselierf08063a2016-10-15 22:37:42 +0000948 return *this;
949 }
Eric Fiselier435db152016-06-17 19:46:40 +0000950
951 path& replace_filename(const path& __replacement) {
952 remove_filename();
953 return (*this /= __replacement);
954 }
955
956 path& replace_extension(const path& __replacement = path());
957
958 _LIBCPP_INLINE_VISIBILITY
959 void swap(path& __rhs) _NOEXCEPT {
960 __pn_.swap(__rhs.__pn_);
961 }
962
Eric Fiselier91a182b2018-04-02 23:03:41 +0000963 // private helper to allow reserving memory in the path
964 _LIBCPP_INLINE_VISIBILITY
965 void __reserve(size_t __s) { __pn_.reserve(__s); }
966
Eric Fiselier435db152016-06-17 19:46:40 +0000967 // native format observers
968 _LIBCPP_INLINE_VISIBILITY
969 const string_type& native() const _NOEXCEPT {
970 return __pn_;
971 }
972
973 _LIBCPP_INLINE_VISIBILITY
974 const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
975
976 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
977
978 template <class _ECharT, class _Traits = char_traits<_ECharT>,
979 class _Allocator = allocator<_ECharT> >
980 basic_string<_ECharT, _Traits, _Allocator>
981 string(const _Allocator& __a = _Allocator()) const {
982 using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
983 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
984 _Str __s(__a);
985 __s.reserve(__pn_.size());
986 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
987 return __s;
988 }
989
990 _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
991 _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); }
992 _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
993 _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
994 _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
995
996 // generic format observers
997 template <class _ECharT, class _Traits = char_traits<_ECharT>,
998 class _Allocator = allocator<_ECharT>
999 >
1000 basic_string<_ECharT, _Traits, _Allocator>
1001 generic_string(const _Allocator& __a = _Allocator()) const {
1002 return string<_ECharT, _Traits, _Allocator>(__a);
1003 }
1004
1005 std::string generic_string() const { return __pn_; }
1006 std::wstring generic_wstring() const { return string<wchar_t>(); }
1007 std::string generic_u8string() const { return __pn_; }
1008 std::u16string generic_u16string() const { return string<char16_t>(); }
1009 std::u32string generic_u32string() const { return string<char32_t>(); }
1010
1011private:
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001012 int __compare(__string_view) const;
1013 __string_view __root_name() const;
1014 __string_view __root_directory() const;
1015 __string_view __root_path_raw() const;
1016 __string_view __relative_path() const;
1017 __string_view __parent_path() const;
1018 __string_view __filename() const;
1019 __string_view __stem() const;
1020 __string_view __extension() const;
Eric Fiselier435db152016-06-17 19:46:40 +00001021
1022public:
1023 // compare
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001024 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);}
1025 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); }
1026 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); }
Eric Fiselier435db152016-06-17 19:46:40 +00001027 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
1028
1029 // decomposition
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001030 _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); }
1031 _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); }
1032 _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); }
1033 _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); }
1034 _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); }
1035 _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); }
1036 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());}
1037 _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); }
Eric Fiselier435db152016-06-17 19:46:40 +00001038
1039 // query
Eric Fiselier23a120c2018-07-25 03:31:48 +00001040 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Marshall Clow8c5edfe2017-11-16 05:48:32 +00001041 bool empty() const _NOEXCEPT { return __pn_.empty(); }
Eric Fiselier435db152016-06-17 19:46:40 +00001042
1043 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); }
1044 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
Eric Fiselierf08063a2016-10-15 22:37:42 +00001045 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); }
Eric Fiselier435db152016-06-17 19:46:40 +00001046 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); }
1047 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); }
1048 _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); }
1049 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1050 _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); }
1051
1052 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
1053 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1054
Eric Fiselier91a182b2018-04-02 23:03:41 +00001055 // relative paths
1056 path lexically_normal() const;
1057 path lexically_relative(const path& __base) const;
1058
1059 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1060 path __result = this->lexically_relative(__base);
1061 if (__result.native().empty())
1062 return *this;
1063 return __result;
1064 }
1065
Eric Fiselier435db152016-06-17 19:46:40 +00001066 // iterators
1067 class _LIBCPP_TYPE_VIS iterator;
1068 typedef iterator const_iterator;
1069
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001070 iterator begin() const;
1071 iterator end() const;
Eric Fiselier435db152016-06-17 19:46:40 +00001072
Eric Fiselier2cd75272018-02-04 03:10:53 +00001073
1074 template <class _CharT, class _Traits>
1075 _LIBCPP_INLINE_VISIBILITY
1076 friend typename enable_if<is_same<_CharT, char>::value &&
1077 is_same<_Traits, char_traits<char>>::value,
1078 basic_ostream<_CharT, _Traits>&
1079 >::type
1080 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1081 __os << std::__quoted(__p.native());
1082 return __os;
1083 }
1084
1085 template <class _CharT, class _Traits>
1086 _LIBCPP_INLINE_VISIBILITY
1087 friend typename enable_if<!is_same<_CharT, char>::value ||
1088 !is_same<_Traits, char_traits<char>>::value,
1089 basic_ostream<_CharT, _Traits>&
1090 >::type
1091 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1092 __os << std::__quoted(__p.string<_CharT, _Traits>());
1093 return __os;
1094 }
1095
1096 template <class _CharT, class _Traits>
1097 _LIBCPP_INLINE_VISIBILITY
1098 friend basic_istream<_CharT, _Traits>&
1099 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
1100 {
1101 basic_string<_CharT, _Traits> __tmp;
1102 __is >> __quoted(__tmp);
1103 __p = __tmp;
1104 return __is;
1105 }
1106
Eric Fiselier435db152016-06-17 19:46:40 +00001107private:
1108 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001109 path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; }
Eric Fiselier435db152016-06-17 19:46:40 +00001110 string_type __pn_;
1111};
1112
Louis Dionne16fe2952018-07-11 23:14:33 +00001113inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001114void swap(path& __lhs, path& __rhs) _NOEXCEPT {
1115 __lhs.swap(__rhs);
1116}
1117
1118_LIBCPP_FUNC_VIS
1119size_t hash_value(const path& __p) _NOEXCEPT;
1120
1121inline _LIBCPP_INLINE_VISIBILITY
1122bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
1123{ return __lhs.compare(__rhs) == 0; }
1124
1125inline _LIBCPP_INLINE_VISIBILITY
1126bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
1127{ return __lhs.compare(__rhs) != 0; }
1128
1129inline _LIBCPP_INLINE_VISIBILITY
1130bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
1131{ return __lhs.compare(__rhs) < 0; }
1132
1133inline _LIBCPP_INLINE_VISIBILITY
1134bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
1135{ return __lhs.compare(__rhs) <= 0; }
1136
1137inline _LIBCPP_INLINE_VISIBILITY
1138bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
1139{ return __lhs.compare(__rhs) > 0; }
1140
1141inline _LIBCPP_INLINE_VISIBILITY
1142bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
1143{ return __lhs.compare(__rhs) >= 0; }
1144
1145inline _LIBCPP_INLINE_VISIBILITY
1146path operator/(const path& __lhs, const path& __rhs) {
David Bolvansky38b37ef2018-05-09 18:57:17 +00001147 path __result(__lhs);
1148 __result /= __rhs;
1149 return __result;
Eric Fiselier435db152016-06-17 19:46:40 +00001150}
1151
Eric Fiselier435db152016-06-17 19:46:40 +00001152template <class _Source>
1153_LIBCPP_INLINE_VISIBILITY
1154typename enable_if<__is_pathable<_Source>::value, path>::type
1155u8path(const _Source& __s){
1156 static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1157 "u8path(Source const&) requires Source have a character type of type 'char'");
1158 return path(__s);
1159}
1160
1161template <class _InputIt>
1162_LIBCPP_INLINE_VISIBILITY
1163typename enable_if<__is_pathable<_InputIt>::value, path>::type
1164u8path(_InputIt __f, _InputIt __l) {
1165 static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1166 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
1167 return path(__f, __l);
1168}
1169
1170class _LIBCPP_TYPE_VIS path::iterator
1171{
1172public:
Eric Fiselier23a120c2018-07-25 03:31:48 +00001173 enum _ParserState : unsigned char {
1174 _Singular,
1175 _BeforeBegin,
1176 _InRootName,
1177 _InRootDir,
1178 _InFilenames,
1179 _InTrailingSep,
1180 _AtEnd
1181 };
1182
1183public:
Eric Fiselier435db152016-06-17 19:46:40 +00001184 typedef bidirectional_iterator_tag iterator_category;
Eric Fiselierc8dac982017-04-04 01:05:59 +00001185
Eric Fiselier435db152016-06-17 19:46:40 +00001186 typedef path value_type;
1187 typedef std::ptrdiff_t difference_type;
1188 typedef const path* pointer;
1189 typedef const path& reference;
Eric Fiselier883af112017-04-13 02:54:13 +00001190
1191 typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
Eric Fiselier23a120c2018-07-25 03:31:48 +00001192
Eric Fiselier435db152016-06-17 19:46:40 +00001193public:
1194 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfc46d252016-10-30 23:30:38 +00001195 iterator() : __stashed_elem_(), __path_ptr_(nullptr),
Eric Fiselier23a120c2018-07-25 03:31:48 +00001196 __entry_(), __state_(_Singular) {}
Eric Fiselier435db152016-06-17 19:46:40 +00001197
1198 iterator(const iterator&) = default;
1199 ~iterator() = default;
1200
1201 iterator& operator=(const iterator&) = default;
1202
1203 _LIBCPP_INLINE_VISIBILITY
1204 reference operator*() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001205 return __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001206 }
1207
1208 _LIBCPP_INLINE_VISIBILITY
1209 pointer operator->() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001210 return &__stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001211 }
1212
1213 _LIBCPP_INLINE_VISIBILITY
1214 iterator& operator++() {
Eric Fiselier23a120c2018-07-25 03:31:48 +00001215 _LIBCPP_ASSERT(__state_ != _Singular,
Eric Fiselierfc46d252016-10-30 23:30:38 +00001216 "attempting to increment a singular iterator");
Eric Fiselier23a120c2018-07-25 03:31:48 +00001217 _LIBCPP_ASSERT(__state_ != _AtEnd,
Eric Fiselierfc46d252016-10-30 23:30:38 +00001218 "attempting to increment the end iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001219 return __increment();
1220 }
1221
1222 _LIBCPP_INLINE_VISIBILITY
1223 iterator operator++(int) {
1224 iterator __it(*this);
1225 this->operator++();
1226 return __it;
1227 }
1228
1229 _LIBCPP_INLINE_VISIBILITY
1230 iterator& operator--() {
Eric Fiselier23a120c2018-07-25 03:31:48 +00001231 _LIBCPP_ASSERT(__state_ != _Singular,
Eric Fiselierfc46d252016-10-30 23:30:38 +00001232 "attempting to decrement a singular iterator");
1233 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1234 "attempting to decrement the begin iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001235 return __decrement();
1236 }
1237
1238 _LIBCPP_INLINE_VISIBILITY
1239 iterator operator--(int) {
1240 iterator __it(*this);
1241 this->operator--();
1242 return __it;
1243 }
1244
1245private:
1246 friend class path;
Eric Fiselier28175a32016-09-16 00:07:16 +00001247
1248 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001249 friend bool operator==(const iterator&, const iterator&);
1250
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001251 iterator& __increment();
1252 iterator& __decrement();
Eric Fiselier435db152016-06-17 19:46:40 +00001253
Eric Fiselierfc46d252016-10-30 23:30:38 +00001254 path __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001255 const path* __path_ptr_;
Eric Fiselierfc46d252016-10-30 23:30:38 +00001256 path::__string_view __entry_;
Eric Fiselier23a120c2018-07-25 03:31:48 +00001257 _ParserState __state_;
Eric Fiselier435db152016-06-17 19:46:40 +00001258};
1259
1260inline _LIBCPP_INLINE_VISIBILITY
1261bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
1262 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
Eric Fiselierfc46d252016-10-30 23:30:38 +00001263 __lhs.__entry_.data() == __rhs.__entry_.data();
Eric Fiselier435db152016-06-17 19:46:40 +00001264}
1265
1266inline _LIBCPP_INLINE_VISIBILITY
1267bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1268 return !(__lhs == __rhs);
1269}
1270
1271class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
1272{
1273public:
1274 _LIBCPP_INLINE_VISIBILITY
1275 filesystem_error(const string& __what, error_code __ec)
1276 : system_error(__ec, __what),
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001277 __storage_(make_shared<_Storage>(path(), path())) {
1278 __create_what(0);
1279 }
Eric Fiselier435db152016-06-17 19:46:40 +00001280
1281 _LIBCPP_INLINE_VISIBILITY
1282 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1283 : system_error(__ec, __what),
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001284 __storage_(make_shared<_Storage>(__p1, path())) {
1285 __create_what(1);
1286 }
Eric Fiselier435db152016-06-17 19:46:40 +00001287
1288 _LIBCPP_INLINE_VISIBILITY
1289 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1290 error_code __ec)
1291 : system_error(__ec, __what),
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001292 __storage_(make_shared<_Storage>(__p1, __p2)) {
1293 __create_what(2);
Eric Fiselier435db152016-06-17 19:46:40 +00001294 }
1295
1296 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001297 const path& path1() const _NOEXCEPT { return __storage_->__p1_; }
1298
1299 _LIBCPP_INLINE_VISIBILITY
1300 const path& path2() const _NOEXCEPT { return __storage_->__p2_; }
Eric Fiselier435db152016-06-17 19:46:40 +00001301
Eric Fiselier435db152016-06-17 19:46:40 +00001302 ~filesystem_error() override; // key function
1303
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001304 _LIBCPP_INLINE_VISIBILITY
1305 const char* what() const _NOEXCEPT override {
1306 return __storage_->__what_.c_str();
1307 }
Eric Fiselier435db152016-06-17 19:46:40 +00001308
Eric Fiseliera75bbde2018-07-23 02:00:52 +00001309 _LIBCPP_FUNC_VIS
1310 void __create_what(int __num_paths);
1311
1312 private:
1313 struct _Storage {
1314 _LIBCPP_INLINE_VISIBILITY
1315 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1316
1317 path __p1_;
1318 path __p2_;
1319 string __what_;
1320 };
1321 shared_ptr<_Storage> __storage_;
Eric Fiselier435db152016-06-17 19:46:40 +00001322};
1323
Marshall Clowed3e2292016-08-25 17:47:09 +00001324template <class... _Args>
Louis Dionne16fe2952018-07-11 23:14:33 +00001325_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001326#ifndef _LIBCPP_NO_EXCEPTIONS
Marshall Clowed3e2292016-08-25 17:47:09 +00001327void __throw_filesystem_error(_Args && ...__args)
1328{
Marshall Clowed3e2292016-08-25 17:47:09 +00001329 throw filesystem_error(std::forward<_Args>(__args)...);
Marshall Clowed3e2292016-08-25 17:47:09 +00001330}
Eric Fiselier6003c772016-12-23 23:37:52 +00001331#else
1332void __throw_filesystem_error(_Args&&...)
1333{
1334 _VSTD::abort();
1335}
1336#endif
1337
Eric Fiselier435db152016-06-17 19:46:40 +00001338// operational functions
1339
1340_LIBCPP_FUNC_VIS
Eric Fiselier91a182b2018-04-02 23:03:41 +00001341path __absolute(const path&, error_code *__ec=nullptr);
1342_LIBCPP_FUNC_VIS
1343path __canonical(const path&, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001344_LIBCPP_FUNC_VIS
1345void __copy(const path& __from, const path& __to, copy_options __opt,
1346 error_code *__ec=nullptr);
1347_LIBCPP_FUNC_VIS
1348bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1349 error_code *__ec=nullptr);
1350_LIBCPP_FUNC_VIS
1351void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1352 error_code *__ec=nullptr);
1353_LIBCPP_FUNC_VIS
1354bool __create_directories(const path& p, error_code *ec=nullptr);
1355_LIBCPP_FUNC_VIS
1356bool __create_directory(const path& p, error_code *ec=nullptr);
1357_LIBCPP_FUNC_VIS
1358bool __create_directory(const path& p, const path & attributes,
1359 error_code *ec=nullptr);
1360_LIBCPP_FUNC_VIS
1361void __create_directory_symlink(const path& __to, const path& __new_symlink,
1362 error_code *__ec=nullptr);
1363_LIBCPP_FUNC_VIS
1364void __create_hard_link(const path& __to, const path& __new_hard_link,
1365 error_code *__ec=nullptr);
1366_LIBCPP_FUNC_VIS
1367void __create_symlink(const path& __to, const path& __new_symlink,
1368 error_code *__ec=nullptr);
1369_LIBCPP_FUNC_VIS
1370path __current_path(error_code *__ec=nullptr);
1371_LIBCPP_FUNC_VIS
1372void __current_path(const path&, error_code *__ec=nullptr);
1373_LIBCPP_FUNC_VIS
1374bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
1375_LIBCPP_FUNC_VIS
1376uintmax_t __file_size(const path&, error_code *__ec=nullptr);
1377_LIBCPP_FUNC_VIS
1378uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
1379_LIBCPP_FUNC_VIS
1380bool __fs_is_empty(const path& p, error_code *ec=nullptr);
1381_LIBCPP_FUNC_VIS
1382file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
1383_LIBCPP_FUNC_VIS
1384void __last_write_time(const path& p, file_time_type new_time,
1385 error_code *ec=nullptr);
1386_LIBCPP_FUNC_VIS
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001387void __permissions(const path&, perms, perm_options, error_code* = nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001388_LIBCPP_FUNC_VIS
1389path __read_symlink(const path& p, error_code *ec=nullptr);
1390_LIBCPP_FUNC_VIS
1391bool __remove(const path& p, error_code *ec=nullptr);
1392_LIBCPP_FUNC_VIS
1393uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
1394_LIBCPP_FUNC_VIS
1395void __rename(const path& from, const path& to, error_code *ec=nullptr);
1396_LIBCPP_FUNC_VIS
1397void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
1398_LIBCPP_FUNC_VIS
1399space_info __space(const path&, error_code *__ec=nullptr);
1400_LIBCPP_FUNC_VIS
1401file_status __status(const path&, error_code *__ec=nullptr);
1402_LIBCPP_FUNC_VIS
1403file_status __symlink_status(const path&, error_code *__ec=nullptr);
1404_LIBCPP_FUNC_VIS
1405path __system_complete(const path&, error_code *__ec=nullptr);
1406_LIBCPP_FUNC_VIS
1407path __temp_directory_path(error_code *__ec=nullptr);
Eric Fiselier91a182b2018-04-02 23:03:41 +00001408_LIBCPP_FUNC_VIS
1409path __weakly_canonical(path const& __p, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001410
1411inline _LIBCPP_INLINE_VISIBILITY
1412path current_path() {
1413 return __current_path();
1414}
1415
1416inline _LIBCPP_INLINE_VISIBILITY
1417path current_path(error_code& __ec) {
1418 return __current_path(&__ec);
1419}
1420
1421inline _LIBCPP_INLINE_VISIBILITY
1422void current_path(const path& __p) {
1423 __current_path(__p);
1424}
1425
1426inline _LIBCPP_INLINE_VISIBILITY
1427void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
1428 __current_path(__p, &__ec);
1429}
1430
Eric Fiselier91a182b2018-04-02 23:03:41 +00001431inline _LIBCPP_INLINE_VISIBILITY
1432path absolute(const path& __p) {
1433 return __absolute(__p);
1434}
Eric Fiselier435db152016-06-17 19:46:40 +00001435
1436inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001437path absolute(const path& __p, error_code &__ec) {
1438 return __absolute(__p, &__ec);
1439}
1440
1441inline _LIBCPP_INLINE_VISIBILITY
1442path canonical(const path& __p) {
1443 return __canonical(__p);
Eric Fiselier435db152016-06-17 19:46:40 +00001444}
1445
1446inline _LIBCPP_INLINE_VISIBILITY
1447path canonical(const path& __p, error_code& __ec) {
Eric Fiselier91a182b2018-04-02 23:03:41 +00001448 return __canonical(__p, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001449}
1450
1451inline _LIBCPP_INLINE_VISIBILITY
1452void copy(const path& __from, const path& __to) {
1453 __copy(__from, __to, copy_options::none);
1454}
1455
1456inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001457void copy(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001458 __copy(__from, __to, copy_options::none, &__ec);
1459}
1460
1461inline _LIBCPP_INLINE_VISIBILITY
1462void copy(const path& __from, const path& __to, copy_options __opt) {
1463 __copy(__from, __to, __opt);
1464}
1465
1466inline _LIBCPP_INLINE_VISIBILITY
1467void copy(const path& __from, const path& __to,
Eric Fiselierd56d5322017-10-30 18:59:59 +00001468 copy_options __opt, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001469 __copy(__from, __to, __opt, &__ec);
1470}
1471
1472inline _LIBCPP_INLINE_VISIBILITY
1473bool copy_file(const path& __from, const path& __to) {
1474 return __copy_file(__from, __to, copy_options::none);
1475}
1476
1477inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001478bool copy_file(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001479 return __copy_file(__from, __to, copy_options::none, &__ec);
1480}
1481
1482inline _LIBCPP_INLINE_VISIBILITY
1483bool copy_file(const path& __from, const path& __to, copy_options __opt) {
1484 return __copy_file(__from, __to, __opt);
1485}
1486
1487inline _LIBCPP_INLINE_VISIBILITY
1488bool copy_file(const path& __from, const path& __to,
Eric Fiseliere1164812018-02-04 07:35:36 +00001489 copy_options __opt, error_code& __ec){
Eric Fiselier435db152016-06-17 19:46:40 +00001490 return __copy_file(__from, __to, __opt, &__ec);
1491}
1492
1493inline _LIBCPP_INLINE_VISIBILITY
1494void copy_symlink(const path& __existing, const path& __new) {
1495 __copy_symlink(__existing, __new);
1496}
1497
1498inline _LIBCPP_INLINE_VISIBILITY
1499void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
1500 __copy_symlink(__ext, __new, &__ec);
1501}
1502
1503inline _LIBCPP_INLINE_VISIBILITY
1504bool create_directories(const path& __p) {
1505 return __create_directories(__p);
1506}
1507
1508inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001509bool create_directories(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001510 return __create_directories(__p, &__ec);
1511}
1512
1513inline _LIBCPP_INLINE_VISIBILITY
1514bool create_directory(const path& __p) {
1515 return __create_directory(__p);
1516}
1517
1518inline _LIBCPP_INLINE_VISIBILITY
1519bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1520 return __create_directory(__p, &__ec);
1521}
1522
1523inline _LIBCPP_INLINE_VISIBILITY
1524bool create_directory(const path& __p, const path& __attrs) {
1525 return __create_directory(__p, __attrs);
1526}
1527
1528inline _LIBCPP_INLINE_VISIBILITY
1529bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
1530 return __create_directory(__p, __attrs, &__ec);
1531}
1532
1533inline _LIBCPP_INLINE_VISIBILITY
1534void create_directory_symlink(const path& __to, const path& __new) {
1535 __create_directory_symlink(__to, __new);
1536}
1537
1538inline _LIBCPP_INLINE_VISIBILITY
1539void create_directory_symlink(const path& __to, const path& __new,
1540 error_code& __ec) _NOEXCEPT {
1541 __create_directory_symlink(__to, __new, &__ec);
1542}
1543
1544inline _LIBCPP_INLINE_VISIBILITY
1545void create_hard_link(const path& __to, const path& __new) {
1546 __create_hard_link(__to, __new);
1547}
1548
1549inline _LIBCPP_INLINE_VISIBILITY
1550void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1551 __create_hard_link(__to, __new, &__ec);
1552}
1553
1554inline _LIBCPP_INLINE_VISIBILITY
1555void create_symlink(const path& __to, const path& __new) {
1556 __create_symlink(__to, __new);
1557}
1558
1559inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001560void create_symlink(const path& __to, const path& __new,
1561 error_code& __ec) _NOEXCEPT {
Eric Fiselier435db152016-06-17 19:46:40 +00001562 return __create_symlink(__to, __new, &__ec);
1563}
1564
1565inline _LIBCPP_INLINE_VISIBILITY
1566bool status_known(file_status __s) _NOEXCEPT {
1567 return __s.type() != file_type::none;
1568}
1569
1570inline _LIBCPP_INLINE_VISIBILITY
1571bool exists(file_status __s) _NOEXCEPT {
1572 return status_known(__s) && __s.type() != file_type::not_found;
1573}
1574
1575inline _LIBCPP_INLINE_VISIBILITY
1576bool exists(const path& __p) {
1577 return exists(__status(__p));
1578}
1579
1580inline _LIBCPP_INLINE_VISIBILITY
1581bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
Eric Fiselier0a367d22016-06-21 22:11:16 +00001582 auto __s = __status(__p, &__ec);
1583 if (status_known(__s)) __ec.clear();
1584 return exists(__s);
Eric Fiselier435db152016-06-17 19:46:40 +00001585}
1586
1587inline _LIBCPP_INLINE_VISIBILITY
1588bool equivalent(const path& __p1, const path& __p2) {
1589 return __equivalent(__p1, __p2);
1590}
1591
1592inline _LIBCPP_INLINE_VISIBILITY
1593bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
1594 return __equivalent(__p1, __p2, &__ec);
1595}
1596
1597inline _LIBCPP_INLINE_VISIBILITY
1598uintmax_t file_size(const path& __p) {
1599 return __file_size(__p);
1600}
1601
1602inline _LIBCPP_INLINE_VISIBILITY
1603uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
1604 return __file_size(__p, &__ec);
1605}
1606
1607inline _LIBCPP_INLINE_VISIBILITY
1608uintmax_t hard_link_count(const path& __p) {
1609 return __hard_link_count(__p);
1610}
1611
1612inline _LIBCPP_INLINE_VISIBILITY
1613uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
1614 return __hard_link_count(__p, &__ec);
1615}
1616
1617inline _LIBCPP_INLINE_VISIBILITY
1618bool is_block_file(file_status __s) _NOEXCEPT {
1619 return __s.type() == file_type::block;
1620}
1621
1622inline _LIBCPP_INLINE_VISIBILITY
1623bool is_block_file(const path& __p) {
1624 return is_block_file(__status(__p));
1625}
1626
1627inline _LIBCPP_INLINE_VISIBILITY
1628bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
1629 return is_block_file(__status(__p, &__ec));
1630}
1631
1632inline _LIBCPP_INLINE_VISIBILITY
1633bool is_character_file(file_status __s) _NOEXCEPT {
1634 return __s.type() == file_type::character;
1635}
1636
1637inline _LIBCPP_INLINE_VISIBILITY
1638bool is_character_file(const path& __p) {
1639 return is_character_file(__status(__p));
1640}
1641
1642inline _LIBCPP_INLINE_VISIBILITY
1643bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
1644 return is_character_file(__status(__p, &__ec));
1645}
1646
1647inline _LIBCPP_INLINE_VISIBILITY
1648bool is_directory(file_status __s) _NOEXCEPT {
1649 return __s.type() == file_type::directory;
1650}
1651
1652inline _LIBCPP_INLINE_VISIBILITY
1653bool is_directory(const path& __p) {
1654 return is_directory(__status(__p));
1655}
1656
1657inline _LIBCPP_INLINE_VISIBILITY
1658bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1659 return is_directory(__status(__p, &__ec));
1660}
1661
1662inline _LIBCPP_INLINE_VISIBILITY
1663bool is_empty(const path& __p) {
1664 return __fs_is_empty(__p);
1665}
1666
1667inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001668bool is_empty(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001669 return __fs_is_empty(__p, &__ec);
1670}
1671
1672inline _LIBCPP_INLINE_VISIBILITY
1673bool is_fifo(file_status __s) _NOEXCEPT {
1674 return __s.type() == file_type::fifo;
1675}
1676inline _LIBCPP_INLINE_VISIBILITY
1677bool is_fifo(const path& __p) {
1678 return is_fifo(__status(__p));
1679}
1680
1681inline _LIBCPP_INLINE_VISIBILITY
1682bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
1683 return is_fifo(__status(__p, &__ec));
1684}
1685
1686inline _LIBCPP_INLINE_VISIBILITY
1687bool is_regular_file(file_status __s) _NOEXCEPT {
1688 return __s.type() == file_type::regular;
1689}
1690
1691inline _LIBCPP_INLINE_VISIBILITY
1692bool is_regular_file(const path& __p) {
1693 return is_regular_file(__status(__p));
1694}
1695
1696inline _LIBCPP_INLINE_VISIBILITY
1697bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
1698 return is_regular_file(__status(__p, &__ec));
1699}
1700
1701inline _LIBCPP_INLINE_VISIBILITY
1702bool is_socket(file_status __s) _NOEXCEPT {
1703 return __s.type() == file_type::socket;
1704}
1705
1706inline _LIBCPP_INLINE_VISIBILITY
1707bool is_socket(const path& __p) {
1708 return is_socket(__status(__p));
1709}
1710
1711inline _LIBCPP_INLINE_VISIBILITY
1712bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
1713 return is_socket(__status(__p, &__ec));
1714}
1715
1716inline _LIBCPP_INLINE_VISIBILITY
1717bool is_symlink(file_status __s) _NOEXCEPT {
1718 return __s.type() == file_type::symlink;
1719}
1720
1721inline _LIBCPP_INLINE_VISIBILITY
1722bool is_symlink(const path& __p) {
1723 return is_symlink(__symlink_status(__p));
1724}
1725
1726inline _LIBCPP_INLINE_VISIBILITY
1727bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
1728 return is_symlink(__symlink_status(__p, &__ec));
1729}
1730
1731inline _LIBCPP_INLINE_VISIBILITY
1732bool is_other(file_status __s) _NOEXCEPT {
1733 return exists(__s)
1734 && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
1735}
1736
1737inline _LIBCPP_INLINE_VISIBILITY
1738bool is_other(const path& __p) {
1739 return is_other(__status(__p));
1740}
1741
1742inline _LIBCPP_INLINE_VISIBILITY
1743bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
1744 return is_other(__status(__p, &__ec));
1745}
1746
1747inline _LIBCPP_INLINE_VISIBILITY
1748file_time_type last_write_time(const path& __p) {
1749 return __last_write_time(__p);
1750}
1751
1752inline _LIBCPP_INLINE_VISIBILITY
1753file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
1754 return __last_write_time(__p, &__ec);
1755}
1756
1757inline _LIBCPP_INLINE_VISIBILITY
1758void last_write_time(const path& __p, file_time_type __t) {
1759 __last_write_time(__p, __t);
1760}
1761
1762inline _LIBCPP_INLINE_VISIBILITY
1763void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
1764 __last_write_time(__p, __t, &__ec);
1765}
1766
1767inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001768void permissions(const path& __p, perms __prms,
1769 perm_options __opts = perm_options::replace) {
1770 __permissions(__p, __prms, __opts);
Eric Fiselier435db152016-06-17 19:46:40 +00001771}
1772
1773inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001774void permissions(const path& __p, perms __prms, error_code& __ec) _NOEXCEPT {
1775 __permissions(__p, __prms, perm_options::replace, &__ec);
1776}
1777
1778inline _LIBCPP_INLINE_VISIBILITY
1779void permissions(const path& __p, perms __prms, perm_options __opts,
1780 error_code& __ec) {
1781 __permissions(__p, __prms, __opts, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001782}
1783
1784inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001785path proximate(const path& __p, const path& __base, error_code& __ec) {
1786 path __tmp = __weakly_canonical(__p, &__ec);
1787 if (__ec)
1788 return {};
1789 path __tmp_base = __weakly_canonical(__base, &__ec);
1790 if (__ec)
1791 return {};
1792 return __tmp.lexically_proximate(__tmp_base);
1793}
1794
1795inline _LIBCPP_INLINE_VISIBILITY
1796path proximate(const path& __p, error_code& __ec) {
1797 return proximate(__p, current_path(), __ec);
1798}
1799
1800inline _LIBCPP_INLINE_VISIBILITY
1801path proximate(const path& __p, const path& __base = current_path()) {
1802 return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
1803}
1804
1805inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001806path read_symlink(const path& __p) {
1807 return __read_symlink(__p);
1808}
1809
1810inline _LIBCPP_INLINE_VISIBILITY
1811path read_symlink(const path& __p, error_code& __ec) {
1812 return __read_symlink(__p, &__ec);
1813}
1814
Eric Fiselier91a182b2018-04-02 23:03:41 +00001815
1816inline _LIBCPP_INLINE_VISIBILITY
1817path relative(const path& __p, const path& __base, error_code& __ec) {
1818 path __tmp = __weakly_canonical(__p, &__ec);
1819 if (__ec)
1820 return path();
1821 path __tmpbase = __weakly_canonical(__base, &__ec);
1822 if (__ec)
1823 return path();
1824 return __tmp.lexically_relative(__tmpbase);
1825}
1826
1827inline _LIBCPP_INLINE_VISIBILITY
1828path relative(const path& __p, error_code& __ec) {
1829 return relative(__p, current_path(), __ec);
1830}
1831
1832inline _LIBCPP_INLINE_VISIBILITY
1833path relative(const path& __p, const path& __base=current_path()) {
1834 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
1835}
1836
1837
Eric Fiselier435db152016-06-17 19:46:40 +00001838inline _LIBCPP_INLINE_VISIBILITY
1839bool remove(const path& __p) {
1840 return __remove(__p);
1841}
1842
1843inline _LIBCPP_INLINE_VISIBILITY
1844bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
1845 return __remove(__p, &__ec);
1846}
1847
1848inline _LIBCPP_INLINE_VISIBILITY
1849uintmax_t remove_all(const path& __p) {
1850 return __remove_all(__p);
1851}
1852
1853inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001854uintmax_t remove_all(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001855 return __remove_all(__p, &__ec);
1856}
1857
1858inline _LIBCPP_INLINE_VISIBILITY
1859void rename(const path& __from, const path& __to) {
1860 return __rename(__from, __to);
1861}
1862
1863inline _LIBCPP_INLINE_VISIBILITY
1864void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1865 return __rename(__from, __to, &__ec);
1866}
1867
1868inline _LIBCPP_INLINE_VISIBILITY
1869void resize_file(const path& __p, uintmax_t __ns) {
1870 return __resize_file(__p, __ns);
1871}
1872
1873inline _LIBCPP_INLINE_VISIBILITY
1874void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
1875 return __resize_file(__p, __ns, &__ec);
1876}
1877
1878inline _LIBCPP_INLINE_VISIBILITY
1879space_info space(const path& __p) {
1880 return __space(__p);
1881}
1882
1883inline _LIBCPP_INLINE_VISIBILITY
1884space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
1885 return __space(__p, &__ec);
1886}
1887
1888inline _LIBCPP_INLINE_VISIBILITY
1889file_status status(const path& __p) {
1890 return __status(__p);
1891}
1892
1893inline _LIBCPP_INLINE_VISIBILITY
1894file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
1895 return __status(__p, &__ec);
1896}
1897
1898inline _LIBCPP_INLINE_VISIBILITY
1899file_status symlink_status(const path& __p) {
1900 return __symlink_status(__p);
1901}
1902
1903inline _LIBCPP_INLINE_VISIBILITY
1904file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
1905 return __symlink_status(__p, &__ec);
1906}
1907
1908inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001909path temp_directory_path() {
1910 return __temp_directory_path();
1911}
1912
1913inline _LIBCPP_INLINE_VISIBILITY
1914path temp_directory_path(error_code& __ec) {
1915 return __temp_directory_path(&__ec);
1916}
1917
Eric Fiselier91a182b2018-04-02 23:03:41 +00001918inline _LIBCPP_INLINE_VISIBILITY
1919path weakly_canonical(path const& __p) {
1920 return __weakly_canonical(__p);
1921}
1922
1923inline _LIBCPP_INLINE_VISIBILITY
1924path weakly_canonical(path const& __p, error_code& __ec) {
1925 return __weakly_canonical(__p, &__ec);
1926}
1927
Eric Fiselier435db152016-06-17 19:46:40 +00001928
Eric Fiselier70474082018-07-20 01:22:32 +00001929class directory_iterator;
1930class recursive_directory_iterator;
1931class __dir_stream;
1932
Eric Fiselier435db152016-06-17 19:46:40 +00001933class directory_entry
1934{
1935 typedef _VSTD_FS::path _Path;
1936
1937public:
1938 // constructors and destructors
1939 directory_entry() _NOEXCEPT = default;
1940 directory_entry(directory_entry const&) = default;
1941 directory_entry(directory_entry&&) _NOEXCEPT = default;
1942
1943 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001944 explicit directory_entry(_Path const& __p) : __p_(__p) {
1945 error_code __ec;
1946 __refresh(&__ec);
1947 }
1948
1949 _LIBCPP_INLINE_VISIBILITY
1950 directory_entry(_Path const& __p, error_code &__ec) : __p_(__p) {
1951 __refresh(&__ec);
1952 }
Eric Fiselier435db152016-06-17 19:46:40 +00001953
1954 ~directory_entry() {}
1955
1956 directory_entry& operator=(directory_entry const&) = default;
1957 directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
1958
1959 _LIBCPP_INLINE_VISIBILITY
1960 void assign(_Path const& __p) {
1961 __p_ = __p;
Eric Fiselier70474082018-07-20 01:22:32 +00001962 error_code __ec;
1963 __refresh(&__ec);
1964 }
1965
1966 _LIBCPP_INLINE_VISIBILITY
1967 void assign(_Path const& __p, error_code& __ec) {
1968 __p_ = __p;
1969 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001970 }
1971
1972 _LIBCPP_INLINE_VISIBILITY
1973 void replace_filename(_Path const& __p) {
Eric Fiselier70474082018-07-20 01:22:32 +00001974 __p_.replace_filename(__p);
1975 error_code __ec;
1976 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001977 }
1978
1979 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001980 void replace_filename(_Path const& __p, error_code &__ec) {
1981 __p_ = __p_.parent_path() / __p;
1982 __refresh(&__ec);
1983 }
1984
1985 _LIBCPP_INLINE_VISIBILITY
1986 void refresh() {
1987 __refresh();
1988 }
1989
1990 _LIBCPP_INLINE_VISIBILITY
1991 void refresh(error_code& __ec) _NOEXCEPT { __refresh(&__ec); }
1992
1993 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001994 _Path const& path() const _NOEXCEPT {
1995 return __p_;
1996 }
1997
1998 _LIBCPP_INLINE_VISIBILITY
1999 operator const _Path&() const _NOEXCEPT {
2000 return __p_;
2001 }
2002
2003 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00002004 bool exists() const {
2005 return _VSTD_FS::exists(file_status{__get_ft()});
2006 }
2007
2008 _LIBCPP_INLINE_VISIBILITY
2009 bool exists(error_code& __ec) const noexcept {
2010 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2011 }
2012
2013 _LIBCPP_INLINE_VISIBILITY
2014 bool is_block_file() const {
2015 return __get_ft() == file_type::block;
2016 }
2017
2018 _LIBCPP_INLINE_VISIBILITY
2019 bool is_block_file(error_code& __ec) const noexcept {
2020 return __get_ft(&__ec) == file_type::block;
2021 }
2022
2023 _LIBCPP_INLINE_VISIBILITY
2024 bool is_character_file() const {
2025 return __get_ft() == file_type::character;
2026 }
2027
2028 _LIBCPP_INLINE_VISIBILITY
2029 bool is_character_file(error_code& __ec) const noexcept {
2030 return __get_ft(&__ec) == file_type::character;
2031 }
2032
2033 _LIBCPP_INLINE_VISIBILITY
2034 bool is_directory() const {
2035 return __get_ft() == file_type::directory;
2036 }
2037
2038 _LIBCPP_INLINE_VISIBILITY
2039 bool is_directory(error_code& __ec) const noexcept {
2040 return __get_ft(&__ec) == file_type::directory;
2041 }
2042
2043 _LIBCPP_INLINE_VISIBILITY
2044 bool is_fifo() const {
2045 return __get_ft() == file_type::fifo;
2046 }
2047
2048 _LIBCPP_INLINE_VISIBILITY
2049 bool is_fifo(error_code& __ec) const noexcept {
2050 return __get_ft(&__ec) == file_type::fifo;
2051 }
2052
2053 _LIBCPP_INLINE_VISIBILITY
2054 bool is_other() const {
2055 return _VSTD_FS::is_other(file_status{__get_ft()});
2056 }
2057
2058 _LIBCPP_INLINE_VISIBILITY
2059 bool is_other(error_code& __ec) const noexcept {
2060 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2061 }
2062
2063 _LIBCPP_INLINE_VISIBILITY
2064 bool is_regular_file() const {
2065 return __get_ft() == file_type::regular;
2066 }
2067
2068 _LIBCPP_INLINE_VISIBILITY
2069 bool is_regular_file(error_code& __ec) const noexcept {
2070 return __get_ft(&__ec) == file_type::regular;
2071 }
2072
2073 _LIBCPP_INLINE_VISIBILITY
2074 bool is_socket() const {
2075 return __get_ft() == file_type::socket;
2076 }
2077
2078 _LIBCPP_INLINE_VISIBILITY
2079 bool is_socket(error_code& __ec) const noexcept {
2080 return __get_ft(&__ec) == file_type::socket;
2081 }
2082
2083 _LIBCPP_INLINE_VISIBILITY
2084 bool is_symlink() const {
2085 return __get_sym_ft() == file_type::symlink;
2086 }
2087
2088 _LIBCPP_INLINE_VISIBILITY
2089 bool is_symlink(error_code& __ec) const noexcept {
2090 return __get_sym_ft(&__ec) == file_type::symlink;
2091 }
2092 _LIBCPP_INLINE_VISIBILITY
2093 uintmax_t file_size() const {
2094 return __get_size();
2095 }
2096
2097 _LIBCPP_INLINE_VISIBILITY
2098 uintmax_t file_size(error_code& __ec) const noexcept {
2099 return __get_size(&__ec);
2100 }
2101
2102 _LIBCPP_INLINE_VISIBILITY
2103 uintmax_t hard_link_count() const {
2104 return __get_nlink();
2105 }
2106
2107 _LIBCPP_INLINE_VISIBILITY
2108 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2109 return __get_nlink(&__ec);
2110 }
2111
2112 _LIBCPP_INLINE_VISIBILITY
2113 file_time_type last_write_time() const {
2114 return __get_write_time();
2115 }
2116
2117 _LIBCPP_INLINE_VISIBILITY
2118 file_time_type last_write_time(error_code& __ec) const noexcept {
2119 return __get_write_time(&__ec);
2120 }
2121
2122 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002123 file_status status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002124 return __get_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002125 }
2126
2127 _LIBCPP_INLINE_VISIBILITY
2128 file_status status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002129 return __get_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002130 }
2131
2132 _LIBCPP_INLINE_VISIBILITY
2133 file_status symlink_status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002134 return __get_symlink_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002135 }
2136
2137 _LIBCPP_INLINE_VISIBILITY
2138 file_status symlink_status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002139 return __get_symlink_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002140 }
2141
2142 _LIBCPP_INLINE_VISIBILITY
2143 bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
2144 return __p_ < __rhs.__p_;
2145 }
2146
2147 _LIBCPP_INLINE_VISIBILITY
2148 bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
2149 return __p_ == __rhs.__p_;
2150 }
2151
2152 _LIBCPP_INLINE_VISIBILITY
2153 bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
2154 return __p_ != __rhs.__p_;
2155 }
2156
2157 _LIBCPP_INLINE_VISIBILITY
2158 bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
2159 return __p_ <= __rhs.__p_;
2160 }
2161
2162 _LIBCPP_INLINE_VISIBILITY
2163 bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
2164 return __p_ > __rhs.__p_;
2165 }
2166
2167 _LIBCPP_INLINE_VISIBILITY
2168 bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
2169 return __p_ >= __rhs.__p_;
2170 }
Eric Fiselier70474082018-07-20 01:22:32 +00002171
2172private:
2173 friend class directory_iterator;
2174 friend class recursive_directory_iterator;
2175 friend class __dir_stream;
2176
2177 enum _CacheType : unsigned char {
2178 _Empty,
2179 _IterSymlink,
2180 _IterNonSymlink,
2181 _RefreshSymlink,
2182 _RefreshSymlinkUnresolved,
2183 _RefreshNonSymlink
2184 };
2185
2186 struct __cached_data {
2187 uintmax_t __size_;
2188 uintmax_t __nlink_;
2189 file_time_type __write_time_;
2190 perms __sym_perms_;
2191 perms __non_sym_perms_;
2192 file_type __type_;
2193 _CacheType __cache_type_;
2194
2195 _LIBCPP_INLINE_VISIBILITY
2196 __cached_data() noexcept { __reset(); }
2197
2198 _LIBCPP_INLINE_VISIBILITY
2199 void __reset() {
2200 __cache_type_ = _Empty;
2201 __type_ = file_type::none;
2202 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2203 __size_ = __nlink_ = uintmax_t(-1);
2204 __write_time_ = file_time_type::min();
2205 }
2206 };
2207
2208 _LIBCPP_INLINE_VISIBILITY
2209 static __cached_data __create_iter_result(file_type __ft) {
2210 __cached_data __data;
2211 __data.__type_ = __ft;
Eric Fiselierc9332892018-07-23 22:40:41 +00002212 __data.__cache_type_ = [&]() {
2213 switch (__ft) {
2214 case file_type::none:
2215 return _Empty;
2216 case file_type::symlink:
2217 return _IterSymlink;
2218 default:
2219 return _IterNonSymlink;
2220 }
2221 }();
Eric Fiselier70474082018-07-20 01:22:32 +00002222 return __data;
2223 }
2224
2225 _LIBCPP_INLINE_VISIBILITY
2226 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2227 __p_ = std::move(__p);
2228 __data_ = __dt;
2229 }
2230
2231 _LIBCPP_FUNC_VIS
2232 error_code __do_refresh() noexcept;
2233
2234 _LIBCPP_INLINE_VISIBILITY
2235 static bool __is_dne_error(error_code const& __ec) {
2236 if (!__ec)
2237 return true;
2238 switch (static_cast<errc>(__ec.value())) {
2239 case errc::no_such_file_or_directory:
2240 case errc::not_a_directory:
2241 return true;
2242 default:
2243 return false;
2244 }
2245 }
2246
2247 _LIBCPP_INLINE_VISIBILITY
2248 void __handle_error(const char* __msg, error_code* __dest_ec,
2249 error_code const& __ec,
2250 bool __allow_dne = false) const {
2251 if (__dest_ec) {
2252 *__dest_ec = __ec;
2253 return;
2254 }
2255 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002256 __throw_filesystem_error(__msg, __p_, __ec);
Eric Fiselier70474082018-07-20 01:22:32 +00002257 }
2258
2259 _LIBCPP_INLINE_VISIBILITY
2260 void __refresh(error_code* __ec = nullptr) {
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002261 __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2262 /*allow_dne*/ true);
Eric Fiselier70474082018-07-20 01:22:32 +00002263 }
2264
2265 _LIBCPP_INLINE_VISIBILITY
2266 file_type __get_sym_ft(error_code *__ec = nullptr) const {
2267 switch (__data_.__cache_type_) {
2268 case _Empty:
2269 return __symlink_status(__p_, __ec).type();
2270 case _IterSymlink:
2271 case _RefreshSymlink:
2272 case _RefreshSymlinkUnresolved:
2273 if (__ec)
2274 __ec->clear();
2275 return file_type::symlink;
2276 case _IterNonSymlink:
2277 case _RefreshNonSymlink:
2278 file_status __st(__data_.__type_);
2279 if (__ec && !_VSTD_FS::exists(__st))
2280 *__ec = make_error_code(errc::no_such_file_or_directory);
2281 else if (__ec)
2282 __ec->clear();
2283 return __data_.__type_;
2284 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002285 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002286 }
2287
2288 _LIBCPP_INLINE_VISIBILITY
2289 file_type __get_ft(error_code *__ec = nullptr) const {
2290 switch (__data_.__cache_type_) {
2291 case _Empty:
2292 case _IterSymlink:
2293 case _RefreshSymlinkUnresolved:
2294 return __status(__p_, __ec).type();
2295 case _IterNonSymlink:
2296 case _RefreshNonSymlink:
2297 case _RefreshSymlink: {
2298 file_status __st(__data_.__type_);
2299 if (__ec && !_VSTD_FS::exists(__st))
2300 *__ec = make_error_code(errc::no_such_file_or_directory);
2301 else if (__ec)
2302 __ec->clear();
2303 return __data_.__type_;
2304 }
2305 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002306 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002307 }
2308
2309 _LIBCPP_INLINE_VISIBILITY
2310 file_status __get_status(error_code *__ec = nullptr) const {
2311 switch (__data_.__cache_type_) {
2312 case _Empty:
2313 case _IterNonSymlink:
2314 case _IterSymlink:
2315 case _RefreshSymlinkUnresolved:
2316 return __status(__p_, __ec);
2317 case _RefreshNonSymlink:
2318 case _RefreshSymlink:
2319 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2320 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002321 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002322 }
2323
2324 _LIBCPP_INLINE_VISIBILITY
2325 file_status __get_symlink_status(error_code *__ec = nullptr) const {
2326 switch (__data_.__cache_type_) {
2327 case _Empty:
2328 case _IterNonSymlink:
2329 case _IterSymlink:
2330 return __symlink_status(__p_, __ec);
2331 case _RefreshNonSymlink:
2332 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2333 case _RefreshSymlink:
2334 case _RefreshSymlinkUnresolved:
2335 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2336 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002337 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002338 }
2339
2340
2341 _LIBCPP_INLINE_VISIBILITY
2342 uintmax_t __get_size(error_code *__ec = nullptr) const {
2343 switch (__data_.__cache_type_) {
2344 case _Empty:
2345 case _IterNonSymlink:
2346 case _IterSymlink:
2347 case _RefreshSymlinkUnresolved:
2348 return _VSTD_FS::__file_size(__p_, __ec);
2349 case _RefreshSymlink:
2350 case _RefreshNonSymlink: {
2351 error_code __m_ec;
2352 file_status __st(__get_ft(&__m_ec));
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002353 __handle_error("in directory_entry::file_size", __ec, __m_ec);
Eric Fiselier70474082018-07-20 01:22:32 +00002354 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2355 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2356 : errc::not_supported;
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002357 __handle_error("in directory_entry::file_size", __ec,
Eric Fiselier70474082018-07-20 01:22:32 +00002358 make_error_code(__err_kind));
2359 }
2360 return __data_.__size_;
2361 }
2362 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002363 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002364 }
2365
2366 _LIBCPP_INLINE_VISIBILITY
2367 uintmax_t __get_nlink(error_code *__ec = nullptr) const {
2368 switch (__data_.__cache_type_) {
2369 case _Empty:
2370 case _IterNonSymlink:
2371 case _IterSymlink:
2372 case _RefreshSymlinkUnresolved:
2373 return _VSTD_FS::__hard_link_count(__p_, __ec);
2374 case _RefreshSymlink:
2375 case _RefreshNonSymlink: {
2376 error_code __m_ec;
2377 (void)__get_ft(&__m_ec);
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002378 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
Eric Fiselier70474082018-07-20 01:22:32 +00002379 return __data_.__nlink_;
2380 }
2381 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002382 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002383 }
2384
2385 _LIBCPP_INLINE_VISIBILITY
2386 file_time_type __get_write_time(error_code *__ec = nullptr) const {
2387 switch (__data_.__cache_type_) {
2388 case _Empty:
2389 case _IterNonSymlink:
2390 case _IterSymlink:
2391 case _RefreshSymlinkUnresolved:
2392 return _VSTD_FS::__last_write_time(__p_, __ec);
2393 case _RefreshSymlink:
2394 case _RefreshNonSymlink: {
2395 error_code __m_ec;
2396 file_status __st(__get_ft(&__m_ec));
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002397 __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
Eric Fiselier70474082018-07-20 01:22:32 +00002398 if (_VSTD_FS::exists(__st) &&
2399 __data_.__write_time_ == file_time_type::min())
Eric Fiseliera75bbde2018-07-23 02:00:52 +00002400 __handle_error("in directory_entry::last_write_time", __ec,
Eric Fiselier70474082018-07-20 01:22:32 +00002401 make_error_code(errc::value_too_large));
2402 return __data_.__write_time_;
2403 }
2404 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002405 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002406 }
Eric Fiselier435db152016-06-17 19:46:40 +00002407private:
2408 _Path __p_;
Eric Fiselier70474082018-07-20 01:22:32 +00002409 __cached_data __data_;
Eric Fiselier435db152016-06-17 19:46:40 +00002410};
2411
Eric Fiselier435db152016-06-17 19:46:40 +00002412class __dir_element_proxy {
2413public:
2414
2415 inline _LIBCPP_INLINE_VISIBILITY
2416 directory_entry operator*() { return _VSTD::move(__elem_); }
2417
2418private:
2419 friend class directory_iterator;
2420 friend class recursive_directory_iterator;
2421 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2422 __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
2423 directory_entry __elem_;
2424};
2425
2426class directory_iterator
2427{
2428public:
2429 typedef directory_entry value_type;
2430 typedef ptrdiff_t difference_type;
2431 typedef value_type const* pointer;
2432 typedef value_type const& reference;
2433 typedef input_iterator_tag iterator_category;
2434
2435public:
2436 //ctor & dtor
2437 directory_iterator() _NOEXCEPT
2438 { }
2439
2440 explicit directory_iterator(const path& __p)
2441 : directory_iterator(__p, nullptr)
2442 { }
2443
2444 directory_iterator(const path& __p, directory_options __opts)
2445 : directory_iterator(__p, nullptr, __opts)
2446 { }
2447
Eric Fiselierd56d5322017-10-30 18:59:59 +00002448 directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002449 : directory_iterator(__p, &__ec)
2450 { }
2451
2452 directory_iterator(const path& __p, directory_options __opts,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002453 error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002454 : directory_iterator(__p, &__ec, __opts)
2455 { }
2456
2457 directory_iterator(const directory_iterator&) = default;
2458 directory_iterator(directory_iterator&&) = default;
2459 directory_iterator& operator=(const directory_iterator&) = default;
2460
2461 directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
2462 // non-default implementation provided to support self-move assign.
2463 if (this != &__o) {
2464 __imp_ = _VSTD::move(__o.__imp_);
2465 }
2466 return *this;
2467 }
2468
2469 ~directory_iterator() = default;
2470
2471 const directory_entry& operator*() const {
2472 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002473 return __dereference();
Eric Fiselier435db152016-06-17 19:46:40 +00002474 }
2475
2476 const directory_entry* operator->() const
2477 { return &**this; }
2478
2479 directory_iterator& operator++()
2480 { return __increment(); }
2481
2482 __dir_element_proxy operator++(int) {
2483 __dir_element_proxy __p(**this);
2484 __increment();
2485 return __p;
2486 }
2487
Eric Fiselierd56d5322017-10-30 18:59:59 +00002488 directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002489 { return __increment(&__ec); }
2490
2491private:
Eric Fiselier28175a32016-09-16 00:07:16 +00002492 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002493 friend bool operator==(const directory_iterator& __lhs,
2494 const directory_iterator& __rhs) _NOEXCEPT;
2495
2496 // construct the dir_stream
2497 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002498 directory_iterator(const path&, error_code *,
2499 directory_options = directory_options::none);
2500
Eric Fiselier435db152016-06-17 19:46:40 +00002501 _LIBCPP_FUNC_VIS
2502 directory_iterator& __increment(error_code * __ec = nullptr);
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002503
Eric Fiselier435db152016-06-17 19:46:40 +00002504 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002505 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002506
2507private:
2508 shared_ptr<__dir_stream> __imp_;
2509};
2510
2511
2512inline _LIBCPP_INLINE_VISIBILITY
2513bool operator==(const directory_iterator& __lhs,
2514 const directory_iterator& __rhs) _NOEXCEPT {
2515 return __lhs.__imp_ == __rhs.__imp_;
2516}
2517
2518inline _LIBCPP_INLINE_VISIBILITY
2519bool operator!=(const directory_iterator& __lhs,
2520 const directory_iterator& __rhs) _NOEXCEPT {
2521 return !(__lhs == __rhs);
2522}
2523
2524// enable directory_iterator range-based for statements
2525inline _LIBCPP_INLINE_VISIBILITY
2526directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
2527 return __iter;
2528}
2529
2530inline _LIBCPP_INLINE_VISIBILITY
2531directory_iterator end(const directory_iterator&) _NOEXCEPT {
2532 return directory_iterator();
2533}
2534
2535class recursive_directory_iterator {
2536public:
2537 using value_type = directory_entry;
2538 using difference_type = std::ptrdiff_t;
2539 using pointer = directory_entry const *;
2540 using reference = directory_entry const &;
2541 using iterator_category = std::input_iterator_tag;
2542
2543public:
2544 // constructors and destructor
2545 _LIBCPP_INLINE_VISIBILITY
2546 recursive_directory_iterator() _NOEXCEPT
2547 : __rec_(false)
2548 {}
2549
2550 _LIBCPP_INLINE_VISIBILITY
2551 explicit recursive_directory_iterator(const path& __p,
2552 directory_options __xoptions = directory_options::none)
2553 : recursive_directory_iterator(__p, __xoptions, nullptr)
2554 { }
2555
2556 _LIBCPP_INLINE_VISIBILITY
2557 recursive_directory_iterator(const path& __p,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002558 directory_options __xoptions, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002559 : recursive_directory_iterator(__p, __xoptions, &__ec)
2560 { }
2561
2562 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002563 recursive_directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002564 : recursive_directory_iterator(__p, directory_options::none, &__ec)
2565 { }
2566
2567 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2568 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2569
2570 recursive_directory_iterator &
2571 operator=(const recursive_directory_iterator&) = default;
2572
2573 _LIBCPP_INLINE_VISIBILITY
2574 recursive_directory_iterator &
2575 operator=(recursive_directory_iterator&& __o) noexcept {
2576 // non-default implementation provided to support self-move assign.
2577 if (this != &__o) {
2578 __imp_ = _VSTD::move(__o.__imp_);
2579 __rec_ = __o.__rec_;
2580 }
2581 return *this;
2582 }
2583
2584 ~recursive_directory_iterator() = default;
2585
2586 _LIBCPP_INLINE_VISIBILITY
2587 const directory_entry& operator*() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002588 { return __dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002589
2590 _LIBCPP_INLINE_VISIBILITY
2591 const directory_entry* operator->() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002592 { return &__dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002593
2594 recursive_directory_iterator& operator++()
2595 { return __increment(); }
2596
2597 _LIBCPP_INLINE_VISIBILITY
2598 __dir_element_proxy operator++(int) {
2599 __dir_element_proxy __p(**this);
2600 __increment();
2601 return __p;
2602 }
2603
2604 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002605 recursive_directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002606 { return __increment(&__ec); }
2607
2608 _LIBCPP_FUNC_VIS directory_options options() const;
2609 _LIBCPP_FUNC_VIS int depth() const;
2610
2611 _LIBCPP_INLINE_VISIBILITY
2612 void pop() { __pop(); }
2613
2614 _LIBCPP_INLINE_VISIBILITY
2615 void pop(error_code& __ec)
2616 { __pop(&__ec); }
2617
2618 _LIBCPP_INLINE_VISIBILITY
2619 bool recursion_pending() const
2620 { return __rec_; }
2621
2622 _LIBCPP_INLINE_VISIBILITY
2623 void disable_recursion_pending()
2624 { __rec_ = false; }
2625
2626private:
2627 recursive_directory_iterator(const path& __p, directory_options __opt,
2628 error_code *__ec);
2629
2630 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002631 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002632
2633 _LIBCPP_FUNC_VIS
2634 bool __try_recursion(error_code* __ec);
2635
2636 _LIBCPP_FUNC_VIS
2637 void __advance(error_code* __ec=nullptr);
2638
2639 _LIBCPP_FUNC_VIS
2640 recursive_directory_iterator& __increment(error_code *__ec=nullptr);
2641
2642 _LIBCPP_FUNC_VIS
2643 void __pop(error_code* __ec=nullptr);
2644
Eric Fiselier28175a32016-09-16 00:07:16 +00002645 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002646 friend bool operator==(const recursive_directory_iterator&,
2647 const recursive_directory_iterator&) _NOEXCEPT;
2648
2649 struct __shared_imp;
2650 shared_ptr<__shared_imp> __imp_;
2651 bool __rec_;
2652}; // class recursive_directory_iterator
2653
2654
Eric Fiselier28175a32016-09-16 00:07:16 +00002655inline _LIBCPP_INLINE_VISIBILITY
2656bool operator==(const recursive_directory_iterator& __lhs,
2657 const recursive_directory_iterator& __rhs) _NOEXCEPT
Eric Fiselier435db152016-06-17 19:46:40 +00002658{
2659 return __lhs.__imp_ == __rhs.__imp_;
2660}
2661
2662_LIBCPP_INLINE_VISIBILITY
2663inline bool operator!=(const recursive_directory_iterator& __lhs,
2664 const recursive_directory_iterator& __rhs) _NOEXCEPT
2665{
2666 return !(__lhs == __rhs);
2667}
2668// enable recursive_directory_iterator range-based for statements
2669inline _LIBCPP_INLINE_VISIBILITY
2670recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
2671 return __iter;
2672}
2673
2674inline _LIBCPP_INLINE_VISIBILITY
2675recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
2676 return recursive_directory_iterator();
2677}
2678
2679_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
2680
Eric Fiselier3ad58be2018-07-20 01:51:48 +00002681_LIBCPP_POP_MACROS
2682
Eric Fiselier435db152016-06-17 19:46:40 +00002683#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM