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