blob: 7aeabeb2d1ec6d3578cb8628d1f267fc29ee001d [file] [log] [blame]
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001// -*- C++ -*-
2//===--------------------------- filesystem -------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Eric Fiselier02cea5e2018-07-27 03:07:09 +00007//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP_FILESYSTEM
10#define _LIBCPP_FILESYSTEM
11/*
12 filesystem synopsis
13
14 namespace std { namespace filesystem {
15
16 class path;
17
18 void swap(path& lhs, path& rhs) noexcept;
19 size_t hash_value(const path& p) noexcept;
20
21 bool operator==(const path& lhs, const path& rhs) noexcept;
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
28 path operator/ (const path& lhs, const path& rhs);
29
30 // fs.path.io operators are friends of path.
31 template <class charT, class traits>
32 friend basic_ostream<charT, traits>&
33 operator<<(basic_ostream<charT, traits>& os, const path& p);
34
35 template <class charT, class traits>
36 friend basic_istream<charT, traits>&
37 operator>>(basic_istream<charT, traits>& is, path& p);
38
39 template <class Source>
40 path u8path(const Source& source);
41 template <class InputIterator>
42 path u8path(InputIterator first, InputIterator last);
43
44 class filesystem_error;
45 class directory_entry;
46
47 class directory_iterator;
48
49 // enable directory_iterator range-based for statements
50 directory_iterator begin(directory_iterator iter) noexcept;
51 directory_iterator end(const directory_iterator&) noexcept;
52
53 class recursive_directory_iterator;
54
55 // enable recursive_directory_iterator range-based for statements
56 recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
57 recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
58
59 class file_status;
60
61 struct space_info
62 {
63 uintmax_t capacity;
64 uintmax_t free;
65 uintmax_t available;
66 };
67
68 enum class file_type;
69 enum class perms;
70 enum class perm_options;
71 enum class copy_options;
72 enum class directory_options;
73
74 typedef chrono::time_point<trivial-clock> file_time_type;
75
76 // operational functions
77
78 path absolute(const path& p);
79 path absolute(const path& p, error_code &ec);
80
81 path canonical(const path& p);
82 path canonical(const path& p, error_code& ec);
83
84 void copy(const path& from, const path& to);
85 void copy(const path& from, const path& to, error_code& ec);
86 void copy(const path& from, const path& to, copy_options options);
87 void copy(const path& from, const path& to, copy_options options,
88 error_code& ec);
89
90 bool copy_file(const path& from, const path& to);
91 bool copy_file(const path& from, const path& to, error_code& ec);
92 bool copy_file(const path& from, const path& to, copy_options option);
93 bool copy_file(const path& from, const path& to, copy_options option,
94 error_code& ec);
95
96 void copy_symlink(const path& existing_symlink, const path& new_symlink);
97 void copy_symlink(const path& existing_symlink, const path& new_symlink,
98 error_code& ec) noexcept;
99
100 bool create_directories(const path& p);
101 bool create_directories(const path& p, error_code& ec);
102
103 bool create_directory(const path& p);
104 bool create_directory(const path& p, error_code& ec) noexcept;
105
106 bool create_directory(const path& p, const path& attributes);
107 bool create_directory(const path& p, const path& attributes,
108 error_code& ec) noexcept;
109
110 void create_directory_symlink(const path& to, const path& new_symlink);
111 void create_directory_symlink(const path& to, const path& new_symlink,
112 error_code& ec) noexcept;
113
114 void create_hard_link(const path& to, const path& new_hard_link);
115 void create_hard_link(const path& to, const path& new_hard_link,
116 error_code& ec) noexcept;
117
118 void create_symlink(const path& to, const path& new_symlink);
119 void create_symlink(const path& to, const path& new_symlink,
120 error_code& ec) noexcept;
121
122 path current_path();
123 path current_path(error_code& ec);
124 void current_path(const path& p);
125 void current_path(const path& p, error_code& ec) noexcept;
126
127 bool exists(file_status s) noexcept;
128 bool exists(const path& p);
129 bool exists(const path& p, error_code& ec) noexcept;
130
131 bool equivalent(const path& p1, const path& p2);
132 bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
133
134 uintmax_t file_size(const path& p);
135 uintmax_t file_size(const path& p, error_code& ec) noexcept;
136
137 uintmax_t hard_link_count(const path& p);
138 uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
139
140 bool is_block_file(file_status s) noexcept;
141 bool is_block_file(const path& p);
142 bool is_block_file(const path& p, error_code& ec) noexcept;
143
144 bool is_character_file(file_status s) noexcept;
145 bool is_character_file(const path& p);
146 bool is_character_file(const path& p, error_code& ec) noexcept;
147
148 bool is_directory(file_status s) noexcept;
149 bool is_directory(const path& p);
150 bool is_directory(const path& p, error_code& ec) noexcept;
151
152 bool is_empty(const path& p);
153 bool is_empty(const path& p, error_code& ec) noexcept;
154
155 bool is_fifo(file_status s) noexcept;
156 bool is_fifo(const path& p);
157 bool is_fifo(const path& p, error_code& ec) noexcept;
158
159 bool is_other(file_status s) noexcept;
160 bool is_other(const path& p);
161 bool is_other(const path& p, error_code& ec) noexcept;
162
163 bool is_regular_file(file_status s) noexcept;
164 bool is_regular_file(const path& p);
165 bool is_regular_file(const path& p, error_code& ec) noexcept;
166
167 bool is_socket(file_status s) noexcept;
168 bool is_socket(const path& p);
169 bool is_socket(const path& p, error_code& ec) noexcept;
170
171 bool is_symlink(file_status s) noexcept;
172 bool is_symlink(const path& p);
173 bool is_symlink(const path& p, error_code& ec) noexcept;
174
175 file_time_type last_write_time(const path& p);
176 file_time_type last_write_time(const path& p, error_code& ec) noexcept;
177 void last_write_time(const path& p, file_time_type new_time);
178 void last_write_time(const path& p, file_time_type new_time,
179 error_code& ec) noexcept;
180
181 void permissions(const path& p, perms prms,
182 perm_options opts=perm_options::replace);
183 void permissions(const path& p, perms prms, error_code& ec) noexcept;
184 void permissions(const path& p, perms prms, perm_options opts,
185 error_code& ec);
186
187 path proximate(const path& p, error_code& ec);
188 path proximate(const path& p, const path& base = current_path());
189 path proximate(const path& p, const path& base, error_code &ec);
190
191 path read_symlink(const path& p);
192 path read_symlink(const path& p, error_code& ec);
193
194 path relative(const path& p, error_code& ec);
195 path relative(const path& p, const path& base=current_path());
196 path relative(const path& p, const path& base, error_code& ec);
197
198 bool remove(const path& p);
199 bool remove(const path& p, error_code& ec) noexcept;
200
201 uintmax_t remove_all(const path& p);
202 uintmax_t remove_all(const path& p, error_code& ec);
203
204 void rename(const path& from, const path& to);
205 void rename(const path& from, const path& to, error_code& ec) noexcept;
206
207 void resize_file(const path& p, uintmax_t size);
208 void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
209
210 space_info space(const path& p);
211 space_info space(const path& p, error_code& ec) noexcept;
212
213 file_status status(const path& p);
214 file_status status(const path& p, error_code& ec) noexcept;
215
216 bool status_known(file_status s) noexcept;
217
218 file_status symlink_status(const path& p);
219 file_status symlink_status(const path& p, error_code& ec) noexcept;
220
221 path temp_directory_path();
222 path temp_directory_path(error_code& ec);
223
224 path weakly_canonical(path const& p);
225 path weakly_canonical(path const& p, error_code& ec);
226
227
228} } // namespaces std::filesystem
229
230*/
231
232#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -0500233#include <__availability>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000234#include <cstddef>
235#include <cstdlib>
236#include <chrono>
237#include <iterator>
238#include <iosfwd>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000239#include <memory>
240#include <stack>
241#include <string>
242#include <system_error>
243#include <utility>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000244#include <string_view>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000245#include <version>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000246
Louis Dionne8d053eb2020-10-09 15:31:05 -0400247#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
248# include <locale>
249# include <iomanip> // for quoted
250#endif
251
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000252#include <__debug>
253
254#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
255#pragma GCC system_header
256#endif
257
258_LIBCPP_PUSH_MACROS
259#include <__undef_macros>
260
261#ifndef _LIBCPP_CXX03_LANG
262
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000263_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
264
Louis Dionnef6bf76a2019-03-20 21:18:14 +0000265_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
266
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000267typedef chrono::time_point<_FilesystemClock> file_time_type;
268
269struct _LIBCPP_TYPE_VIS space_info {
270 uintmax_t capacity;
271 uintmax_t free;
272 uintmax_t available;
273};
274
275enum class _LIBCPP_ENUM_VIS file_type : signed char {
276 none = 0,
277 not_found = -1,
278 regular = 1,
279 directory = 2,
280 symlink = 3,
281 block = 4,
282 character = 5,
283 fifo = 6,
284 socket = 7,
285 unknown = 8
286};
287
288enum class _LIBCPP_ENUM_VIS perms : unsigned {
289 none = 0,
290
291 owner_read = 0400,
292 owner_write = 0200,
293 owner_exec = 0100,
294 owner_all = 0700,
295
296 group_read = 040,
297 group_write = 020,
298 group_exec = 010,
299 group_all = 070,
300
301 others_read = 04,
302 others_write = 02,
303 others_exec = 01,
304 others_all = 07,
305
306 all = 0777,
307
308 set_uid = 04000,
309 set_gid = 02000,
310 sticky_bit = 01000,
311 mask = 07777,
312 unknown = 0xFFFF,
313};
314
315_LIBCPP_INLINE_VISIBILITY
316inline constexpr perms operator&(perms _LHS, perms _RHS) {
317 return static_cast<perms>(static_cast<unsigned>(_LHS) &
318 static_cast<unsigned>(_RHS));
319}
320
321_LIBCPP_INLINE_VISIBILITY
322inline constexpr perms operator|(perms _LHS, perms _RHS) {
323 return static_cast<perms>(static_cast<unsigned>(_LHS) |
324 static_cast<unsigned>(_RHS));
325}
326
327_LIBCPP_INLINE_VISIBILITY
328inline constexpr perms operator^(perms _LHS, perms _RHS) {
329 return static_cast<perms>(static_cast<unsigned>(_LHS) ^
330 static_cast<unsigned>(_RHS));
331}
332
333_LIBCPP_INLINE_VISIBILITY
334inline constexpr perms operator~(perms _LHS) {
335 return static_cast<perms>(~static_cast<unsigned>(_LHS));
336}
337
338_LIBCPP_INLINE_VISIBILITY
339inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
340
341_LIBCPP_INLINE_VISIBILITY
342inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
343
344_LIBCPP_INLINE_VISIBILITY
345inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
346
347enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
348 replace = 1,
349 add = 2,
350 remove = 4,
351 nofollow = 8
352};
353
354_LIBCPP_INLINE_VISIBILITY
355inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
356 return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
357 static_cast<unsigned>(_RHS));
358}
359
360_LIBCPP_INLINE_VISIBILITY
361inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
362 return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
363 static_cast<unsigned>(_RHS));
364}
365
366_LIBCPP_INLINE_VISIBILITY
367inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
368 return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
369 static_cast<unsigned>(_RHS));
370}
371
372_LIBCPP_INLINE_VISIBILITY
373inline constexpr perm_options operator~(perm_options _LHS) {
374 return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
375}
376
377_LIBCPP_INLINE_VISIBILITY
378inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
379 return _LHS = _LHS & _RHS;
380}
381
382_LIBCPP_INLINE_VISIBILITY
383inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
384 return _LHS = _LHS | _RHS;
385}
386
387_LIBCPP_INLINE_VISIBILITY
388inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
389 return _LHS = _LHS ^ _RHS;
390}
391
392enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
393 none = 0,
394 skip_existing = 1,
395 overwrite_existing = 2,
396 update_existing = 4,
397 recursive = 8,
398 copy_symlinks = 16,
399 skip_symlinks = 32,
400 directories_only = 64,
401 create_symlinks = 128,
402 create_hard_links = 256,
403 __in_recursive_copy = 512,
404};
405
406_LIBCPP_INLINE_VISIBILITY
407inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
408 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
409 static_cast<unsigned short>(_RHS));
410}
411
412_LIBCPP_INLINE_VISIBILITY
413inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
414 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
415 static_cast<unsigned short>(_RHS));
416}
417
418_LIBCPP_INLINE_VISIBILITY
419inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
420 return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
421 static_cast<unsigned short>(_RHS));
422}
423
424_LIBCPP_INLINE_VISIBILITY
425inline constexpr copy_options operator~(copy_options _LHS) {
426 return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
427}
428
429_LIBCPP_INLINE_VISIBILITY
430inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
431 return _LHS = _LHS & _RHS;
432}
433
434_LIBCPP_INLINE_VISIBILITY
435inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
436 return _LHS = _LHS | _RHS;
437}
438
439_LIBCPP_INLINE_VISIBILITY
440inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
441 return _LHS = _LHS ^ _RHS;
442}
443
444enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
445 none = 0,
446 follow_directory_symlink = 1,
447 skip_permission_denied = 2
448};
449
450_LIBCPP_INLINE_VISIBILITY
451inline constexpr directory_options operator&(directory_options _LHS,
452 directory_options _RHS) {
453 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
454 static_cast<unsigned char>(_RHS));
455}
456
457_LIBCPP_INLINE_VISIBILITY
458inline constexpr directory_options operator|(directory_options _LHS,
459 directory_options _RHS) {
460 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
461 static_cast<unsigned char>(_RHS));
462}
463
464_LIBCPP_INLINE_VISIBILITY
465inline constexpr directory_options operator^(directory_options _LHS,
466 directory_options _RHS) {
467 return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
468 static_cast<unsigned char>(_RHS));
469}
470
471_LIBCPP_INLINE_VISIBILITY
472inline constexpr directory_options operator~(directory_options _LHS) {
473 return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
474}
475
476_LIBCPP_INLINE_VISIBILITY
477inline directory_options& operator&=(directory_options& _LHS,
478 directory_options _RHS) {
479 return _LHS = _LHS & _RHS;
480}
481
482_LIBCPP_INLINE_VISIBILITY
483inline directory_options& operator|=(directory_options& _LHS,
484 directory_options _RHS) {
485 return _LHS = _LHS | _RHS;
486}
487
488_LIBCPP_INLINE_VISIBILITY
489inline directory_options& operator^=(directory_options& _LHS,
490 directory_options _RHS) {
491 return _LHS = _LHS ^ _RHS;
492}
493
494class _LIBCPP_TYPE_VIS file_status {
495public:
496 // constructors
497 _LIBCPP_INLINE_VISIBILITY
498 file_status() noexcept : file_status(file_type::none) {}
499 _LIBCPP_INLINE_VISIBILITY
500 explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
501 : __ft_(__ft),
502 __prms_(__prms) {}
503
504 file_status(const file_status&) noexcept = default;
505 file_status(file_status&&) noexcept = default;
506
507 _LIBCPP_INLINE_VISIBILITY
508 ~file_status() {}
509
510 file_status& operator=(const file_status&) noexcept = default;
511 file_status& operator=(file_status&&) noexcept = default;
512
513 // observers
514 _LIBCPP_INLINE_VISIBILITY
515 file_type type() const noexcept { return __ft_; }
516
517 _LIBCPP_INLINE_VISIBILITY
518 perms permissions() const noexcept { return __prms_; }
519
520 // modifiers
521 _LIBCPP_INLINE_VISIBILITY
522 void type(file_type __ft) noexcept { __ft_ = __ft; }
523
524 _LIBCPP_INLINE_VISIBILITY
525 void permissions(perms __p) noexcept { __prms_ = __p; }
526
527private:
528 file_type __ft_;
529 perms __prms_;
530};
531
532class _LIBCPP_TYPE_VIS directory_entry;
533
534template <class _Tp>
535struct __can_convert_char {
536 static const bool value = false;
537};
538template <class _Tp>
539struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
540template <>
541struct __can_convert_char<char> {
542 static const bool value = true;
543 using __char_type = char;
544};
545template <>
546struct __can_convert_char<wchar_t> {
547 static const bool value = true;
548 using __char_type = wchar_t;
549};
Martin Storsjöe3a71972020-10-26 13:18:46 +0200550#ifndef _LIBCPP_NO_HAS_CHAR8_T
551template <>
552struct __can_convert_char<char8_t> {
553 static const bool value = true;
554 using __char_type = char8_t;
555};
556#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000557template <>
558struct __can_convert_char<char16_t> {
559 static const bool value = true;
560 using __char_type = char16_t;
561};
562template <>
563struct __can_convert_char<char32_t> {
564 static const bool value = true;
565 using __char_type = char32_t;
566};
567
568template <class _ECharT>
569typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
570__is_separator(_ECharT __e) {
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200571#if defined(_LIBCPP_WIN32API)
572 return __e == _ECharT('/') || __e == _ECharT('\\');
573#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000574 return __e == _ECharT('/');
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200575#endif
Eric Fiselierb41db9a2018-10-01 01:59:37 +0000576}
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000577
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200578#ifndef _LIBCPP_NO_HAS_CHAR8_T
579typedef u8string __u8_string;
580#else
581typedef string __u8_string;
582#endif
583
Martin Storsjö2ae96532020-10-27 11:46:06 +0200584struct _NullSentinel {};
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000585
586template <class _Tp>
587using _Void = void;
588
589template <class _Tp, class = void>
590struct __is_pathable_string : public false_type {};
591
592template <class _ECharT, class _Traits, class _Alloc>
593struct __is_pathable_string<
594 basic_string<_ECharT, _Traits, _Alloc>,
595 _Void<typename __can_convert_char<_ECharT>::__char_type> >
596 : public __can_convert_char<_ECharT> {
597 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
598 using _Base = __can_convert_char<_ECharT>;
599 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
600 static _ECharT const* __range_end(_Str const& __s) {
601 return __s.data() + __s.length();
602 }
603 static _ECharT __first_or_null(_Str const& __s) {
604 return __s.empty() ? _ECharT{} : __s[0];
605 }
606};
607
608template <class _ECharT, class _Traits>
609struct __is_pathable_string<
610 basic_string_view<_ECharT, _Traits>,
611 _Void<typename __can_convert_char<_ECharT>::__char_type> >
612 : public __can_convert_char<_ECharT> {
613 using _Str = basic_string_view<_ECharT, _Traits>;
614 using _Base = __can_convert_char<_ECharT>;
615 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
616 static _ECharT const* __range_end(_Str const& __s) {
617 return __s.data() + __s.length();
618 }
619 static _ECharT __first_or_null(_Str const& __s) {
620 return __s.empty() ? _ECharT{} : __s[0];
621 }
622};
623
624template <class _Source, class _DS = typename decay<_Source>::type,
625 class _UnqualPtrType =
626 typename remove_const<typename remove_pointer<_DS>::type>::type,
627 bool _IsCharPtr = is_pointer<_DS>::value&&
628 __can_convert_char<_UnqualPtrType>::value>
629struct __is_pathable_char_array : false_type {};
630
631template <class _Source, class _ECharT, class _UPtr>
632struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
633 : __can_convert_char<typename remove_const<_ECharT>::type> {
634 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
635
636 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
637 static _ECharT const* __range_end(const _ECharT* __b) {
638 using _Iter = const _ECharT*;
Martin Storsjö2ae96532020-10-27 11:46:06 +0200639 const _ECharT __sentinel = _ECharT{};
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000640 _Iter __e = __b;
Martin Storsjö2ae96532020-10-27 11:46:06 +0200641 for (; *__e != __sentinel; ++__e)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000642 ;
643 return __e;
644 }
645
646 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
647};
648
Eric Fiseliercd5a6772019-11-18 01:46:58 -0500649template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value,
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000650 class = void>
651struct __is_pathable_iter : false_type {};
652
653template <class _Iter>
654struct __is_pathable_iter<
655 _Iter, true,
656 _Void<typename __can_convert_char<
657 typename iterator_traits<_Iter>::value_type>::__char_type> >
658 : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
659 using _ECharT = typename iterator_traits<_Iter>::value_type;
660 using _Base = __can_convert_char<_ECharT>;
661
662 static _Iter __range_begin(_Iter __b) { return __b; }
Martin Storsjö2ae96532020-10-27 11:46:06 +0200663 static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; }
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000664
665 static _ECharT __first_or_null(_Iter __b) { return *__b; }
666};
667
668template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
669 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
670 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
671struct __is_pathable : false_type {
672 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
673};
674
675template <class _Tp>
676struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
677
678template <class _Tp>
679struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
680};
681
682template <class _Tp>
683struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
684
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200685#if defined(_LIBCPP_WIN32API)
686typedef wstring __path_string;
687typedef wchar_t __path_value;
688#else
689typedef string __path_string;
690typedef char __path_value;
691#endif
692
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000693template <class _ECharT>
Louis Dionne8d053eb2020-10-09 15:31:05 -0400694struct _PathCVT;
695
696#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
697template <class _ECharT>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000698struct _PathCVT {
699 static_assert(__can_convert_char<_ECharT>::value,
700 "Char type not convertible");
701
702 typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200703#if defined(_LIBCPP_WIN32API)
704 typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
705#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000706
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200707 static void __append_range(__path_string& __dest, _ECharT const* __b,
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000708 _ECharT const* __e) {
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200709#if defined(_LIBCPP_WIN32API)
710 string __utf8;
711 _Narrower()(back_inserter(__utf8), __b, __e);
712 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
713#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000714 _Narrower()(back_inserter(__dest), __b, __e);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200715#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000716 }
717
718 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200719 static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000720 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
721 if (__b == __e)
722 return;
723 basic_string<_ECharT> __tmp(__b, __e);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200724#if defined(_LIBCPP_WIN32API)
725 string __utf8;
726 _Narrower()(back_inserter(__utf8), __tmp.data(),
727 __tmp.data() + __tmp.length());
728 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
729#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000730 _Narrower()(back_inserter(__dest), __tmp.data(),
731 __tmp.data() + __tmp.length());
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200732#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000733 }
734
735 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200736 static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000737 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
Martin Storsjö2ae96532020-10-27 11:46:06 +0200738 const _ECharT __sentinel = _ECharT{};
739 if (*__b == __sentinel)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000740 return;
741 basic_string<_ECharT> __tmp;
Martin Storsjö2ae96532020-10-27 11:46:06 +0200742 for (; *__b != __sentinel; ++__b)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000743 __tmp.push_back(*__b);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200744#if defined(_LIBCPP_WIN32API)
745 string __utf8;
746 _Narrower()(back_inserter(__utf8), __tmp.data(),
747 __tmp.data() + __tmp.length());
748 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
749#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000750 _Narrower()(back_inserter(__dest), __tmp.data(),
751 __tmp.data() + __tmp.length());
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200752#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000753 }
754
755 template <class _Source>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200756 static void __append_source(__path_string& __dest, _Source const& __s) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000757 using _Traits = __is_pathable<_Source>;
758 __append_range(__dest, _Traits::__range_begin(__s),
759 _Traits::__range_end(__s));
760 }
761};
Louis Dionne8d053eb2020-10-09 15:31:05 -0400762#endif // !_LIBCPP_HAS_NO_LOCALIZATION
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000763
764template <>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200765struct _PathCVT<__path_value> {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000766
767 template <class _Iter>
Eric Fiseliercd5a6772019-11-18 01:46:58 -0500768 static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200769 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000770 for (; __b != __e; ++__b)
771 __dest.push_back(*__b);
772 }
773
774 template <class _Iter>
Eric Fiseliercd5a6772019-11-18 01:46:58 -0500775 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200776 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000777 __dest.__append_forward_unsafe(__b, __e);
778 }
779
780 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200781 static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
Martin Storsjö2ae96532020-10-27 11:46:06 +0200782 const char __sentinel = char{};
783 for (; *__b != __sentinel; ++__b)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000784 __dest.push_back(*__b);
785 }
786
787 template <class _Source>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200788 static void __append_source(__path_string& __dest, _Source const& __s) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000789 using _Traits = __is_pathable<_Source>;
790 __append_range(__dest, _Traits::__range_begin(__s),
791 _Traits::__range_end(__s));
792 }
793};
794
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200795#if defined(_LIBCPP_WIN32API)
796template <class _ECharT>
797struct _PathExport {
798 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
799 typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
800
801 template <class _Str>
802 static void __append(_Str& __dest, const __path_string& __src) {
803 string __utf8;
804 _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
805 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
806 }
807};
808
809template <>
810struct _PathExport<wchar_t> {
811 template <class _Str>
812 static void __append(_Str& __dest, const __path_string& __src) {
813 __dest.append(__src.begin(), __src.end());
814 }
815};
816
817template <>
818struct _PathExport<char16_t> {
819 template <class _Str>
820 static void __append(_Str& __dest, const __path_string& __src) {
821 __dest.append(__src.begin(), __src.end());
822 }
823};
824
825#ifndef _LIBCPP_NO_HAS_CHAR8_T
826template <>
827struct _PathExport<char8_t> {
828 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
829
830 template <class _Str>
831 static void __append(_Str& __dest, const __path_string& __src) {
832 _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
833 }
834};
835#endif /* !_LIBCPP_NO_HAS_CHAR8_T */
836#endif /* _LIBCPP_WIN32API */
837
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000838class _LIBCPP_TYPE_VIS path {
839 template <class _SourceOrIter, class _Tp = path&>
840 using _EnableIfPathable =
841 typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
842
843 template <class _Tp>
844 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
845
846 template <class _Tp>
847 using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
848
849public:
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200850#if defined(_LIBCPP_WIN32API)
851 typedef wchar_t value_type;
852 static constexpr value_type preferred_separator = L'\\';
853#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000854 typedef char value_type;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000855 static constexpr value_type preferred_separator = '/';
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200856#endif
857 typedef basic_string<value_type> string_type;
858 typedef basic_string_view<value_type> __string_view;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000859
860 enum class _LIBCPP_ENUM_VIS format : unsigned char {
861 auto_format,
862 native_format,
863 generic_format
864 };
865
866 // constructors and destructor
867 _LIBCPP_INLINE_VISIBILITY path() noexcept {}
868 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
869 _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
870 : __pn_(_VSTD::move(__p.__pn_)) {}
871
872 _LIBCPP_INLINE_VISIBILITY
873 path(string_type&& __s, format = format::auto_format) noexcept
874 : __pn_(_VSTD::move(__s)) {}
875
876 template <class _Source, class = _EnableIfPathable<_Source, void> >
877 path(const _Source& __src, format = format::auto_format) {
878 _SourceCVT<_Source>::__append_source(__pn_, __src);
879 }
880
881 template <class _InputIt>
882 path(_InputIt __first, _InputIt __last, format = format::auto_format) {
883 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
884 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
885 }
886
Louis Dionne8d053eb2020-10-09 15:31:05 -0400887#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000888 // TODO Implement locale conversions.
889 template <class _Source, class = _EnableIfPathable<_Source, void> >
890 path(const _Source& __src, const locale& __loc, format = format::auto_format);
891 template <class _InputIt>
892 path(_InputIt __first, _InputIt _last, const locale& __loc,
893 format = format::auto_format);
Louis Dionne8d053eb2020-10-09 15:31:05 -0400894#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000895
896 _LIBCPP_INLINE_VISIBILITY
897 ~path() = default;
898
899 // assignments
900 _LIBCPP_INLINE_VISIBILITY
901 path& operator=(const path& __p) {
902 __pn_ = __p.__pn_;
903 return *this;
904 }
905
906 _LIBCPP_INLINE_VISIBILITY
907 path& operator=(path&& __p) noexcept {
908 __pn_ = _VSTD::move(__p.__pn_);
909 return *this;
910 }
911
912 template <class = void>
913 _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
914 __pn_ = _VSTD::move(__s);
915 return *this;
916 }
917
918 _LIBCPP_INLINE_VISIBILITY
919 path& assign(string_type&& __s) noexcept {
920 __pn_ = _VSTD::move(__s);
921 return *this;
922 }
923
924 template <class _Source>
925 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
926 operator=(const _Source& __src) {
927 return this->assign(__src);
928 }
929
930 template <class _Source>
931 _EnableIfPathable<_Source> assign(const _Source& __src) {
932 __pn_.clear();
933 _SourceCVT<_Source>::__append_source(__pn_, __src);
934 return *this;
935 }
936
937 template <class _InputIt>
938 path& assign(_InputIt __first, _InputIt __last) {
939 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
940 __pn_.clear();
941 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
942 return *this;
943 }
944
945private:
946 template <class _ECharT>
947 static bool __source_is_absolute(_ECharT __first_or_null) {
948 return __is_separator(__first_or_null);
949 }
950
951public:
952 // appends
953 path& operator/=(const path& __p) {
954 if (__p.is_absolute()) {
955 __pn_ = __p.__pn_;
956 return *this;
957 }
958 if (has_filename())
959 __pn_ += preferred_separator;
960 __pn_ += __p.native();
961 return *this;
962 }
963
964 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
965 // is known at compile time to be "/' since the user almost certainly intended
966 // to append a separator instead of overwriting the path with "/"
967 template <class _Source>
968 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
969 operator/=(const _Source& __src) {
970 return this->append(__src);
971 }
972
973 template <class _Source>
974 _EnableIfPathable<_Source> append(const _Source& __src) {
975 using _Traits = __is_pathable<_Source>;
976 using _CVT = _PathCVT<_SourceChar<_Source> >;
977 if (__source_is_absolute(_Traits::__first_or_null(__src)))
978 __pn_.clear();
979 else if (has_filename())
980 __pn_ += preferred_separator;
981 _CVT::__append_source(__pn_, __src);
982 return *this;
983 }
984
985 template <class _InputIt>
986 path& append(_InputIt __first, _InputIt __last) {
987 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
988 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
989 using _CVT = _PathCVT<_ItVal>;
990 if (__first != __last && __source_is_absolute(*__first))
991 __pn_.clear();
992 else if (has_filename())
993 __pn_ += preferred_separator;
994 _CVT::__append_range(__pn_, __first, __last);
995 return *this;
996 }
997
998 // concatenation
999 _LIBCPP_INLINE_VISIBILITY
1000 path& operator+=(const path& __x) {
1001 __pn_ += __x.__pn_;
1002 return *this;
1003 }
1004
1005 _LIBCPP_INLINE_VISIBILITY
1006 path& operator+=(const string_type& __x) {
1007 __pn_ += __x;
1008 return *this;
1009 }
1010
1011 _LIBCPP_INLINE_VISIBILITY
1012 path& operator+=(__string_view __x) {
1013 __pn_ += __x;
1014 return *this;
1015 }
1016
1017 _LIBCPP_INLINE_VISIBILITY
1018 path& operator+=(const value_type* __x) {
1019 __pn_ += __x;
1020 return *this;
1021 }
1022
1023 _LIBCPP_INLINE_VISIBILITY
1024 path& operator+=(value_type __x) {
1025 __pn_ += __x;
1026 return *this;
1027 }
1028
1029 template <class _ECharT>
1030 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
1031 operator+=(_ECharT __x) {
Marek Kurdej306a1b02020-12-07 20:07:25 +01001032 _PathCVT<_ECharT>::__append_source(__pn_,
1033 basic_string_view<_ECharT>(&__x, 1));
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001034 return *this;
1035 }
1036
1037 template <class _Source>
1038 _EnableIfPathable<_Source> operator+=(const _Source& __x) {
1039 return this->concat(__x);
1040 }
1041
1042 template <class _Source>
1043 _EnableIfPathable<_Source> concat(const _Source& __x) {
1044 _SourceCVT<_Source>::__append_source(__pn_, __x);
1045 return *this;
1046 }
1047
1048 template <class _InputIt>
1049 path& concat(_InputIt __first, _InputIt __last) {
1050 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1051 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1052 return *this;
1053 }
1054
1055 // modifiers
1056 _LIBCPP_INLINE_VISIBILITY
1057 void clear() noexcept { __pn_.clear(); }
1058
1059 path& make_preferred() { return *this; }
1060
1061 _LIBCPP_INLINE_VISIBILITY
1062 path& remove_filename() {
1063 auto __fname = __filename();
1064 if (!__fname.empty())
1065 __pn_.erase(__fname.data() - __pn_.data());
1066 return *this;
1067 }
1068
1069 path& replace_filename(const path& __replacement) {
1070 remove_filename();
1071 return (*this /= __replacement);
1072 }
1073
1074 path& replace_extension(const path& __replacement = path());
1075
1076 _LIBCPP_INLINE_VISIBILITY
1077 void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
1078
1079 // private helper to allow reserving memory in the path
1080 _LIBCPP_INLINE_VISIBILITY
1081 void __reserve(size_t __s) { __pn_.reserve(__s); }
1082
1083 // native format observers
1084 _LIBCPP_INLINE_VISIBILITY
1085 const string_type& native() const noexcept { return __pn_; }
1086
1087 _LIBCPP_INLINE_VISIBILITY
1088 const value_type* c_str() const noexcept { return __pn_.c_str(); }
1089
1090 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
1091
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001092#if defined(_LIBCPP_WIN32API)
1093 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
1094
1095 _VSTD::wstring generic_wstring() const { return __pn_; }
1096
1097#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1098 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1099 class _Allocator = allocator<_ECharT> >
1100 basic_string<_ECharT, _Traits, _Allocator>
1101 string(const _Allocator& __a = _Allocator()) const {
1102 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1103 _Str __s(__a);
1104 __s.reserve(__pn_.size());
1105 _PathExport<_ECharT>::__append(__s, __pn_);
1106 return __s;
1107 }
1108
1109 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
1110 return string<char>();
1111 }
1112 _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
1113 return string<__u8_string::value_type>();
1114 }
1115
1116 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1117 return string<char16_t>();
1118 }
1119 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1120 return string<char32_t>();
1121 }
1122
1123 // generic format observers
1124 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1125 class _Allocator = allocator<_ECharT> >
1126 basic_string<_ECharT, _Traits, _Allocator>
1127 generic_string(const _Allocator& __a = _Allocator()) const {
1128 return string<_ECharT, _Traits, _Allocator>(__a);
1129 }
1130
1131 _VSTD::string generic_string() const { return generic_string<char>(); }
1132 _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
1133 _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1134 __u8_string generic_u8string() const { return u8string(); }
1135#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1136#else /* _LIBCPP_WIN32API */
1137
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001138 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001139#ifndef _LIBCPP_NO_HAS_CHAR8_T
1140 _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1141#else
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001142 _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001143#endif
Louis Dionne8d053eb2020-10-09 15:31:05 -04001144
1145#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001146 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1147 class _Allocator = allocator<_ECharT> >
1148 basic_string<_ECharT, _Traits, _Allocator>
1149 string(const _Allocator& __a = _Allocator()) const {
1150 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
1151 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1152 _Str __s(__a);
1153 __s.reserve(__pn_.size());
1154 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1155 return __s;
1156 }
1157
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001158 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001159 return string<wchar_t>();
1160 }
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001161 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001162 return string<char16_t>();
1163 }
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001164 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001165 return string<char32_t>();
1166 }
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001167#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001168
1169 // generic format observers
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001170 _VSTD::string generic_string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001171#ifndef _LIBCPP_NO_HAS_CHAR8_T
1172 _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1173#else
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001174 _VSTD::string generic_u8string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001175#endif
Louis Dionne8d053eb2020-10-09 15:31:05 -04001176
1177#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001178 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1179 class _Allocator = allocator<_ECharT> >
1180 basic_string<_ECharT, _Traits, _Allocator>
1181 generic_string(const _Allocator& __a = _Allocator()) const {
1182 return string<_ECharT, _Traits, _Allocator>(__a);
1183 }
1184
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001185 _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
1186 _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
1187 _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001188#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1189#endif /* !_LIBCPP_WIN32API */
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001190
1191private:
1192 int __compare(__string_view) const;
1193 __string_view __root_name() const;
1194 __string_view __root_directory() const;
1195 __string_view __root_path_raw() const;
1196 __string_view __relative_path() const;
1197 __string_view __parent_path() const;
1198 __string_view __filename() const;
1199 __string_view __stem() const;
1200 __string_view __extension() const;
1201
1202public:
1203 // compare
1204 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
1205 return __compare(__p.__pn_);
1206 }
1207 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
1208 return __compare(__s);
1209 }
1210 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
1211 return __compare(__s);
1212 }
1213 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
1214 return __compare(__s);
1215 }
1216
1217 // decomposition
1218 _LIBCPP_INLINE_VISIBILITY path root_name() const {
1219 return string_type(__root_name());
1220 }
1221 _LIBCPP_INLINE_VISIBILITY path root_directory() const {
1222 return string_type(__root_directory());
1223 }
1224 _LIBCPP_INLINE_VISIBILITY path root_path() const {
1225 return root_name().append(string_type(__root_directory()));
1226 }
1227 _LIBCPP_INLINE_VISIBILITY path relative_path() const {
1228 return string_type(__relative_path());
1229 }
1230 _LIBCPP_INLINE_VISIBILITY path parent_path() const {
1231 return string_type(__parent_path());
1232 }
1233 _LIBCPP_INLINE_VISIBILITY path filename() const {
1234 return string_type(__filename());
1235 }
1236 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
1237 _LIBCPP_INLINE_VISIBILITY path extension() const {
1238 return string_type(__extension());
1239 }
1240
1241 // query
1242 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
1243 empty() const noexcept {
1244 return __pn_.empty();
1245 }
1246
1247 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
1248 return !__root_name().empty();
1249 }
1250 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
1251 return !__root_directory().empty();
1252 }
1253 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
1254 return !__root_path_raw().empty();
1255 }
1256 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
1257 return !__relative_path().empty();
1258 }
1259 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
1260 return !__parent_path().empty();
1261 }
1262 _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
1263 return !__filename().empty();
1264 }
1265 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1266 _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
1267 return !__extension().empty();
1268 }
1269
1270 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1271 return has_root_directory();
1272 }
1273 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1274
1275 // relative paths
1276 path lexically_normal() const;
1277 path lexically_relative(const path& __base) const;
1278
1279 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1280 path __result = this->lexically_relative(__base);
1281 if (__result.native().empty())
1282 return *this;
1283 return __result;
1284 }
1285
1286 // iterators
1287 class _LIBCPP_TYPE_VIS iterator;
1288 typedef iterator const_iterator;
1289
1290 iterator begin() const;
1291 iterator end() const;
1292
Louis Dionne8d053eb2020-10-09 15:31:05 -04001293#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001294 template <class _CharT, class _Traits>
1295 _LIBCPP_INLINE_VISIBILITY friend
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001296 typename enable_if<is_same<_CharT, value_type>::value &&
1297 is_same<_Traits, char_traits<value_type> >::value,
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001298 basic_ostream<_CharT, _Traits>&>::type
1299 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001300 __os << _VSTD::__quoted(__p.native());
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001301 return __os;
1302 }
1303
1304 template <class _CharT, class _Traits>
1305 _LIBCPP_INLINE_VISIBILITY friend
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001306 typename enable_if<!is_same<_CharT, value_type>::value ||
1307 !is_same<_Traits, char_traits<value_type> >::value,
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001308 basic_ostream<_CharT, _Traits>&>::type
1309 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001310 __os << _VSTD::__quoted(__p.string<_CharT, _Traits>());
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001311 return __os;
1312 }
1313
1314 template <class _CharT, class _Traits>
1315 _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
1316 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
1317 basic_string<_CharT, _Traits> __tmp;
1318 __is >> __quoted(__tmp);
1319 __p = __tmp;
1320 return __is;
1321 }
Louis Dionne8d053eb2020-10-09 15:31:05 -04001322#endif // !_LIBCPP_HAS_NO_LOCALIZATION
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001323
Eric Fiselierab3f9d62018-12-21 04:09:01 +00001324 friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
1325 return __lhs.compare(__rhs) == 0;
1326 }
1327 friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
1328 return __lhs.compare(__rhs) != 0;
1329 }
1330 friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
1331 return __lhs.compare(__rhs) < 0;
1332 }
1333 friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
1334 return __lhs.compare(__rhs) <= 0;
1335 }
1336 friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
1337 return __lhs.compare(__rhs) > 0;
1338 }
1339 friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
1340 return __lhs.compare(__rhs) >= 0;
1341 }
1342
1343 friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1344 const path& __rhs) {
1345 path __result(__lhs);
1346 __result /= __rhs;
1347 return __result;
1348 }
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001349private:
1350 inline _LIBCPP_INLINE_VISIBILITY path&
1351 __assign_view(__string_view const& __s) noexcept {
1352 __pn_ = string_type(__s);
1353 return *this;
1354 }
1355 string_type __pn_;
1356};
1357
1358inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
1359 __lhs.swap(__rhs);
1360}
1361
1362_LIBCPP_FUNC_VIS
1363size_t hash_value(const path& __p) noexcept;
1364
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001365template <class _Source>
Martin Storsjöe3a71972020-10-26 13:18:46 +02001366_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001367 typename enable_if<__is_pathable<_Source>::value, path>::type
1368 u8path(const _Source& __s) {
1369 static_assert(
Martin Storsjöe3a71972020-10-26 13:18:46 +02001370#ifndef _LIBCPP_NO_HAS_CHAR8_T
1371 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
1372#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001373 is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1374 "u8path(Source const&) requires Source have a character type of type "
Martin Storsjö929dff92020-12-15 09:15:37 +02001375 "'char' or 'char8_t'");
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001376 return path(__s);
1377}
1378
1379template <class _InputIt>
Martin Storsjöe3a71972020-10-26 13:18:46 +02001380_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001381 typename enable_if<__is_pathable<_InputIt>::value, path>::type
1382 u8path(_InputIt __f, _InputIt __l) {
1383 static_assert(
Martin Storsjöe3a71972020-10-26 13:18:46 +02001384#ifndef _LIBCPP_NO_HAS_CHAR8_T
1385 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1386#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001387 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
Martin Storsjöe3a71972020-10-26 13:18:46 +02001388 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
Martin Storsjö929dff92020-12-15 09:15:37 +02001389 " or 'char8_t'");
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001390 return path(__f, __l);
1391}
1392
1393class _LIBCPP_TYPE_VIS path::iterator {
1394public:
1395 enum _ParserState : unsigned char {
1396 _Singular,
1397 _BeforeBegin,
1398 _InRootName,
1399 _InRootDir,
1400 _InFilenames,
1401 _InTrailingSep,
1402 _AtEnd
1403 };
1404
1405public:
1406 typedef bidirectional_iterator_tag iterator_category;
1407
1408 typedef path value_type;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001409 typedef ptrdiff_t difference_type;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001410 typedef const path* pointer;
1411 typedef const path& reference;
1412
1413 typedef void
1414 __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1415
1416public:
1417 _LIBCPP_INLINE_VISIBILITY
1418 iterator()
1419 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
1420 __state_(_Singular) {}
1421
1422 iterator(const iterator&) = default;
1423 ~iterator() = default;
1424
1425 iterator& operator=(const iterator&) = default;
1426
1427 _LIBCPP_INLINE_VISIBILITY
1428 reference operator*() const { return __stashed_elem_; }
1429
1430 _LIBCPP_INLINE_VISIBILITY
1431 pointer operator->() const { return &__stashed_elem_; }
1432
1433 _LIBCPP_INLINE_VISIBILITY
1434 iterator& operator++() {
1435 _LIBCPP_ASSERT(__state_ != _Singular,
1436 "attempting to increment a singular iterator");
1437 _LIBCPP_ASSERT(__state_ != _AtEnd,
1438 "attempting to increment the end iterator");
1439 return __increment();
1440 }
1441
1442 _LIBCPP_INLINE_VISIBILITY
1443 iterator operator++(int) {
1444 iterator __it(*this);
1445 this->operator++();
1446 return __it;
1447 }
1448
1449 _LIBCPP_INLINE_VISIBILITY
1450 iterator& operator--() {
1451 _LIBCPP_ASSERT(__state_ != _Singular,
1452 "attempting to decrement a singular iterator");
1453 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1454 "attempting to decrement the begin iterator");
1455 return __decrement();
1456 }
1457
1458 _LIBCPP_INLINE_VISIBILITY
1459 iterator operator--(int) {
1460 iterator __it(*this);
1461 this->operator--();
1462 return __it;
1463 }
1464
1465private:
1466 friend class path;
1467
1468 inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
1469 const iterator&);
1470
1471 iterator& __increment();
1472 iterator& __decrement();
1473
1474 path __stashed_elem_;
1475 const path* __path_ptr_;
1476 path::__string_view __entry_;
1477 _ParserState __state_;
1478};
1479
1480inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
1481 const path::iterator& __rhs) {
1482 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1483 __lhs.__entry_.data() == __rhs.__entry_.data();
1484}
1485
1486inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
1487 const path::iterator& __rhs) {
1488 return !(__lhs == __rhs);
1489}
1490
Louis Dionnef6bf76a2019-03-20 21:18:14 +00001491// TODO(ldionne): We need to pop the pragma and push it again after
1492// filesystem_error to work around PR41078.
1493_LIBCPP_AVAILABILITY_FILESYSTEM_POP
1494
1495class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001496public:
1497 _LIBCPP_INLINE_VISIBILITY
1498 filesystem_error(const string& __what, error_code __ec)
1499 : system_error(__ec, __what),
1500 __storage_(make_shared<_Storage>(path(), path())) {
1501 __create_what(0);
1502 }
1503
1504 _LIBCPP_INLINE_VISIBILITY
1505 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1506 : system_error(__ec, __what),
1507 __storage_(make_shared<_Storage>(__p1, path())) {
1508 __create_what(1);
1509 }
1510
1511 _LIBCPP_INLINE_VISIBILITY
1512 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1513 error_code __ec)
1514 : system_error(__ec, __what),
1515 __storage_(make_shared<_Storage>(__p1, __p2)) {
1516 __create_what(2);
1517 }
1518
1519 _LIBCPP_INLINE_VISIBILITY
1520 const path& path1() const noexcept { return __storage_->__p1_; }
1521
1522 _LIBCPP_INLINE_VISIBILITY
1523 const path& path2() const noexcept { return __storage_->__p2_; }
1524
Dimitry Andric47269ce2020-03-13 19:36:26 +01001525 filesystem_error(const filesystem_error&) = default;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001526 ~filesystem_error() override; // key function
1527
1528 _LIBCPP_INLINE_VISIBILITY
1529 const char* what() const noexcept override {
1530 return __storage_->__what_.c_str();
1531 }
1532
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001533 void __create_what(int __num_paths);
1534
1535private:
Louis Dionne48ae8892019-03-19 17:47:53 +00001536 struct _LIBCPP_HIDDEN _Storage {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001537 _LIBCPP_INLINE_VISIBILITY
1538 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1539
1540 path __p1_;
1541 path __p2_;
1542 string __what_;
1543 };
1544 shared_ptr<_Storage> __storage_;
1545};
1546
Louis Dionnef6bf76a2019-03-20 21:18:14 +00001547_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
1548
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001549template <class... _Args>
1550_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1551#ifndef _LIBCPP_NO_EXCEPTIONS
Louis Dionne6251ef02019-02-05 15:46:52 +00001552void __throw_filesystem_error(_Args&&... __args) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001553 throw filesystem_error(_VSTD::forward<_Args>(__args)...);
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001554}
1555#else
Louis Dionne6251ef02019-02-05 15:46:52 +00001556void __throw_filesystem_error(_Args&&...) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001557 _VSTD::abort();
1558}
1559#endif
1560
1561// operational functions
1562
1563_LIBCPP_FUNC_VIS
1564path __absolute(const path&, error_code* __ec = nullptr);
1565_LIBCPP_FUNC_VIS
1566path __canonical(const path&, error_code* __ec = nullptr);
1567_LIBCPP_FUNC_VIS
1568void __copy(const path& __from, const path& __to, copy_options __opt,
1569 error_code* __ec = nullptr);
1570_LIBCPP_FUNC_VIS
1571bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1572 error_code* __ec = nullptr);
1573_LIBCPP_FUNC_VIS
1574void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1575 error_code* __ec = nullptr);
1576_LIBCPP_FUNC_VIS
1577bool __create_directories(const path& p, error_code* ec = nullptr);
1578_LIBCPP_FUNC_VIS
1579bool __create_directory(const path& p, error_code* ec = nullptr);
1580_LIBCPP_FUNC_VIS
1581bool __create_directory(const path& p, const path& attributes,
1582 error_code* ec = nullptr);
1583_LIBCPP_FUNC_VIS
1584void __create_directory_symlink(const path& __to, const path& __new_symlink,
1585 error_code* __ec = nullptr);
1586_LIBCPP_FUNC_VIS
1587void __create_hard_link(const path& __to, const path& __new_hard_link,
1588 error_code* __ec = nullptr);
1589_LIBCPP_FUNC_VIS
1590void __create_symlink(const path& __to, const path& __new_symlink,
1591 error_code* __ec = nullptr);
1592_LIBCPP_FUNC_VIS
1593path __current_path(error_code* __ec = nullptr);
1594_LIBCPP_FUNC_VIS
1595void __current_path(const path&, error_code* __ec = nullptr);
1596_LIBCPP_FUNC_VIS
1597bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
1598_LIBCPP_FUNC_VIS
1599uintmax_t __file_size(const path&, error_code* __ec = nullptr);
1600_LIBCPP_FUNC_VIS
1601uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
1602_LIBCPP_FUNC_VIS
1603bool __fs_is_empty(const path& p, error_code* ec = nullptr);
1604_LIBCPP_FUNC_VIS
1605file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
1606_LIBCPP_FUNC_VIS
1607void __last_write_time(const path& p, file_time_type new_time,
1608 error_code* ec = nullptr);
1609_LIBCPP_FUNC_VIS
1610void __permissions(const path&, perms, perm_options, error_code* = nullptr);
1611_LIBCPP_FUNC_VIS
1612path __read_symlink(const path& p, error_code* ec = nullptr);
1613_LIBCPP_FUNC_VIS
1614bool __remove(const path& p, error_code* ec = nullptr);
1615_LIBCPP_FUNC_VIS
1616uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
1617_LIBCPP_FUNC_VIS
1618void __rename(const path& from, const path& to, error_code* ec = nullptr);
1619_LIBCPP_FUNC_VIS
1620void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
1621_LIBCPP_FUNC_VIS
1622space_info __space(const path&, error_code* __ec = nullptr);
1623_LIBCPP_FUNC_VIS
1624file_status __status(const path&, error_code* __ec = nullptr);
1625_LIBCPP_FUNC_VIS
1626file_status __symlink_status(const path&, error_code* __ec = nullptr);
1627_LIBCPP_FUNC_VIS
1628path __system_complete(const path&, error_code* __ec = nullptr);
1629_LIBCPP_FUNC_VIS
1630path __temp_directory_path(error_code* __ec = nullptr);
1631_LIBCPP_FUNC_VIS
1632path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
1633
1634inline _LIBCPP_INLINE_VISIBILITY path current_path() {
1635 return __current_path();
1636}
1637
1638inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
1639 return __current_path(&__ec);
1640}
1641
1642inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
1643 __current_path(__p);
1644}
1645
1646inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
1647 error_code& __ec) noexcept {
1648 __current_path(__p, &__ec);
1649}
1650
1651inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
1652 return __absolute(__p);
1653}
1654
1655inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
1656 error_code& __ec) {
1657 return __absolute(__p, &__ec);
1658}
1659
1660inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
1661 return __canonical(__p);
1662}
1663
1664inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
1665 error_code& __ec) {
1666 return __canonical(__p, &__ec);
1667}
1668
1669inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
1670 const path& __to) {
1671 __copy(__from, __to, copy_options::none);
1672}
1673
1674inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1675 error_code& __ec) {
1676 __copy(__from, __to, copy_options::none, &__ec);
1677}
1678
1679inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1680 copy_options __opt) {
1681 __copy(__from, __to, __opt);
1682}
1683
1684inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1685 copy_options __opt,
1686 error_code& __ec) {
1687 __copy(__from, __to, __opt, &__ec);
1688}
1689
1690inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1691 const path& __to) {
1692 return __copy_file(__from, __to, copy_options::none);
1693}
1694
1695inline _LIBCPP_INLINE_VISIBILITY bool
1696copy_file(const path& __from, const path& __to, error_code& __ec) {
1697 return __copy_file(__from, __to, copy_options::none, &__ec);
1698}
1699
1700inline _LIBCPP_INLINE_VISIBILITY bool
1701copy_file(const path& __from, const path& __to, copy_options __opt) {
1702 return __copy_file(__from, __to, __opt);
1703}
1704
1705inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1706 const path& __to,
1707 copy_options __opt,
1708 error_code& __ec) {
1709 return __copy_file(__from, __to, __opt, &__ec);
1710}
1711
1712inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
1713 const path& __new) {
1714 __copy_symlink(__existing, __new);
1715}
1716
1717inline _LIBCPP_INLINE_VISIBILITY void
1718copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
1719 __copy_symlink(__ext, __new, &__ec);
1720}
1721
1722inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
1723 return __create_directories(__p);
1724}
1725
1726inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
1727 error_code& __ec) {
1728 return __create_directories(__p, &__ec);
1729}
1730
1731inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
1732 return __create_directory(__p);
1733}
1734
1735inline _LIBCPP_INLINE_VISIBILITY bool
1736create_directory(const path& __p, error_code& __ec) noexcept {
1737 return __create_directory(__p, &__ec);
1738}
1739
1740inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
1741 const path& __attrs) {
1742 return __create_directory(__p, __attrs);
1743}
1744
1745inline _LIBCPP_INLINE_VISIBILITY bool
1746create_directory(const path& __p, const path& __attrs,
1747 error_code& __ec) noexcept {
1748 return __create_directory(__p, __attrs, &__ec);
1749}
1750
1751inline _LIBCPP_INLINE_VISIBILITY void
1752create_directory_symlink(const path& __to, const path& __new) {
1753 __create_directory_symlink(__to, __new);
1754}
1755
1756inline _LIBCPP_INLINE_VISIBILITY void
1757create_directory_symlink(const path& __to, const path& __new,
1758 error_code& __ec) noexcept {
1759 __create_directory_symlink(__to, __new, &__ec);
1760}
1761
1762inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
1763 const path& __new) {
1764 __create_hard_link(__to, __new);
1765}
1766
1767inline _LIBCPP_INLINE_VISIBILITY void
1768create_hard_link(const path& __to, const path& __new,
1769 error_code& __ec) noexcept {
1770 __create_hard_link(__to, __new, &__ec);
1771}
1772
1773inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
1774 const path& __new) {
1775 __create_symlink(__to, __new);
1776}
1777
1778inline _LIBCPP_INLINE_VISIBILITY void
1779create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
1780 return __create_symlink(__to, __new, &__ec);
1781}
1782
1783inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
1784 return __s.type() != file_type::none;
1785}
1786
1787inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
1788 return status_known(__s) && __s.type() != file_type::not_found;
1789}
1790
1791inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
1792 return exists(__status(__p));
1793}
1794
1795inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
1796 error_code& __ec) noexcept {
1797 auto __s = __status(__p, &__ec);
1798 if (status_known(__s))
1799 __ec.clear();
1800 return exists(__s);
1801}
1802
1803inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
1804 const path& __p2) {
1805 return __equivalent(__p1, __p2);
1806}
1807
1808inline _LIBCPP_INLINE_VISIBILITY bool
1809equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
1810 return __equivalent(__p1, __p2, &__ec);
1811}
1812
1813inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
1814 return __file_size(__p);
1815}
1816
1817inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1818file_size(const path& __p, error_code& __ec) noexcept {
1819 return __file_size(__p, &__ec);
1820}
1821
1822inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
1823 return __hard_link_count(__p);
1824}
1825
1826inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1827hard_link_count(const path& __p, error_code& __ec) noexcept {
1828 return __hard_link_count(__p, &__ec);
1829}
1830
1831inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
1832 return __s.type() == file_type::block;
1833}
1834
1835inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
1836 return is_block_file(__status(__p));
1837}
1838
1839inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
1840 error_code& __ec) noexcept {
1841 return is_block_file(__status(__p, &__ec));
1842}
1843
1844inline _LIBCPP_INLINE_VISIBILITY bool
1845is_character_file(file_status __s) noexcept {
1846 return __s.type() == file_type::character;
1847}
1848
1849inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
1850 return is_character_file(__status(__p));
1851}
1852
1853inline _LIBCPP_INLINE_VISIBILITY bool
1854is_character_file(const path& __p, error_code& __ec) noexcept {
1855 return is_character_file(__status(__p, &__ec));
1856}
1857
1858inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
1859 return __s.type() == file_type::directory;
1860}
1861
1862inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
1863 return is_directory(__status(__p));
1864}
1865
1866inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
1867 error_code& __ec) noexcept {
1868 return is_directory(__status(__p, &__ec));
1869}
1870
1871inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
1872 return __fs_is_empty(__p);
1873}
1874
1875inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
1876 error_code& __ec) {
1877 return __fs_is_empty(__p, &__ec);
1878}
1879
1880inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
1881 return __s.type() == file_type::fifo;
1882}
1883inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
1884 return is_fifo(__status(__p));
1885}
1886
1887inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
1888 error_code& __ec) noexcept {
1889 return is_fifo(__status(__p, &__ec));
1890}
1891
1892inline _LIBCPP_INLINE_VISIBILITY bool
1893is_regular_file(file_status __s) noexcept {
1894 return __s.type() == file_type::regular;
1895}
1896
1897inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
1898 return is_regular_file(__status(__p));
1899}
1900
1901inline _LIBCPP_INLINE_VISIBILITY bool
1902is_regular_file(const path& __p, error_code& __ec) noexcept {
1903 return is_regular_file(__status(__p, &__ec));
1904}
1905
1906inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
1907 return __s.type() == file_type::socket;
1908}
1909
1910inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
1911 return is_socket(__status(__p));
1912}
1913
1914inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
1915 error_code& __ec) noexcept {
1916 return is_socket(__status(__p, &__ec));
1917}
1918
1919inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
1920 return __s.type() == file_type::symlink;
1921}
1922
1923inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
1924 return is_symlink(__symlink_status(__p));
1925}
1926
1927inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
1928 error_code& __ec) noexcept {
1929 return is_symlink(__symlink_status(__p, &__ec));
1930}
1931
1932inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
1933 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
1934 !is_symlink(__s);
1935}
1936
1937inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
1938 return is_other(__status(__p));
1939}
1940
1941inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
1942 error_code& __ec) noexcept {
1943 return is_other(__status(__p, &__ec));
1944}
1945
1946inline _LIBCPP_INLINE_VISIBILITY file_time_type
1947last_write_time(const path& __p) {
1948 return __last_write_time(__p);
1949}
1950
1951inline _LIBCPP_INLINE_VISIBILITY file_time_type
1952last_write_time(const path& __p, error_code& __ec) noexcept {
1953 return __last_write_time(__p, &__ec);
1954}
1955
1956inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
1957 file_time_type __t) {
1958 __last_write_time(__p, __t);
1959}
1960
1961inline _LIBCPP_INLINE_VISIBILITY void
1962last_write_time(const path& __p, file_time_type __t,
1963 error_code& __ec) noexcept {
1964 __last_write_time(__p, __t, &__ec);
1965}
1966
1967inline _LIBCPP_INLINE_VISIBILITY void
1968permissions(const path& __p, perms __prms,
1969 perm_options __opts = perm_options::replace) {
1970 __permissions(__p, __prms, __opts);
1971}
1972
1973inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
1974 error_code& __ec) noexcept {
1975 __permissions(__p, __prms, perm_options::replace, &__ec);
1976}
1977
1978inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
1979 perm_options __opts,
1980 error_code& __ec) {
1981 __permissions(__p, __prms, __opts, &__ec);
1982}
1983
1984inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
1985 const path& __base,
1986 error_code& __ec) {
1987 path __tmp = __weakly_canonical(__p, &__ec);
1988 if (__ec)
1989 return {};
1990 path __tmp_base = __weakly_canonical(__base, &__ec);
1991 if (__ec)
1992 return {};
1993 return __tmp.lexically_proximate(__tmp_base);
1994}
1995
1996inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
1997 error_code& __ec) {
1998 return proximate(__p, current_path(), __ec);
1999}
2000
2001inline _LIBCPP_INLINE_VISIBILITY path
2002proximate(const path& __p, const path& __base = current_path()) {
2003 return __weakly_canonical(__p).lexically_proximate(
2004 __weakly_canonical(__base));
2005}
2006
2007inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
2008 return __read_symlink(__p);
2009}
2010
2011inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
2012 error_code& __ec) {
2013 return __read_symlink(__p, &__ec);
2014}
2015
2016inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2017 const path& __base,
2018 error_code& __ec) {
2019 path __tmp = __weakly_canonical(__p, &__ec);
2020 if (__ec)
2021 return path();
2022 path __tmpbase = __weakly_canonical(__base, &__ec);
2023 if (__ec)
2024 return path();
2025 return __tmp.lexically_relative(__tmpbase);
2026}
2027
2028inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2029 error_code& __ec) {
2030 return relative(__p, current_path(), __ec);
2031}
2032
2033inline _LIBCPP_INLINE_VISIBILITY path
2034relative(const path& __p, const path& __base = current_path()) {
2035 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
2036}
2037
2038inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
2039 return __remove(__p);
2040}
2041
2042inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
2043 error_code& __ec) noexcept {
2044 return __remove(__p, &__ec);
2045}
2046
2047inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
2048 return __remove_all(__p);
2049}
2050
2051inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
2052 error_code& __ec) {
2053 return __remove_all(__p, &__ec);
2054}
2055
2056inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
2057 const path& __to) {
2058 return __rename(__from, __to);
2059}
2060
2061inline _LIBCPP_INLINE_VISIBILITY void
2062rename(const path& __from, const path& __to, error_code& __ec) noexcept {
2063 return __rename(__from, __to, &__ec);
2064}
2065
2066inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
2067 uintmax_t __ns) {
2068 return __resize_file(__p, __ns);
2069}
2070
2071inline _LIBCPP_INLINE_VISIBILITY void
2072resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
2073 return __resize_file(__p, __ns, &__ec);
2074}
2075
2076inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
2077 return __space(__p);
2078}
2079
2080inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
2081 error_code& __ec) noexcept {
2082 return __space(__p, &__ec);
2083}
2084
2085inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
2086 return __status(__p);
2087}
2088
2089inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
2090 error_code& __ec) noexcept {
2091 return __status(__p, &__ec);
2092}
2093
2094inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
2095 return __symlink_status(__p);
2096}
2097
2098inline _LIBCPP_INLINE_VISIBILITY file_status
2099symlink_status(const path& __p, error_code& __ec) noexcept {
2100 return __symlink_status(__p, &__ec);
2101}
2102
2103inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
2104 return __temp_directory_path();
2105}
2106
2107inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
2108 return __temp_directory_path(&__ec);
2109}
2110
2111inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
2112 return __weakly_canonical(__p);
2113}
2114
2115inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
2116 error_code& __ec) {
2117 return __weakly_canonical(__p, &__ec);
2118}
2119
2120class directory_iterator;
2121class recursive_directory_iterator;
Louis Dionne48ae8892019-03-19 17:47:53 +00002122class _LIBCPP_HIDDEN __dir_stream;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002123
2124class directory_entry {
2125 typedef _VSTD_FS::path _Path;
2126
2127public:
2128 // constructors and destructors
2129 directory_entry() noexcept = default;
2130 directory_entry(directory_entry const&) = default;
2131 directory_entry(directory_entry&&) noexcept = default;
2132
2133 _LIBCPP_INLINE_VISIBILITY
2134 explicit directory_entry(_Path const& __p) : __p_(__p) {
2135 error_code __ec;
2136 __refresh(&__ec);
2137 }
2138
2139 _LIBCPP_INLINE_VISIBILITY
2140 directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
2141 __refresh(&__ec);
2142 }
2143
2144 ~directory_entry() {}
2145
2146 directory_entry& operator=(directory_entry const&) = default;
2147 directory_entry& operator=(directory_entry&&) noexcept = default;
2148
2149 _LIBCPP_INLINE_VISIBILITY
2150 void assign(_Path const& __p) {
2151 __p_ = __p;
2152 error_code __ec;
2153 __refresh(&__ec);
2154 }
2155
2156 _LIBCPP_INLINE_VISIBILITY
2157 void assign(_Path const& __p, error_code& __ec) {
2158 __p_ = __p;
2159 __refresh(&__ec);
2160 }
2161
2162 _LIBCPP_INLINE_VISIBILITY
2163 void replace_filename(_Path const& __p) {
2164 __p_.replace_filename(__p);
2165 error_code __ec;
2166 __refresh(&__ec);
2167 }
2168
2169 _LIBCPP_INLINE_VISIBILITY
2170 void replace_filename(_Path const& __p, error_code& __ec) {
2171 __p_ = __p_.parent_path() / __p;
2172 __refresh(&__ec);
2173 }
2174
2175 _LIBCPP_INLINE_VISIBILITY
2176 void refresh() { __refresh(); }
2177
2178 _LIBCPP_INLINE_VISIBILITY
2179 void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
2180
2181 _LIBCPP_INLINE_VISIBILITY
2182 _Path const& path() const noexcept { return __p_; }
2183
2184 _LIBCPP_INLINE_VISIBILITY
2185 operator const _Path&() const noexcept { return __p_; }
2186
2187 _LIBCPP_INLINE_VISIBILITY
2188 bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
2189
2190 _LIBCPP_INLINE_VISIBILITY
2191 bool exists(error_code& __ec) const noexcept {
2192 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2193 }
2194
2195 _LIBCPP_INLINE_VISIBILITY
2196 bool is_block_file() const { return __get_ft() == file_type::block; }
2197
2198 _LIBCPP_INLINE_VISIBILITY
2199 bool is_block_file(error_code& __ec) const noexcept {
2200 return __get_ft(&__ec) == file_type::block;
2201 }
2202
2203 _LIBCPP_INLINE_VISIBILITY
2204 bool is_character_file() const { return __get_ft() == file_type::character; }
2205
2206 _LIBCPP_INLINE_VISIBILITY
2207 bool is_character_file(error_code& __ec) const noexcept {
2208 return __get_ft(&__ec) == file_type::character;
2209 }
2210
2211 _LIBCPP_INLINE_VISIBILITY
2212 bool is_directory() const { return __get_ft() == file_type::directory; }
2213
2214 _LIBCPP_INLINE_VISIBILITY
2215 bool is_directory(error_code& __ec) const noexcept {
2216 return __get_ft(&__ec) == file_type::directory;
2217 }
2218
2219 _LIBCPP_INLINE_VISIBILITY
2220 bool is_fifo() const { return __get_ft() == file_type::fifo; }
2221
2222 _LIBCPP_INLINE_VISIBILITY
2223 bool is_fifo(error_code& __ec) const noexcept {
2224 return __get_ft(&__ec) == file_type::fifo;
2225 }
2226
2227 _LIBCPP_INLINE_VISIBILITY
2228 bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
2229
2230 _LIBCPP_INLINE_VISIBILITY
2231 bool is_other(error_code& __ec) const noexcept {
2232 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2233 }
2234
2235 _LIBCPP_INLINE_VISIBILITY
2236 bool is_regular_file() const { return __get_ft() == file_type::regular; }
2237
2238 _LIBCPP_INLINE_VISIBILITY
2239 bool is_regular_file(error_code& __ec) const noexcept {
2240 return __get_ft(&__ec) == file_type::regular;
2241 }
2242
2243 _LIBCPP_INLINE_VISIBILITY
2244 bool is_socket() const { return __get_ft() == file_type::socket; }
2245
2246 _LIBCPP_INLINE_VISIBILITY
2247 bool is_socket(error_code& __ec) const noexcept {
2248 return __get_ft(&__ec) == file_type::socket;
2249 }
2250
2251 _LIBCPP_INLINE_VISIBILITY
2252 bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
2253
2254 _LIBCPP_INLINE_VISIBILITY
2255 bool is_symlink(error_code& __ec) const noexcept {
2256 return __get_sym_ft(&__ec) == file_type::symlink;
2257 }
2258 _LIBCPP_INLINE_VISIBILITY
2259 uintmax_t file_size() const { return __get_size(); }
2260
2261 _LIBCPP_INLINE_VISIBILITY
2262 uintmax_t file_size(error_code& __ec) const noexcept {
2263 return __get_size(&__ec);
2264 }
2265
2266 _LIBCPP_INLINE_VISIBILITY
2267 uintmax_t hard_link_count() const { return __get_nlink(); }
2268
2269 _LIBCPP_INLINE_VISIBILITY
2270 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2271 return __get_nlink(&__ec);
2272 }
2273
2274 _LIBCPP_INLINE_VISIBILITY
2275 file_time_type last_write_time() const { return __get_write_time(); }
2276
2277 _LIBCPP_INLINE_VISIBILITY
2278 file_time_type last_write_time(error_code& __ec) const noexcept {
2279 return __get_write_time(&__ec);
2280 }
2281
2282 _LIBCPP_INLINE_VISIBILITY
2283 file_status status() const { return __get_status(); }
2284
2285 _LIBCPP_INLINE_VISIBILITY
2286 file_status status(error_code& __ec) const noexcept {
2287 return __get_status(&__ec);
2288 }
2289
2290 _LIBCPP_INLINE_VISIBILITY
2291 file_status symlink_status() const { return __get_symlink_status(); }
2292
2293 _LIBCPP_INLINE_VISIBILITY
2294 file_status symlink_status(error_code& __ec) const noexcept {
2295 return __get_symlink_status(&__ec);
2296 }
2297
2298 _LIBCPP_INLINE_VISIBILITY
2299 bool operator<(directory_entry const& __rhs) const noexcept {
2300 return __p_ < __rhs.__p_;
2301 }
2302
2303 _LIBCPP_INLINE_VISIBILITY
2304 bool operator==(directory_entry const& __rhs) const noexcept {
2305 return __p_ == __rhs.__p_;
2306 }
2307
2308 _LIBCPP_INLINE_VISIBILITY
2309 bool operator!=(directory_entry const& __rhs) const noexcept {
2310 return __p_ != __rhs.__p_;
2311 }
2312
2313 _LIBCPP_INLINE_VISIBILITY
2314 bool operator<=(directory_entry const& __rhs) const noexcept {
2315 return __p_ <= __rhs.__p_;
2316 }
2317
2318 _LIBCPP_INLINE_VISIBILITY
2319 bool operator>(directory_entry const& __rhs) const noexcept {
2320 return __p_ > __rhs.__p_;
2321 }
2322
2323 _LIBCPP_INLINE_VISIBILITY
2324 bool operator>=(directory_entry const& __rhs) const noexcept {
2325 return __p_ >= __rhs.__p_;
2326 }
2327
2328private:
2329 friend class directory_iterator;
2330 friend class recursive_directory_iterator;
2331 friend class __dir_stream;
2332
2333 enum _CacheType : unsigned char {
2334 _Empty,
2335 _IterSymlink,
2336 _IterNonSymlink,
2337 _RefreshSymlink,
2338 _RefreshSymlinkUnresolved,
2339 _RefreshNonSymlink
2340 };
2341
2342 struct __cached_data {
2343 uintmax_t __size_;
2344 uintmax_t __nlink_;
2345 file_time_type __write_time_;
2346 perms __sym_perms_;
2347 perms __non_sym_perms_;
2348 file_type __type_;
2349 _CacheType __cache_type_;
2350
2351 _LIBCPP_INLINE_VISIBILITY
2352 __cached_data() noexcept { __reset(); }
2353
2354 _LIBCPP_INLINE_VISIBILITY
2355 void __reset() {
2356 __cache_type_ = _Empty;
2357 __type_ = file_type::none;
2358 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2359 __size_ = __nlink_ = uintmax_t(-1);
2360 __write_time_ = file_time_type::min();
2361 }
2362 };
2363
2364 _LIBCPP_INLINE_VISIBILITY
2365 static __cached_data __create_iter_result(file_type __ft) {
2366 __cached_data __data;
2367 __data.__type_ = __ft;
2368 __data.__cache_type_ = [&]() {
2369 switch (__ft) {
2370 case file_type::none:
2371 return _Empty;
2372 case file_type::symlink:
2373 return _IterSymlink;
2374 default:
2375 return _IterNonSymlink;
2376 }
2377 }();
2378 return __data;
2379 }
2380
2381 _LIBCPP_INLINE_VISIBILITY
2382 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002383 __p_ = _VSTD::move(__p);
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002384 __data_ = __dt;
2385 }
2386
2387 _LIBCPP_FUNC_VIS
2388 error_code __do_refresh() noexcept;
2389
2390 _LIBCPP_INLINE_VISIBILITY
2391 static bool __is_dne_error(error_code const& __ec) {
2392 if (!__ec)
2393 return true;
2394 switch (static_cast<errc>(__ec.value())) {
2395 case errc::no_such_file_or_directory:
2396 case errc::not_a_directory:
2397 return true;
2398 default:
2399 return false;
2400 }
2401 }
2402
2403 _LIBCPP_INLINE_VISIBILITY
2404 void __handle_error(const char* __msg, error_code* __dest_ec,
2405 error_code const& __ec, bool __allow_dne = false) const {
2406 if (__dest_ec) {
2407 *__dest_ec = __ec;
2408 return;
2409 }
2410 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2411 __throw_filesystem_error(__msg, __p_, __ec);
2412 }
2413
2414 _LIBCPP_INLINE_VISIBILITY
2415 void __refresh(error_code* __ec = nullptr) {
2416 __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2417 /*allow_dne*/ true);
2418 }
2419
2420 _LIBCPP_INLINE_VISIBILITY
2421 file_type __get_sym_ft(error_code* __ec = nullptr) const {
2422 switch (__data_.__cache_type_) {
2423 case _Empty:
2424 return __symlink_status(__p_, __ec).type();
2425 case _IterSymlink:
2426 case _RefreshSymlink:
2427 case _RefreshSymlinkUnresolved:
2428 if (__ec)
2429 __ec->clear();
2430 return file_type::symlink;
2431 case _IterNonSymlink:
2432 case _RefreshNonSymlink:
2433 file_status __st(__data_.__type_);
2434 if (__ec && !_VSTD_FS::exists(__st))
2435 *__ec = make_error_code(errc::no_such_file_or_directory);
2436 else if (__ec)
2437 __ec->clear();
2438 return __data_.__type_;
2439 }
2440 _LIBCPP_UNREACHABLE();
2441 }
2442
2443 _LIBCPP_INLINE_VISIBILITY
2444 file_type __get_ft(error_code* __ec = nullptr) const {
2445 switch (__data_.__cache_type_) {
2446 case _Empty:
2447 case _IterSymlink:
2448 case _RefreshSymlinkUnresolved:
2449 return __status(__p_, __ec).type();
2450 case _IterNonSymlink:
2451 case _RefreshNonSymlink:
2452 case _RefreshSymlink: {
2453 file_status __st(__data_.__type_);
2454 if (__ec && !_VSTD_FS::exists(__st))
2455 *__ec = make_error_code(errc::no_such_file_or_directory);
2456 else if (__ec)
2457 __ec->clear();
2458 return __data_.__type_;
2459 }
2460 }
2461 _LIBCPP_UNREACHABLE();
2462 }
2463
2464 _LIBCPP_INLINE_VISIBILITY
2465 file_status __get_status(error_code* __ec = nullptr) const {
2466 switch (__data_.__cache_type_) {
2467 case _Empty:
2468 case _IterNonSymlink:
2469 case _IterSymlink:
2470 case _RefreshSymlinkUnresolved:
2471 return __status(__p_, __ec);
2472 case _RefreshNonSymlink:
2473 case _RefreshSymlink:
2474 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2475 }
2476 _LIBCPP_UNREACHABLE();
2477 }
2478
2479 _LIBCPP_INLINE_VISIBILITY
2480 file_status __get_symlink_status(error_code* __ec = nullptr) const {
2481 switch (__data_.__cache_type_) {
2482 case _Empty:
2483 case _IterNonSymlink:
2484 case _IterSymlink:
2485 return __symlink_status(__p_, __ec);
2486 case _RefreshNonSymlink:
2487 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2488 case _RefreshSymlink:
2489 case _RefreshSymlinkUnresolved:
2490 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2491 }
2492 _LIBCPP_UNREACHABLE();
2493 }
2494
2495 _LIBCPP_INLINE_VISIBILITY
2496 uintmax_t __get_size(error_code* __ec = nullptr) const {
2497 switch (__data_.__cache_type_) {
2498 case _Empty:
2499 case _IterNonSymlink:
2500 case _IterSymlink:
2501 case _RefreshSymlinkUnresolved:
2502 return _VSTD_FS::__file_size(__p_, __ec);
2503 case _RefreshSymlink:
2504 case _RefreshNonSymlink: {
2505 error_code __m_ec;
2506 file_status __st(__get_ft(&__m_ec));
2507 __handle_error("in directory_entry::file_size", __ec, __m_ec);
2508 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2509 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2510 : errc::not_supported;
2511 __handle_error("in directory_entry::file_size", __ec,
2512 make_error_code(__err_kind));
2513 }
2514 return __data_.__size_;
2515 }
2516 }
2517 _LIBCPP_UNREACHABLE();
2518 }
2519
2520 _LIBCPP_INLINE_VISIBILITY
2521 uintmax_t __get_nlink(error_code* __ec = nullptr) const {
2522 switch (__data_.__cache_type_) {
2523 case _Empty:
2524 case _IterNonSymlink:
2525 case _IterSymlink:
2526 case _RefreshSymlinkUnresolved:
2527 return _VSTD_FS::__hard_link_count(__p_, __ec);
2528 case _RefreshSymlink:
2529 case _RefreshNonSymlink: {
2530 error_code __m_ec;
2531 (void)__get_ft(&__m_ec);
2532 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
2533 return __data_.__nlink_;
2534 }
2535 }
2536 _LIBCPP_UNREACHABLE();
2537 }
2538
2539 _LIBCPP_INLINE_VISIBILITY
2540 file_time_type __get_write_time(error_code* __ec = nullptr) const {
2541 switch (__data_.__cache_type_) {
2542 case _Empty:
2543 case _IterNonSymlink:
2544 case _IterSymlink:
2545 case _RefreshSymlinkUnresolved:
2546 return _VSTD_FS::__last_write_time(__p_, __ec);
2547 case _RefreshSymlink:
2548 case _RefreshNonSymlink: {
2549 error_code __m_ec;
2550 file_status __st(__get_ft(&__m_ec));
2551 __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
2552 if (_VSTD_FS::exists(__st) &&
2553 __data_.__write_time_ == file_time_type::min())
2554 __handle_error("in directory_entry::last_write_time", __ec,
2555 make_error_code(errc::value_too_large));
2556 return __data_.__write_time_;
2557 }
2558 }
2559 _LIBCPP_UNREACHABLE();
2560 }
2561
2562private:
2563 _Path __p_;
2564 __cached_data __data_;
2565};
2566
2567class __dir_element_proxy {
2568public:
2569 inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
2570 return _VSTD::move(__elem_);
2571 }
2572
2573private:
2574 friend class directory_iterator;
2575 friend class recursive_directory_iterator;
2576 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2577 __dir_element_proxy(__dir_element_proxy&& __o)
2578 : __elem_(_VSTD::move(__o.__elem_)) {}
2579 directory_entry __elem_;
2580};
2581
2582class directory_iterator {
2583public:
2584 typedef directory_entry value_type;
2585 typedef ptrdiff_t difference_type;
2586 typedef value_type const* pointer;
2587 typedef value_type const& reference;
2588 typedef input_iterator_tag iterator_category;
2589
2590public:
2591 //ctor & dtor
2592 directory_iterator() noexcept {}
2593
2594 explicit directory_iterator(const path& __p)
2595 : directory_iterator(__p, nullptr) {}
2596
2597 directory_iterator(const path& __p, directory_options __opts)
2598 : directory_iterator(__p, nullptr, __opts) {}
2599
2600 directory_iterator(const path& __p, error_code& __ec)
2601 : directory_iterator(__p, &__ec) {}
2602
2603 directory_iterator(const path& __p, directory_options __opts,
2604 error_code& __ec)
2605 : directory_iterator(__p, &__ec, __opts) {}
2606
2607 directory_iterator(const directory_iterator&) = default;
2608 directory_iterator(directory_iterator&&) = default;
2609 directory_iterator& operator=(const directory_iterator&) = default;
2610
2611 directory_iterator& operator=(directory_iterator&& __o) noexcept {
2612 // non-default implementation provided to support self-move assign.
2613 if (this != &__o) {
2614 __imp_ = _VSTD::move(__o.__imp_);
2615 }
2616 return *this;
2617 }
2618
2619 ~directory_iterator() = default;
2620
2621 const directory_entry& operator*() const {
2622 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
2623 return __dereference();
2624 }
2625
2626 const directory_entry* operator->() const { return &**this; }
2627
2628 directory_iterator& operator++() { return __increment(); }
2629
2630 __dir_element_proxy operator++(int) {
2631 __dir_element_proxy __p(**this);
2632 __increment();
2633 return __p;
2634 }
2635
2636 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
2637
2638private:
2639 inline _LIBCPP_INLINE_VISIBILITY friend bool
2640 operator==(const directory_iterator& __lhs,
2641 const directory_iterator& __rhs) noexcept;
2642
2643 // construct the dir_stream
2644 _LIBCPP_FUNC_VIS
2645 directory_iterator(const path&, error_code*,
2646 directory_options = directory_options::none);
2647
2648 _LIBCPP_FUNC_VIS
2649 directory_iterator& __increment(error_code* __ec = nullptr);
2650
2651 _LIBCPP_FUNC_VIS
2652 const directory_entry& __dereference() const;
2653
2654private:
2655 shared_ptr<__dir_stream> __imp_;
2656};
2657
2658inline _LIBCPP_INLINE_VISIBILITY bool
2659operator==(const directory_iterator& __lhs,
2660 const directory_iterator& __rhs) noexcept {
2661 return __lhs.__imp_ == __rhs.__imp_;
2662}
2663
2664inline _LIBCPP_INLINE_VISIBILITY bool
2665operator!=(const directory_iterator& __lhs,
2666 const directory_iterator& __rhs) noexcept {
2667 return !(__lhs == __rhs);
2668}
2669
2670// enable directory_iterator range-based for statements
2671inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2672begin(directory_iterator __iter) noexcept {
2673 return __iter;
2674}
2675
2676inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2677end(const directory_iterator&) noexcept {
2678 return directory_iterator();
2679}
2680
2681class recursive_directory_iterator {
2682public:
2683 using value_type = directory_entry;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002684 using difference_type = ptrdiff_t;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002685 using pointer = directory_entry const*;
2686 using reference = directory_entry const&;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002687 using iterator_category = input_iterator_tag;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002688
2689public:
2690 // constructors and destructor
2691 _LIBCPP_INLINE_VISIBILITY
2692 recursive_directory_iterator() noexcept : __rec_(false) {}
2693
2694 _LIBCPP_INLINE_VISIBILITY
2695 explicit recursive_directory_iterator(
2696 const path& __p, directory_options __xoptions = directory_options::none)
2697 : recursive_directory_iterator(__p, __xoptions, nullptr) {}
2698
2699 _LIBCPP_INLINE_VISIBILITY
2700 recursive_directory_iterator(const path& __p, directory_options __xoptions,
2701 error_code& __ec)
2702 : recursive_directory_iterator(__p, __xoptions, &__ec) {}
2703
2704 _LIBCPP_INLINE_VISIBILITY
2705 recursive_directory_iterator(const path& __p, error_code& __ec)
2706 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
2707
2708 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2709 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2710
2711 recursive_directory_iterator&
2712 operator=(const recursive_directory_iterator&) = default;
2713
2714 _LIBCPP_INLINE_VISIBILITY
2715 recursive_directory_iterator&
2716 operator=(recursive_directory_iterator&& __o) noexcept {
2717 // non-default implementation provided to support self-move assign.
2718 if (this != &__o) {
2719 __imp_ = _VSTD::move(__o.__imp_);
2720 __rec_ = __o.__rec_;
2721 }
2722 return *this;
2723 }
2724
2725 ~recursive_directory_iterator() = default;
2726
2727 _LIBCPP_INLINE_VISIBILITY
2728 const directory_entry& operator*() const { return __dereference(); }
2729
2730 _LIBCPP_INLINE_VISIBILITY
2731 const directory_entry* operator->() const { return &__dereference(); }
2732
2733 recursive_directory_iterator& operator++() { return __increment(); }
2734
2735 _LIBCPP_INLINE_VISIBILITY
2736 __dir_element_proxy operator++(int) {
2737 __dir_element_proxy __p(**this);
2738 __increment();
2739 return __p;
2740 }
2741
2742 _LIBCPP_INLINE_VISIBILITY
2743 recursive_directory_iterator& increment(error_code& __ec) {
2744 return __increment(&__ec);
2745 }
2746
2747 _LIBCPP_FUNC_VIS directory_options options() const;
2748 _LIBCPP_FUNC_VIS int depth() const;
2749
2750 _LIBCPP_INLINE_VISIBILITY
2751 void pop() { __pop(); }
2752
2753 _LIBCPP_INLINE_VISIBILITY
2754 void pop(error_code& __ec) { __pop(&__ec); }
2755
2756 _LIBCPP_INLINE_VISIBILITY
2757 bool recursion_pending() const { return __rec_; }
2758
2759 _LIBCPP_INLINE_VISIBILITY
2760 void disable_recursion_pending() { __rec_ = false; }
2761
2762private:
Louis Dionne0ba10dc2019-08-13 15:02:53 +00002763 _LIBCPP_FUNC_VIS
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002764 recursive_directory_iterator(const path& __p, directory_options __opt,
2765 error_code* __ec);
2766
2767 _LIBCPP_FUNC_VIS
2768 const directory_entry& __dereference() const;
2769
2770 _LIBCPP_FUNC_VIS
2771 bool __try_recursion(error_code* __ec);
2772
2773 _LIBCPP_FUNC_VIS
2774 void __advance(error_code* __ec = nullptr);
2775
2776 _LIBCPP_FUNC_VIS
2777 recursive_directory_iterator& __increment(error_code* __ec = nullptr);
2778
2779 _LIBCPP_FUNC_VIS
2780 void __pop(error_code* __ec = nullptr);
2781
2782 inline _LIBCPP_INLINE_VISIBILITY friend bool
2783 operator==(const recursive_directory_iterator&,
2784 const recursive_directory_iterator&) noexcept;
2785
Louis Dionne48ae8892019-03-19 17:47:53 +00002786 struct _LIBCPP_HIDDEN __shared_imp;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002787 shared_ptr<__shared_imp> __imp_;
2788 bool __rec_;
2789}; // class recursive_directory_iterator
2790
2791inline _LIBCPP_INLINE_VISIBILITY bool
2792operator==(const recursive_directory_iterator& __lhs,
2793 const recursive_directory_iterator& __rhs) noexcept {
2794 return __lhs.__imp_ == __rhs.__imp_;
2795}
2796
2797_LIBCPP_INLINE_VISIBILITY
2798inline bool operator!=(const recursive_directory_iterator& __lhs,
2799 const recursive_directory_iterator& __rhs) noexcept {
2800 return !(__lhs == __rhs);
2801}
2802// enable recursive_directory_iterator range-based for statements
2803inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2804begin(recursive_directory_iterator __iter) noexcept {
2805 return __iter;
2806}
2807
2808inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2809end(const recursive_directory_iterator&) noexcept {
2810 return recursive_directory_iterator();
2811}
2812
Louis Dionnef6bf76a2019-03-20 21:18:14 +00002813_LIBCPP_AVAILABILITY_FILESYSTEM_POP
2814
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002815_LIBCPP_END_NAMESPACE_FILESYSTEM
2816
2817#endif // !_LIBCPP_CXX03_LANG
2818
2819_LIBCPP_POP_MACROS
2820
2821#endif // _LIBCPP_FILESYSTEM