blob: e39790c50955c9a13b6e575629df60d2d05cbca1 [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
Martin Storsjöfc25e3a2020-10-27 13:30:34 +0200693#if defined(_LIBCPP_WIN32API)
694_LIBCPP_FUNC_VIS
695size_t __wide_to_char(const wstring&, char*, size_t);
696_LIBCPP_FUNC_VIS
697size_t __char_to_wide(const string&, wchar_t*, size_t);
698#endif
699
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000700template <class _ECharT>
Louis Dionne8d053eb2020-10-09 15:31:05 -0400701struct _PathCVT;
702
703#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
704template <class _ECharT>
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000705struct _PathCVT {
706 static_assert(__can_convert_char<_ECharT>::value,
707 "Char type not convertible");
708
709 typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200710#if defined(_LIBCPP_WIN32API)
711 typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
712#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000713
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200714 static void __append_range(__path_string& __dest, _ECharT const* __b,
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000715 _ECharT const* __e) {
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200716#if defined(_LIBCPP_WIN32API)
717 string __utf8;
718 _Narrower()(back_inserter(__utf8), __b, __e);
719 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
720#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000721 _Narrower()(back_inserter(__dest), __b, __e);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200722#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000723 }
724
725 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200726 static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000727 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
728 if (__b == __e)
729 return;
730 basic_string<_ECharT> __tmp(__b, __e);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200731#if defined(_LIBCPP_WIN32API)
732 string __utf8;
733 _Narrower()(back_inserter(__utf8), __tmp.data(),
734 __tmp.data() + __tmp.length());
735 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
736#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000737 _Narrower()(back_inserter(__dest), __tmp.data(),
738 __tmp.data() + __tmp.length());
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200739#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000740 }
741
742 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200743 static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000744 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
Martin Storsjö2ae96532020-10-27 11:46:06 +0200745 const _ECharT __sentinel = _ECharT{};
746 if (*__b == __sentinel)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000747 return;
748 basic_string<_ECharT> __tmp;
Martin Storsjö2ae96532020-10-27 11:46:06 +0200749 for (; *__b != __sentinel; ++__b)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000750 __tmp.push_back(*__b);
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200751#if defined(_LIBCPP_WIN32API)
752 string __utf8;
753 _Narrower()(back_inserter(__utf8), __tmp.data(),
754 __tmp.data() + __tmp.length());
755 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
756#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000757 _Narrower()(back_inserter(__dest), __tmp.data(),
758 __tmp.data() + __tmp.length());
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200759#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000760 }
761
762 template <class _Source>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200763 static void __append_source(__path_string& __dest, _Source const& __s) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000764 using _Traits = __is_pathable<_Source>;
765 __append_range(__dest, _Traits::__range_begin(__s),
766 _Traits::__range_end(__s));
767 }
768};
Louis Dionne8d053eb2020-10-09 15:31:05 -0400769#endif // !_LIBCPP_HAS_NO_LOCALIZATION
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000770
771template <>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200772struct _PathCVT<__path_value> {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000773
774 template <class _Iter>
Eric Fiseliercd5a6772019-11-18 01:46:58 -0500775 static typename enable_if<__is_exactly_cpp17_input_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 for (; __b != __e; ++__b)
778 __dest.push_back(*__b);
779 }
780
781 template <class _Iter>
Eric Fiseliercd5a6772019-11-18 01:46:58 -0500782 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200783 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000784 __dest.__append_forward_unsafe(__b, __e);
785 }
786
787 template <class _Iter>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200788 static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
Martin Storsjö2ae96532020-10-27 11:46:06 +0200789 const char __sentinel = char{};
790 for (; *__b != __sentinel; ++__b)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000791 __dest.push_back(*__b);
792 }
793
794 template <class _Source>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200795 static void __append_source(__path_string& __dest, _Source const& __s) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000796 using _Traits = __is_pathable<_Source>;
797 __append_range(__dest, _Traits::__range_begin(__s),
798 _Traits::__range_end(__s));
799 }
800};
801
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200802#if defined(_LIBCPP_WIN32API)
Martin Storsjöfc25e3a2020-10-27 13:30:34 +0200803template <>
804struct _PathCVT<char> {
805
806 static void
807 __append_string(__path_string& __dest, const basic_string<char> &__str) {
808 size_t __size = __char_to_wide(__str, nullptr, 0);
809 size_t __pos = __dest.size();
810 __dest.resize(__pos + __size);
811 __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size);
812 }
813
814 template <class _Iter>
815 static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
816 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
817 basic_string<char> __tmp(__b, __e);
818 __append_string(__dest, __tmp);
819 }
820
821 template <class _Iter>
822 static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
823 __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
824 basic_string<char> __tmp(__b, __e);
825 __append_string(__dest, __tmp);
826 }
827
828 template <class _Iter>
829 static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
830 const char __sentinel = char{};
831 basic_string<char> __tmp;
832 for (; *__b != __sentinel; ++__b)
833 __tmp.push_back(*__b);
834 __append_string(__dest, __tmp);
835 }
836
837 template <class _Source>
838 static void __append_source(__path_string& __dest, _Source const& __s) {
839 using _Traits = __is_pathable<_Source>;
840 __append_range(__dest, _Traits::__range_begin(__s),
841 _Traits::__range_end(__s));
842 }
843};
844
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200845template <class _ECharT>
846struct _PathExport {
847 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
848 typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
849
850 template <class _Str>
851 static void __append(_Str& __dest, const __path_string& __src) {
852 string __utf8;
853 _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
854 _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
855 }
856};
857
858template <>
Martin Storsjöfc25e3a2020-10-27 13:30:34 +0200859struct _PathExport<char> {
860 template <class _Str>
861 static void __append(_Str& __dest, const __path_string& __src) {
862 size_t __size = __wide_to_char(__src, nullptr, 0);
863 size_t __pos = __dest.size();
864 __dest.resize(__size);
865 __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size);
866 }
867};
868
869template <>
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200870struct _PathExport<wchar_t> {
871 template <class _Str>
872 static void __append(_Str& __dest, const __path_string& __src) {
873 __dest.append(__src.begin(), __src.end());
874 }
875};
876
877template <>
878struct _PathExport<char16_t> {
879 template <class _Str>
880 static void __append(_Str& __dest, const __path_string& __src) {
881 __dest.append(__src.begin(), __src.end());
882 }
883};
884
885#ifndef _LIBCPP_NO_HAS_CHAR8_T
886template <>
887struct _PathExport<char8_t> {
888 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
889
890 template <class _Str>
891 static void __append(_Str& __dest, const __path_string& __src) {
892 _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
893 }
894};
895#endif /* !_LIBCPP_NO_HAS_CHAR8_T */
896#endif /* _LIBCPP_WIN32API */
897
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000898class _LIBCPP_TYPE_VIS path {
899 template <class _SourceOrIter, class _Tp = path&>
900 using _EnableIfPathable =
901 typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
902
903 template <class _Tp>
904 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
905
906 template <class _Tp>
907 using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
908
909public:
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200910#if defined(_LIBCPP_WIN32API)
911 typedef wchar_t value_type;
912 static constexpr value_type preferred_separator = L'\\';
913#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000914 typedef char value_type;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000915 static constexpr value_type preferred_separator = '/';
Martin Storsjöe482f4b2020-10-27 13:09:08 +0200916#endif
917 typedef basic_string<value_type> string_type;
918 typedef basic_string_view<value_type> __string_view;
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000919
920 enum class _LIBCPP_ENUM_VIS format : unsigned char {
921 auto_format,
922 native_format,
923 generic_format
924 };
925
926 // constructors and destructor
927 _LIBCPP_INLINE_VISIBILITY path() noexcept {}
928 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
929 _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
930 : __pn_(_VSTD::move(__p.__pn_)) {}
931
932 _LIBCPP_INLINE_VISIBILITY
933 path(string_type&& __s, format = format::auto_format) noexcept
934 : __pn_(_VSTD::move(__s)) {}
935
936 template <class _Source, class = _EnableIfPathable<_Source, void> >
937 path(const _Source& __src, format = format::auto_format) {
938 _SourceCVT<_Source>::__append_source(__pn_, __src);
939 }
940
941 template <class _InputIt>
942 path(_InputIt __first, _InputIt __last, format = format::auto_format) {
943 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
944 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
945 }
946
Louis Dionne8d053eb2020-10-09 15:31:05 -0400947#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000948 // TODO Implement locale conversions.
949 template <class _Source, class = _EnableIfPathable<_Source, void> >
950 path(const _Source& __src, const locale& __loc, format = format::auto_format);
951 template <class _InputIt>
952 path(_InputIt __first, _InputIt _last, const locale& __loc,
953 format = format::auto_format);
Louis Dionne8d053eb2020-10-09 15:31:05 -0400954#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +0000955
956 _LIBCPP_INLINE_VISIBILITY
957 ~path() = default;
958
959 // assignments
960 _LIBCPP_INLINE_VISIBILITY
961 path& operator=(const path& __p) {
962 __pn_ = __p.__pn_;
963 return *this;
964 }
965
966 _LIBCPP_INLINE_VISIBILITY
967 path& operator=(path&& __p) noexcept {
968 __pn_ = _VSTD::move(__p.__pn_);
969 return *this;
970 }
971
972 template <class = void>
973 _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
974 __pn_ = _VSTD::move(__s);
975 return *this;
976 }
977
978 _LIBCPP_INLINE_VISIBILITY
979 path& assign(string_type&& __s) noexcept {
980 __pn_ = _VSTD::move(__s);
981 return *this;
982 }
983
984 template <class _Source>
985 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
986 operator=(const _Source& __src) {
987 return this->assign(__src);
988 }
989
990 template <class _Source>
991 _EnableIfPathable<_Source> assign(const _Source& __src) {
992 __pn_.clear();
993 _SourceCVT<_Source>::__append_source(__pn_, __src);
994 return *this;
995 }
996
997 template <class _InputIt>
998 path& assign(_InputIt __first, _InputIt __last) {
999 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1000 __pn_.clear();
1001 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1002 return *this;
1003 }
1004
1005private:
1006 template <class _ECharT>
1007 static bool __source_is_absolute(_ECharT __first_or_null) {
1008 return __is_separator(__first_or_null);
1009 }
1010
1011public:
1012 // appends
1013 path& operator/=(const path& __p) {
1014 if (__p.is_absolute()) {
1015 __pn_ = __p.__pn_;
1016 return *this;
1017 }
1018 if (has_filename())
1019 __pn_ += preferred_separator;
1020 __pn_ += __p.native();
1021 return *this;
1022 }
1023
1024 // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
1025 // is known at compile time to be "/' since the user almost certainly intended
1026 // to append a separator instead of overwriting the path with "/"
1027 template <class _Source>
1028 _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1029 operator/=(const _Source& __src) {
1030 return this->append(__src);
1031 }
1032
1033 template <class _Source>
1034 _EnableIfPathable<_Source> append(const _Source& __src) {
1035 using _Traits = __is_pathable<_Source>;
1036 using _CVT = _PathCVT<_SourceChar<_Source> >;
1037 if (__source_is_absolute(_Traits::__first_or_null(__src)))
1038 __pn_.clear();
1039 else if (has_filename())
1040 __pn_ += preferred_separator;
1041 _CVT::__append_source(__pn_, __src);
1042 return *this;
1043 }
1044
1045 template <class _InputIt>
1046 path& append(_InputIt __first, _InputIt __last) {
1047 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1048 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
1049 using _CVT = _PathCVT<_ItVal>;
1050 if (__first != __last && __source_is_absolute(*__first))
1051 __pn_.clear();
1052 else if (has_filename())
1053 __pn_ += preferred_separator;
1054 _CVT::__append_range(__pn_, __first, __last);
1055 return *this;
1056 }
1057
1058 // concatenation
1059 _LIBCPP_INLINE_VISIBILITY
1060 path& operator+=(const path& __x) {
1061 __pn_ += __x.__pn_;
1062 return *this;
1063 }
1064
1065 _LIBCPP_INLINE_VISIBILITY
1066 path& operator+=(const string_type& __x) {
1067 __pn_ += __x;
1068 return *this;
1069 }
1070
1071 _LIBCPP_INLINE_VISIBILITY
1072 path& operator+=(__string_view __x) {
1073 __pn_ += __x;
1074 return *this;
1075 }
1076
1077 _LIBCPP_INLINE_VISIBILITY
1078 path& operator+=(const value_type* __x) {
1079 __pn_ += __x;
1080 return *this;
1081 }
1082
1083 _LIBCPP_INLINE_VISIBILITY
1084 path& operator+=(value_type __x) {
1085 __pn_ += __x;
1086 return *this;
1087 }
1088
1089 template <class _ECharT>
1090 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
1091 operator+=(_ECharT __x) {
Marek Kurdej306a1b02020-12-07 20:07:25 +01001092 _PathCVT<_ECharT>::__append_source(__pn_,
1093 basic_string_view<_ECharT>(&__x, 1));
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001094 return *this;
1095 }
1096
1097 template <class _Source>
1098 _EnableIfPathable<_Source> operator+=(const _Source& __x) {
1099 return this->concat(__x);
1100 }
1101
1102 template <class _Source>
1103 _EnableIfPathable<_Source> concat(const _Source& __x) {
1104 _SourceCVT<_Source>::__append_source(__pn_, __x);
1105 return *this;
1106 }
1107
1108 template <class _InputIt>
1109 path& concat(_InputIt __first, _InputIt __last) {
1110 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1111 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1112 return *this;
1113 }
1114
1115 // modifiers
1116 _LIBCPP_INLINE_VISIBILITY
1117 void clear() noexcept { __pn_.clear(); }
1118
1119 path& make_preferred() { return *this; }
1120
1121 _LIBCPP_INLINE_VISIBILITY
1122 path& remove_filename() {
1123 auto __fname = __filename();
1124 if (!__fname.empty())
1125 __pn_.erase(__fname.data() - __pn_.data());
1126 return *this;
1127 }
1128
1129 path& replace_filename(const path& __replacement) {
1130 remove_filename();
1131 return (*this /= __replacement);
1132 }
1133
1134 path& replace_extension(const path& __replacement = path());
1135
1136 _LIBCPP_INLINE_VISIBILITY
1137 void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
1138
1139 // private helper to allow reserving memory in the path
1140 _LIBCPP_INLINE_VISIBILITY
1141 void __reserve(size_t __s) { __pn_.reserve(__s); }
1142
1143 // native format observers
1144 _LIBCPP_INLINE_VISIBILITY
1145 const string_type& native() const noexcept { return __pn_; }
1146
1147 _LIBCPP_INLINE_VISIBILITY
1148 const value_type* c_str() const noexcept { return __pn_.c_str(); }
1149
1150 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
1151
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001152#if defined(_LIBCPP_WIN32API)
1153 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
1154
1155 _VSTD::wstring generic_wstring() const { return __pn_; }
1156
1157#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1158 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1159 class _Allocator = allocator<_ECharT> >
1160 basic_string<_ECharT, _Traits, _Allocator>
1161 string(const _Allocator& __a = _Allocator()) const {
1162 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1163 _Str __s(__a);
1164 __s.reserve(__pn_.size());
1165 _PathExport<_ECharT>::__append(__s, __pn_);
1166 return __s;
1167 }
1168
1169 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
1170 return string<char>();
1171 }
1172 _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001173 using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1174 __u8_string __s;
1175 __s.reserve(__pn_.size());
1176 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1177 return __s;
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001178 }
1179
1180 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1181 return string<char16_t>();
1182 }
1183 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1184 return string<char32_t>();
1185 }
1186
1187 // generic format observers
1188 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1189 class _Allocator = allocator<_ECharT> >
1190 basic_string<_ECharT, _Traits, _Allocator>
1191 generic_string(const _Allocator& __a = _Allocator()) const {
1192 return string<_ECharT, _Traits, _Allocator>(__a);
1193 }
1194
1195 _VSTD::string generic_string() const { return generic_string<char>(); }
1196 _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
1197 _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1198 __u8_string generic_u8string() const { return u8string(); }
1199#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1200#else /* _LIBCPP_WIN32API */
1201
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001202 _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001203#ifndef _LIBCPP_NO_HAS_CHAR8_T
1204 _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1205#else
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001206 _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001207#endif
Louis Dionne8d053eb2020-10-09 15:31:05 -04001208
1209#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001210 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1211 class _Allocator = allocator<_ECharT> >
1212 basic_string<_ECharT, _Traits, _Allocator>
1213 string(const _Allocator& __a = _Allocator()) const {
1214 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
1215 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1216 _Str __s(__a);
1217 __s.reserve(__pn_.size());
1218 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1219 return __s;
1220 }
1221
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001222 _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001223 return string<wchar_t>();
1224 }
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001225 _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001226 return string<char16_t>();
1227 }
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001228 _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001229 return string<char32_t>();
1230 }
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001231#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001232
1233 // generic format observers
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001234 _VSTD::string generic_string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001235#ifndef _LIBCPP_NO_HAS_CHAR8_T
1236 _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1237#else
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001238 _VSTD::string generic_u8string() const { return __pn_; }
Martin Storsjöe3a71972020-10-26 13:18:46 +02001239#endif
Louis Dionne8d053eb2020-10-09 15:31:05 -04001240
1241#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001242 template <class _ECharT, class _Traits = char_traits<_ECharT>,
1243 class _Allocator = allocator<_ECharT> >
1244 basic_string<_ECharT, _Traits, _Allocator>
1245 generic_string(const _Allocator& __a = _Allocator()) const {
1246 return string<_ECharT, _Traits, _Allocator>(__a);
1247 }
1248
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001249 _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
1250 _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
1251 _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001252#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1253#endif /* !_LIBCPP_WIN32API */
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001254
1255private:
1256 int __compare(__string_view) const;
1257 __string_view __root_name() const;
1258 __string_view __root_directory() const;
1259 __string_view __root_path_raw() const;
1260 __string_view __relative_path() const;
1261 __string_view __parent_path() const;
1262 __string_view __filename() const;
1263 __string_view __stem() const;
1264 __string_view __extension() const;
1265
1266public:
1267 // compare
1268 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
1269 return __compare(__p.__pn_);
1270 }
1271 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
1272 return __compare(__s);
1273 }
1274 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
1275 return __compare(__s);
1276 }
1277 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
1278 return __compare(__s);
1279 }
1280
1281 // decomposition
1282 _LIBCPP_INLINE_VISIBILITY path root_name() const {
1283 return string_type(__root_name());
1284 }
1285 _LIBCPP_INLINE_VISIBILITY path root_directory() const {
1286 return string_type(__root_directory());
1287 }
1288 _LIBCPP_INLINE_VISIBILITY path root_path() const {
1289 return root_name().append(string_type(__root_directory()));
1290 }
1291 _LIBCPP_INLINE_VISIBILITY path relative_path() const {
1292 return string_type(__relative_path());
1293 }
1294 _LIBCPP_INLINE_VISIBILITY path parent_path() const {
1295 return string_type(__parent_path());
1296 }
1297 _LIBCPP_INLINE_VISIBILITY path filename() const {
1298 return string_type(__filename());
1299 }
1300 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
1301 _LIBCPP_INLINE_VISIBILITY path extension() const {
1302 return string_type(__extension());
1303 }
1304
1305 // query
1306 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
1307 empty() const noexcept {
1308 return __pn_.empty();
1309 }
1310
1311 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
1312 return !__root_name().empty();
1313 }
1314 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
1315 return !__root_directory().empty();
1316 }
1317 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
1318 return !__root_path_raw().empty();
1319 }
1320 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
1321 return !__relative_path().empty();
1322 }
1323 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
1324 return !__parent_path().empty();
1325 }
1326 _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
1327 return !__filename().empty();
1328 }
1329 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1330 _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
1331 return !__extension().empty();
1332 }
1333
1334 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1335 return has_root_directory();
1336 }
1337 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1338
1339 // relative paths
1340 path lexically_normal() const;
1341 path lexically_relative(const path& __base) const;
1342
1343 _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1344 path __result = this->lexically_relative(__base);
1345 if (__result.native().empty())
1346 return *this;
1347 return __result;
1348 }
1349
1350 // iterators
1351 class _LIBCPP_TYPE_VIS iterator;
1352 typedef iterator const_iterator;
1353
1354 iterator begin() const;
1355 iterator end() const;
1356
Louis Dionne8d053eb2020-10-09 15:31:05 -04001357#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001358 template <class _CharT, class _Traits>
1359 _LIBCPP_INLINE_VISIBILITY friend
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001360 typename enable_if<is_same<_CharT, value_type>::value &&
1361 is_same<_Traits, char_traits<value_type> >::value,
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001362 basic_ostream<_CharT, _Traits>&>::type
1363 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001364 __os << _VSTD::__quoted(__p.native());
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001365 return __os;
1366 }
1367
1368 template <class _CharT, class _Traits>
1369 _LIBCPP_INLINE_VISIBILITY friend
Martin Storsjöe482f4b2020-10-27 13:09:08 +02001370 typename enable_if<!is_same<_CharT, value_type>::value ||
1371 !is_same<_Traits, char_traits<value_type> >::value,
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001372 basic_ostream<_CharT, _Traits>&>::type
1373 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001374 __os << _VSTD::__quoted(__p.string<_CharT, _Traits>());
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001375 return __os;
1376 }
1377
1378 template <class _CharT, class _Traits>
1379 _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
1380 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
1381 basic_string<_CharT, _Traits> __tmp;
1382 __is >> __quoted(__tmp);
1383 __p = __tmp;
1384 return __is;
1385 }
Louis Dionne8d053eb2020-10-09 15:31:05 -04001386#endif // !_LIBCPP_HAS_NO_LOCALIZATION
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001387
Eric Fiselierab3f9d62018-12-21 04:09:01 +00001388 friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
1389 return __lhs.compare(__rhs) == 0;
1390 }
1391 friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
1392 return __lhs.compare(__rhs) != 0;
1393 }
1394 friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
1395 return __lhs.compare(__rhs) < 0;
1396 }
1397 friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
1398 return __lhs.compare(__rhs) <= 0;
1399 }
1400 friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
1401 return __lhs.compare(__rhs) > 0;
1402 }
1403 friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
1404 return __lhs.compare(__rhs) >= 0;
1405 }
1406
1407 friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1408 const path& __rhs) {
1409 path __result(__lhs);
1410 __result /= __rhs;
1411 return __result;
1412 }
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001413private:
1414 inline _LIBCPP_INLINE_VISIBILITY path&
1415 __assign_view(__string_view const& __s) noexcept {
1416 __pn_ = string_type(__s);
1417 return *this;
1418 }
1419 string_type __pn_;
1420};
1421
1422inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
1423 __lhs.swap(__rhs);
1424}
1425
1426_LIBCPP_FUNC_VIS
1427size_t hash_value(const path& __p) noexcept;
1428
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001429template <class _InputIt>
Martin Storsjöe3a71972020-10-26 13:18:46 +02001430_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001431 typename enable_if<__is_pathable<_InputIt>::value, path>::type
1432 u8path(_InputIt __f, _InputIt __l) {
1433 static_assert(
Martin Storsjöe3a71972020-10-26 13:18:46 +02001434#ifndef _LIBCPP_NO_HAS_CHAR8_T
1435 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1436#endif
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001437 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
Martin Storsjöe3a71972020-10-26 13:18:46 +02001438 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
Martin Storsjö929dff92020-12-15 09:15:37 +02001439 " or 'char8_t'");
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001440#if defined(_LIBCPP_WIN32API)
1441 string __tmp(__f, __l);
1442 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1443 _VSTD::wstring __w;
1444 __w.reserve(__tmp.size());
1445 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1446 return path(__w);
1447#else
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001448 return path(__f, __l);
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001449#endif /* !_LIBCPP_WIN32API */
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001450}
1451
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001452#if defined(_LIBCPP_WIN32API)
1453template <class _InputIt>
1454_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1455 typename enable_if<__is_pathable<_InputIt>::value, path>::type
1456 u8path(_InputIt __f, _NullSentinel) {
1457 static_assert(
1458#ifndef _LIBCPP_NO_HAS_CHAR8_T
1459 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1460#endif
1461 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1462 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1463 " or 'char8_t'");
1464 string __tmp;
1465 const char __sentinel = char{};
1466 for (; *__f != __sentinel; ++__f)
1467 __tmp.push_back(*__f);
1468 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1469 _VSTD::wstring __w;
1470 __w.reserve(__tmp.size());
1471 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1472 return path(__w);
1473}
1474#endif /* _LIBCPP_WIN32API */
1475
Martin Storsjö367d7f02020-11-05 00:21:30 +02001476template <class _Source>
1477_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1478 typename enable_if<__is_pathable<_Source>::value, path>::type
1479 u8path(const _Source& __s) {
1480 static_assert(
1481#ifndef _LIBCPP_NO_HAS_CHAR8_T
1482 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
1483#endif
1484 is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1485 "u8path(Source const&) requires Source have a character type of type "
1486 "'char' or 'char8_t'");
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001487#if defined(_LIBCPP_WIN32API)
1488 using _Traits = __is_pathable<_Source>;
1489 return u8path(__unwrap_iter(_Traits::__range_begin(__s)), __unwrap_iter(_Traits::__range_end(__s)));
1490#else
Martin Storsjö367d7f02020-11-05 00:21:30 +02001491 return path(__s);
Martin Storsjöfc25e3a2020-10-27 13:30:34 +02001492#endif
Martin Storsjö367d7f02020-11-05 00:21:30 +02001493}
1494
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001495class _LIBCPP_TYPE_VIS path::iterator {
1496public:
1497 enum _ParserState : unsigned char {
1498 _Singular,
1499 _BeforeBegin,
1500 _InRootName,
1501 _InRootDir,
1502 _InFilenames,
1503 _InTrailingSep,
1504 _AtEnd
1505 };
1506
1507public:
1508 typedef bidirectional_iterator_tag iterator_category;
1509
1510 typedef path value_type;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001511 typedef ptrdiff_t difference_type;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001512 typedef const path* pointer;
1513 typedef const path& reference;
1514
1515 typedef void
1516 __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1517
1518public:
1519 _LIBCPP_INLINE_VISIBILITY
1520 iterator()
1521 : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
1522 __state_(_Singular) {}
1523
1524 iterator(const iterator&) = default;
1525 ~iterator() = default;
1526
1527 iterator& operator=(const iterator&) = default;
1528
1529 _LIBCPP_INLINE_VISIBILITY
1530 reference operator*() const { return __stashed_elem_; }
1531
1532 _LIBCPP_INLINE_VISIBILITY
1533 pointer operator->() const { return &__stashed_elem_; }
1534
1535 _LIBCPP_INLINE_VISIBILITY
1536 iterator& operator++() {
1537 _LIBCPP_ASSERT(__state_ != _Singular,
1538 "attempting to increment a singular iterator");
1539 _LIBCPP_ASSERT(__state_ != _AtEnd,
1540 "attempting to increment the end iterator");
1541 return __increment();
1542 }
1543
1544 _LIBCPP_INLINE_VISIBILITY
1545 iterator operator++(int) {
1546 iterator __it(*this);
1547 this->operator++();
1548 return __it;
1549 }
1550
1551 _LIBCPP_INLINE_VISIBILITY
1552 iterator& operator--() {
1553 _LIBCPP_ASSERT(__state_ != _Singular,
1554 "attempting to decrement a singular iterator");
1555 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1556 "attempting to decrement the begin iterator");
1557 return __decrement();
1558 }
1559
1560 _LIBCPP_INLINE_VISIBILITY
1561 iterator operator--(int) {
1562 iterator __it(*this);
1563 this->operator--();
1564 return __it;
1565 }
1566
1567private:
1568 friend class path;
1569
1570 inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
1571 const iterator&);
1572
1573 iterator& __increment();
1574 iterator& __decrement();
1575
1576 path __stashed_elem_;
1577 const path* __path_ptr_;
1578 path::__string_view __entry_;
1579 _ParserState __state_;
1580};
1581
1582inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
1583 const path::iterator& __rhs) {
1584 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1585 __lhs.__entry_.data() == __rhs.__entry_.data();
1586}
1587
1588inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
1589 const path::iterator& __rhs) {
1590 return !(__lhs == __rhs);
1591}
1592
Louis Dionnef6bf76a2019-03-20 21:18:14 +00001593// TODO(ldionne): We need to pop the pragma and push it again after
1594// filesystem_error to work around PR41078.
1595_LIBCPP_AVAILABILITY_FILESYSTEM_POP
1596
1597class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001598public:
1599 _LIBCPP_INLINE_VISIBILITY
1600 filesystem_error(const string& __what, error_code __ec)
1601 : system_error(__ec, __what),
1602 __storage_(make_shared<_Storage>(path(), path())) {
1603 __create_what(0);
1604 }
1605
1606 _LIBCPP_INLINE_VISIBILITY
1607 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1608 : system_error(__ec, __what),
1609 __storage_(make_shared<_Storage>(__p1, path())) {
1610 __create_what(1);
1611 }
1612
1613 _LIBCPP_INLINE_VISIBILITY
1614 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1615 error_code __ec)
1616 : system_error(__ec, __what),
1617 __storage_(make_shared<_Storage>(__p1, __p2)) {
1618 __create_what(2);
1619 }
1620
1621 _LIBCPP_INLINE_VISIBILITY
1622 const path& path1() const noexcept { return __storage_->__p1_; }
1623
1624 _LIBCPP_INLINE_VISIBILITY
1625 const path& path2() const noexcept { return __storage_->__p2_; }
1626
Dimitry Andric47269ce2020-03-13 19:36:26 +01001627 filesystem_error(const filesystem_error&) = default;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001628 ~filesystem_error() override; // key function
1629
1630 _LIBCPP_INLINE_VISIBILITY
1631 const char* what() const noexcept override {
1632 return __storage_->__what_.c_str();
1633 }
1634
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001635 void __create_what(int __num_paths);
1636
1637private:
Louis Dionne48ae8892019-03-19 17:47:53 +00001638 struct _LIBCPP_HIDDEN _Storage {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001639 _LIBCPP_INLINE_VISIBILITY
1640 _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1641
1642 path __p1_;
1643 path __p2_;
1644 string __what_;
1645 };
1646 shared_ptr<_Storage> __storage_;
1647};
1648
Louis Dionnef6bf76a2019-03-20 21:18:14 +00001649_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
1650
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001651template <class... _Args>
1652_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1653#ifndef _LIBCPP_NO_EXCEPTIONS
Louis Dionne6251ef02019-02-05 15:46:52 +00001654void __throw_filesystem_error(_Args&&... __args) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001655 throw filesystem_error(_VSTD::forward<_Args>(__args)...);
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001656}
1657#else
Louis Dionne6251ef02019-02-05 15:46:52 +00001658void __throw_filesystem_error(_Args&&...) {
Eric Fiselier02cea5e2018-07-27 03:07:09 +00001659 _VSTD::abort();
1660}
1661#endif
1662
1663// operational functions
1664
1665_LIBCPP_FUNC_VIS
1666path __absolute(const path&, error_code* __ec = nullptr);
1667_LIBCPP_FUNC_VIS
1668path __canonical(const path&, error_code* __ec = nullptr);
1669_LIBCPP_FUNC_VIS
1670void __copy(const path& __from, const path& __to, copy_options __opt,
1671 error_code* __ec = nullptr);
1672_LIBCPP_FUNC_VIS
1673bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1674 error_code* __ec = nullptr);
1675_LIBCPP_FUNC_VIS
1676void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1677 error_code* __ec = nullptr);
1678_LIBCPP_FUNC_VIS
1679bool __create_directories(const path& p, error_code* ec = nullptr);
1680_LIBCPP_FUNC_VIS
1681bool __create_directory(const path& p, error_code* ec = nullptr);
1682_LIBCPP_FUNC_VIS
1683bool __create_directory(const path& p, const path& attributes,
1684 error_code* ec = nullptr);
1685_LIBCPP_FUNC_VIS
1686void __create_directory_symlink(const path& __to, const path& __new_symlink,
1687 error_code* __ec = nullptr);
1688_LIBCPP_FUNC_VIS
1689void __create_hard_link(const path& __to, const path& __new_hard_link,
1690 error_code* __ec = nullptr);
1691_LIBCPP_FUNC_VIS
1692void __create_symlink(const path& __to, const path& __new_symlink,
1693 error_code* __ec = nullptr);
1694_LIBCPP_FUNC_VIS
1695path __current_path(error_code* __ec = nullptr);
1696_LIBCPP_FUNC_VIS
1697void __current_path(const path&, error_code* __ec = nullptr);
1698_LIBCPP_FUNC_VIS
1699bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
1700_LIBCPP_FUNC_VIS
1701uintmax_t __file_size(const path&, error_code* __ec = nullptr);
1702_LIBCPP_FUNC_VIS
1703uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
1704_LIBCPP_FUNC_VIS
1705bool __fs_is_empty(const path& p, error_code* ec = nullptr);
1706_LIBCPP_FUNC_VIS
1707file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
1708_LIBCPP_FUNC_VIS
1709void __last_write_time(const path& p, file_time_type new_time,
1710 error_code* ec = nullptr);
1711_LIBCPP_FUNC_VIS
1712void __permissions(const path&, perms, perm_options, error_code* = nullptr);
1713_LIBCPP_FUNC_VIS
1714path __read_symlink(const path& p, error_code* ec = nullptr);
1715_LIBCPP_FUNC_VIS
1716bool __remove(const path& p, error_code* ec = nullptr);
1717_LIBCPP_FUNC_VIS
1718uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
1719_LIBCPP_FUNC_VIS
1720void __rename(const path& from, const path& to, error_code* ec = nullptr);
1721_LIBCPP_FUNC_VIS
1722void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
1723_LIBCPP_FUNC_VIS
1724space_info __space(const path&, error_code* __ec = nullptr);
1725_LIBCPP_FUNC_VIS
1726file_status __status(const path&, error_code* __ec = nullptr);
1727_LIBCPP_FUNC_VIS
1728file_status __symlink_status(const path&, error_code* __ec = nullptr);
1729_LIBCPP_FUNC_VIS
1730path __system_complete(const path&, error_code* __ec = nullptr);
1731_LIBCPP_FUNC_VIS
1732path __temp_directory_path(error_code* __ec = nullptr);
1733_LIBCPP_FUNC_VIS
1734path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
1735
1736inline _LIBCPP_INLINE_VISIBILITY path current_path() {
1737 return __current_path();
1738}
1739
1740inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
1741 return __current_path(&__ec);
1742}
1743
1744inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
1745 __current_path(__p);
1746}
1747
1748inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
1749 error_code& __ec) noexcept {
1750 __current_path(__p, &__ec);
1751}
1752
1753inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
1754 return __absolute(__p);
1755}
1756
1757inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
1758 error_code& __ec) {
1759 return __absolute(__p, &__ec);
1760}
1761
1762inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
1763 return __canonical(__p);
1764}
1765
1766inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
1767 error_code& __ec) {
1768 return __canonical(__p, &__ec);
1769}
1770
1771inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
1772 const path& __to) {
1773 __copy(__from, __to, copy_options::none);
1774}
1775
1776inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1777 error_code& __ec) {
1778 __copy(__from, __to, copy_options::none, &__ec);
1779}
1780
1781inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1782 copy_options __opt) {
1783 __copy(__from, __to, __opt);
1784}
1785
1786inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1787 copy_options __opt,
1788 error_code& __ec) {
1789 __copy(__from, __to, __opt, &__ec);
1790}
1791
1792inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1793 const path& __to) {
1794 return __copy_file(__from, __to, copy_options::none);
1795}
1796
1797inline _LIBCPP_INLINE_VISIBILITY bool
1798copy_file(const path& __from, const path& __to, error_code& __ec) {
1799 return __copy_file(__from, __to, copy_options::none, &__ec);
1800}
1801
1802inline _LIBCPP_INLINE_VISIBILITY bool
1803copy_file(const path& __from, const path& __to, copy_options __opt) {
1804 return __copy_file(__from, __to, __opt);
1805}
1806
1807inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1808 const path& __to,
1809 copy_options __opt,
1810 error_code& __ec) {
1811 return __copy_file(__from, __to, __opt, &__ec);
1812}
1813
1814inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
1815 const path& __new) {
1816 __copy_symlink(__existing, __new);
1817}
1818
1819inline _LIBCPP_INLINE_VISIBILITY void
1820copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
1821 __copy_symlink(__ext, __new, &__ec);
1822}
1823
1824inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
1825 return __create_directories(__p);
1826}
1827
1828inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
1829 error_code& __ec) {
1830 return __create_directories(__p, &__ec);
1831}
1832
1833inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
1834 return __create_directory(__p);
1835}
1836
1837inline _LIBCPP_INLINE_VISIBILITY bool
1838create_directory(const path& __p, error_code& __ec) noexcept {
1839 return __create_directory(__p, &__ec);
1840}
1841
1842inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
1843 const path& __attrs) {
1844 return __create_directory(__p, __attrs);
1845}
1846
1847inline _LIBCPP_INLINE_VISIBILITY bool
1848create_directory(const path& __p, const path& __attrs,
1849 error_code& __ec) noexcept {
1850 return __create_directory(__p, __attrs, &__ec);
1851}
1852
1853inline _LIBCPP_INLINE_VISIBILITY void
1854create_directory_symlink(const path& __to, const path& __new) {
1855 __create_directory_symlink(__to, __new);
1856}
1857
1858inline _LIBCPP_INLINE_VISIBILITY void
1859create_directory_symlink(const path& __to, const path& __new,
1860 error_code& __ec) noexcept {
1861 __create_directory_symlink(__to, __new, &__ec);
1862}
1863
1864inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
1865 const path& __new) {
1866 __create_hard_link(__to, __new);
1867}
1868
1869inline _LIBCPP_INLINE_VISIBILITY void
1870create_hard_link(const path& __to, const path& __new,
1871 error_code& __ec) noexcept {
1872 __create_hard_link(__to, __new, &__ec);
1873}
1874
1875inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
1876 const path& __new) {
1877 __create_symlink(__to, __new);
1878}
1879
1880inline _LIBCPP_INLINE_VISIBILITY void
1881create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
1882 return __create_symlink(__to, __new, &__ec);
1883}
1884
1885inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
1886 return __s.type() != file_type::none;
1887}
1888
1889inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
1890 return status_known(__s) && __s.type() != file_type::not_found;
1891}
1892
1893inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
1894 return exists(__status(__p));
1895}
1896
1897inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
1898 error_code& __ec) noexcept {
1899 auto __s = __status(__p, &__ec);
1900 if (status_known(__s))
1901 __ec.clear();
1902 return exists(__s);
1903}
1904
1905inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
1906 const path& __p2) {
1907 return __equivalent(__p1, __p2);
1908}
1909
1910inline _LIBCPP_INLINE_VISIBILITY bool
1911equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
1912 return __equivalent(__p1, __p2, &__ec);
1913}
1914
1915inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
1916 return __file_size(__p);
1917}
1918
1919inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1920file_size(const path& __p, error_code& __ec) noexcept {
1921 return __file_size(__p, &__ec);
1922}
1923
1924inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
1925 return __hard_link_count(__p);
1926}
1927
1928inline _LIBCPP_INLINE_VISIBILITY uintmax_t
1929hard_link_count(const path& __p, error_code& __ec) noexcept {
1930 return __hard_link_count(__p, &__ec);
1931}
1932
1933inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
1934 return __s.type() == file_type::block;
1935}
1936
1937inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
1938 return is_block_file(__status(__p));
1939}
1940
1941inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
1942 error_code& __ec) noexcept {
1943 return is_block_file(__status(__p, &__ec));
1944}
1945
1946inline _LIBCPP_INLINE_VISIBILITY bool
1947is_character_file(file_status __s) noexcept {
1948 return __s.type() == file_type::character;
1949}
1950
1951inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
1952 return is_character_file(__status(__p));
1953}
1954
1955inline _LIBCPP_INLINE_VISIBILITY bool
1956is_character_file(const path& __p, error_code& __ec) noexcept {
1957 return is_character_file(__status(__p, &__ec));
1958}
1959
1960inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
1961 return __s.type() == file_type::directory;
1962}
1963
1964inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
1965 return is_directory(__status(__p));
1966}
1967
1968inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
1969 error_code& __ec) noexcept {
1970 return is_directory(__status(__p, &__ec));
1971}
1972
1973inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
1974 return __fs_is_empty(__p);
1975}
1976
1977inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
1978 error_code& __ec) {
1979 return __fs_is_empty(__p, &__ec);
1980}
1981
1982inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
1983 return __s.type() == file_type::fifo;
1984}
1985inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
1986 return is_fifo(__status(__p));
1987}
1988
1989inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
1990 error_code& __ec) noexcept {
1991 return is_fifo(__status(__p, &__ec));
1992}
1993
1994inline _LIBCPP_INLINE_VISIBILITY bool
1995is_regular_file(file_status __s) noexcept {
1996 return __s.type() == file_type::regular;
1997}
1998
1999inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
2000 return is_regular_file(__status(__p));
2001}
2002
2003inline _LIBCPP_INLINE_VISIBILITY bool
2004is_regular_file(const path& __p, error_code& __ec) noexcept {
2005 return is_regular_file(__status(__p, &__ec));
2006}
2007
2008inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
2009 return __s.type() == file_type::socket;
2010}
2011
2012inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
2013 return is_socket(__status(__p));
2014}
2015
2016inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
2017 error_code& __ec) noexcept {
2018 return is_socket(__status(__p, &__ec));
2019}
2020
2021inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
2022 return __s.type() == file_type::symlink;
2023}
2024
2025inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
2026 return is_symlink(__symlink_status(__p));
2027}
2028
2029inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
2030 error_code& __ec) noexcept {
2031 return is_symlink(__symlink_status(__p, &__ec));
2032}
2033
2034inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
2035 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
2036 !is_symlink(__s);
2037}
2038
2039inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
2040 return is_other(__status(__p));
2041}
2042
2043inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
2044 error_code& __ec) noexcept {
2045 return is_other(__status(__p, &__ec));
2046}
2047
2048inline _LIBCPP_INLINE_VISIBILITY file_time_type
2049last_write_time(const path& __p) {
2050 return __last_write_time(__p);
2051}
2052
2053inline _LIBCPP_INLINE_VISIBILITY file_time_type
2054last_write_time(const path& __p, error_code& __ec) noexcept {
2055 return __last_write_time(__p, &__ec);
2056}
2057
2058inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
2059 file_time_type __t) {
2060 __last_write_time(__p, __t);
2061}
2062
2063inline _LIBCPP_INLINE_VISIBILITY void
2064last_write_time(const path& __p, file_time_type __t,
2065 error_code& __ec) noexcept {
2066 __last_write_time(__p, __t, &__ec);
2067}
2068
2069inline _LIBCPP_INLINE_VISIBILITY void
2070permissions(const path& __p, perms __prms,
2071 perm_options __opts = perm_options::replace) {
2072 __permissions(__p, __prms, __opts);
2073}
2074
2075inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2076 error_code& __ec) noexcept {
2077 __permissions(__p, __prms, perm_options::replace, &__ec);
2078}
2079
2080inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2081 perm_options __opts,
2082 error_code& __ec) {
2083 __permissions(__p, __prms, __opts, &__ec);
2084}
2085
2086inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2087 const path& __base,
2088 error_code& __ec) {
2089 path __tmp = __weakly_canonical(__p, &__ec);
2090 if (__ec)
2091 return {};
2092 path __tmp_base = __weakly_canonical(__base, &__ec);
2093 if (__ec)
2094 return {};
2095 return __tmp.lexically_proximate(__tmp_base);
2096}
2097
2098inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2099 error_code& __ec) {
2100 return proximate(__p, current_path(), __ec);
2101}
2102
2103inline _LIBCPP_INLINE_VISIBILITY path
2104proximate(const path& __p, const path& __base = current_path()) {
2105 return __weakly_canonical(__p).lexically_proximate(
2106 __weakly_canonical(__base));
2107}
2108
2109inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
2110 return __read_symlink(__p);
2111}
2112
2113inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
2114 error_code& __ec) {
2115 return __read_symlink(__p, &__ec);
2116}
2117
2118inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2119 const path& __base,
2120 error_code& __ec) {
2121 path __tmp = __weakly_canonical(__p, &__ec);
2122 if (__ec)
2123 return path();
2124 path __tmpbase = __weakly_canonical(__base, &__ec);
2125 if (__ec)
2126 return path();
2127 return __tmp.lexically_relative(__tmpbase);
2128}
2129
2130inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2131 error_code& __ec) {
2132 return relative(__p, current_path(), __ec);
2133}
2134
2135inline _LIBCPP_INLINE_VISIBILITY path
2136relative(const path& __p, const path& __base = current_path()) {
2137 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
2138}
2139
2140inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
2141 return __remove(__p);
2142}
2143
2144inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
2145 error_code& __ec) noexcept {
2146 return __remove(__p, &__ec);
2147}
2148
2149inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
2150 return __remove_all(__p);
2151}
2152
2153inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
2154 error_code& __ec) {
2155 return __remove_all(__p, &__ec);
2156}
2157
2158inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
2159 const path& __to) {
2160 return __rename(__from, __to);
2161}
2162
2163inline _LIBCPP_INLINE_VISIBILITY void
2164rename(const path& __from, const path& __to, error_code& __ec) noexcept {
2165 return __rename(__from, __to, &__ec);
2166}
2167
2168inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
2169 uintmax_t __ns) {
2170 return __resize_file(__p, __ns);
2171}
2172
2173inline _LIBCPP_INLINE_VISIBILITY void
2174resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
2175 return __resize_file(__p, __ns, &__ec);
2176}
2177
2178inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
2179 return __space(__p);
2180}
2181
2182inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
2183 error_code& __ec) noexcept {
2184 return __space(__p, &__ec);
2185}
2186
2187inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
2188 return __status(__p);
2189}
2190
2191inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
2192 error_code& __ec) noexcept {
2193 return __status(__p, &__ec);
2194}
2195
2196inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
2197 return __symlink_status(__p);
2198}
2199
2200inline _LIBCPP_INLINE_VISIBILITY file_status
2201symlink_status(const path& __p, error_code& __ec) noexcept {
2202 return __symlink_status(__p, &__ec);
2203}
2204
2205inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
2206 return __temp_directory_path();
2207}
2208
2209inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
2210 return __temp_directory_path(&__ec);
2211}
2212
2213inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
2214 return __weakly_canonical(__p);
2215}
2216
2217inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
2218 error_code& __ec) {
2219 return __weakly_canonical(__p, &__ec);
2220}
2221
2222class directory_iterator;
2223class recursive_directory_iterator;
Louis Dionne48ae8892019-03-19 17:47:53 +00002224class _LIBCPP_HIDDEN __dir_stream;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002225
2226class directory_entry {
2227 typedef _VSTD_FS::path _Path;
2228
2229public:
2230 // constructors and destructors
2231 directory_entry() noexcept = default;
2232 directory_entry(directory_entry const&) = default;
2233 directory_entry(directory_entry&&) noexcept = default;
2234
2235 _LIBCPP_INLINE_VISIBILITY
2236 explicit directory_entry(_Path const& __p) : __p_(__p) {
2237 error_code __ec;
2238 __refresh(&__ec);
2239 }
2240
2241 _LIBCPP_INLINE_VISIBILITY
2242 directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
2243 __refresh(&__ec);
2244 }
2245
2246 ~directory_entry() {}
2247
2248 directory_entry& operator=(directory_entry const&) = default;
2249 directory_entry& operator=(directory_entry&&) noexcept = default;
2250
2251 _LIBCPP_INLINE_VISIBILITY
2252 void assign(_Path const& __p) {
2253 __p_ = __p;
2254 error_code __ec;
2255 __refresh(&__ec);
2256 }
2257
2258 _LIBCPP_INLINE_VISIBILITY
2259 void assign(_Path const& __p, error_code& __ec) {
2260 __p_ = __p;
2261 __refresh(&__ec);
2262 }
2263
2264 _LIBCPP_INLINE_VISIBILITY
2265 void replace_filename(_Path const& __p) {
2266 __p_.replace_filename(__p);
2267 error_code __ec;
2268 __refresh(&__ec);
2269 }
2270
2271 _LIBCPP_INLINE_VISIBILITY
2272 void replace_filename(_Path const& __p, error_code& __ec) {
2273 __p_ = __p_.parent_path() / __p;
2274 __refresh(&__ec);
2275 }
2276
2277 _LIBCPP_INLINE_VISIBILITY
2278 void refresh() { __refresh(); }
2279
2280 _LIBCPP_INLINE_VISIBILITY
2281 void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
2282
2283 _LIBCPP_INLINE_VISIBILITY
2284 _Path const& path() const noexcept { return __p_; }
2285
2286 _LIBCPP_INLINE_VISIBILITY
2287 operator const _Path&() const noexcept { return __p_; }
2288
2289 _LIBCPP_INLINE_VISIBILITY
2290 bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
2291
2292 _LIBCPP_INLINE_VISIBILITY
2293 bool exists(error_code& __ec) const noexcept {
2294 return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2295 }
2296
2297 _LIBCPP_INLINE_VISIBILITY
2298 bool is_block_file() const { return __get_ft() == file_type::block; }
2299
2300 _LIBCPP_INLINE_VISIBILITY
2301 bool is_block_file(error_code& __ec) const noexcept {
2302 return __get_ft(&__ec) == file_type::block;
2303 }
2304
2305 _LIBCPP_INLINE_VISIBILITY
2306 bool is_character_file() const { return __get_ft() == file_type::character; }
2307
2308 _LIBCPP_INLINE_VISIBILITY
2309 bool is_character_file(error_code& __ec) const noexcept {
2310 return __get_ft(&__ec) == file_type::character;
2311 }
2312
2313 _LIBCPP_INLINE_VISIBILITY
2314 bool is_directory() const { return __get_ft() == file_type::directory; }
2315
2316 _LIBCPP_INLINE_VISIBILITY
2317 bool is_directory(error_code& __ec) const noexcept {
2318 return __get_ft(&__ec) == file_type::directory;
2319 }
2320
2321 _LIBCPP_INLINE_VISIBILITY
2322 bool is_fifo() const { return __get_ft() == file_type::fifo; }
2323
2324 _LIBCPP_INLINE_VISIBILITY
2325 bool is_fifo(error_code& __ec) const noexcept {
2326 return __get_ft(&__ec) == file_type::fifo;
2327 }
2328
2329 _LIBCPP_INLINE_VISIBILITY
2330 bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
2331
2332 _LIBCPP_INLINE_VISIBILITY
2333 bool is_other(error_code& __ec) const noexcept {
2334 return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2335 }
2336
2337 _LIBCPP_INLINE_VISIBILITY
2338 bool is_regular_file() const { return __get_ft() == file_type::regular; }
2339
2340 _LIBCPP_INLINE_VISIBILITY
2341 bool is_regular_file(error_code& __ec) const noexcept {
2342 return __get_ft(&__ec) == file_type::regular;
2343 }
2344
2345 _LIBCPP_INLINE_VISIBILITY
2346 bool is_socket() const { return __get_ft() == file_type::socket; }
2347
2348 _LIBCPP_INLINE_VISIBILITY
2349 bool is_socket(error_code& __ec) const noexcept {
2350 return __get_ft(&__ec) == file_type::socket;
2351 }
2352
2353 _LIBCPP_INLINE_VISIBILITY
2354 bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
2355
2356 _LIBCPP_INLINE_VISIBILITY
2357 bool is_symlink(error_code& __ec) const noexcept {
2358 return __get_sym_ft(&__ec) == file_type::symlink;
2359 }
2360 _LIBCPP_INLINE_VISIBILITY
2361 uintmax_t file_size() const { return __get_size(); }
2362
2363 _LIBCPP_INLINE_VISIBILITY
2364 uintmax_t file_size(error_code& __ec) const noexcept {
2365 return __get_size(&__ec);
2366 }
2367
2368 _LIBCPP_INLINE_VISIBILITY
2369 uintmax_t hard_link_count() const { return __get_nlink(); }
2370
2371 _LIBCPP_INLINE_VISIBILITY
2372 uintmax_t hard_link_count(error_code& __ec) const noexcept {
2373 return __get_nlink(&__ec);
2374 }
2375
2376 _LIBCPP_INLINE_VISIBILITY
2377 file_time_type last_write_time() const { return __get_write_time(); }
2378
2379 _LIBCPP_INLINE_VISIBILITY
2380 file_time_type last_write_time(error_code& __ec) const noexcept {
2381 return __get_write_time(&__ec);
2382 }
2383
2384 _LIBCPP_INLINE_VISIBILITY
2385 file_status status() const { return __get_status(); }
2386
2387 _LIBCPP_INLINE_VISIBILITY
2388 file_status status(error_code& __ec) const noexcept {
2389 return __get_status(&__ec);
2390 }
2391
2392 _LIBCPP_INLINE_VISIBILITY
2393 file_status symlink_status() const { return __get_symlink_status(); }
2394
2395 _LIBCPP_INLINE_VISIBILITY
2396 file_status symlink_status(error_code& __ec) const noexcept {
2397 return __get_symlink_status(&__ec);
2398 }
2399
2400 _LIBCPP_INLINE_VISIBILITY
2401 bool operator<(directory_entry const& __rhs) const noexcept {
2402 return __p_ < __rhs.__p_;
2403 }
2404
2405 _LIBCPP_INLINE_VISIBILITY
2406 bool operator==(directory_entry const& __rhs) const noexcept {
2407 return __p_ == __rhs.__p_;
2408 }
2409
2410 _LIBCPP_INLINE_VISIBILITY
2411 bool operator!=(directory_entry const& __rhs) const noexcept {
2412 return __p_ != __rhs.__p_;
2413 }
2414
2415 _LIBCPP_INLINE_VISIBILITY
2416 bool operator<=(directory_entry const& __rhs) const noexcept {
2417 return __p_ <= __rhs.__p_;
2418 }
2419
2420 _LIBCPP_INLINE_VISIBILITY
2421 bool operator>(directory_entry const& __rhs) const noexcept {
2422 return __p_ > __rhs.__p_;
2423 }
2424
2425 _LIBCPP_INLINE_VISIBILITY
2426 bool operator>=(directory_entry const& __rhs) const noexcept {
2427 return __p_ >= __rhs.__p_;
2428 }
2429
2430private:
2431 friend class directory_iterator;
2432 friend class recursive_directory_iterator;
2433 friend class __dir_stream;
2434
2435 enum _CacheType : unsigned char {
2436 _Empty,
2437 _IterSymlink,
2438 _IterNonSymlink,
2439 _RefreshSymlink,
2440 _RefreshSymlinkUnresolved,
2441 _RefreshNonSymlink
2442 };
2443
2444 struct __cached_data {
2445 uintmax_t __size_;
2446 uintmax_t __nlink_;
2447 file_time_type __write_time_;
2448 perms __sym_perms_;
2449 perms __non_sym_perms_;
2450 file_type __type_;
2451 _CacheType __cache_type_;
2452
2453 _LIBCPP_INLINE_VISIBILITY
2454 __cached_data() noexcept { __reset(); }
2455
2456 _LIBCPP_INLINE_VISIBILITY
2457 void __reset() {
2458 __cache_type_ = _Empty;
2459 __type_ = file_type::none;
2460 __sym_perms_ = __non_sym_perms_ = perms::unknown;
2461 __size_ = __nlink_ = uintmax_t(-1);
2462 __write_time_ = file_time_type::min();
2463 }
2464 };
2465
2466 _LIBCPP_INLINE_VISIBILITY
2467 static __cached_data __create_iter_result(file_type __ft) {
2468 __cached_data __data;
2469 __data.__type_ = __ft;
2470 __data.__cache_type_ = [&]() {
2471 switch (__ft) {
2472 case file_type::none:
2473 return _Empty;
2474 case file_type::symlink:
2475 return _IterSymlink;
2476 default:
2477 return _IterNonSymlink;
2478 }
2479 }();
2480 return __data;
2481 }
2482
2483 _LIBCPP_INLINE_VISIBILITY
2484 void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002485 __p_ = _VSTD::move(__p);
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002486 __data_ = __dt;
2487 }
2488
2489 _LIBCPP_FUNC_VIS
2490 error_code __do_refresh() noexcept;
2491
2492 _LIBCPP_INLINE_VISIBILITY
2493 static bool __is_dne_error(error_code const& __ec) {
2494 if (!__ec)
2495 return true;
2496 switch (static_cast<errc>(__ec.value())) {
2497 case errc::no_such_file_or_directory:
2498 case errc::not_a_directory:
2499 return true;
2500 default:
2501 return false;
2502 }
2503 }
2504
2505 _LIBCPP_INLINE_VISIBILITY
2506 void __handle_error(const char* __msg, error_code* __dest_ec,
2507 error_code const& __ec, bool __allow_dne = false) const {
2508 if (__dest_ec) {
2509 *__dest_ec = __ec;
2510 return;
2511 }
2512 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2513 __throw_filesystem_error(__msg, __p_, __ec);
2514 }
2515
2516 _LIBCPP_INLINE_VISIBILITY
2517 void __refresh(error_code* __ec = nullptr) {
2518 __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2519 /*allow_dne*/ true);
2520 }
2521
2522 _LIBCPP_INLINE_VISIBILITY
2523 file_type __get_sym_ft(error_code* __ec = nullptr) const {
2524 switch (__data_.__cache_type_) {
2525 case _Empty:
2526 return __symlink_status(__p_, __ec).type();
2527 case _IterSymlink:
2528 case _RefreshSymlink:
2529 case _RefreshSymlinkUnresolved:
2530 if (__ec)
2531 __ec->clear();
2532 return file_type::symlink;
2533 case _IterNonSymlink:
2534 case _RefreshNonSymlink:
2535 file_status __st(__data_.__type_);
2536 if (__ec && !_VSTD_FS::exists(__st))
2537 *__ec = make_error_code(errc::no_such_file_or_directory);
2538 else if (__ec)
2539 __ec->clear();
2540 return __data_.__type_;
2541 }
2542 _LIBCPP_UNREACHABLE();
2543 }
2544
2545 _LIBCPP_INLINE_VISIBILITY
2546 file_type __get_ft(error_code* __ec = nullptr) const {
2547 switch (__data_.__cache_type_) {
2548 case _Empty:
2549 case _IterSymlink:
2550 case _RefreshSymlinkUnresolved:
2551 return __status(__p_, __ec).type();
2552 case _IterNonSymlink:
2553 case _RefreshNonSymlink:
2554 case _RefreshSymlink: {
2555 file_status __st(__data_.__type_);
2556 if (__ec && !_VSTD_FS::exists(__st))
2557 *__ec = make_error_code(errc::no_such_file_or_directory);
2558 else if (__ec)
2559 __ec->clear();
2560 return __data_.__type_;
2561 }
2562 }
2563 _LIBCPP_UNREACHABLE();
2564 }
2565
2566 _LIBCPP_INLINE_VISIBILITY
2567 file_status __get_status(error_code* __ec = nullptr) const {
2568 switch (__data_.__cache_type_) {
2569 case _Empty:
2570 case _IterNonSymlink:
2571 case _IterSymlink:
2572 case _RefreshSymlinkUnresolved:
2573 return __status(__p_, __ec);
2574 case _RefreshNonSymlink:
2575 case _RefreshSymlink:
2576 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2577 }
2578 _LIBCPP_UNREACHABLE();
2579 }
2580
2581 _LIBCPP_INLINE_VISIBILITY
2582 file_status __get_symlink_status(error_code* __ec = nullptr) const {
2583 switch (__data_.__cache_type_) {
2584 case _Empty:
2585 case _IterNonSymlink:
2586 case _IterSymlink:
2587 return __symlink_status(__p_, __ec);
2588 case _RefreshNonSymlink:
2589 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2590 case _RefreshSymlink:
2591 case _RefreshSymlinkUnresolved:
2592 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2593 }
2594 _LIBCPP_UNREACHABLE();
2595 }
2596
2597 _LIBCPP_INLINE_VISIBILITY
2598 uintmax_t __get_size(error_code* __ec = nullptr) const {
2599 switch (__data_.__cache_type_) {
2600 case _Empty:
2601 case _IterNonSymlink:
2602 case _IterSymlink:
2603 case _RefreshSymlinkUnresolved:
2604 return _VSTD_FS::__file_size(__p_, __ec);
2605 case _RefreshSymlink:
2606 case _RefreshNonSymlink: {
2607 error_code __m_ec;
2608 file_status __st(__get_ft(&__m_ec));
2609 __handle_error("in directory_entry::file_size", __ec, __m_ec);
2610 if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2611 errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2612 : errc::not_supported;
2613 __handle_error("in directory_entry::file_size", __ec,
2614 make_error_code(__err_kind));
2615 }
2616 return __data_.__size_;
2617 }
2618 }
2619 _LIBCPP_UNREACHABLE();
2620 }
2621
2622 _LIBCPP_INLINE_VISIBILITY
2623 uintmax_t __get_nlink(error_code* __ec = nullptr) const {
2624 switch (__data_.__cache_type_) {
2625 case _Empty:
2626 case _IterNonSymlink:
2627 case _IterSymlink:
2628 case _RefreshSymlinkUnresolved:
2629 return _VSTD_FS::__hard_link_count(__p_, __ec);
2630 case _RefreshSymlink:
2631 case _RefreshNonSymlink: {
2632 error_code __m_ec;
2633 (void)__get_ft(&__m_ec);
2634 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
2635 return __data_.__nlink_;
2636 }
2637 }
2638 _LIBCPP_UNREACHABLE();
2639 }
2640
2641 _LIBCPP_INLINE_VISIBILITY
2642 file_time_type __get_write_time(error_code* __ec = nullptr) const {
2643 switch (__data_.__cache_type_) {
2644 case _Empty:
2645 case _IterNonSymlink:
2646 case _IterSymlink:
2647 case _RefreshSymlinkUnresolved:
2648 return _VSTD_FS::__last_write_time(__p_, __ec);
2649 case _RefreshSymlink:
2650 case _RefreshNonSymlink: {
2651 error_code __m_ec;
2652 file_status __st(__get_ft(&__m_ec));
2653 __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
2654 if (_VSTD_FS::exists(__st) &&
2655 __data_.__write_time_ == file_time_type::min())
2656 __handle_error("in directory_entry::last_write_time", __ec,
2657 make_error_code(errc::value_too_large));
2658 return __data_.__write_time_;
2659 }
2660 }
2661 _LIBCPP_UNREACHABLE();
2662 }
2663
2664private:
2665 _Path __p_;
2666 __cached_data __data_;
2667};
2668
2669class __dir_element_proxy {
2670public:
2671 inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
2672 return _VSTD::move(__elem_);
2673 }
2674
2675private:
2676 friend class directory_iterator;
2677 friend class recursive_directory_iterator;
2678 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2679 __dir_element_proxy(__dir_element_proxy&& __o)
2680 : __elem_(_VSTD::move(__o.__elem_)) {}
2681 directory_entry __elem_;
2682};
2683
2684class directory_iterator {
2685public:
2686 typedef directory_entry value_type;
2687 typedef ptrdiff_t difference_type;
2688 typedef value_type const* pointer;
2689 typedef value_type const& reference;
2690 typedef input_iterator_tag iterator_category;
2691
2692public:
2693 //ctor & dtor
2694 directory_iterator() noexcept {}
2695
2696 explicit directory_iterator(const path& __p)
2697 : directory_iterator(__p, nullptr) {}
2698
2699 directory_iterator(const path& __p, directory_options __opts)
2700 : directory_iterator(__p, nullptr, __opts) {}
2701
2702 directory_iterator(const path& __p, error_code& __ec)
2703 : directory_iterator(__p, &__ec) {}
2704
2705 directory_iterator(const path& __p, directory_options __opts,
2706 error_code& __ec)
2707 : directory_iterator(__p, &__ec, __opts) {}
2708
2709 directory_iterator(const directory_iterator&) = default;
2710 directory_iterator(directory_iterator&&) = default;
2711 directory_iterator& operator=(const directory_iterator&) = default;
2712
2713 directory_iterator& operator=(directory_iterator&& __o) noexcept {
2714 // non-default implementation provided to support self-move assign.
2715 if (this != &__o) {
2716 __imp_ = _VSTD::move(__o.__imp_);
2717 }
2718 return *this;
2719 }
2720
2721 ~directory_iterator() = default;
2722
2723 const directory_entry& operator*() const {
2724 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
2725 return __dereference();
2726 }
2727
2728 const directory_entry* operator->() const { return &**this; }
2729
2730 directory_iterator& operator++() { return __increment(); }
2731
2732 __dir_element_proxy operator++(int) {
2733 __dir_element_proxy __p(**this);
2734 __increment();
2735 return __p;
2736 }
2737
2738 directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
2739
2740private:
2741 inline _LIBCPP_INLINE_VISIBILITY friend bool
2742 operator==(const directory_iterator& __lhs,
2743 const directory_iterator& __rhs) noexcept;
2744
2745 // construct the dir_stream
2746 _LIBCPP_FUNC_VIS
2747 directory_iterator(const path&, error_code*,
2748 directory_options = directory_options::none);
2749
2750 _LIBCPP_FUNC_VIS
2751 directory_iterator& __increment(error_code* __ec = nullptr);
2752
2753 _LIBCPP_FUNC_VIS
2754 const directory_entry& __dereference() const;
2755
2756private:
2757 shared_ptr<__dir_stream> __imp_;
2758};
2759
2760inline _LIBCPP_INLINE_VISIBILITY bool
2761operator==(const directory_iterator& __lhs,
2762 const directory_iterator& __rhs) noexcept {
2763 return __lhs.__imp_ == __rhs.__imp_;
2764}
2765
2766inline _LIBCPP_INLINE_VISIBILITY bool
2767operator!=(const directory_iterator& __lhs,
2768 const directory_iterator& __rhs) noexcept {
2769 return !(__lhs == __rhs);
2770}
2771
2772// enable directory_iterator range-based for statements
2773inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2774begin(directory_iterator __iter) noexcept {
2775 return __iter;
2776}
2777
2778inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2779end(const directory_iterator&) noexcept {
2780 return directory_iterator();
2781}
2782
2783class recursive_directory_iterator {
2784public:
2785 using value_type = directory_entry;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002786 using difference_type = ptrdiff_t;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002787 using pointer = directory_entry const*;
2788 using reference = directory_entry const&;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002789 using iterator_category = input_iterator_tag;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002790
2791public:
2792 // constructors and destructor
2793 _LIBCPP_INLINE_VISIBILITY
2794 recursive_directory_iterator() noexcept : __rec_(false) {}
2795
2796 _LIBCPP_INLINE_VISIBILITY
2797 explicit recursive_directory_iterator(
2798 const path& __p, directory_options __xoptions = directory_options::none)
2799 : recursive_directory_iterator(__p, __xoptions, nullptr) {}
2800
2801 _LIBCPP_INLINE_VISIBILITY
2802 recursive_directory_iterator(const path& __p, directory_options __xoptions,
2803 error_code& __ec)
2804 : recursive_directory_iterator(__p, __xoptions, &__ec) {}
2805
2806 _LIBCPP_INLINE_VISIBILITY
2807 recursive_directory_iterator(const path& __p, error_code& __ec)
2808 : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
2809
2810 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2811 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2812
2813 recursive_directory_iterator&
2814 operator=(const recursive_directory_iterator&) = default;
2815
2816 _LIBCPP_INLINE_VISIBILITY
2817 recursive_directory_iterator&
2818 operator=(recursive_directory_iterator&& __o) noexcept {
2819 // non-default implementation provided to support self-move assign.
2820 if (this != &__o) {
2821 __imp_ = _VSTD::move(__o.__imp_);
2822 __rec_ = __o.__rec_;
2823 }
2824 return *this;
2825 }
2826
2827 ~recursive_directory_iterator() = default;
2828
2829 _LIBCPP_INLINE_VISIBILITY
2830 const directory_entry& operator*() const { return __dereference(); }
2831
2832 _LIBCPP_INLINE_VISIBILITY
2833 const directory_entry* operator->() const { return &__dereference(); }
2834
2835 recursive_directory_iterator& operator++() { return __increment(); }
2836
2837 _LIBCPP_INLINE_VISIBILITY
2838 __dir_element_proxy operator++(int) {
2839 __dir_element_proxy __p(**this);
2840 __increment();
2841 return __p;
2842 }
2843
2844 _LIBCPP_INLINE_VISIBILITY
2845 recursive_directory_iterator& increment(error_code& __ec) {
2846 return __increment(&__ec);
2847 }
2848
2849 _LIBCPP_FUNC_VIS directory_options options() const;
2850 _LIBCPP_FUNC_VIS int depth() const;
2851
2852 _LIBCPP_INLINE_VISIBILITY
2853 void pop() { __pop(); }
2854
2855 _LIBCPP_INLINE_VISIBILITY
2856 void pop(error_code& __ec) { __pop(&__ec); }
2857
2858 _LIBCPP_INLINE_VISIBILITY
2859 bool recursion_pending() const { return __rec_; }
2860
2861 _LIBCPP_INLINE_VISIBILITY
2862 void disable_recursion_pending() { __rec_ = false; }
2863
2864private:
Louis Dionne0ba10dc2019-08-13 15:02:53 +00002865 _LIBCPP_FUNC_VIS
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002866 recursive_directory_iterator(const path& __p, directory_options __opt,
2867 error_code* __ec);
2868
2869 _LIBCPP_FUNC_VIS
2870 const directory_entry& __dereference() const;
2871
2872 _LIBCPP_FUNC_VIS
2873 bool __try_recursion(error_code* __ec);
2874
2875 _LIBCPP_FUNC_VIS
2876 void __advance(error_code* __ec = nullptr);
2877
2878 _LIBCPP_FUNC_VIS
2879 recursive_directory_iterator& __increment(error_code* __ec = nullptr);
2880
2881 _LIBCPP_FUNC_VIS
2882 void __pop(error_code* __ec = nullptr);
2883
2884 inline _LIBCPP_INLINE_VISIBILITY friend bool
2885 operator==(const recursive_directory_iterator&,
2886 const recursive_directory_iterator&) noexcept;
2887
Louis Dionne48ae8892019-03-19 17:47:53 +00002888 struct _LIBCPP_HIDDEN __shared_imp;
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002889 shared_ptr<__shared_imp> __imp_;
2890 bool __rec_;
2891}; // class recursive_directory_iterator
2892
2893inline _LIBCPP_INLINE_VISIBILITY bool
2894operator==(const recursive_directory_iterator& __lhs,
2895 const recursive_directory_iterator& __rhs) noexcept {
2896 return __lhs.__imp_ == __rhs.__imp_;
2897}
2898
2899_LIBCPP_INLINE_VISIBILITY
2900inline bool operator!=(const recursive_directory_iterator& __lhs,
2901 const recursive_directory_iterator& __rhs) noexcept {
2902 return !(__lhs == __rhs);
2903}
2904// enable recursive_directory_iterator range-based for statements
2905inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2906begin(recursive_directory_iterator __iter) noexcept {
2907 return __iter;
2908}
2909
2910inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
2911end(const recursive_directory_iterator&) noexcept {
2912 return recursive_directory_iterator();
2913}
2914
Louis Dionnef6bf76a2019-03-20 21:18:14 +00002915_LIBCPP_AVAILABILITY_FILESYSTEM_POP
2916
Eric Fiselier02cea5e2018-07-27 03:07:09 +00002917_LIBCPP_END_NAMESPACE_FILESYSTEM
2918
2919#endif // !_LIBCPP_CXX03_LANG
2920
2921_LIBCPP_POP_MACROS
2922
2923#endif // _LIBCPP_FILESYSTEM