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