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