blob: 2d2c11765167554f6c803f7e919277ae1fc446ab [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
Marshall Clow8c5edfe2017-11-16 05:48:32 +00001040 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1041 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:
1173 typedef bidirectional_iterator_tag iterator_category;
Eric Fiselierc8dac982017-04-04 01:05:59 +00001174
Eric Fiselier435db152016-06-17 19:46:40 +00001175 typedef path value_type;
1176 typedef std::ptrdiff_t difference_type;
1177 typedef const path* pointer;
1178 typedef const path& reference;
Eric Fiselier883af112017-04-13 02:54:13 +00001179
1180 typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
Eric Fiselier435db152016-06-17 19:46:40 +00001181public:
1182 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfc46d252016-10-30 23:30:38 +00001183 iterator() : __stashed_elem_(), __path_ptr_(nullptr),
1184 __entry_(), __state_(__singular) {}
Eric Fiselier435db152016-06-17 19:46:40 +00001185
1186 iterator(const iterator&) = default;
1187 ~iterator() = default;
1188
1189 iterator& operator=(const iterator&) = default;
1190
1191 _LIBCPP_INLINE_VISIBILITY
1192 reference operator*() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001193 return __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001194 }
1195
1196 _LIBCPP_INLINE_VISIBILITY
1197 pointer operator->() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001198 return &__stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001199 }
1200
1201 _LIBCPP_INLINE_VISIBILITY
1202 iterator& operator++() {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001203 _LIBCPP_ASSERT(__state_ != __singular,
1204 "attempting to increment a singular iterator");
1205 _LIBCPP_ASSERT(__state_ != __at_end,
1206 "attempting to increment the end iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001207 return __increment();
1208 }
1209
1210 _LIBCPP_INLINE_VISIBILITY
1211 iterator operator++(int) {
1212 iterator __it(*this);
1213 this->operator++();
1214 return __it;
1215 }
1216
1217 _LIBCPP_INLINE_VISIBILITY
1218 iterator& operator--() {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001219 _LIBCPP_ASSERT(__state_ != __singular,
1220 "attempting to decrement a singular iterator");
1221 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1222 "attempting to decrement the begin iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001223 return __decrement();
1224 }
1225
1226 _LIBCPP_INLINE_VISIBILITY
1227 iterator operator--(int) {
1228 iterator __it(*this);
1229 this->operator--();
1230 return __it;
1231 }
1232
1233private:
1234 friend class path;
Eric Fiselier28175a32016-09-16 00:07:16 +00001235
Eric Fiselierfc46d252016-10-30 23:30:38 +00001236 static constexpr unsigned char __singular = 0;
1237 static constexpr unsigned char __at_end = 6;
1238
Eric Fiselier28175a32016-09-16 00:07:16 +00001239 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001240 friend bool operator==(const iterator&, const iterator&);
1241
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001242 iterator& __increment();
1243 iterator& __decrement();
Eric Fiselier435db152016-06-17 19:46:40 +00001244
Eric Fiselierfc46d252016-10-30 23:30:38 +00001245 path __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001246 const path* __path_ptr_;
Eric Fiselierfc46d252016-10-30 23:30:38 +00001247 path::__string_view __entry_;
1248 unsigned char __state_;
Eric Fiselier435db152016-06-17 19:46:40 +00001249};
1250
1251inline _LIBCPP_INLINE_VISIBILITY
1252bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
1253 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
Eric Fiselierfc46d252016-10-30 23:30:38 +00001254 __lhs.__entry_.data() == __rhs.__entry_.data();
Eric Fiselier435db152016-06-17 19:46:40 +00001255}
1256
1257inline _LIBCPP_INLINE_VISIBILITY
1258bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1259 return !(__lhs == __rhs);
1260}
1261
1262class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
1263{
1264public:
1265 _LIBCPP_INLINE_VISIBILITY
1266 filesystem_error(const string& __what, error_code __ec)
1267 : system_error(__ec, __what),
1268 __paths_(make_shared<_Storage>(path(), path()))
1269 {}
1270
1271 _LIBCPP_INLINE_VISIBILITY
1272 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1273 : system_error(__ec, __what),
1274 __paths_(make_shared<_Storage>(__p1, path()))
1275 {}
1276
1277 _LIBCPP_INLINE_VISIBILITY
1278 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1279 error_code __ec)
1280 : system_error(__ec, __what),
1281 __paths_(make_shared<_Storage>(__p1, __p2))
1282 {}
1283
1284 _LIBCPP_INLINE_VISIBILITY
1285 const path& path1() const _NOEXCEPT {
1286 return __paths_->first;
1287 }
1288
1289 _LIBCPP_INLINE_VISIBILITY
1290 const path& path2() const _NOEXCEPT {
1291 return __paths_->second;
1292 }
1293
Eric Fiselier435db152016-06-17 19:46:40 +00001294 ~filesystem_error() override; // key function
1295
1296 // TODO(ericwf): Create a custom error message.
1297 //const char* what() const _NOEXCEPT;
1298
1299private:
1300 typedef pair<path, path> _Storage;
1301 shared_ptr<_Storage> __paths_;
1302};
1303
Marshall Clowed3e2292016-08-25 17:47:09 +00001304template <class... _Args>
Louis Dionne16fe2952018-07-11 23:14:33 +00001305_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001306#ifndef _LIBCPP_NO_EXCEPTIONS
Marshall Clowed3e2292016-08-25 17:47:09 +00001307void __throw_filesystem_error(_Args && ...__args)
1308{
Marshall Clowed3e2292016-08-25 17:47:09 +00001309 throw filesystem_error(std::forward<_Args>(__args)...);
Marshall Clowed3e2292016-08-25 17:47:09 +00001310}
Eric Fiselier6003c772016-12-23 23:37:52 +00001311#else
1312void __throw_filesystem_error(_Args&&...)
1313{
1314 _VSTD::abort();
1315}
1316#endif
1317
Marshall Clowed3e2292016-08-25 17:47:09 +00001318
Eric Fiselier435db152016-06-17 19:46:40 +00001319// operational functions
1320
1321_LIBCPP_FUNC_VIS
Eric Fiselier91a182b2018-04-02 23:03:41 +00001322path __absolute(const path&, error_code *__ec=nullptr);
1323_LIBCPP_FUNC_VIS
1324path __canonical(const path&, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001325_LIBCPP_FUNC_VIS
1326void __copy(const path& __from, const path& __to, copy_options __opt,
1327 error_code *__ec=nullptr);
1328_LIBCPP_FUNC_VIS
1329bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1330 error_code *__ec=nullptr);
1331_LIBCPP_FUNC_VIS
1332void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1333 error_code *__ec=nullptr);
1334_LIBCPP_FUNC_VIS
1335bool __create_directories(const path& p, error_code *ec=nullptr);
1336_LIBCPP_FUNC_VIS
1337bool __create_directory(const path& p, error_code *ec=nullptr);
1338_LIBCPP_FUNC_VIS
1339bool __create_directory(const path& p, const path & attributes,
1340 error_code *ec=nullptr);
1341_LIBCPP_FUNC_VIS
1342void __create_directory_symlink(const path& __to, const path& __new_symlink,
1343 error_code *__ec=nullptr);
1344_LIBCPP_FUNC_VIS
1345void __create_hard_link(const path& __to, const path& __new_hard_link,
1346 error_code *__ec=nullptr);
1347_LIBCPP_FUNC_VIS
1348void __create_symlink(const path& __to, const path& __new_symlink,
1349 error_code *__ec=nullptr);
1350_LIBCPP_FUNC_VIS
1351path __current_path(error_code *__ec=nullptr);
1352_LIBCPP_FUNC_VIS
1353void __current_path(const path&, error_code *__ec=nullptr);
1354_LIBCPP_FUNC_VIS
1355bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
1356_LIBCPP_FUNC_VIS
1357uintmax_t __file_size(const path&, error_code *__ec=nullptr);
1358_LIBCPP_FUNC_VIS
1359uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
1360_LIBCPP_FUNC_VIS
1361bool __fs_is_empty(const path& p, error_code *ec=nullptr);
1362_LIBCPP_FUNC_VIS
1363file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
1364_LIBCPP_FUNC_VIS
1365void __last_write_time(const path& p, file_time_type new_time,
1366 error_code *ec=nullptr);
1367_LIBCPP_FUNC_VIS
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001368void __permissions(const path&, perms, perm_options, error_code* = nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001369_LIBCPP_FUNC_VIS
1370path __read_symlink(const path& p, error_code *ec=nullptr);
1371_LIBCPP_FUNC_VIS
1372bool __remove(const path& p, error_code *ec=nullptr);
1373_LIBCPP_FUNC_VIS
1374uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
1375_LIBCPP_FUNC_VIS
1376void __rename(const path& from, const path& to, error_code *ec=nullptr);
1377_LIBCPP_FUNC_VIS
1378void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
1379_LIBCPP_FUNC_VIS
1380space_info __space(const path&, error_code *__ec=nullptr);
1381_LIBCPP_FUNC_VIS
1382file_status __status(const path&, error_code *__ec=nullptr);
1383_LIBCPP_FUNC_VIS
1384file_status __symlink_status(const path&, error_code *__ec=nullptr);
1385_LIBCPP_FUNC_VIS
1386path __system_complete(const path&, error_code *__ec=nullptr);
1387_LIBCPP_FUNC_VIS
1388path __temp_directory_path(error_code *__ec=nullptr);
Eric Fiselier91a182b2018-04-02 23:03:41 +00001389_LIBCPP_FUNC_VIS
1390path __weakly_canonical(path const& __p, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001391
1392inline _LIBCPP_INLINE_VISIBILITY
1393path current_path() {
1394 return __current_path();
1395}
1396
1397inline _LIBCPP_INLINE_VISIBILITY
1398path current_path(error_code& __ec) {
1399 return __current_path(&__ec);
1400}
1401
1402inline _LIBCPP_INLINE_VISIBILITY
1403void current_path(const path& __p) {
1404 __current_path(__p);
1405}
1406
1407inline _LIBCPP_INLINE_VISIBILITY
1408void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
1409 __current_path(__p, &__ec);
1410}
1411
Eric Fiselier91a182b2018-04-02 23:03:41 +00001412inline _LIBCPP_INLINE_VISIBILITY
1413path absolute(const path& __p) {
1414 return __absolute(__p);
1415}
Eric Fiselier435db152016-06-17 19:46:40 +00001416
1417inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001418path absolute(const path& __p, error_code &__ec) {
1419 return __absolute(__p, &__ec);
1420}
1421
1422inline _LIBCPP_INLINE_VISIBILITY
1423path canonical(const path& __p) {
1424 return __canonical(__p);
Eric Fiselier435db152016-06-17 19:46:40 +00001425}
1426
1427inline _LIBCPP_INLINE_VISIBILITY
1428path canonical(const path& __p, error_code& __ec) {
Eric Fiselier91a182b2018-04-02 23:03:41 +00001429 return __canonical(__p, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001430}
1431
1432inline _LIBCPP_INLINE_VISIBILITY
1433void copy(const path& __from, const path& __to) {
1434 __copy(__from, __to, copy_options::none);
1435}
1436
1437inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001438void copy(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001439 __copy(__from, __to, copy_options::none, &__ec);
1440}
1441
1442inline _LIBCPP_INLINE_VISIBILITY
1443void copy(const path& __from, const path& __to, copy_options __opt) {
1444 __copy(__from, __to, __opt);
1445}
1446
1447inline _LIBCPP_INLINE_VISIBILITY
1448void copy(const path& __from, const path& __to,
Eric Fiselierd56d5322017-10-30 18:59:59 +00001449 copy_options __opt, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001450 __copy(__from, __to, __opt, &__ec);
1451}
1452
1453inline _LIBCPP_INLINE_VISIBILITY
1454bool copy_file(const path& __from, const path& __to) {
1455 return __copy_file(__from, __to, copy_options::none);
1456}
1457
1458inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001459bool copy_file(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001460 return __copy_file(__from, __to, copy_options::none, &__ec);
1461}
1462
1463inline _LIBCPP_INLINE_VISIBILITY
1464bool copy_file(const path& __from, const path& __to, copy_options __opt) {
1465 return __copy_file(__from, __to, __opt);
1466}
1467
1468inline _LIBCPP_INLINE_VISIBILITY
1469bool copy_file(const path& __from, const path& __to,
Eric Fiseliere1164812018-02-04 07:35:36 +00001470 copy_options __opt, error_code& __ec){
Eric Fiselier435db152016-06-17 19:46:40 +00001471 return __copy_file(__from, __to, __opt, &__ec);
1472}
1473
1474inline _LIBCPP_INLINE_VISIBILITY
1475void copy_symlink(const path& __existing, const path& __new) {
1476 __copy_symlink(__existing, __new);
1477}
1478
1479inline _LIBCPP_INLINE_VISIBILITY
1480void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
1481 __copy_symlink(__ext, __new, &__ec);
1482}
1483
1484inline _LIBCPP_INLINE_VISIBILITY
1485bool create_directories(const path& __p) {
1486 return __create_directories(__p);
1487}
1488
1489inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001490bool create_directories(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001491 return __create_directories(__p, &__ec);
1492}
1493
1494inline _LIBCPP_INLINE_VISIBILITY
1495bool create_directory(const path& __p) {
1496 return __create_directory(__p);
1497}
1498
1499inline _LIBCPP_INLINE_VISIBILITY
1500bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1501 return __create_directory(__p, &__ec);
1502}
1503
1504inline _LIBCPP_INLINE_VISIBILITY
1505bool create_directory(const path& __p, const path& __attrs) {
1506 return __create_directory(__p, __attrs);
1507}
1508
1509inline _LIBCPP_INLINE_VISIBILITY
1510bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
1511 return __create_directory(__p, __attrs, &__ec);
1512}
1513
1514inline _LIBCPP_INLINE_VISIBILITY
1515void create_directory_symlink(const path& __to, const path& __new) {
1516 __create_directory_symlink(__to, __new);
1517}
1518
1519inline _LIBCPP_INLINE_VISIBILITY
1520void create_directory_symlink(const path& __to, const path& __new,
1521 error_code& __ec) _NOEXCEPT {
1522 __create_directory_symlink(__to, __new, &__ec);
1523}
1524
1525inline _LIBCPP_INLINE_VISIBILITY
1526void create_hard_link(const path& __to, const path& __new) {
1527 __create_hard_link(__to, __new);
1528}
1529
1530inline _LIBCPP_INLINE_VISIBILITY
1531void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1532 __create_hard_link(__to, __new, &__ec);
1533}
1534
1535inline _LIBCPP_INLINE_VISIBILITY
1536void create_symlink(const path& __to, const path& __new) {
1537 __create_symlink(__to, __new);
1538}
1539
1540inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001541void create_symlink(const path& __to, const path& __new,
1542 error_code& __ec) _NOEXCEPT {
Eric Fiselier435db152016-06-17 19:46:40 +00001543 return __create_symlink(__to, __new, &__ec);
1544}
1545
1546inline _LIBCPP_INLINE_VISIBILITY
1547bool status_known(file_status __s) _NOEXCEPT {
1548 return __s.type() != file_type::none;
1549}
1550
1551inline _LIBCPP_INLINE_VISIBILITY
1552bool exists(file_status __s) _NOEXCEPT {
1553 return status_known(__s) && __s.type() != file_type::not_found;
1554}
1555
1556inline _LIBCPP_INLINE_VISIBILITY
1557bool exists(const path& __p) {
1558 return exists(__status(__p));
1559}
1560
1561inline _LIBCPP_INLINE_VISIBILITY
1562bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
Eric Fiselier0a367d22016-06-21 22:11:16 +00001563 auto __s = __status(__p, &__ec);
1564 if (status_known(__s)) __ec.clear();
1565 return exists(__s);
Eric Fiselier435db152016-06-17 19:46:40 +00001566}
1567
1568inline _LIBCPP_INLINE_VISIBILITY
1569bool equivalent(const path& __p1, const path& __p2) {
1570 return __equivalent(__p1, __p2);
1571}
1572
1573inline _LIBCPP_INLINE_VISIBILITY
1574bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
1575 return __equivalent(__p1, __p2, &__ec);
1576}
1577
1578inline _LIBCPP_INLINE_VISIBILITY
1579uintmax_t file_size(const path& __p) {
1580 return __file_size(__p);
1581}
1582
1583inline _LIBCPP_INLINE_VISIBILITY
1584uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
1585 return __file_size(__p, &__ec);
1586}
1587
1588inline _LIBCPP_INLINE_VISIBILITY
1589uintmax_t hard_link_count(const path& __p) {
1590 return __hard_link_count(__p);
1591}
1592
1593inline _LIBCPP_INLINE_VISIBILITY
1594uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
1595 return __hard_link_count(__p, &__ec);
1596}
1597
1598inline _LIBCPP_INLINE_VISIBILITY
1599bool is_block_file(file_status __s) _NOEXCEPT {
1600 return __s.type() == file_type::block;
1601}
1602
1603inline _LIBCPP_INLINE_VISIBILITY
1604bool is_block_file(const path& __p) {
1605 return is_block_file(__status(__p));
1606}
1607
1608inline _LIBCPP_INLINE_VISIBILITY
1609bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
1610 return is_block_file(__status(__p, &__ec));
1611}
1612
1613inline _LIBCPP_INLINE_VISIBILITY
1614bool is_character_file(file_status __s) _NOEXCEPT {
1615 return __s.type() == file_type::character;
1616}
1617
1618inline _LIBCPP_INLINE_VISIBILITY
1619bool is_character_file(const path& __p) {
1620 return is_character_file(__status(__p));
1621}
1622
1623inline _LIBCPP_INLINE_VISIBILITY
1624bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
1625 return is_character_file(__status(__p, &__ec));
1626}
1627
1628inline _LIBCPP_INLINE_VISIBILITY
1629bool is_directory(file_status __s) _NOEXCEPT {
1630 return __s.type() == file_type::directory;
1631}
1632
1633inline _LIBCPP_INLINE_VISIBILITY
1634bool is_directory(const path& __p) {
1635 return is_directory(__status(__p));
1636}
1637
1638inline _LIBCPP_INLINE_VISIBILITY
1639bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1640 return is_directory(__status(__p, &__ec));
1641}
1642
1643inline _LIBCPP_INLINE_VISIBILITY
1644bool is_empty(const path& __p) {
1645 return __fs_is_empty(__p);
1646}
1647
1648inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001649bool is_empty(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001650 return __fs_is_empty(__p, &__ec);
1651}
1652
1653inline _LIBCPP_INLINE_VISIBILITY
1654bool is_fifo(file_status __s) _NOEXCEPT {
1655 return __s.type() == file_type::fifo;
1656}
1657inline _LIBCPP_INLINE_VISIBILITY
1658bool is_fifo(const path& __p) {
1659 return is_fifo(__status(__p));
1660}
1661
1662inline _LIBCPP_INLINE_VISIBILITY
1663bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
1664 return is_fifo(__status(__p, &__ec));
1665}
1666
1667inline _LIBCPP_INLINE_VISIBILITY
1668bool is_regular_file(file_status __s) _NOEXCEPT {
1669 return __s.type() == file_type::regular;
1670}
1671
1672inline _LIBCPP_INLINE_VISIBILITY
1673bool is_regular_file(const path& __p) {
1674 return is_regular_file(__status(__p));
1675}
1676
1677inline _LIBCPP_INLINE_VISIBILITY
1678bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
1679 return is_regular_file(__status(__p, &__ec));
1680}
1681
1682inline _LIBCPP_INLINE_VISIBILITY
1683bool is_socket(file_status __s) _NOEXCEPT {
1684 return __s.type() == file_type::socket;
1685}
1686
1687inline _LIBCPP_INLINE_VISIBILITY
1688bool is_socket(const path& __p) {
1689 return is_socket(__status(__p));
1690}
1691
1692inline _LIBCPP_INLINE_VISIBILITY
1693bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
1694 return is_socket(__status(__p, &__ec));
1695}
1696
1697inline _LIBCPP_INLINE_VISIBILITY
1698bool is_symlink(file_status __s) _NOEXCEPT {
1699 return __s.type() == file_type::symlink;
1700}
1701
1702inline _LIBCPP_INLINE_VISIBILITY
1703bool is_symlink(const path& __p) {
1704 return is_symlink(__symlink_status(__p));
1705}
1706
1707inline _LIBCPP_INLINE_VISIBILITY
1708bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
1709 return is_symlink(__symlink_status(__p, &__ec));
1710}
1711
1712inline _LIBCPP_INLINE_VISIBILITY
1713bool is_other(file_status __s) _NOEXCEPT {
1714 return exists(__s)
1715 && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
1716}
1717
1718inline _LIBCPP_INLINE_VISIBILITY
1719bool is_other(const path& __p) {
1720 return is_other(__status(__p));
1721}
1722
1723inline _LIBCPP_INLINE_VISIBILITY
1724bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
1725 return is_other(__status(__p, &__ec));
1726}
1727
1728inline _LIBCPP_INLINE_VISIBILITY
1729file_time_type last_write_time(const path& __p) {
1730 return __last_write_time(__p);
1731}
1732
1733inline _LIBCPP_INLINE_VISIBILITY
1734file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
1735 return __last_write_time(__p, &__ec);
1736}
1737
1738inline _LIBCPP_INLINE_VISIBILITY
1739void last_write_time(const path& __p, file_time_type __t) {
1740 __last_write_time(__p, __t);
1741}
1742
1743inline _LIBCPP_INLINE_VISIBILITY
1744void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
1745 __last_write_time(__p, __t, &__ec);
1746}
1747
1748inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001749void permissions(const path& __p, perms __prms,
1750 perm_options __opts = perm_options::replace) {
1751 __permissions(__p, __prms, __opts);
Eric Fiselier435db152016-06-17 19:46:40 +00001752}
1753
1754inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001755void permissions(const path& __p, perms __prms, error_code& __ec) _NOEXCEPT {
1756 __permissions(__p, __prms, perm_options::replace, &__ec);
1757}
1758
1759inline _LIBCPP_INLINE_VISIBILITY
1760void permissions(const path& __p, perms __prms, perm_options __opts,
1761 error_code& __ec) {
1762 __permissions(__p, __prms, __opts, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001763}
1764
1765inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001766path proximate(const path& __p, const path& __base, error_code& __ec) {
1767 path __tmp = __weakly_canonical(__p, &__ec);
1768 if (__ec)
1769 return {};
1770 path __tmp_base = __weakly_canonical(__base, &__ec);
1771 if (__ec)
1772 return {};
1773 return __tmp.lexically_proximate(__tmp_base);
1774}
1775
1776inline _LIBCPP_INLINE_VISIBILITY
1777path proximate(const path& __p, error_code& __ec) {
1778 return proximate(__p, current_path(), __ec);
1779}
1780
1781inline _LIBCPP_INLINE_VISIBILITY
1782path proximate(const path& __p, const path& __base = current_path()) {
1783 return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
1784}
1785
1786inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001787path read_symlink(const path& __p) {
1788 return __read_symlink(__p);
1789}
1790
1791inline _LIBCPP_INLINE_VISIBILITY
1792path read_symlink(const path& __p, error_code& __ec) {
1793 return __read_symlink(__p, &__ec);
1794}
1795
Eric Fiselier91a182b2018-04-02 23:03:41 +00001796
1797inline _LIBCPP_INLINE_VISIBILITY
1798path relative(const path& __p, const path& __base, error_code& __ec) {
1799 path __tmp = __weakly_canonical(__p, &__ec);
1800 if (__ec)
1801 return path();
1802 path __tmpbase = __weakly_canonical(__base, &__ec);
1803 if (__ec)
1804 return path();
1805 return __tmp.lexically_relative(__tmpbase);
1806}
1807
1808inline _LIBCPP_INLINE_VISIBILITY
1809path relative(const path& __p, error_code& __ec) {
1810 return relative(__p, current_path(), __ec);
1811}
1812
1813inline _LIBCPP_INLINE_VISIBILITY
1814path relative(const path& __p, const path& __base=current_path()) {
1815 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
1816}
1817
1818
Eric Fiselier435db152016-06-17 19:46:40 +00001819inline _LIBCPP_INLINE_VISIBILITY
1820bool remove(const path& __p) {
1821 return __remove(__p);
1822}
1823
1824inline _LIBCPP_INLINE_VISIBILITY
1825bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
1826 return __remove(__p, &__ec);
1827}
1828
1829inline _LIBCPP_INLINE_VISIBILITY
1830uintmax_t remove_all(const path& __p) {
1831 return __remove_all(__p);
1832}
1833
1834inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001835uintmax_t remove_all(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001836 return __remove_all(__p, &__ec);
1837}
1838
1839inline _LIBCPP_INLINE_VISIBILITY
1840void rename(const path& __from, const path& __to) {
1841 return __rename(__from, __to);
1842}
1843
1844inline _LIBCPP_INLINE_VISIBILITY
1845void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1846 return __rename(__from, __to, &__ec);
1847}
1848
1849inline _LIBCPP_INLINE_VISIBILITY
1850void resize_file(const path& __p, uintmax_t __ns) {
1851 return __resize_file(__p, __ns);
1852}
1853
1854inline _LIBCPP_INLINE_VISIBILITY
1855void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
1856 return __resize_file(__p, __ns, &__ec);
1857}
1858
1859inline _LIBCPP_INLINE_VISIBILITY
1860space_info space(const path& __p) {
1861 return __space(__p);
1862}
1863
1864inline _LIBCPP_INLINE_VISIBILITY
1865space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
1866 return __space(__p, &__ec);
1867}
1868
1869inline _LIBCPP_INLINE_VISIBILITY
1870file_status status(const path& __p) {
1871 return __status(__p);
1872}
1873
1874inline _LIBCPP_INLINE_VISIBILITY
1875file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
1876 return __status(__p, &__ec);
1877}
1878
1879inline _LIBCPP_INLINE_VISIBILITY
1880file_status symlink_status(const path& __p) {
1881 return __symlink_status(__p);
1882}
1883
1884inline _LIBCPP_INLINE_VISIBILITY
1885file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
1886 return __symlink_status(__p, &__ec);
1887}
1888
1889inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001890path temp_directory_path() {
1891 return __temp_directory_path();
1892}
1893
1894inline _LIBCPP_INLINE_VISIBILITY
1895path temp_directory_path(error_code& __ec) {
1896 return __temp_directory_path(&__ec);
1897}
1898
Eric Fiselier91a182b2018-04-02 23:03:41 +00001899inline _LIBCPP_INLINE_VISIBILITY
1900path weakly_canonical(path const& __p) {
1901 return __weakly_canonical(__p);
1902}
1903
1904inline _LIBCPP_INLINE_VISIBILITY
1905path weakly_canonical(path const& __p, error_code& __ec) {
1906 return __weakly_canonical(__p, &__ec);
1907}
1908
Eric Fiselier435db152016-06-17 19:46:40 +00001909
Eric Fiselier70474082018-07-20 01:22:32 +00001910class directory_iterator;
1911class recursive_directory_iterator;
1912class __dir_stream;
1913
Eric Fiselier435db152016-06-17 19:46:40 +00001914class directory_entry
1915{
1916 typedef _VSTD_FS::path _Path;
1917
1918public:
1919 // constructors and destructors
1920 directory_entry() _NOEXCEPT = default;
1921 directory_entry(directory_entry const&) = default;
1922 directory_entry(directory_entry&&) _NOEXCEPT = default;
1923
1924 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001925 explicit directory_entry(_Path const& __p) : __p_(__p) {
1926 error_code __ec;
1927 __refresh(&__ec);
1928 }
1929
1930 _LIBCPP_INLINE_VISIBILITY
1931 directory_entry(_Path const& __p, error_code &__ec) : __p_(__p) {
1932 __refresh(&__ec);
1933 }
Eric Fiselier435db152016-06-17 19:46:40 +00001934
1935 ~directory_entry() {}
1936
1937 directory_entry& operator=(directory_entry const&) = default;
1938 directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
1939
1940 _LIBCPP_INLINE_VISIBILITY
1941 void assign(_Path const& __p) {
1942 __p_ = __p;
Eric Fiselier70474082018-07-20 01:22:32 +00001943 error_code __ec;
1944 __refresh(&__ec);
1945 }
1946
1947 _LIBCPP_INLINE_VISIBILITY
1948 void assign(_Path const& __p, error_code& __ec) {
1949 __p_ = __p;
1950 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001951 }
1952
1953 _LIBCPP_INLINE_VISIBILITY
1954 void replace_filename(_Path const& __p) {
Eric Fiselier70474082018-07-20 01:22:32 +00001955 __p_.replace_filename(__p);
1956 error_code __ec;
1957 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001958 }
1959
1960 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001961 void replace_filename(_Path const& __p, error_code &__ec) {
1962 __p_ = __p_.parent_path() / __p;
1963 __refresh(&__ec);
1964 }
1965
1966 _LIBCPP_INLINE_VISIBILITY
1967 void refresh() {
1968 __refresh();
1969 }
1970
1971 _LIBCPP_INLINE_VISIBILITY
1972 void refresh(error_code& __ec) _NOEXCEPT { __refresh(&__ec); }
1973
1974 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001975 _Path const& path() const _NOEXCEPT {
1976 return __p_;
1977 }
1978
1979 _LIBCPP_INLINE_VISIBILITY
1980 operator const _Path&() const _NOEXCEPT {
1981 return __p_;
1982 }
1983
1984 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001985 bool exists() const {
1986 return _VSTD_FS::exists(file_status{__get_ft()});
1987 }
1988
1989 _LIBCPP_INLINE_VISIBILITY
1990 bool exists(error_code& __ec) const noexcept {
1991 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
1992 }
1993
1994 _LIBCPP_INLINE_VISIBILITY
1995 bool is_block_file() const {
1996 return __get_ft() == file_type::block;
1997 }
1998
1999 _LIBCPP_INLINE_VISIBILITY
2000 bool is_block_file(error_code& __ec) const noexcept {
2001 return __get_ft(&__ec) == file_type::block;
2002 }
2003
2004 _LIBCPP_INLINE_VISIBILITY
2005 bool is_character_file() const {
2006 return __get_ft() == file_type::character;
2007 }
2008
2009 _LIBCPP_INLINE_VISIBILITY
2010 bool is_character_file(error_code& __ec) const noexcept {
2011 return __get_ft(&__ec) == file_type::character;
2012 }
2013
2014 _LIBCPP_INLINE_VISIBILITY
2015 bool is_directory() const {
2016 return __get_ft() == file_type::directory;
2017 }
2018
2019 _LIBCPP_INLINE_VISIBILITY
2020 bool is_directory(error_code& __ec) const noexcept {
2021 return __get_ft(&__ec) == file_type::directory;
2022 }
2023
2024 _LIBCPP_INLINE_VISIBILITY
2025 bool is_fifo() const {
2026 return __get_ft() == file_type::fifo;
2027 }
2028
2029 _LIBCPP_INLINE_VISIBILITY
2030 bool is_fifo(error_code& __ec) const noexcept {
2031 return __get_ft(&__ec) == file_type::fifo;
2032 }
2033
2034 _LIBCPP_INLINE_VISIBILITY
2035 bool is_other() const {
2036 return _VSTD_FS::is_other(file_status{__get_ft()});
2037 }
2038
2039 _LIBCPP_INLINE_VISIBILITY
2040 bool is_other(error_code& __ec) const noexcept {
2041 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2042 }
2043
2044 _LIBCPP_INLINE_VISIBILITY
2045 bool is_regular_file() const {
2046 return __get_ft() == file_type::regular;
2047 }
2048
2049 _LIBCPP_INLINE_VISIBILITY
2050 bool is_regular_file(error_code& __ec) const noexcept {
2051 return __get_ft(&__ec) == file_type::regular;
2052 }
2053
2054 _LIBCPP_INLINE_VISIBILITY
2055 bool is_socket() const {
2056 return __get_ft() == file_type::socket;
2057 }
2058
2059 _LIBCPP_INLINE_VISIBILITY
2060 bool is_socket(error_code& __ec) const noexcept {
2061 return __get_ft(&__ec) == file_type::socket;
2062 }
2063
2064 _LIBCPP_INLINE_VISIBILITY
2065 bool is_symlink() const {
2066 return __get_sym_ft() == file_type::symlink;
2067 }
2068
2069 _LIBCPP_INLINE_VISIBILITY
2070 bool is_symlink(error_code& __ec) const noexcept {
2071 return __get_sym_ft(&__ec) == file_type::symlink;
2072 }
2073 _LIBCPP_INLINE_VISIBILITY
2074 uintmax_t file_size() const {
2075 return __get_size();
2076 }
2077
2078 _LIBCPP_INLINE_VISIBILITY
2079 uintmax_t file_size(error_code& __ec) const noexcept {
2080 return __get_size(&__ec);
2081 }
2082
2083 _LIBCPP_INLINE_VISIBILITY
2084 uintmax_t hard_link_count() const {
2085 return __get_nlink();
2086 }
2087
2088 _LIBCPP_INLINE_VISIBILITY
2089 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2090 return __get_nlink(&__ec);
2091 }
2092
2093 _LIBCPP_INLINE_VISIBILITY
2094 file_time_type last_write_time() const {
2095 return __get_write_time();
2096 }
2097
2098 _LIBCPP_INLINE_VISIBILITY
2099 file_time_type last_write_time(error_code& __ec) const noexcept {
2100 return __get_write_time(&__ec);
2101 }
2102
2103 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002104 file_status status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002105 return __get_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002106 }
2107
2108 _LIBCPP_INLINE_VISIBILITY
2109 file_status status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002110 return __get_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002111 }
2112
2113 _LIBCPP_INLINE_VISIBILITY
2114 file_status symlink_status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002115 return __get_symlink_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002116 }
2117
2118 _LIBCPP_INLINE_VISIBILITY
2119 file_status symlink_status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002120 return __get_symlink_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002121 }
2122
2123 _LIBCPP_INLINE_VISIBILITY
2124 bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
2125 return __p_ < __rhs.__p_;
2126 }
2127
2128 _LIBCPP_INLINE_VISIBILITY
2129 bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
2130 return __p_ == __rhs.__p_;
2131 }
2132
2133 _LIBCPP_INLINE_VISIBILITY
2134 bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
2135 return __p_ != __rhs.__p_;
2136 }
2137
2138 _LIBCPP_INLINE_VISIBILITY
2139 bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
2140 return __p_ <= __rhs.__p_;
2141 }
2142
2143 _LIBCPP_INLINE_VISIBILITY
2144 bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
2145 return __p_ > __rhs.__p_;
2146 }
2147
2148 _LIBCPP_INLINE_VISIBILITY
2149 bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
2150 return __p_ >= __rhs.__p_;
2151 }
Eric Fiselier70474082018-07-20 01:22:32 +00002152
2153private:
2154 friend class directory_iterator;
2155 friend class recursive_directory_iterator;
2156 friend class __dir_stream;
2157
2158 enum _CacheType : unsigned char {
2159 _Empty,
2160 _IterSymlink,
2161 _IterNonSymlink,
2162 _RefreshSymlink,
2163 _RefreshSymlinkUnresolved,
2164 _RefreshNonSymlink
2165 };
2166
2167 struct __cached_data {
2168 uintmax_t __size_;
2169 uintmax_t __nlink_;
2170 file_time_type __write_time_;
2171 perms __sym_perms_;
2172 perms __non_sym_perms_;
2173 file_type __type_;
2174 _CacheType __cache_type_;
2175
2176 _LIBCPP_INLINE_VISIBILITY
2177 __cached_data() noexcept { __reset(); }
2178
2179 _LIBCPP_INLINE_VISIBILITY
2180 void __reset() {
2181 __cache_type_ = _Empty;
2182 __type_ = file_type::none;
2183 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2184 __size_ = __nlink_ = uintmax_t(-1);
2185 __write_time_ = file_time_type::min();
2186 }
2187 };
2188
2189 _LIBCPP_INLINE_VISIBILITY
2190 static __cached_data __create_iter_result(file_type __ft) {
2191 __cached_data __data;
2192 __data.__type_ = __ft;
2193 __data.__cache_type_ =
2194 __ft == file_type::symlink ? _IterSymlink : _IterNonSymlink;
2195 return __data;
2196 }
2197
2198 _LIBCPP_INLINE_VISIBILITY
2199 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2200 __p_ = std::move(__p);
2201 __data_ = __dt;
2202 }
2203
2204 _LIBCPP_FUNC_VIS
2205 error_code __do_refresh() noexcept;
2206
2207 _LIBCPP_INLINE_VISIBILITY
2208 static bool __is_dne_error(error_code const& __ec) {
2209 if (!__ec)
2210 return true;
2211 switch (static_cast<errc>(__ec.value())) {
2212 case errc::no_such_file_or_directory:
2213 case errc::not_a_directory:
2214 return true;
2215 default:
2216 return false;
2217 }
2218 }
2219
2220 _LIBCPP_INLINE_VISIBILITY
2221 void __handle_error(const char* __msg, error_code* __dest_ec,
2222 error_code const& __ec,
2223 bool __allow_dne = false) const {
2224 if (__dest_ec) {
2225 *__dest_ec = __ec;
2226 return;
2227 }
2228 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2229 __throw_filesystem_error(__msg, __p_, _Path{}, __ec);
2230 }
2231
2232 _LIBCPP_INLINE_VISIBILITY
2233 void __refresh(error_code* __ec = nullptr) {
2234 __handle_error("refresh", __ec, __do_refresh(), /*allow_dne*/ true);
2235 }
2236
2237 _LIBCPP_INLINE_VISIBILITY
2238 file_type __get_sym_ft(error_code *__ec = nullptr) const {
2239 switch (__data_.__cache_type_) {
2240 case _Empty:
2241 return __symlink_status(__p_, __ec).type();
2242 case _IterSymlink:
2243 case _RefreshSymlink:
2244 case _RefreshSymlinkUnresolved:
2245 if (__ec)
2246 __ec->clear();
2247 return file_type::symlink;
2248 case _IterNonSymlink:
2249 case _RefreshNonSymlink:
2250 file_status __st(__data_.__type_);
2251 if (__ec && !_VSTD_FS::exists(__st))
2252 *__ec = make_error_code(errc::no_such_file_or_directory);
2253 else if (__ec)
2254 __ec->clear();
2255 return __data_.__type_;
2256 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002257 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002258 }
2259
2260 _LIBCPP_INLINE_VISIBILITY
2261 file_type __get_ft(error_code *__ec = nullptr) const {
2262 switch (__data_.__cache_type_) {
2263 case _Empty:
2264 case _IterSymlink:
2265 case _RefreshSymlinkUnresolved:
2266 return __status(__p_, __ec).type();
2267 case _IterNonSymlink:
2268 case _RefreshNonSymlink:
2269 case _RefreshSymlink: {
2270 file_status __st(__data_.__type_);
2271 if (__ec && !_VSTD_FS::exists(__st))
2272 *__ec = make_error_code(errc::no_such_file_or_directory);
2273 else if (__ec)
2274 __ec->clear();
2275 return __data_.__type_;
2276 }
2277 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002278 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002279 }
2280
2281 _LIBCPP_INLINE_VISIBILITY
2282 file_status __get_status(error_code *__ec = nullptr) const {
2283 switch (__data_.__cache_type_) {
2284 case _Empty:
2285 case _IterNonSymlink:
2286 case _IterSymlink:
2287 case _RefreshSymlinkUnresolved:
2288 return __status(__p_, __ec);
2289 case _RefreshNonSymlink:
2290 case _RefreshSymlink:
2291 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2292 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002293 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002294 }
2295
2296 _LIBCPP_INLINE_VISIBILITY
2297 file_status __get_symlink_status(error_code *__ec = nullptr) const {
2298 switch (__data_.__cache_type_) {
2299 case _Empty:
2300 case _IterNonSymlink:
2301 case _IterSymlink:
2302 return __symlink_status(__p_, __ec);
2303 case _RefreshNonSymlink:
2304 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2305 case _RefreshSymlink:
2306 case _RefreshSymlinkUnresolved:
2307 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2308 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002309 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002310 }
2311
2312
2313 _LIBCPP_INLINE_VISIBILITY
2314 uintmax_t __get_size(error_code *__ec = nullptr) const {
2315 switch (__data_.__cache_type_) {
2316 case _Empty:
2317 case _IterNonSymlink:
2318 case _IterSymlink:
2319 case _RefreshSymlinkUnresolved:
2320 return _VSTD_FS::__file_size(__p_, __ec);
2321 case _RefreshSymlink:
2322 case _RefreshNonSymlink: {
2323 error_code __m_ec;
2324 file_status __st(__get_ft(&__m_ec));
2325 __handle_error("directory_entry::file_size", __ec, __m_ec);
2326 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2327 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2328 : errc::not_supported;
2329 __handle_error("directory_entry::file_size", __ec,
2330 make_error_code(__err_kind));
2331 }
2332 return __data_.__size_;
2333 }
2334 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002335 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002336 }
2337
2338 _LIBCPP_INLINE_VISIBILITY
2339 uintmax_t __get_nlink(error_code *__ec = nullptr) const {
2340 switch (__data_.__cache_type_) {
2341 case _Empty:
2342 case _IterNonSymlink:
2343 case _IterSymlink:
2344 case _RefreshSymlinkUnresolved:
2345 return _VSTD_FS::__hard_link_count(__p_, __ec);
2346 case _RefreshSymlink:
2347 case _RefreshNonSymlink: {
2348 error_code __m_ec;
2349 (void)__get_ft(&__m_ec);
2350 __handle_error("directory_entry::hard_link_count", __ec, __m_ec);
2351 return __data_.__nlink_;
2352 }
2353 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002354 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002355 }
2356
2357 _LIBCPP_INLINE_VISIBILITY
2358 file_time_type __get_write_time(error_code *__ec = nullptr) const {
2359 switch (__data_.__cache_type_) {
2360 case _Empty:
2361 case _IterNonSymlink:
2362 case _IterSymlink:
2363 case _RefreshSymlinkUnresolved:
2364 return _VSTD_FS::__last_write_time(__p_, __ec);
2365 case _RefreshSymlink:
2366 case _RefreshNonSymlink: {
2367 error_code __m_ec;
2368 file_status __st(__get_ft(&__m_ec));
2369 __handle_error("directory_entry::last_write_time", __ec, __m_ec);
2370 if (_VSTD_FS::exists(__st) &&
2371 __data_.__write_time_ == file_time_type::min())
2372 __handle_error("directory_entry::last_write_time", __ec,
2373 make_error_code(errc::value_too_large));
2374 return __data_.__write_time_;
2375 }
2376 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002377 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002378 }
Eric Fiselier435db152016-06-17 19:46:40 +00002379private:
2380 _Path __p_;
Eric Fiselier70474082018-07-20 01:22:32 +00002381 __cached_data __data_;
Eric Fiselier435db152016-06-17 19:46:40 +00002382};
2383
Eric Fiselier435db152016-06-17 19:46:40 +00002384class __dir_element_proxy {
2385public:
2386
2387 inline _LIBCPP_INLINE_VISIBILITY
2388 directory_entry operator*() { return _VSTD::move(__elem_); }
2389
2390private:
2391 friend class directory_iterator;
2392 friend class recursive_directory_iterator;
2393 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2394 __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
2395 directory_entry __elem_;
2396};
2397
2398class directory_iterator
2399{
2400public:
2401 typedef directory_entry value_type;
2402 typedef ptrdiff_t difference_type;
2403 typedef value_type const* pointer;
2404 typedef value_type const& reference;
2405 typedef input_iterator_tag iterator_category;
2406
2407public:
2408 //ctor & dtor
2409 directory_iterator() _NOEXCEPT
2410 { }
2411
2412 explicit directory_iterator(const path& __p)
2413 : directory_iterator(__p, nullptr)
2414 { }
2415
2416 directory_iterator(const path& __p, directory_options __opts)
2417 : directory_iterator(__p, nullptr, __opts)
2418 { }
2419
Eric Fiselierd56d5322017-10-30 18:59:59 +00002420 directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002421 : directory_iterator(__p, &__ec)
2422 { }
2423
2424 directory_iterator(const path& __p, directory_options __opts,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002425 error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002426 : directory_iterator(__p, &__ec, __opts)
2427 { }
2428
2429 directory_iterator(const directory_iterator&) = default;
2430 directory_iterator(directory_iterator&&) = default;
2431 directory_iterator& operator=(const directory_iterator&) = default;
2432
2433 directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
2434 // non-default implementation provided to support self-move assign.
2435 if (this != &__o) {
2436 __imp_ = _VSTD::move(__o.__imp_);
2437 }
2438 return *this;
2439 }
2440
2441 ~directory_iterator() = default;
2442
2443 const directory_entry& operator*() const {
2444 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002445 return __dereference();
Eric Fiselier435db152016-06-17 19:46:40 +00002446 }
2447
2448 const directory_entry* operator->() const
2449 { return &**this; }
2450
2451 directory_iterator& operator++()
2452 { return __increment(); }
2453
2454 __dir_element_proxy operator++(int) {
2455 __dir_element_proxy __p(**this);
2456 __increment();
2457 return __p;
2458 }
2459
Eric Fiselierd56d5322017-10-30 18:59:59 +00002460 directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002461 { return __increment(&__ec); }
2462
2463private:
Eric Fiselier28175a32016-09-16 00:07:16 +00002464 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002465 friend bool operator==(const directory_iterator& __lhs,
2466 const directory_iterator& __rhs) _NOEXCEPT;
2467
2468 // construct the dir_stream
2469 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002470 directory_iterator(const path&, error_code *,
2471 directory_options = directory_options::none);
2472
Eric Fiselier435db152016-06-17 19:46:40 +00002473 _LIBCPP_FUNC_VIS
2474 directory_iterator& __increment(error_code * __ec = nullptr);
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002475
Eric Fiselier435db152016-06-17 19:46:40 +00002476 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002477 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002478
2479private:
2480 shared_ptr<__dir_stream> __imp_;
2481};
2482
2483
2484inline _LIBCPP_INLINE_VISIBILITY
2485bool operator==(const directory_iterator& __lhs,
2486 const directory_iterator& __rhs) _NOEXCEPT {
2487 return __lhs.__imp_ == __rhs.__imp_;
2488}
2489
2490inline _LIBCPP_INLINE_VISIBILITY
2491bool operator!=(const directory_iterator& __lhs,
2492 const directory_iterator& __rhs) _NOEXCEPT {
2493 return !(__lhs == __rhs);
2494}
2495
2496// enable directory_iterator range-based for statements
2497inline _LIBCPP_INLINE_VISIBILITY
2498directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
2499 return __iter;
2500}
2501
2502inline _LIBCPP_INLINE_VISIBILITY
2503directory_iterator end(const directory_iterator&) _NOEXCEPT {
2504 return directory_iterator();
2505}
2506
2507class recursive_directory_iterator {
2508public:
2509 using value_type = directory_entry;
2510 using difference_type = std::ptrdiff_t;
2511 using pointer = directory_entry const *;
2512 using reference = directory_entry const &;
2513 using iterator_category = std::input_iterator_tag;
2514
2515public:
2516 // constructors and destructor
2517 _LIBCPP_INLINE_VISIBILITY
2518 recursive_directory_iterator() _NOEXCEPT
2519 : __rec_(false)
2520 {}
2521
2522 _LIBCPP_INLINE_VISIBILITY
2523 explicit recursive_directory_iterator(const path& __p,
2524 directory_options __xoptions = directory_options::none)
2525 : recursive_directory_iterator(__p, __xoptions, nullptr)
2526 { }
2527
2528 _LIBCPP_INLINE_VISIBILITY
2529 recursive_directory_iterator(const path& __p,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002530 directory_options __xoptions, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002531 : recursive_directory_iterator(__p, __xoptions, &__ec)
2532 { }
2533
2534 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002535 recursive_directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002536 : recursive_directory_iterator(__p, directory_options::none, &__ec)
2537 { }
2538
2539 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2540 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2541
2542 recursive_directory_iterator &
2543 operator=(const recursive_directory_iterator&) = default;
2544
2545 _LIBCPP_INLINE_VISIBILITY
2546 recursive_directory_iterator &
2547 operator=(recursive_directory_iterator&& __o) noexcept {
2548 // non-default implementation provided to support self-move assign.
2549 if (this != &__o) {
2550 __imp_ = _VSTD::move(__o.__imp_);
2551 __rec_ = __o.__rec_;
2552 }
2553 return *this;
2554 }
2555
2556 ~recursive_directory_iterator() = default;
2557
2558 _LIBCPP_INLINE_VISIBILITY
2559 const directory_entry& operator*() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002560 { return __dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002561
2562 _LIBCPP_INLINE_VISIBILITY
2563 const directory_entry* operator->() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002564 { return &__dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002565
2566 recursive_directory_iterator& operator++()
2567 { return __increment(); }
2568
2569 _LIBCPP_INLINE_VISIBILITY
2570 __dir_element_proxy operator++(int) {
2571 __dir_element_proxy __p(**this);
2572 __increment();
2573 return __p;
2574 }
2575
2576 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002577 recursive_directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002578 { return __increment(&__ec); }
2579
2580 _LIBCPP_FUNC_VIS directory_options options() const;
2581 _LIBCPP_FUNC_VIS int depth() const;
2582
2583 _LIBCPP_INLINE_VISIBILITY
2584 void pop() { __pop(); }
2585
2586 _LIBCPP_INLINE_VISIBILITY
2587 void pop(error_code& __ec)
2588 { __pop(&__ec); }
2589
2590 _LIBCPP_INLINE_VISIBILITY
2591 bool recursion_pending() const
2592 { return __rec_; }
2593
2594 _LIBCPP_INLINE_VISIBILITY
2595 void disable_recursion_pending()
2596 { __rec_ = false; }
2597
2598private:
2599 recursive_directory_iterator(const path& __p, directory_options __opt,
2600 error_code *__ec);
2601
2602 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002603 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002604
2605 _LIBCPP_FUNC_VIS
2606 bool __try_recursion(error_code* __ec);
2607
2608 _LIBCPP_FUNC_VIS
2609 void __advance(error_code* __ec=nullptr);
2610
2611 _LIBCPP_FUNC_VIS
2612 recursive_directory_iterator& __increment(error_code *__ec=nullptr);
2613
2614 _LIBCPP_FUNC_VIS
2615 void __pop(error_code* __ec=nullptr);
2616
Eric Fiselier28175a32016-09-16 00:07:16 +00002617 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002618 friend bool operator==(const recursive_directory_iterator&,
2619 const recursive_directory_iterator&) _NOEXCEPT;
2620
2621 struct __shared_imp;
2622 shared_ptr<__shared_imp> __imp_;
2623 bool __rec_;
2624}; // class recursive_directory_iterator
2625
2626
Eric Fiselier28175a32016-09-16 00:07:16 +00002627inline _LIBCPP_INLINE_VISIBILITY
2628bool operator==(const recursive_directory_iterator& __lhs,
2629 const recursive_directory_iterator& __rhs) _NOEXCEPT
Eric Fiselier435db152016-06-17 19:46:40 +00002630{
2631 return __lhs.__imp_ == __rhs.__imp_;
2632}
2633
2634_LIBCPP_INLINE_VISIBILITY
2635inline bool operator!=(const recursive_directory_iterator& __lhs,
2636 const recursive_directory_iterator& __rhs) _NOEXCEPT
2637{
2638 return !(__lhs == __rhs);
2639}
2640// enable recursive_directory_iterator range-based for statements
2641inline _LIBCPP_INLINE_VISIBILITY
2642recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
2643 return __iter;
2644}
2645
2646inline _LIBCPP_INLINE_VISIBILITY
2647recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
2648 return recursive_directory_iterator();
2649}
2650
2651_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
2652
Eric Fiselier3ad58be2018-07-20 01:51:48 +00002653_LIBCPP_POP_MACROS
2654
Eric Fiselier435db152016-06-17 19:46:40 +00002655#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM