blob: 6481aa680a23730cdc166c7ca11addc4095c23ca [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
254#define __cpp_lib_experimental_filesystem 201406
255
256_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
257
258typedef chrono::time_point<std::chrono::system_clock> file_time_type;
259
260struct _LIBCPP_TYPE_VIS space_info
261{
262 uintmax_t capacity;
263 uintmax_t free;
264 uintmax_t available;
265};
266
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000267enum class _LIBCPP_ENUM_VIS file_type : signed char
Eric Fiselier435db152016-06-17 19:46:40 +0000268{
269 none = 0,
270 not_found = -1,
271 regular = 1,
272 directory = 2,
273 symlink = 3,
274 block = 4,
275 character = 5,
276 fifo = 6,
277 socket = 7,
278 unknown = 8
279};
280
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000281enum class _LIBCPP_ENUM_VIS perms : unsigned
Eric Fiselier435db152016-06-17 19:46:40 +0000282{
283 none = 0,
284
285 owner_read = 0400,
286 owner_write = 0200,
287 owner_exec = 0100,
288 owner_all = 0700,
289
290 group_read = 040,
291 group_write = 020,
292 group_exec = 010,
293 group_all = 070,
294
295 others_read = 04,
296 others_write = 02,
297 others_exec = 01,
298 others_all = 07,
299
300 all = 0777,
301
302 set_uid = 04000,
303 set_gid = 02000,
304 sticky_bit = 01000,
305 mask = 07777,
306 unknown = 0xFFFF,
Eric Fiselier435db152016-06-17 19:46:40 +0000307};
308
309_LIBCPP_INLINE_VISIBILITY
310inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
311{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
312
313_LIBCPP_INLINE_VISIBILITY
314inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
315{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
316
317_LIBCPP_INLINE_VISIBILITY
318inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
319{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
320
321_LIBCPP_INLINE_VISIBILITY
322inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
323{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
324
325_LIBCPP_INLINE_VISIBILITY
326inline perms& operator&=(perms& _LHS, perms _RHS)
327{ return _LHS = _LHS & _RHS; }
328
329_LIBCPP_INLINE_VISIBILITY
330inline perms& operator|=(perms& _LHS, perms _RHS)
331{ return _LHS = _LHS | _RHS; }
332
333_LIBCPP_INLINE_VISIBILITY
334inline perms& operator^=(perms& _LHS, perms _RHS)
335{ return _LHS = _LHS ^ _RHS; }
336
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +0000337enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
338 replace = 1,
339 add = 2,
340 remove = 4,
341 nofollow = 8
342};
343
344_LIBCPP_INLINE_VISIBILITY
345inline _LIBCPP_CONSTEXPR perm_options operator&(perm_options _LHS, perm_options _RHS)
346{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
347
348_LIBCPP_INLINE_VISIBILITY
349inline _LIBCPP_CONSTEXPR perm_options operator|(perm_options _LHS, perm_options _RHS)
350{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
351
352_LIBCPP_INLINE_VISIBILITY
353inline _LIBCPP_CONSTEXPR perm_options operator^(perm_options _LHS, perm_options _RHS)
354{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
355
356_LIBCPP_INLINE_VISIBILITY
357inline _LIBCPP_CONSTEXPR perm_options operator~(perm_options _LHS)
358{ return static_cast<perm_options>(~static_cast<unsigned>(_LHS)); }
359
360_LIBCPP_INLINE_VISIBILITY
361inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS)
362{ return _LHS = _LHS & _RHS; }
363
364_LIBCPP_INLINE_VISIBILITY
365inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS)
366{ return _LHS = _LHS | _RHS; }
367
368_LIBCPP_INLINE_VISIBILITY
369inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS)
370{ return _LHS = _LHS ^ _RHS; }
371
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000372enum class _LIBCPP_ENUM_VIS copy_options : unsigned short
Eric Fiselier435db152016-06-17 19:46:40 +0000373{
374 none = 0,
375 skip_existing = 1,
376 overwrite_existing = 2,
377 update_existing = 4,
378 recursive = 8,
379 copy_symlinks = 16,
380 skip_symlinks = 32,
381 directories_only = 64,
382 create_symlinks = 128,
383 create_hard_links = 256,
384 __in_recursive_copy = 512,
385};
386
387_LIBCPP_INLINE_VISIBILITY
388inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
389{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
390
391_LIBCPP_INLINE_VISIBILITY
392inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
393{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
394
395_LIBCPP_INLINE_VISIBILITY
396inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
397{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
398
399_LIBCPP_INLINE_VISIBILITY
400inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
401{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
402
403_LIBCPP_INLINE_VISIBILITY
404inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
405{ return _LHS = _LHS & _RHS; }
406
407_LIBCPP_INLINE_VISIBILITY
408inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
409{ return _LHS = _LHS | _RHS; }
410
411_LIBCPP_INLINE_VISIBILITY
412inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
413{ return _LHS = _LHS ^ _RHS; }
414
415
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000416enum class _LIBCPP_ENUM_VIS directory_options : unsigned char
Eric Fiselier435db152016-06-17 19:46:40 +0000417{
418 none = 0,
419 follow_directory_symlink = 1,
420 skip_permission_denied = 2
421};
422
423_LIBCPP_INLINE_VISIBILITY
424inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
425{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
426
427_LIBCPP_INLINE_VISIBILITY
428inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
429{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
430
431_LIBCPP_INLINE_VISIBILITY
432inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
433{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
434
435_LIBCPP_INLINE_VISIBILITY
436inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
437{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
438
439_LIBCPP_INLINE_VISIBILITY
440inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
441{ return _LHS = _LHS & _RHS; }
442
443_LIBCPP_INLINE_VISIBILITY
444inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
445{ return _LHS = _LHS | _RHS; }
446
447_LIBCPP_INLINE_VISIBILITY
448inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
449{ return _LHS = _LHS ^ _RHS; }
450
451
452class _LIBCPP_TYPE_VIS file_status
453{
454public:
455 // constructors
456 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6afd7e82017-03-06 21:02:06 +0000457 file_status() _NOEXCEPT : file_status(file_type::none) {}
458 _LIBCPP_INLINE_VISIBILITY
459 explicit file_status(file_type __ft,
460 perms __prms = perms::unknown) _NOEXCEPT
Eric Fiselier435db152016-06-17 19:46:40 +0000461 : __ft_(__ft), __prms_(__prms)
462 {}
463
464 file_status(const file_status&) _NOEXCEPT = default;
465 file_status(file_status&&) _NOEXCEPT = default;
466
467 _LIBCPP_INLINE_VISIBILITY
468 ~file_status() {}
469
470 file_status& operator=(const file_status&) _NOEXCEPT = default;
471 file_status& operator=(file_status&&) _NOEXCEPT = default;
472
473 // observers
Louis Dionne16fe2952018-07-11 23:14:33 +0000474 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000475 file_type type() const _NOEXCEPT {
476 return __ft_;
477 }
478
Louis Dionne16fe2952018-07-11 23:14:33 +0000479 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000480 perms permissions() const _NOEXCEPT {
481 return __prms_;
482 }
483
484 // modifiers
Louis Dionne16fe2952018-07-11 23:14:33 +0000485 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000486 void type(file_type __ft) _NOEXCEPT {
487 __ft_ = __ft;
488 }
489
Louis Dionne16fe2952018-07-11 23:14:33 +0000490 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000491 void permissions(perms __p) _NOEXCEPT {
492 __prms_ = __p;
493 }
494private:
495 file_type __ft_;
496 perms __prms_;
497};
498
499class _LIBCPP_TYPE_VIS directory_entry;
500
501template <class _Tp> struct __can_convert_char {
502 static const bool value = false;
503};
Eric Fiselierc355aa32016-08-28 21:26:01 +0000504template <class _Tp> struct __can_convert_char<const _Tp>
505 : public __can_convert_char<_Tp> {
506};
Eric Fiselier435db152016-06-17 19:46:40 +0000507template <> struct __can_convert_char<char> {
508 static const bool value = true;
509 using __char_type = char;
510};
511template <> struct __can_convert_char<wchar_t> {
512 static const bool value = true;
513 using __char_type = wchar_t;
514};
515template <> struct __can_convert_char<char16_t> {
516 static const bool value = true;
517 using __char_type = char16_t;
518};
519template <> struct __can_convert_char<char32_t> {
520 static const bool value = true;
521 using __char_type = char32_t;
522};
523
524template <class _ECharT>
525typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
526__is_separator(_ECharT __e) {
527 return __e == _ECharT('/');
528};
529
530struct _NullSentinal {};
531
532template <class _Tp>
533using _Void = void;
534
535template <class _Tp, class = void>
536struct __is_pathable_string : public false_type {};
537
538template <class _ECharT, class _Traits, class _Alloc>
539struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
540 _Void<typename __can_convert_char<_ECharT>::__char_type>>
541: public __can_convert_char<_ECharT>
542{
543 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
544 using _Base = __can_convert_char<_ECharT>;
545 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
546 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
547 static _ECharT __first_or_null(_Str const& __s) {
548 return __s.empty() ? _ECharT{} : __s[0];
549 }
550};
551
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000552
553template <class _ECharT, class _Traits>
554struct __is_pathable_string<basic_string_view<_ECharT, _Traits>,
555 _Void<typename __can_convert_char<_ECharT>::__char_type>>
556: public __can_convert_char<_ECharT>
557{
558 using _Str = basic_string_view<_ECharT, _Traits>;
559 using _Base = __can_convert_char<_ECharT>;
560 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
561 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
562 static _ECharT __first_or_null(_Str const& __s) {
563 return __s.empty() ? _ECharT{} : __s[0];
564 }
565};
566
Eric Fiselier435db152016-06-17 19:46:40 +0000567template <class _Source,
568 class _DS = typename decay<_Source>::type,
569 class _UnqualPtrType = typename remove_const<
570 typename remove_pointer<_DS>::type>::type,
571 bool _IsCharPtr = is_pointer<_DS>::value &&
572 __can_convert_char<_UnqualPtrType>::value
573 >
574struct __is_pathable_char_array : false_type {};
575
576template <class _Source, class _ECharT, class _UPtr>
577struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
578 : __can_convert_char<typename remove_const<_ECharT>::type>
579{
580 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
581
582 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
583 static _ECharT const* __range_end(const _ECharT* __b)
584 {
585 using _Iter = const _ECharT*;
586 const _ECharT __sentinal = _ECharT{};
587 _Iter __e = __b;
588 for (; *__e != __sentinal; ++__e)
589 ;
590 return __e;
591 }
592
593 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
594};
595
596template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
597struct __is_pathable_iter : false_type {};
598
599template <class _Iter>
600struct __is_pathable_iter<_Iter, true,
601 _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
602 : __can_convert_char<typename iterator_traits<_Iter>::value_type>
603{
604 using _ECharT = typename iterator_traits<_Iter>::value_type;
605 using _Base = __can_convert_char<_ECharT>;
606
607 static _Iter __range_begin(_Iter __b) { return __b; }
608 static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
609
610 static _ECharT __first_or_null(_Iter __b) { return *__b; }
611};
612
613template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
614 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
615 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
616 >
617struct __is_pathable : false_type {
618 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
619};
620
621template <class _Tp>
622struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
623
624
625template <class _Tp>
626struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
627
628
629template <class _Tp>
630struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
631
632
633template <class _ECharT>
634struct _PathCVT {
635 static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
636
637 typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
638
639 static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) {
640 _Narrower()(back_inserter(__dest), __b, __e);
641 }
642
643 template <class _Iter>
644 static void __append_range(string& __dest, _Iter __b, _Iter __e) {
645 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
646 if (__b == __e) return;
647 basic_string<_ECharT> __tmp(__b, __e);
648 _Narrower()(back_inserter(__dest), __tmp.data(),
649 __tmp.data() + __tmp.length());
650 }
651
652 template <class _Iter>
653 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
654 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
655 const _ECharT __sentinal = _ECharT{};
656 if (*__b == __sentinal) return;
657 basic_string<_ECharT> __tmp;
658 for (; *__b != __sentinal; ++__b)
659 __tmp.push_back(*__b);
660 _Narrower()(back_inserter(__dest), __tmp.data(),
661 __tmp.data() + __tmp.length());
662 }
663
664 template <class _Source>
665 static void __append_source(string& __dest, _Source const& __s)
666 {
667 using _Traits = __is_pathable<_Source>;
668 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
669 }
670};
671
672template <>
673struct _PathCVT<char> {
Eric Fiselier70027d62016-10-30 23:53:50 +0000674
Eric Fiselier435db152016-06-17 19:46:40 +0000675 template <class _Iter>
Eric Fiselierdb7ee8f2016-10-31 02:46:25 +0000676 static typename enable_if<
677 __is_exactly_input_iterator<_Iter>::value
678 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
679 for (; __b != __e; ++__b)
680 __dest.push_back(*__b);
681 }
682
683 template <class _Iter>
684 static typename enable_if<
685 __is_forward_iterator<_Iter>::value
686 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
687 __dest.__append_forward_unsafe(__b, __e);
Eric Fiselier435db152016-06-17 19:46:40 +0000688 }
689
690 template <class _Iter>
691 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
692 const char __sentinal = char{};
693 for (; *__b != __sentinal; ++__b)
694 __dest.push_back(*__b);
695 }
696
697 template <class _Source>
698 static void __append_source(string& __dest, _Source const& __s)
699 {
700 using _Traits = __is_pathable<_Source>;
Eric Fiselier70027d62016-10-30 23:53:50 +0000701 __append_range(__dest, _Traits::__range_begin(__s),
702 _Traits::__range_end(__s));
Eric Fiselier435db152016-06-17 19:46:40 +0000703 }
704};
705
706
707class _LIBCPP_TYPE_VIS path
708{
709 template <class _SourceOrIter, class _Tp = path&>
710 using _EnableIfPathable = typename
711 enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
712
713 template <class _Tp>
714 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
715
716 template <class _Tp>
717 using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
718
719public:
720 typedef char value_type;
721 typedef basic_string<value_type> string_type;
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000722 typedef _VSTD::string_view __string_view;
Eric Fiselier435db152016-06-17 19:46:40 +0000723 static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
724
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000725 enum class _LIBCPP_ENUM_VIS format : unsigned char {
726 auto_format,
727 native_format,
728 generic_format
729 };
730
Eric Fiselier435db152016-06-17 19:46:40 +0000731 // constructors and destructor
732 _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
733 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
734 _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
735
736 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000737 path(string_type&& __s, format = format::auto_format) _NOEXCEPT
738 : __pn_(_VSTD::move(__s)) {}
Eric Fiselier435db152016-06-17 19:46:40 +0000739
740 template <
741 class _Source,
742 class = _EnableIfPathable<_Source, void>
743 >
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000744 path(const _Source& __src, format = format::auto_format) {
Eric Fiselier435db152016-06-17 19:46:40 +0000745 _SourceCVT<_Source>::__append_source(__pn_, __src);
746 }
747
748 template <class _InputIt>
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000749 path(_InputIt __first, _InputIt __last, format = format::auto_format) {
Eric Fiselier435db152016-06-17 19:46:40 +0000750 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
751 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
752 }
753
754 // TODO Implement locale conversions.
755 template <class _Source,
756 class = _EnableIfPathable<_Source, void>
757 >
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000758 path(const _Source& __src, const locale& __loc,
759 format = format::auto_format);
Eric Fiselier435db152016-06-17 19:46:40 +0000760 template <class _InputIt>
Eric Fiselierb5b088c2018-04-02 23:35:24 +0000761 path(_InputIt __first, _InputIt _last, const locale& __loc,
762 format = format::auto_format);
Eric Fiselier435db152016-06-17 19:46:40 +0000763
764 _LIBCPP_INLINE_VISIBILITY
765 ~path() = default;
766
767 // assignments
768 _LIBCPP_INLINE_VISIBILITY
769 path& operator=(const path& __p) {
770 __pn_ = __p.__pn_;
771 return *this;
772 }
773
774 _LIBCPP_INLINE_VISIBILITY
775 path& operator=(path&& __p) _NOEXCEPT {
776 __pn_ = _VSTD::move(__p.__pn_);
777 return *this;
778 }
779
Eric Fiselier8beffc82017-01-18 05:48:55 +0000780 template <class = void>
Eric Fiselier435db152016-06-17 19:46:40 +0000781 _LIBCPP_INLINE_VISIBILITY
782 path& operator=(string_type&& __s) _NOEXCEPT {
783 __pn_ = _VSTD::move(__s);
784 return *this;
785 }
786
787 _LIBCPP_INLINE_VISIBILITY
788 path& assign(string_type&& __s) _NOEXCEPT {
789 __pn_ = _VSTD::move(__s);
790 return *this;
791 }
792
793 template <class _Source>
794 _LIBCPP_INLINE_VISIBILITY
795 _EnableIfPathable<_Source>
796 operator=(const _Source& __src)
797 { return this->assign(__src); }
798
799
800 template <class _Source>
801 _EnableIfPathable<_Source>
802 assign(const _Source& __src) {
803 __pn_.clear();
804 _SourceCVT<_Source>::__append_source(__pn_, __src);
805 return *this;
806 }
807
808 template <class _InputIt>
809 path& assign(_InputIt __first, _InputIt __last) {
810 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
811 __pn_.clear();
812 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
813 return *this;
814 }
815
816private:
817 template <class _ECharT>
Eric Fiselier91a182b2018-04-02 23:03:41 +0000818 static bool __source_is_absolute(_ECharT __first_or_null) {
819 return __is_separator(__first_or_null);
Eric Fiselier435db152016-06-17 19:46:40 +0000820 }
821
822public:
823 // appends
824 path& operator/=(const path& __p) {
Eric Fiselier91a182b2018-04-02 23:03:41 +0000825 if (__p.is_absolute()) {
826 __pn_ = __p.__pn_;
827 return *this;
828 }
829 if (has_filename())
830 __pn_ += preferred_separator;
Eric Fiselier435db152016-06-17 19:46:40 +0000831 __pn_ += __p.native();
832 return *this;
833 }
834
Eric Fiselier91a182b2018-04-02 23:03:41 +0000835 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
836 // is known at compile time to be "/' since the user almost certainly intended
837 // to append a separator instead of overwriting the path with "/"
Eric Fiselier435db152016-06-17 19:46:40 +0000838 template <class _Source>
839 _LIBCPP_INLINE_VISIBILITY
840 _EnableIfPathable<_Source>
841 operator/=(const _Source& __src) {
842 return this->append(__src);
843 }
844
845 template <class _Source>
846 _EnableIfPathable<_Source>
847 append(const _Source& __src) {
848 using _Traits = __is_pathable<_Source>;
849 using _CVT = _PathCVT<_SourceChar<_Source>>;
Eric Fiselier91a182b2018-04-02 23:03:41 +0000850 if (__source_is_absolute(_Traits::__first_or_null(__src)))
851 __pn_.clear();
852 else if (has_filename())
853 __pn_ += preferred_separator;
Eric Fiselier435db152016-06-17 19:46:40 +0000854 _CVT::__append_source(__pn_, __src);
855 return *this;
856 }
857
858 template <class _InputIt>
859 path& append(_InputIt __first, _InputIt __last) {
860 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
861 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
862 using _CVT = _PathCVT<_ItVal>;
Eric Fiselier91a182b2018-04-02 23:03:41 +0000863 if (__first != __last && __source_is_absolute(*__first))
864 __pn_.clear();
865 else if (has_filename())
866 __pn_ += preferred_separator;
867 _CVT::__append_range(__pn_, __first, __last);
Eric Fiselier435db152016-06-17 19:46:40 +0000868 return *this;
869 }
870
871 // concatenation
872 _LIBCPP_INLINE_VISIBILITY
873 path& operator+=(const path& __x) {
874 __pn_ += __x.__pn_;
875 return *this;
876 }
877
878 _LIBCPP_INLINE_VISIBILITY
879 path& operator+=(const string_type& __x) {
880 __pn_ += __x;
881 return *this;
882 }
883
884 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb05e1b02016-07-23 03:10:56 +0000885 path& operator+=(__string_view __x) {
886 __pn_ += __x;
887 return *this;
888 }
889
890 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +0000891 path& operator+=(const value_type* __x) {
892 __pn_ += __x;
893 return *this;
894 }
895
896 _LIBCPP_INLINE_VISIBILITY
897 path& operator+=(value_type __x) {
898 __pn_ += __x;
899 return *this;
900 }
901
Eric Fiselier435db152016-06-17 19:46:40 +0000902 template <class _ECharT>
903 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
904 operator+=(_ECharT __x)
905 {
906 basic_string<_ECharT> __tmp;
907 __tmp += __x;
908 _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
909 return *this;
910 }
911
912 template <class _Source>
913 _EnableIfPathable<_Source>
914 operator+=(const _Source& __x) {
915 return this->concat(__x);
916 }
917
918 template <class _Source>
919 _EnableIfPathable<_Source>
920 concat(const _Source& __x) {
921 _SourceCVT<_Source>::__append_source(__pn_, __x);
922 return *this;
923 }
924
925 template <class _InputIt>
926 path& concat(_InputIt __first, _InputIt __last) {
927 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
928 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
929 return *this;
930 }
931
932 // modifiers
933 _LIBCPP_INLINE_VISIBILITY
934 void clear() _NOEXCEPT {
935 __pn_.clear();
936 }
937
938 path& make_preferred() { return *this; }
Eric Fiselierf08063a2016-10-15 22:37:42 +0000939
940 _LIBCPP_INLINE_VISIBILITY
941 path& remove_filename() {
Eric Fiselier91a182b2018-04-02 23:03:41 +0000942 auto __fname = __filename();
943 if (!__fname.empty())
944 __pn_.erase(__fname.data() - __pn_.data());
Eric Fiselierf08063a2016-10-15 22:37:42 +0000945 return *this;
946 }
Eric Fiselier435db152016-06-17 19:46:40 +0000947
948 path& replace_filename(const path& __replacement) {
949 remove_filename();
950 return (*this /= __replacement);
951 }
952
953 path& replace_extension(const path& __replacement = path());
954
955 _LIBCPP_INLINE_VISIBILITY
956 void swap(path& __rhs) _NOEXCEPT {
957 __pn_.swap(__rhs.__pn_);
958 }
959
Eric Fiselier91a182b2018-04-02 23:03:41 +0000960 // private helper to allow reserving memory in the path
961 _LIBCPP_INLINE_VISIBILITY
962 void __reserve(size_t __s) { __pn_.reserve(__s); }
963
Eric Fiselier435db152016-06-17 19:46:40 +0000964 // native format observers
965 _LIBCPP_INLINE_VISIBILITY
966 const string_type& native() const _NOEXCEPT {
967 return __pn_;
968 }
969
970 _LIBCPP_INLINE_VISIBILITY
971 const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
972
973 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
974
975 template <class _ECharT, class _Traits = char_traits<_ECharT>,
976 class _Allocator = allocator<_ECharT> >
977 basic_string<_ECharT, _Traits, _Allocator>
978 string(const _Allocator& __a = _Allocator()) const {
979 using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
980 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
981 _Str __s(__a);
982 __s.reserve(__pn_.size());
983 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
984 return __s;
985 }
986
987 _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
988 _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); }
989 _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
990 _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
991 _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
992
993 // generic format observers
994 template <class _ECharT, class _Traits = char_traits<_ECharT>,
995 class _Allocator = allocator<_ECharT>
996 >
997 basic_string<_ECharT, _Traits, _Allocator>
998 generic_string(const _Allocator& __a = _Allocator()) const {
999 return string<_ECharT, _Traits, _Allocator>(__a);
1000 }
1001
1002 std::string generic_string() const { return __pn_; }
1003 std::wstring generic_wstring() const { return string<wchar_t>(); }
1004 std::string generic_u8string() const { return __pn_; }
1005 std::u16string generic_u16string() const { return string<char16_t>(); }
1006 std::u32string generic_u32string() const { return string<char32_t>(); }
1007
1008private:
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001009 int __compare(__string_view) const;
1010 __string_view __root_name() const;
1011 __string_view __root_directory() const;
1012 __string_view __root_path_raw() const;
1013 __string_view __relative_path() const;
1014 __string_view __parent_path() const;
1015 __string_view __filename() const;
1016 __string_view __stem() const;
1017 __string_view __extension() const;
Eric Fiselier435db152016-06-17 19:46:40 +00001018
1019public:
1020 // compare
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001021 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);}
1022 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); }
1023 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); }
Eric Fiselier435db152016-06-17 19:46:40 +00001024 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
1025
1026 // decomposition
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001027 _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); }
1028 _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); }
1029 _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); }
1030 _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); }
1031 _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); }
1032 _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); }
1033 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());}
1034 _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); }
Eric Fiselier435db152016-06-17 19:46:40 +00001035
1036 // query
Marshall Clow8c5edfe2017-11-16 05:48:32 +00001037 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1038 bool empty() const _NOEXCEPT { return __pn_.empty(); }
Eric Fiselier435db152016-06-17 19:46:40 +00001039
1040 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); }
1041 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
Eric Fiselierf08063a2016-10-15 22:37:42 +00001042 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); }
Eric Fiselier435db152016-06-17 19:46:40 +00001043 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); }
1044 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); }
1045 _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); }
1046 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1047 _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); }
1048
1049 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
1050 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1051
Eric Fiselier91a182b2018-04-02 23:03:41 +00001052 // relative paths
1053 path lexically_normal() const;
1054 path lexically_relative(const path& __base) const;
1055
1056 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1057 path __result = this->lexically_relative(__base);
1058 if (__result.native().empty())
1059 return *this;
1060 return __result;
1061 }
1062
Eric Fiselier435db152016-06-17 19:46:40 +00001063 // iterators
1064 class _LIBCPP_TYPE_VIS iterator;
1065 typedef iterator const_iterator;
1066
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001067 iterator begin() const;
1068 iterator end() const;
Eric Fiselier435db152016-06-17 19:46:40 +00001069
Eric Fiselier2cd75272018-02-04 03:10:53 +00001070
1071 template <class _CharT, class _Traits>
1072 _LIBCPP_INLINE_VISIBILITY
1073 friend typename enable_if<is_same<_CharT, char>::value &&
1074 is_same<_Traits, char_traits<char>>::value,
1075 basic_ostream<_CharT, _Traits>&
1076 >::type
1077 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1078 __os << std::__quoted(__p.native());
1079 return __os;
1080 }
1081
1082 template <class _CharT, class _Traits>
1083 _LIBCPP_INLINE_VISIBILITY
1084 friend typename enable_if<!is_same<_CharT, char>::value ||
1085 !is_same<_Traits, char_traits<char>>::value,
1086 basic_ostream<_CharT, _Traits>&
1087 >::type
1088 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1089 __os << std::__quoted(__p.string<_CharT, _Traits>());
1090 return __os;
1091 }
1092
1093 template <class _CharT, class _Traits>
1094 _LIBCPP_INLINE_VISIBILITY
1095 friend basic_istream<_CharT, _Traits>&
1096 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
1097 {
1098 basic_string<_CharT, _Traits> __tmp;
1099 __is >> __quoted(__tmp);
1100 __p = __tmp;
1101 return __is;
1102 }
1103
Eric Fiselier435db152016-06-17 19:46:40 +00001104private:
1105 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierb05e1b02016-07-23 03:10:56 +00001106 path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; }
Eric Fiselier435db152016-06-17 19:46:40 +00001107 string_type __pn_;
1108};
1109
Louis Dionne16fe2952018-07-11 23:14:33 +00001110inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001111void swap(path& __lhs, path& __rhs) _NOEXCEPT {
1112 __lhs.swap(__rhs);
1113}
1114
1115_LIBCPP_FUNC_VIS
1116size_t hash_value(const path& __p) _NOEXCEPT;
1117
1118inline _LIBCPP_INLINE_VISIBILITY
1119bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
1120{ return __lhs.compare(__rhs) == 0; }
1121
1122inline _LIBCPP_INLINE_VISIBILITY
1123bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
1124{ return __lhs.compare(__rhs) != 0; }
1125
1126inline _LIBCPP_INLINE_VISIBILITY
1127bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
1128{ return __lhs.compare(__rhs) < 0; }
1129
1130inline _LIBCPP_INLINE_VISIBILITY
1131bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
1132{ return __lhs.compare(__rhs) <= 0; }
1133
1134inline _LIBCPP_INLINE_VISIBILITY
1135bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
1136{ return __lhs.compare(__rhs) > 0; }
1137
1138inline _LIBCPP_INLINE_VISIBILITY
1139bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
1140{ return __lhs.compare(__rhs) >= 0; }
1141
1142inline _LIBCPP_INLINE_VISIBILITY
1143path operator/(const path& __lhs, const path& __rhs) {
David Bolvansky38b37ef2018-05-09 18:57:17 +00001144 path __result(__lhs);
1145 __result /= __rhs;
1146 return __result;
Eric Fiselier435db152016-06-17 19:46:40 +00001147}
1148
Eric Fiselier435db152016-06-17 19:46:40 +00001149template <class _Source>
1150_LIBCPP_INLINE_VISIBILITY
1151typename enable_if<__is_pathable<_Source>::value, path>::type
1152u8path(const _Source& __s){
1153 static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1154 "u8path(Source const&) requires Source have a character type of type 'char'");
1155 return path(__s);
1156}
1157
1158template <class _InputIt>
1159_LIBCPP_INLINE_VISIBILITY
1160typename enable_if<__is_pathable<_InputIt>::value, path>::type
1161u8path(_InputIt __f, _InputIt __l) {
1162 static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1163 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
1164 return path(__f, __l);
1165}
1166
1167class _LIBCPP_TYPE_VIS path::iterator
1168{
1169public:
1170 typedef bidirectional_iterator_tag iterator_category;
Eric Fiselierc8dac982017-04-04 01:05:59 +00001171
Eric Fiselier435db152016-06-17 19:46:40 +00001172 typedef path value_type;
1173 typedef std::ptrdiff_t difference_type;
1174 typedef const path* pointer;
1175 typedef const path& reference;
Eric Fiselier883af112017-04-13 02:54:13 +00001176
1177 typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
Eric Fiselier435db152016-06-17 19:46:40 +00001178public:
1179 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfc46d252016-10-30 23:30:38 +00001180 iterator() : __stashed_elem_(), __path_ptr_(nullptr),
1181 __entry_(), __state_(__singular) {}
Eric Fiselier435db152016-06-17 19:46:40 +00001182
1183 iterator(const iterator&) = default;
1184 ~iterator() = default;
1185
1186 iterator& operator=(const iterator&) = default;
1187
1188 _LIBCPP_INLINE_VISIBILITY
1189 reference operator*() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001190 return __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001191 }
1192
1193 _LIBCPP_INLINE_VISIBILITY
1194 pointer operator->() const {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001195 return &__stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001196 }
1197
1198 _LIBCPP_INLINE_VISIBILITY
1199 iterator& operator++() {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001200 _LIBCPP_ASSERT(__state_ != __singular,
1201 "attempting to increment a singular iterator");
1202 _LIBCPP_ASSERT(__state_ != __at_end,
1203 "attempting to increment the end iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001204 return __increment();
1205 }
1206
1207 _LIBCPP_INLINE_VISIBILITY
1208 iterator operator++(int) {
1209 iterator __it(*this);
1210 this->operator++();
1211 return __it;
1212 }
1213
1214 _LIBCPP_INLINE_VISIBILITY
1215 iterator& operator--() {
Eric Fiselierfc46d252016-10-30 23:30:38 +00001216 _LIBCPP_ASSERT(__state_ != __singular,
1217 "attempting to decrement a singular iterator");
1218 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1219 "attempting to decrement the begin iterator");
Eric Fiselier435db152016-06-17 19:46:40 +00001220 return __decrement();
1221 }
1222
1223 _LIBCPP_INLINE_VISIBILITY
1224 iterator operator--(int) {
1225 iterator __it(*this);
1226 this->operator--();
1227 return __it;
1228 }
1229
1230private:
1231 friend class path;
Eric Fiselier28175a32016-09-16 00:07:16 +00001232
Eric Fiselierfc46d252016-10-30 23:30:38 +00001233 static constexpr unsigned char __singular = 0;
1234 static constexpr unsigned char __at_end = 6;
1235
Eric Fiselier28175a32016-09-16 00:07:16 +00001236 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001237 friend bool operator==(const iterator&, const iterator&);
1238
Saleem Abdulrasool53a32382017-01-30 03:58:26 +00001239 iterator& __increment();
1240 iterator& __decrement();
Eric Fiselier435db152016-06-17 19:46:40 +00001241
Eric Fiselierfc46d252016-10-30 23:30:38 +00001242 path __stashed_elem_;
Eric Fiselier435db152016-06-17 19:46:40 +00001243 const path* __path_ptr_;
Eric Fiselierfc46d252016-10-30 23:30:38 +00001244 path::__string_view __entry_;
1245 unsigned char __state_;
Eric Fiselier435db152016-06-17 19:46:40 +00001246};
1247
1248inline _LIBCPP_INLINE_VISIBILITY
1249bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
1250 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
Eric Fiselierfc46d252016-10-30 23:30:38 +00001251 __lhs.__entry_.data() == __rhs.__entry_.data();
Eric Fiselier435db152016-06-17 19:46:40 +00001252}
1253
1254inline _LIBCPP_INLINE_VISIBILITY
1255bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1256 return !(__lhs == __rhs);
1257}
1258
1259class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
1260{
1261public:
1262 _LIBCPP_INLINE_VISIBILITY
1263 filesystem_error(const string& __what, error_code __ec)
1264 : system_error(__ec, __what),
1265 __paths_(make_shared<_Storage>(path(), path()))
1266 {}
1267
1268 _LIBCPP_INLINE_VISIBILITY
1269 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1270 : system_error(__ec, __what),
1271 __paths_(make_shared<_Storage>(__p1, path()))
1272 {}
1273
1274 _LIBCPP_INLINE_VISIBILITY
1275 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1276 error_code __ec)
1277 : system_error(__ec, __what),
1278 __paths_(make_shared<_Storage>(__p1, __p2))
1279 {}
1280
1281 _LIBCPP_INLINE_VISIBILITY
1282 const path& path1() const _NOEXCEPT {
1283 return __paths_->first;
1284 }
1285
1286 _LIBCPP_INLINE_VISIBILITY
1287 const path& path2() const _NOEXCEPT {
1288 return __paths_->second;
1289 }
1290
Eric Fiselier435db152016-06-17 19:46:40 +00001291 ~filesystem_error() override; // key function
1292
1293 // TODO(ericwf): Create a custom error message.
1294 //const char* what() const _NOEXCEPT;
1295
1296private:
1297 typedef pair<path, path> _Storage;
1298 shared_ptr<_Storage> __paths_;
1299};
1300
Marshall Clowed3e2292016-08-25 17:47:09 +00001301template <class... _Args>
Louis Dionne16fe2952018-07-11 23:14:33 +00001302_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6003c772016-12-23 23:37:52 +00001303#ifndef _LIBCPP_NO_EXCEPTIONS
Marshall Clowed3e2292016-08-25 17:47:09 +00001304void __throw_filesystem_error(_Args && ...__args)
1305{
Marshall Clowed3e2292016-08-25 17:47:09 +00001306 throw filesystem_error(std::forward<_Args>(__args)...);
Marshall Clowed3e2292016-08-25 17:47:09 +00001307}
Eric Fiselier6003c772016-12-23 23:37:52 +00001308#else
1309void __throw_filesystem_error(_Args&&...)
1310{
1311 _VSTD::abort();
1312}
1313#endif
1314
Marshall Clowed3e2292016-08-25 17:47:09 +00001315
Eric Fiselier435db152016-06-17 19:46:40 +00001316// operational functions
1317
1318_LIBCPP_FUNC_VIS
Eric Fiselier91a182b2018-04-02 23:03:41 +00001319path __absolute(const path&, error_code *__ec=nullptr);
1320_LIBCPP_FUNC_VIS
1321path __canonical(const path&, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001322_LIBCPP_FUNC_VIS
1323void __copy(const path& __from, const path& __to, copy_options __opt,
1324 error_code *__ec=nullptr);
1325_LIBCPP_FUNC_VIS
1326bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1327 error_code *__ec=nullptr);
1328_LIBCPP_FUNC_VIS
1329void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1330 error_code *__ec=nullptr);
1331_LIBCPP_FUNC_VIS
1332bool __create_directories(const path& p, error_code *ec=nullptr);
1333_LIBCPP_FUNC_VIS
1334bool __create_directory(const path& p, error_code *ec=nullptr);
1335_LIBCPP_FUNC_VIS
1336bool __create_directory(const path& p, const path & attributes,
1337 error_code *ec=nullptr);
1338_LIBCPP_FUNC_VIS
1339void __create_directory_symlink(const path& __to, const path& __new_symlink,
1340 error_code *__ec=nullptr);
1341_LIBCPP_FUNC_VIS
1342void __create_hard_link(const path& __to, const path& __new_hard_link,
1343 error_code *__ec=nullptr);
1344_LIBCPP_FUNC_VIS
1345void __create_symlink(const path& __to, const path& __new_symlink,
1346 error_code *__ec=nullptr);
1347_LIBCPP_FUNC_VIS
1348path __current_path(error_code *__ec=nullptr);
1349_LIBCPP_FUNC_VIS
1350void __current_path(const path&, error_code *__ec=nullptr);
1351_LIBCPP_FUNC_VIS
1352bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
1353_LIBCPP_FUNC_VIS
1354uintmax_t __file_size(const path&, error_code *__ec=nullptr);
1355_LIBCPP_FUNC_VIS
1356uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
1357_LIBCPP_FUNC_VIS
1358bool __fs_is_empty(const path& p, error_code *ec=nullptr);
1359_LIBCPP_FUNC_VIS
1360file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
1361_LIBCPP_FUNC_VIS
1362void __last_write_time(const path& p, file_time_type new_time,
1363 error_code *ec=nullptr);
1364_LIBCPP_FUNC_VIS
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001365void __permissions(const path&, perms, perm_options, error_code* = nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001366_LIBCPP_FUNC_VIS
1367path __read_symlink(const path& p, error_code *ec=nullptr);
1368_LIBCPP_FUNC_VIS
1369bool __remove(const path& p, error_code *ec=nullptr);
1370_LIBCPP_FUNC_VIS
1371uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
1372_LIBCPP_FUNC_VIS
1373void __rename(const path& from, const path& to, error_code *ec=nullptr);
1374_LIBCPP_FUNC_VIS
1375void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
1376_LIBCPP_FUNC_VIS
1377space_info __space(const path&, error_code *__ec=nullptr);
1378_LIBCPP_FUNC_VIS
1379file_status __status(const path&, error_code *__ec=nullptr);
1380_LIBCPP_FUNC_VIS
1381file_status __symlink_status(const path&, error_code *__ec=nullptr);
1382_LIBCPP_FUNC_VIS
1383path __system_complete(const path&, error_code *__ec=nullptr);
1384_LIBCPP_FUNC_VIS
1385path __temp_directory_path(error_code *__ec=nullptr);
Eric Fiselier91a182b2018-04-02 23:03:41 +00001386_LIBCPP_FUNC_VIS
1387path __weakly_canonical(path const& __p, error_code *__ec=nullptr);
Eric Fiselier435db152016-06-17 19:46:40 +00001388
1389inline _LIBCPP_INLINE_VISIBILITY
1390path current_path() {
1391 return __current_path();
1392}
1393
1394inline _LIBCPP_INLINE_VISIBILITY
1395path current_path(error_code& __ec) {
1396 return __current_path(&__ec);
1397}
1398
1399inline _LIBCPP_INLINE_VISIBILITY
1400void current_path(const path& __p) {
1401 __current_path(__p);
1402}
1403
1404inline _LIBCPP_INLINE_VISIBILITY
1405void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
1406 __current_path(__p, &__ec);
1407}
1408
Eric Fiselier91a182b2018-04-02 23:03:41 +00001409inline _LIBCPP_INLINE_VISIBILITY
1410path absolute(const path& __p) {
1411 return __absolute(__p);
1412}
Eric Fiselier435db152016-06-17 19:46:40 +00001413
1414inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001415path absolute(const path& __p, error_code &__ec) {
1416 return __absolute(__p, &__ec);
1417}
1418
1419inline _LIBCPP_INLINE_VISIBILITY
1420path canonical(const path& __p) {
1421 return __canonical(__p);
Eric Fiselier435db152016-06-17 19:46:40 +00001422}
1423
1424inline _LIBCPP_INLINE_VISIBILITY
1425path canonical(const path& __p, error_code& __ec) {
Eric Fiselier91a182b2018-04-02 23:03:41 +00001426 return __canonical(__p, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001427}
1428
1429inline _LIBCPP_INLINE_VISIBILITY
1430void copy(const path& __from, const path& __to) {
1431 __copy(__from, __to, copy_options::none);
1432}
1433
1434inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001435void copy(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001436 __copy(__from, __to, copy_options::none, &__ec);
1437}
1438
1439inline _LIBCPP_INLINE_VISIBILITY
1440void copy(const path& __from, const path& __to, copy_options __opt) {
1441 __copy(__from, __to, __opt);
1442}
1443
1444inline _LIBCPP_INLINE_VISIBILITY
1445void copy(const path& __from, const path& __to,
Eric Fiselierd56d5322017-10-30 18:59:59 +00001446 copy_options __opt, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001447 __copy(__from, __to, __opt, &__ec);
1448}
1449
1450inline _LIBCPP_INLINE_VISIBILITY
1451bool copy_file(const path& __from, const path& __to) {
1452 return __copy_file(__from, __to, copy_options::none);
1453}
1454
1455inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001456bool copy_file(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001457 return __copy_file(__from, __to, copy_options::none, &__ec);
1458}
1459
1460inline _LIBCPP_INLINE_VISIBILITY
1461bool copy_file(const path& __from, const path& __to, copy_options __opt) {
1462 return __copy_file(__from, __to, __opt);
1463}
1464
1465inline _LIBCPP_INLINE_VISIBILITY
1466bool copy_file(const path& __from, const path& __to,
Eric Fiseliere1164812018-02-04 07:35:36 +00001467 copy_options __opt, error_code& __ec){
Eric Fiselier435db152016-06-17 19:46:40 +00001468 return __copy_file(__from, __to, __opt, &__ec);
1469}
1470
1471inline _LIBCPP_INLINE_VISIBILITY
1472void copy_symlink(const path& __existing, const path& __new) {
1473 __copy_symlink(__existing, __new);
1474}
1475
1476inline _LIBCPP_INLINE_VISIBILITY
1477void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
1478 __copy_symlink(__ext, __new, &__ec);
1479}
1480
1481inline _LIBCPP_INLINE_VISIBILITY
1482bool create_directories(const path& __p) {
1483 return __create_directories(__p);
1484}
1485
1486inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001487bool create_directories(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001488 return __create_directories(__p, &__ec);
1489}
1490
1491inline _LIBCPP_INLINE_VISIBILITY
1492bool create_directory(const path& __p) {
1493 return __create_directory(__p);
1494}
1495
1496inline _LIBCPP_INLINE_VISIBILITY
1497bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1498 return __create_directory(__p, &__ec);
1499}
1500
1501inline _LIBCPP_INLINE_VISIBILITY
1502bool create_directory(const path& __p, const path& __attrs) {
1503 return __create_directory(__p, __attrs);
1504}
1505
1506inline _LIBCPP_INLINE_VISIBILITY
1507bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
1508 return __create_directory(__p, __attrs, &__ec);
1509}
1510
1511inline _LIBCPP_INLINE_VISIBILITY
1512void create_directory_symlink(const path& __to, const path& __new) {
1513 __create_directory_symlink(__to, __new);
1514}
1515
1516inline _LIBCPP_INLINE_VISIBILITY
1517void create_directory_symlink(const path& __to, const path& __new,
1518 error_code& __ec) _NOEXCEPT {
1519 __create_directory_symlink(__to, __new, &__ec);
1520}
1521
1522inline _LIBCPP_INLINE_VISIBILITY
1523void create_hard_link(const path& __to, const path& __new) {
1524 __create_hard_link(__to, __new);
1525}
1526
1527inline _LIBCPP_INLINE_VISIBILITY
1528void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1529 __create_hard_link(__to, __new, &__ec);
1530}
1531
1532inline _LIBCPP_INLINE_VISIBILITY
1533void create_symlink(const path& __to, const path& __new) {
1534 __create_symlink(__to, __new);
1535}
1536
1537inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001538void create_symlink(const path& __to, const path& __new,
1539 error_code& __ec) _NOEXCEPT {
Eric Fiselier435db152016-06-17 19:46:40 +00001540 return __create_symlink(__to, __new, &__ec);
1541}
1542
1543inline _LIBCPP_INLINE_VISIBILITY
1544bool status_known(file_status __s) _NOEXCEPT {
1545 return __s.type() != file_type::none;
1546}
1547
1548inline _LIBCPP_INLINE_VISIBILITY
1549bool exists(file_status __s) _NOEXCEPT {
1550 return status_known(__s) && __s.type() != file_type::not_found;
1551}
1552
1553inline _LIBCPP_INLINE_VISIBILITY
1554bool exists(const path& __p) {
1555 return exists(__status(__p));
1556}
1557
1558inline _LIBCPP_INLINE_VISIBILITY
1559bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
Eric Fiselier0a367d22016-06-21 22:11:16 +00001560 auto __s = __status(__p, &__ec);
1561 if (status_known(__s)) __ec.clear();
1562 return exists(__s);
Eric Fiselier435db152016-06-17 19:46:40 +00001563}
1564
1565inline _LIBCPP_INLINE_VISIBILITY
1566bool equivalent(const path& __p1, const path& __p2) {
1567 return __equivalent(__p1, __p2);
1568}
1569
1570inline _LIBCPP_INLINE_VISIBILITY
1571bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
1572 return __equivalent(__p1, __p2, &__ec);
1573}
1574
1575inline _LIBCPP_INLINE_VISIBILITY
1576uintmax_t file_size(const path& __p) {
1577 return __file_size(__p);
1578}
1579
1580inline _LIBCPP_INLINE_VISIBILITY
1581uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
1582 return __file_size(__p, &__ec);
1583}
1584
1585inline _LIBCPP_INLINE_VISIBILITY
1586uintmax_t hard_link_count(const path& __p) {
1587 return __hard_link_count(__p);
1588}
1589
1590inline _LIBCPP_INLINE_VISIBILITY
1591uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
1592 return __hard_link_count(__p, &__ec);
1593}
1594
1595inline _LIBCPP_INLINE_VISIBILITY
1596bool is_block_file(file_status __s) _NOEXCEPT {
1597 return __s.type() == file_type::block;
1598}
1599
1600inline _LIBCPP_INLINE_VISIBILITY
1601bool is_block_file(const path& __p) {
1602 return is_block_file(__status(__p));
1603}
1604
1605inline _LIBCPP_INLINE_VISIBILITY
1606bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
1607 return is_block_file(__status(__p, &__ec));
1608}
1609
1610inline _LIBCPP_INLINE_VISIBILITY
1611bool is_character_file(file_status __s) _NOEXCEPT {
1612 return __s.type() == file_type::character;
1613}
1614
1615inline _LIBCPP_INLINE_VISIBILITY
1616bool is_character_file(const path& __p) {
1617 return is_character_file(__status(__p));
1618}
1619
1620inline _LIBCPP_INLINE_VISIBILITY
1621bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
1622 return is_character_file(__status(__p, &__ec));
1623}
1624
1625inline _LIBCPP_INLINE_VISIBILITY
1626bool is_directory(file_status __s) _NOEXCEPT {
1627 return __s.type() == file_type::directory;
1628}
1629
1630inline _LIBCPP_INLINE_VISIBILITY
1631bool is_directory(const path& __p) {
1632 return is_directory(__status(__p));
1633}
1634
1635inline _LIBCPP_INLINE_VISIBILITY
1636bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1637 return is_directory(__status(__p, &__ec));
1638}
1639
1640inline _LIBCPP_INLINE_VISIBILITY
1641bool is_empty(const path& __p) {
1642 return __fs_is_empty(__p);
1643}
1644
1645inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00001646bool is_empty(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001647 return __fs_is_empty(__p, &__ec);
1648}
1649
1650inline _LIBCPP_INLINE_VISIBILITY
1651bool is_fifo(file_status __s) _NOEXCEPT {
1652 return __s.type() == file_type::fifo;
1653}
1654inline _LIBCPP_INLINE_VISIBILITY
1655bool is_fifo(const path& __p) {
1656 return is_fifo(__status(__p));
1657}
1658
1659inline _LIBCPP_INLINE_VISIBILITY
1660bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
1661 return is_fifo(__status(__p, &__ec));
1662}
1663
1664inline _LIBCPP_INLINE_VISIBILITY
1665bool is_regular_file(file_status __s) _NOEXCEPT {
1666 return __s.type() == file_type::regular;
1667}
1668
1669inline _LIBCPP_INLINE_VISIBILITY
1670bool is_regular_file(const path& __p) {
1671 return is_regular_file(__status(__p));
1672}
1673
1674inline _LIBCPP_INLINE_VISIBILITY
1675bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
1676 return is_regular_file(__status(__p, &__ec));
1677}
1678
1679inline _LIBCPP_INLINE_VISIBILITY
1680bool is_socket(file_status __s) _NOEXCEPT {
1681 return __s.type() == file_type::socket;
1682}
1683
1684inline _LIBCPP_INLINE_VISIBILITY
1685bool is_socket(const path& __p) {
1686 return is_socket(__status(__p));
1687}
1688
1689inline _LIBCPP_INLINE_VISIBILITY
1690bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
1691 return is_socket(__status(__p, &__ec));
1692}
1693
1694inline _LIBCPP_INLINE_VISIBILITY
1695bool is_symlink(file_status __s) _NOEXCEPT {
1696 return __s.type() == file_type::symlink;
1697}
1698
1699inline _LIBCPP_INLINE_VISIBILITY
1700bool is_symlink(const path& __p) {
1701 return is_symlink(__symlink_status(__p));
1702}
1703
1704inline _LIBCPP_INLINE_VISIBILITY
1705bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
1706 return is_symlink(__symlink_status(__p, &__ec));
1707}
1708
1709inline _LIBCPP_INLINE_VISIBILITY
1710bool is_other(file_status __s) _NOEXCEPT {
1711 return exists(__s)
1712 && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
1713}
1714
1715inline _LIBCPP_INLINE_VISIBILITY
1716bool is_other(const path& __p) {
1717 return is_other(__status(__p));
1718}
1719
1720inline _LIBCPP_INLINE_VISIBILITY
1721bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
1722 return is_other(__status(__p, &__ec));
1723}
1724
1725inline _LIBCPP_INLINE_VISIBILITY
1726file_time_type last_write_time(const path& __p) {
1727 return __last_write_time(__p);
1728}
1729
1730inline _LIBCPP_INLINE_VISIBILITY
1731file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
1732 return __last_write_time(__p, &__ec);
1733}
1734
1735inline _LIBCPP_INLINE_VISIBILITY
1736void last_write_time(const path& __p, file_time_type __t) {
1737 __last_write_time(__p, __t);
1738}
1739
1740inline _LIBCPP_INLINE_VISIBILITY
1741void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
1742 __last_write_time(__p, __t, &__ec);
1743}
1744
1745inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001746void permissions(const path& __p, perms __prms,
1747 perm_options __opts = perm_options::replace) {
1748 __permissions(__p, __prms, __opts);
Eric Fiselier435db152016-06-17 19:46:40 +00001749}
1750
1751inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier4f3dc0e2018-03-26 06:23:55 +00001752void permissions(const path& __p, perms __prms, error_code& __ec) _NOEXCEPT {
1753 __permissions(__p, __prms, perm_options::replace, &__ec);
1754}
1755
1756inline _LIBCPP_INLINE_VISIBILITY
1757void permissions(const path& __p, perms __prms, perm_options __opts,
1758 error_code& __ec) {
1759 __permissions(__p, __prms, __opts, &__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001760}
1761
1762inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier91a182b2018-04-02 23:03:41 +00001763path proximate(const path& __p, const path& __base, error_code& __ec) {
1764 path __tmp = __weakly_canonical(__p, &__ec);
1765 if (__ec)
1766 return {};
1767 path __tmp_base = __weakly_canonical(__base, &__ec);
1768 if (__ec)
1769 return {};
1770 return __tmp.lexically_proximate(__tmp_base);
1771}
1772
1773inline _LIBCPP_INLINE_VISIBILITY
1774path proximate(const path& __p, error_code& __ec) {
1775 return proximate(__p, current_path(), __ec);
1776}
1777
1778inline _LIBCPP_INLINE_VISIBILITY
1779path proximate(const path& __p, const path& __base = current_path()) {
1780 return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
1781}
1782
1783inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001784path read_symlink(const path& __p) {
1785 return __read_symlink(__p);
1786}
1787
1788inline _LIBCPP_INLINE_VISIBILITY
1789path read_symlink(const path& __p, error_code& __ec) {
1790 return __read_symlink(__p, &__ec);
1791}
1792
Eric Fiselier91a182b2018-04-02 23:03:41 +00001793
1794inline _LIBCPP_INLINE_VISIBILITY
1795path relative(const path& __p, const path& __base, error_code& __ec) {
1796 path __tmp = __weakly_canonical(__p, &__ec);
1797 if (__ec)
1798 return path();
1799 path __tmpbase = __weakly_canonical(__base, &__ec);
1800 if (__ec)
1801 return path();
1802 return __tmp.lexically_relative(__tmpbase);
1803}
1804
1805inline _LIBCPP_INLINE_VISIBILITY
1806path relative(const path& __p, error_code& __ec) {
1807 return relative(__p, current_path(), __ec);
1808}
1809
1810inline _LIBCPP_INLINE_VISIBILITY
1811path relative(const path& __p, const path& __base=current_path()) {
1812 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
1813}
1814
1815
Eric Fiselier435db152016-06-17 19:46:40 +00001816inline _LIBCPP_INLINE_VISIBILITY
1817bool remove(const path& __p) {
1818 return __remove(__p);
1819}
1820
1821inline _LIBCPP_INLINE_VISIBILITY
1822bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
1823 return __remove(__p, &__ec);
1824}
1825
1826inline _LIBCPP_INLINE_VISIBILITY
1827uintmax_t remove_all(const path& __p) {
1828 return __remove_all(__p);
1829}
1830
1831inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere1164812018-02-04 07:35:36 +00001832uintmax_t remove_all(const path& __p, error_code& __ec) {
Eric Fiselier435db152016-06-17 19:46:40 +00001833 return __remove_all(__p, &__ec);
1834}
1835
1836inline _LIBCPP_INLINE_VISIBILITY
1837void rename(const path& __from, const path& __to) {
1838 return __rename(__from, __to);
1839}
1840
1841inline _LIBCPP_INLINE_VISIBILITY
1842void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1843 return __rename(__from, __to, &__ec);
1844}
1845
1846inline _LIBCPP_INLINE_VISIBILITY
1847void resize_file(const path& __p, uintmax_t __ns) {
1848 return __resize_file(__p, __ns);
1849}
1850
1851inline _LIBCPP_INLINE_VISIBILITY
1852void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
1853 return __resize_file(__p, __ns, &__ec);
1854}
1855
1856inline _LIBCPP_INLINE_VISIBILITY
1857space_info space(const path& __p) {
1858 return __space(__p);
1859}
1860
1861inline _LIBCPP_INLINE_VISIBILITY
1862space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
1863 return __space(__p, &__ec);
1864}
1865
1866inline _LIBCPP_INLINE_VISIBILITY
1867file_status status(const path& __p) {
1868 return __status(__p);
1869}
1870
1871inline _LIBCPP_INLINE_VISIBILITY
1872file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
1873 return __status(__p, &__ec);
1874}
1875
1876inline _LIBCPP_INLINE_VISIBILITY
1877file_status symlink_status(const path& __p) {
1878 return __symlink_status(__p);
1879}
1880
1881inline _LIBCPP_INLINE_VISIBILITY
1882file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
1883 return __symlink_status(__p, &__ec);
1884}
1885
1886inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001887path temp_directory_path() {
1888 return __temp_directory_path();
1889}
1890
1891inline _LIBCPP_INLINE_VISIBILITY
1892path temp_directory_path(error_code& __ec) {
1893 return __temp_directory_path(&__ec);
1894}
1895
Eric Fiselier91a182b2018-04-02 23:03:41 +00001896inline _LIBCPP_INLINE_VISIBILITY
1897path weakly_canonical(path const& __p) {
1898 return __weakly_canonical(__p);
1899}
1900
1901inline _LIBCPP_INLINE_VISIBILITY
1902path weakly_canonical(path const& __p, error_code& __ec) {
1903 return __weakly_canonical(__p, &__ec);
1904}
1905
Eric Fiselier435db152016-06-17 19:46:40 +00001906
Eric Fiselier70474082018-07-20 01:22:32 +00001907class directory_iterator;
1908class recursive_directory_iterator;
1909class __dir_stream;
1910
Eric Fiselier435db152016-06-17 19:46:40 +00001911class directory_entry
1912{
1913 typedef _VSTD_FS::path _Path;
1914
1915public:
1916 // constructors and destructors
1917 directory_entry() _NOEXCEPT = default;
1918 directory_entry(directory_entry const&) = default;
1919 directory_entry(directory_entry&&) _NOEXCEPT = default;
1920
1921 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001922 explicit directory_entry(_Path const& __p) : __p_(__p) {
1923 error_code __ec;
1924 __refresh(&__ec);
1925 }
1926
1927 _LIBCPP_INLINE_VISIBILITY
1928 directory_entry(_Path const& __p, error_code &__ec) : __p_(__p) {
1929 __refresh(&__ec);
1930 }
Eric Fiselier435db152016-06-17 19:46:40 +00001931
1932 ~directory_entry() {}
1933
1934 directory_entry& operator=(directory_entry const&) = default;
1935 directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
1936
1937 _LIBCPP_INLINE_VISIBILITY
1938 void assign(_Path const& __p) {
1939 __p_ = __p;
Eric Fiselier70474082018-07-20 01:22:32 +00001940 error_code __ec;
1941 __refresh(&__ec);
1942 }
1943
1944 _LIBCPP_INLINE_VISIBILITY
1945 void assign(_Path const& __p, error_code& __ec) {
1946 __p_ = __p;
1947 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001948 }
1949
1950 _LIBCPP_INLINE_VISIBILITY
1951 void replace_filename(_Path const& __p) {
Eric Fiselier70474082018-07-20 01:22:32 +00001952 __p_.replace_filename(__p);
1953 error_code __ec;
1954 __refresh(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00001955 }
1956
1957 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001958 void replace_filename(_Path const& __p, error_code &__ec) {
1959 __p_ = __p_.parent_path() / __p;
1960 __refresh(&__ec);
1961 }
1962
1963 _LIBCPP_INLINE_VISIBILITY
1964 void refresh() {
1965 __refresh();
1966 }
1967
1968 _LIBCPP_INLINE_VISIBILITY
1969 void refresh(error_code& __ec) _NOEXCEPT { __refresh(&__ec); }
1970
1971 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00001972 _Path const& path() const _NOEXCEPT {
1973 return __p_;
1974 }
1975
1976 _LIBCPP_INLINE_VISIBILITY
1977 operator const _Path&() const _NOEXCEPT {
1978 return __p_;
1979 }
1980
1981 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier70474082018-07-20 01:22:32 +00001982 bool exists() const {
1983 return _VSTD_FS::exists(file_status{__get_ft()});
1984 }
1985
1986 _LIBCPP_INLINE_VISIBILITY
1987 bool exists(error_code& __ec) const noexcept {
1988 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
1989 }
1990
1991 _LIBCPP_INLINE_VISIBILITY
1992 bool is_block_file() const {
1993 return __get_ft() == file_type::block;
1994 }
1995
1996 _LIBCPP_INLINE_VISIBILITY
1997 bool is_block_file(error_code& __ec) const noexcept {
1998 return __get_ft(&__ec) == file_type::block;
1999 }
2000
2001 _LIBCPP_INLINE_VISIBILITY
2002 bool is_character_file() const {
2003 return __get_ft() == file_type::character;
2004 }
2005
2006 _LIBCPP_INLINE_VISIBILITY
2007 bool is_character_file(error_code& __ec) const noexcept {
2008 return __get_ft(&__ec) == file_type::character;
2009 }
2010
2011 _LIBCPP_INLINE_VISIBILITY
2012 bool is_directory() const {
2013 return __get_ft() == file_type::directory;
2014 }
2015
2016 _LIBCPP_INLINE_VISIBILITY
2017 bool is_directory(error_code& __ec) const noexcept {
2018 return __get_ft(&__ec) == file_type::directory;
2019 }
2020
2021 _LIBCPP_INLINE_VISIBILITY
2022 bool is_fifo() const {
2023 return __get_ft() == file_type::fifo;
2024 }
2025
2026 _LIBCPP_INLINE_VISIBILITY
2027 bool is_fifo(error_code& __ec) const noexcept {
2028 return __get_ft(&__ec) == file_type::fifo;
2029 }
2030
2031 _LIBCPP_INLINE_VISIBILITY
2032 bool is_other() const {
2033 return _VSTD_FS::is_other(file_status{__get_ft()});
2034 }
2035
2036 _LIBCPP_INLINE_VISIBILITY
2037 bool is_other(error_code& __ec) const noexcept {
2038 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2039 }
2040
2041 _LIBCPP_INLINE_VISIBILITY
2042 bool is_regular_file() const {
2043 return __get_ft() == file_type::regular;
2044 }
2045
2046 _LIBCPP_INLINE_VISIBILITY
2047 bool is_regular_file(error_code& __ec) const noexcept {
2048 return __get_ft(&__ec) == file_type::regular;
2049 }
2050
2051 _LIBCPP_INLINE_VISIBILITY
2052 bool is_socket() const {
2053 return __get_ft() == file_type::socket;
2054 }
2055
2056 _LIBCPP_INLINE_VISIBILITY
2057 bool is_socket(error_code& __ec) const noexcept {
2058 return __get_ft(&__ec) == file_type::socket;
2059 }
2060
2061 _LIBCPP_INLINE_VISIBILITY
2062 bool is_symlink() const {
2063 return __get_sym_ft() == file_type::symlink;
2064 }
2065
2066 _LIBCPP_INLINE_VISIBILITY
2067 bool is_symlink(error_code& __ec) const noexcept {
2068 return __get_sym_ft(&__ec) == file_type::symlink;
2069 }
2070 _LIBCPP_INLINE_VISIBILITY
2071 uintmax_t file_size() const {
2072 return __get_size();
2073 }
2074
2075 _LIBCPP_INLINE_VISIBILITY
2076 uintmax_t file_size(error_code& __ec) const noexcept {
2077 return __get_size(&__ec);
2078 }
2079
2080 _LIBCPP_INLINE_VISIBILITY
2081 uintmax_t hard_link_count() const {
2082 return __get_nlink();
2083 }
2084
2085 _LIBCPP_INLINE_VISIBILITY
2086 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2087 return __get_nlink(&__ec);
2088 }
2089
2090 _LIBCPP_INLINE_VISIBILITY
2091 file_time_type last_write_time() const {
2092 return __get_write_time();
2093 }
2094
2095 _LIBCPP_INLINE_VISIBILITY
2096 file_time_type last_write_time(error_code& __ec) const noexcept {
2097 return __get_write_time(&__ec);
2098 }
2099
2100 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002101 file_status status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002102 return __get_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002103 }
2104
2105 _LIBCPP_INLINE_VISIBILITY
2106 file_status status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002107 return __get_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002108 }
2109
2110 _LIBCPP_INLINE_VISIBILITY
2111 file_status symlink_status() const {
Eric Fiselier70474082018-07-20 01:22:32 +00002112 return __get_symlink_status();
Eric Fiselier435db152016-06-17 19:46:40 +00002113 }
2114
2115 _LIBCPP_INLINE_VISIBILITY
2116 file_status symlink_status(error_code& __ec) const _NOEXCEPT {
Eric Fiselier70474082018-07-20 01:22:32 +00002117 return __get_symlink_status(&__ec);
Eric Fiselier435db152016-06-17 19:46:40 +00002118 }
2119
2120 _LIBCPP_INLINE_VISIBILITY
2121 bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
2122 return __p_ < __rhs.__p_;
2123 }
2124
2125 _LIBCPP_INLINE_VISIBILITY
2126 bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
2127 return __p_ == __rhs.__p_;
2128 }
2129
2130 _LIBCPP_INLINE_VISIBILITY
2131 bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
2132 return __p_ != __rhs.__p_;
2133 }
2134
2135 _LIBCPP_INLINE_VISIBILITY
2136 bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
2137 return __p_ <= __rhs.__p_;
2138 }
2139
2140 _LIBCPP_INLINE_VISIBILITY
2141 bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
2142 return __p_ > __rhs.__p_;
2143 }
2144
2145 _LIBCPP_INLINE_VISIBILITY
2146 bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
2147 return __p_ >= __rhs.__p_;
2148 }
Eric Fiselier70474082018-07-20 01:22:32 +00002149
2150private:
2151 friend class directory_iterator;
2152 friend class recursive_directory_iterator;
2153 friend class __dir_stream;
2154
2155 enum _CacheType : unsigned char {
2156 _Empty,
2157 _IterSymlink,
2158 _IterNonSymlink,
2159 _RefreshSymlink,
2160 _RefreshSymlinkUnresolved,
2161 _RefreshNonSymlink
2162 };
2163
2164 struct __cached_data {
2165 uintmax_t __size_;
2166 uintmax_t __nlink_;
2167 file_time_type __write_time_;
2168 perms __sym_perms_;
2169 perms __non_sym_perms_;
2170 file_type __type_;
2171 _CacheType __cache_type_;
2172
2173 _LIBCPP_INLINE_VISIBILITY
2174 __cached_data() noexcept { __reset(); }
2175
2176 _LIBCPP_INLINE_VISIBILITY
2177 void __reset() {
2178 __cache_type_ = _Empty;
2179 __type_ = file_type::none;
2180 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2181 __size_ = __nlink_ = uintmax_t(-1);
2182 __write_time_ = file_time_type::min();
2183 }
2184 };
2185
2186 _LIBCPP_INLINE_VISIBILITY
2187 static __cached_data __create_iter_result(file_type __ft) {
2188 __cached_data __data;
2189 __data.__type_ = __ft;
2190 __data.__cache_type_ =
2191 __ft == file_type::symlink ? _IterSymlink : _IterNonSymlink;
2192 return __data;
2193 }
2194
2195 _LIBCPP_INLINE_VISIBILITY
2196 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2197 __p_ = std::move(__p);
2198 __data_ = __dt;
2199 }
2200
2201 _LIBCPP_FUNC_VIS
2202 error_code __do_refresh() noexcept;
2203
2204 _LIBCPP_INLINE_VISIBILITY
2205 static bool __is_dne_error(error_code const& __ec) {
2206 if (!__ec)
2207 return true;
2208 switch (static_cast<errc>(__ec.value())) {
2209 case errc::no_such_file_or_directory:
2210 case errc::not_a_directory:
2211 return true;
2212 default:
2213 return false;
2214 }
2215 }
2216
2217 _LIBCPP_INLINE_VISIBILITY
2218 void __handle_error(const char* __msg, error_code* __dest_ec,
2219 error_code const& __ec,
2220 bool __allow_dne = false) const {
2221 if (__dest_ec) {
2222 *__dest_ec = __ec;
2223 return;
2224 }
2225 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2226 __throw_filesystem_error(__msg, __p_, _Path{}, __ec);
2227 }
2228
2229 _LIBCPP_INLINE_VISIBILITY
2230 void __refresh(error_code* __ec = nullptr) {
2231 __handle_error("refresh", __ec, __do_refresh(), /*allow_dne*/ true);
2232 }
2233
2234 _LIBCPP_INLINE_VISIBILITY
2235 file_type __get_sym_ft(error_code *__ec = nullptr) const {
2236 switch (__data_.__cache_type_) {
2237 case _Empty:
2238 return __symlink_status(__p_, __ec).type();
2239 case _IterSymlink:
2240 case _RefreshSymlink:
2241 case _RefreshSymlinkUnresolved:
2242 if (__ec)
2243 __ec->clear();
2244 return file_type::symlink;
2245 case _IterNonSymlink:
2246 case _RefreshNonSymlink:
2247 file_status __st(__data_.__type_);
2248 if (__ec && !_VSTD_FS::exists(__st))
2249 *__ec = make_error_code(errc::no_such_file_or_directory);
2250 else if (__ec)
2251 __ec->clear();
2252 return __data_.__type_;
2253 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002254 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002255 }
2256
2257 _LIBCPP_INLINE_VISIBILITY
2258 file_type __get_ft(error_code *__ec = nullptr) const {
2259 switch (__data_.__cache_type_) {
2260 case _Empty:
2261 case _IterSymlink:
2262 case _RefreshSymlinkUnresolved:
2263 return __status(__p_, __ec).type();
2264 case _IterNonSymlink:
2265 case _RefreshNonSymlink:
2266 case _RefreshSymlink: {
2267 file_status __st(__data_.__type_);
2268 if (__ec && !_VSTD_FS::exists(__st))
2269 *__ec = make_error_code(errc::no_such_file_or_directory);
2270 else if (__ec)
2271 __ec->clear();
2272 return __data_.__type_;
2273 }
2274 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002275 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002276 }
2277
2278 _LIBCPP_INLINE_VISIBILITY
2279 file_status __get_status(error_code *__ec = nullptr) const {
2280 switch (__data_.__cache_type_) {
2281 case _Empty:
2282 case _IterNonSymlink:
2283 case _IterSymlink:
2284 case _RefreshSymlinkUnresolved:
2285 return __status(__p_, __ec);
2286 case _RefreshNonSymlink:
2287 case _RefreshSymlink:
2288 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2289 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002290 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002291 }
2292
2293 _LIBCPP_INLINE_VISIBILITY
2294 file_status __get_symlink_status(error_code *__ec = nullptr) const {
2295 switch (__data_.__cache_type_) {
2296 case _Empty:
2297 case _IterNonSymlink:
2298 case _IterSymlink:
2299 return __symlink_status(__p_, __ec);
2300 case _RefreshNonSymlink:
2301 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2302 case _RefreshSymlink:
2303 case _RefreshSymlinkUnresolved:
2304 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2305 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002306 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002307 }
2308
2309
2310 _LIBCPP_INLINE_VISIBILITY
2311 uintmax_t __get_size(error_code *__ec = nullptr) const {
2312 switch (__data_.__cache_type_) {
2313 case _Empty:
2314 case _IterNonSymlink:
2315 case _IterSymlink:
2316 case _RefreshSymlinkUnresolved:
2317 return _VSTD_FS::__file_size(__p_, __ec);
2318 case _RefreshSymlink:
2319 case _RefreshNonSymlink: {
2320 error_code __m_ec;
2321 file_status __st(__get_ft(&__m_ec));
2322 __handle_error("directory_entry::file_size", __ec, __m_ec);
2323 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2324 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2325 : errc::not_supported;
2326 __handle_error("directory_entry::file_size", __ec,
2327 make_error_code(__err_kind));
2328 }
2329 return __data_.__size_;
2330 }
2331 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002332 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002333 }
2334
2335 _LIBCPP_INLINE_VISIBILITY
2336 uintmax_t __get_nlink(error_code *__ec = nullptr) const {
2337 switch (__data_.__cache_type_) {
2338 case _Empty:
2339 case _IterNonSymlink:
2340 case _IterSymlink:
2341 case _RefreshSymlinkUnresolved:
2342 return _VSTD_FS::__hard_link_count(__p_, __ec);
2343 case _RefreshSymlink:
2344 case _RefreshNonSymlink: {
2345 error_code __m_ec;
2346 (void)__get_ft(&__m_ec);
2347 __handle_error("directory_entry::hard_link_count", __ec, __m_ec);
2348 return __data_.__nlink_;
2349 }
2350 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002351 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002352 }
2353
2354 _LIBCPP_INLINE_VISIBILITY
2355 file_time_type __get_write_time(error_code *__ec = nullptr) const {
2356 switch (__data_.__cache_type_) {
2357 case _Empty:
2358 case _IterNonSymlink:
2359 case _IterSymlink:
2360 case _RefreshSymlinkUnresolved:
2361 return _VSTD_FS::__last_write_time(__p_, __ec);
2362 case _RefreshSymlink:
2363 case _RefreshNonSymlink: {
2364 error_code __m_ec;
2365 file_status __st(__get_ft(&__m_ec));
2366 __handle_error("directory_entry::last_write_time", __ec, __m_ec);
2367 if (_VSTD_FS::exists(__st) &&
2368 __data_.__write_time_ == file_time_type::min())
2369 __handle_error("directory_entry::last_write_time", __ec,
2370 make_error_code(errc::value_too_large));
2371 return __data_.__write_time_;
2372 }
2373 }
Eric Fiselierb3b129c2018-07-20 01:44:33 +00002374 _LIBCPP_UNREACHABLE();
Eric Fiselier70474082018-07-20 01:22:32 +00002375 }
Eric Fiselier435db152016-06-17 19:46:40 +00002376private:
2377 _Path __p_;
Eric Fiselier70474082018-07-20 01:22:32 +00002378 __cached_data __data_;
Eric Fiselier435db152016-06-17 19:46:40 +00002379};
2380
Eric Fiselier435db152016-06-17 19:46:40 +00002381class __dir_element_proxy {
2382public:
2383
2384 inline _LIBCPP_INLINE_VISIBILITY
2385 directory_entry operator*() { return _VSTD::move(__elem_); }
2386
2387private:
2388 friend class directory_iterator;
2389 friend class recursive_directory_iterator;
2390 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2391 __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
2392 directory_entry __elem_;
2393};
2394
2395class directory_iterator
2396{
2397public:
2398 typedef directory_entry value_type;
2399 typedef ptrdiff_t difference_type;
2400 typedef value_type const* pointer;
2401 typedef value_type const& reference;
2402 typedef input_iterator_tag iterator_category;
2403
2404public:
2405 //ctor & dtor
2406 directory_iterator() _NOEXCEPT
2407 { }
2408
2409 explicit directory_iterator(const path& __p)
2410 : directory_iterator(__p, nullptr)
2411 { }
2412
2413 directory_iterator(const path& __p, directory_options __opts)
2414 : directory_iterator(__p, nullptr, __opts)
2415 { }
2416
Eric Fiselierd56d5322017-10-30 18:59:59 +00002417 directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002418 : directory_iterator(__p, &__ec)
2419 { }
2420
2421 directory_iterator(const path& __p, directory_options __opts,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002422 error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002423 : directory_iterator(__p, &__ec, __opts)
2424 { }
2425
2426 directory_iterator(const directory_iterator&) = default;
2427 directory_iterator(directory_iterator&&) = default;
2428 directory_iterator& operator=(const directory_iterator&) = default;
2429
2430 directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
2431 // non-default implementation provided to support self-move assign.
2432 if (this != &__o) {
2433 __imp_ = _VSTD::move(__o.__imp_);
2434 }
2435 return *this;
2436 }
2437
2438 ~directory_iterator() = default;
2439
2440 const directory_entry& operator*() const {
2441 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002442 return __dereference();
Eric Fiselier435db152016-06-17 19:46:40 +00002443 }
2444
2445 const directory_entry* operator->() const
2446 { return &**this; }
2447
2448 directory_iterator& operator++()
2449 { return __increment(); }
2450
2451 __dir_element_proxy operator++(int) {
2452 __dir_element_proxy __p(**this);
2453 __increment();
2454 return __p;
2455 }
2456
Eric Fiselierd56d5322017-10-30 18:59:59 +00002457 directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002458 { return __increment(&__ec); }
2459
2460private:
Eric Fiselier28175a32016-09-16 00:07:16 +00002461 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002462 friend bool operator==(const directory_iterator& __lhs,
2463 const directory_iterator& __rhs) _NOEXCEPT;
2464
2465 // construct the dir_stream
2466 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002467 directory_iterator(const path&, error_code *,
2468 directory_options = directory_options::none);
2469
Eric Fiselier435db152016-06-17 19:46:40 +00002470 _LIBCPP_FUNC_VIS
2471 directory_iterator& __increment(error_code * __ec = nullptr);
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002472
Eric Fiselier435db152016-06-17 19:46:40 +00002473 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002474 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002475
2476private:
2477 shared_ptr<__dir_stream> __imp_;
2478};
2479
2480
2481inline _LIBCPP_INLINE_VISIBILITY
2482bool operator==(const directory_iterator& __lhs,
2483 const directory_iterator& __rhs) _NOEXCEPT {
2484 return __lhs.__imp_ == __rhs.__imp_;
2485}
2486
2487inline _LIBCPP_INLINE_VISIBILITY
2488bool operator!=(const directory_iterator& __lhs,
2489 const directory_iterator& __rhs) _NOEXCEPT {
2490 return !(__lhs == __rhs);
2491}
2492
2493// enable directory_iterator range-based for statements
2494inline _LIBCPP_INLINE_VISIBILITY
2495directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
2496 return __iter;
2497}
2498
2499inline _LIBCPP_INLINE_VISIBILITY
2500directory_iterator end(const directory_iterator&) _NOEXCEPT {
2501 return directory_iterator();
2502}
2503
2504class recursive_directory_iterator {
2505public:
2506 using value_type = directory_entry;
2507 using difference_type = std::ptrdiff_t;
2508 using pointer = directory_entry const *;
2509 using reference = directory_entry const &;
2510 using iterator_category = std::input_iterator_tag;
2511
2512public:
2513 // constructors and destructor
2514 _LIBCPP_INLINE_VISIBILITY
2515 recursive_directory_iterator() _NOEXCEPT
2516 : __rec_(false)
2517 {}
2518
2519 _LIBCPP_INLINE_VISIBILITY
2520 explicit recursive_directory_iterator(const path& __p,
2521 directory_options __xoptions = directory_options::none)
2522 : recursive_directory_iterator(__p, __xoptions, nullptr)
2523 { }
2524
2525 _LIBCPP_INLINE_VISIBILITY
2526 recursive_directory_iterator(const path& __p,
Eric Fiselierd56d5322017-10-30 18:59:59 +00002527 directory_options __xoptions, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002528 : recursive_directory_iterator(__p, __xoptions, &__ec)
2529 { }
2530
2531 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002532 recursive_directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002533 : recursive_directory_iterator(__p, directory_options::none, &__ec)
2534 { }
2535
2536 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2537 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2538
2539 recursive_directory_iterator &
2540 operator=(const recursive_directory_iterator&) = default;
2541
2542 _LIBCPP_INLINE_VISIBILITY
2543 recursive_directory_iterator &
2544 operator=(recursive_directory_iterator&& __o) noexcept {
2545 // non-default implementation provided to support self-move assign.
2546 if (this != &__o) {
2547 __imp_ = _VSTD::move(__o.__imp_);
2548 __rec_ = __o.__rec_;
2549 }
2550 return *this;
2551 }
2552
2553 ~recursive_directory_iterator() = default;
2554
2555 _LIBCPP_INLINE_VISIBILITY
2556 const directory_entry& operator*() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002557 { return __dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002558
2559 _LIBCPP_INLINE_VISIBILITY
2560 const directory_entry* operator->() const
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002561 { return &__dereference(); }
Eric Fiselier435db152016-06-17 19:46:40 +00002562
2563 recursive_directory_iterator& operator++()
2564 { return __increment(); }
2565
2566 _LIBCPP_INLINE_VISIBILITY
2567 __dir_element_proxy operator++(int) {
2568 __dir_element_proxy __p(**this);
2569 __increment();
2570 return __p;
2571 }
2572
2573 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierd56d5322017-10-30 18:59:59 +00002574 recursive_directory_iterator& increment(error_code& __ec)
Eric Fiselier435db152016-06-17 19:46:40 +00002575 { return __increment(&__ec); }
2576
2577 _LIBCPP_FUNC_VIS directory_options options() const;
2578 _LIBCPP_FUNC_VIS int depth() const;
2579
2580 _LIBCPP_INLINE_VISIBILITY
2581 void pop() { __pop(); }
2582
2583 _LIBCPP_INLINE_VISIBILITY
2584 void pop(error_code& __ec)
2585 { __pop(&__ec); }
2586
2587 _LIBCPP_INLINE_VISIBILITY
2588 bool recursion_pending() const
2589 { return __rec_; }
2590
2591 _LIBCPP_INLINE_VISIBILITY
2592 void disable_recursion_pending()
2593 { __rec_ = false; }
2594
2595private:
2596 recursive_directory_iterator(const path& __p, directory_options __opt,
2597 error_code *__ec);
2598
2599 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolfbb2d0e2017-01-30 00:15:47 +00002600 const directory_entry& __dereference() const;
Eric Fiselier435db152016-06-17 19:46:40 +00002601
2602 _LIBCPP_FUNC_VIS
2603 bool __try_recursion(error_code* __ec);
2604
2605 _LIBCPP_FUNC_VIS
2606 void __advance(error_code* __ec=nullptr);
2607
2608 _LIBCPP_FUNC_VIS
2609 recursive_directory_iterator& __increment(error_code *__ec=nullptr);
2610
2611 _LIBCPP_FUNC_VIS
2612 void __pop(error_code* __ec=nullptr);
2613
Eric Fiselier28175a32016-09-16 00:07:16 +00002614 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier435db152016-06-17 19:46:40 +00002615 friend bool operator==(const recursive_directory_iterator&,
2616 const recursive_directory_iterator&) _NOEXCEPT;
2617
2618 struct __shared_imp;
2619 shared_ptr<__shared_imp> __imp_;
2620 bool __rec_;
2621}; // class recursive_directory_iterator
2622
2623
Eric Fiselier28175a32016-09-16 00:07:16 +00002624inline _LIBCPP_INLINE_VISIBILITY
2625bool operator==(const recursive_directory_iterator& __lhs,
2626 const recursive_directory_iterator& __rhs) _NOEXCEPT
Eric Fiselier435db152016-06-17 19:46:40 +00002627{
2628 return __lhs.__imp_ == __rhs.__imp_;
2629}
2630
2631_LIBCPP_INLINE_VISIBILITY
2632inline bool operator!=(const recursive_directory_iterator& __lhs,
2633 const recursive_directory_iterator& __rhs) _NOEXCEPT
2634{
2635 return !(__lhs == __rhs);
2636}
2637// enable recursive_directory_iterator range-based for statements
2638inline _LIBCPP_INLINE_VISIBILITY
2639recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
2640 return __iter;
2641}
2642
2643inline _LIBCPP_INLINE_VISIBILITY
2644recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
2645 return recursive_directory_iterator();
2646}
2647
2648_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
2649
2650#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM