blob: 39750d9b4412d239075b4d118824d75914d37a35 [file] [log] [blame]
Eric Fiselier6e9a6942016-06-17 19:46:40 +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_EXPERIMENTAL_FILESYSTEM
11#define _LIBCPP_EXPERIMENTAL_FILESYSTEM
12/*
13 filesystem synopsis
14
15 namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
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
Eric Fiselier0b47a652018-02-04 03:10:53 +000031 // fs.path.io operators are friends of path.
Eric Fiselier6e9a6942016-06-17 19:46:40 +000032 template <class charT, class traits>
Eric Fiselier0b47a652018-02-04 03:10:53 +000033 friend basic_ostream<charT, traits>&
Eric Fiselier6e9a6942016-06-17 19:46:40 +000034 operator<<(basic_ostream<charT, traits>& os, const path& p);
35
36 template <class charT, class traits>
Eric Fiselier0b47a652018-02-04 03:10:53 +000037 friend basic_istream<charT, traits>&
Eric Fiselier6e9a6942016-06-17 19:46:40 +000038 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 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, const path& base=current_path());
79
80 path canonical(const path& p, const path& base = current_path());
81 path canonical(const path& p, error_code& ec);
82 path canonical(const path& p, const path& base, error_code& ec);
83
84 void copy(const path& from, const path& to);
Eric Fiseliera4c272d2017-10-30 18:59:59 +000085 void copy(const path& from, const path& to, error_code& ec);
Eric Fiselier6e9a6942016-06-17 19:46:40 +000086 void copy(const path& from, const path& to, copy_options options);
87 void copy(const path& from, const path& to, copy_options options,
Eric Fiseliera4c272d2017-10-30 18:59:59 +000088 error_code& ec);
Eric Fiselier6e9a6942016-06-17 19:46:40 +000089
90 bool copy_file(const path& from, const path& to);
91 bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT;
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) _NOEXCEPT;
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) _NOEXCEPT;
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 void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT;
183
184 path read_symlink(const path& p);
185 path read_symlink(const path& p, error_code& ec);
186
187 bool remove(const path& p);
188 bool remove(const path& p, error_code& ec) _NOEXCEPT;
189
190 uintmax_t remove_all(const path& p);
191 uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT;
192
193 void rename(const path& from, const path& to);
194 void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
195
196 void resize_file(const path& p, uintmax_t size);
197 void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT;
198
199 space_info space(const path& p);
200 space_info space(const path& p, error_code& ec) _NOEXCEPT;
201
202 file_status status(const path& p);
203 file_status status(const path& p, error_code& ec) _NOEXCEPT;
204
205 bool status_known(file_status s) _NOEXCEPT;
206
207 file_status symlink_status(const path& p);
208 file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
209
210 path system_complete(const path& p);
211 path system_complete(const path& p, error_code& ec);
212
213 path temp_directory_path();
214 path temp_directory_path(error_code& ec);
215
216} } } } // namespaces std::experimental::filesystem::v1
217
218*/
219
220#include <experimental/__config>
221#include <cstddef>
222#include <chrono>
223#include <iterator>
224#include <iosfwd>
225#include <locale>
226#include <memory>
227#include <stack>
228#include <string>
229#include <system_error>
230#include <utility>
231#include <iomanip> // for quoted
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000232#include <string_view>
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000233
234#include <__debug>
235
236#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
237#pragma GCC system_header
238#endif
239
240#define __cpp_lib_experimental_filesystem 201406
241
242_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
243
244typedef chrono::time_point<std::chrono::system_clock> file_time_type;
245
246struct _LIBCPP_TYPE_VIS space_info
247{
248 uintmax_t capacity;
249 uintmax_t free;
250 uintmax_t available;
251};
252
Eric Fiselier833d6442016-09-15 22:27:07 +0000253enum class _LIBCPP_ENUM_VIS file_type : signed char
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000254{
255 none = 0,
256 not_found = -1,
257 regular = 1,
258 directory = 2,
259 symlink = 3,
260 block = 4,
261 character = 5,
262 fifo = 6,
263 socket = 7,
264 unknown = 8
265};
266
Eric Fiselier833d6442016-09-15 22:27:07 +0000267enum class _LIBCPP_ENUM_VIS perms : unsigned
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000268{
269 none = 0,
270
271 owner_read = 0400,
272 owner_write = 0200,
273 owner_exec = 0100,
274 owner_all = 0700,
275
276 group_read = 040,
277 group_write = 020,
278 group_exec = 010,
279 group_all = 070,
280
281 others_read = 04,
282 others_write = 02,
283 others_exec = 01,
284 others_all = 07,
285
286 all = 0777,
287
288 set_uid = 04000,
289 set_gid = 02000,
290 sticky_bit = 01000,
291 mask = 07777,
292 unknown = 0xFFFF,
293
294 add_perms = 0x10000,
295 remove_perms = 0x20000,
Eric Fiselier7c96ddb2016-06-21 22:42:42 +0000296 symlink_nofollow = 0x40000
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000297};
298
299_LIBCPP_INLINE_VISIBILITY
300inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
301{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
302
303_LIBCPP_INLINE_VISIBILITY
304inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
305{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
306
307_LIBCPP_INLINE_VISIBILITY
308inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
309{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
310
311_LIBCPP_INLINE_VISIBILITY
312inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
313{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
314
315_LIBCPP_INLINE_VISIBILITY
316inline perms& operator&=(perms& _LHS, perms _RHS)
317{ return _LHS = _LHS & _RHS; }
318
319_LIBCPP_INLINE_VISIBILITY
320inline perms& operator|=(perms& _LHS, perms _RHS)
321{ return _LHS = _LHS | _RHS; }
322
323_LIBCPP_INLINE_VISIBILITY
324inline perms& operator^=(perms& _LHS, perms _RHS)
325{ return _LHS = _LHS ^ _RHS; }
326
Eric Fiselier833d6442016-09-15 22:27:07 +0000327enum class _LIBCPP_ENUM_VIS copy_options : unsigned short
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000328{
329 none = 0,
330 skip_existing = 1,
331 overwrite_existing = 2,
332 update_existing = 4,
333 recursive = 8,
334 copy_symlinks = 16,
335 skip_symlinks = 32,
336 directories_only = 64,
337 create_symlinks = 128,
338 create_hard_links = 256,
339 __in_recursive_copy = 512,
340};
341
342_LIBCPP_INLINE_VISIBILITY
343inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
344{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
345
346_LIBCPP_INLINE_VISIBILITY
347inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
348{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
349
350_LIBCPP_INLINE_VISIBILITY
351inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
352{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
353
354_LIBCPP_INLINE_VISIBILITY
355inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
356{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
357
358_LIBCPP_INLINE_VISIBILITY
359inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
360{ return _LHS = _LHS & _RHS; }
361
362_LIBCPP_INLINE_VISIBILITY
363inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
364{ return _LHS = _LHS | _RHS; }
365
366_LIBCPP_INLINE_VISIBILITY
367inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
368{ return _LHS = _LHS ^ _RHS; }
369
370
Eric Fiselier833d6442016-09-15 22:27:07 +0000371enum class _LIBCPP_ENUM_VIS directory_options : unsigned char
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000372{
373 none = 0,
374 follow_directory_symlink = 1,
375 skip_permission_denied = 2
376};
377
378_LIBCPP_INLINE_VISIBILITY
379inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
380{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
381
382_LIBCPP_INLINE_VISIBILITY
383inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
384{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
385
386_LIBCPP_INLINE_VISIBILITY
387inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
388{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
389
390_LIBCPP_INLINE_VISIBILITY
391inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
392{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
393
394_LIBCPP_INLINE_VISIBILITY
395inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
396{ return _LHS = _LHS & _RHS; }
397
398_LIBCPP_INLINE_VISIBILITY
399inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
400{ return _LHS = _LHS | _RHS; }
401
402_LIBCPP_INLINE_VISIBILITY
403inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
404{ return _LHS = _LHS ^ _RHS; }
405
406
407class _LIBCPP_TYPE_VIS file_status
408{
409public:
410 // constructors
411 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7c7df642017-03-06 21:02:06 +0000412 file_status() _NOEXCEPT : file_status(file_type::none) {}
413 _LIBCPP_INLINE_VISIBILITY
414 explicit file_status(file_type __ft,
415 perms __prms = perms::unknown) _NOEXCEPT
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000416 : __ft_(__ft), __prms_(__prms)
417 {}
418
419 file_status(const file_status&) _NOEXCEPT = default;
420 file_status(file_status&&) _NOEXCEPT = default;
421
422 _LIBCPP_INLINE_VISIBILITY
423 ~file_status() {}
424
425 file_status& operator=(const file_status&) _NOEXCEPT = default;
426 file_status& operator=(file_status&&) _NOEXCEPT = default;
427
428 // observers
429 _LIBCPP_ALWAYS_INLINE
430 file_type type() const _NOEXCEPT {
431 return __ft_;
432 }
433
434 _LIBCPP_ALWAYS_INLINE
435 perms permissions() const _NOEXCEPT {
436 return __prms_;
437 }
438
439 // modifiers
440 _LIBCPP_ALWAYS_INLINE
441 void type(file_type __ft) _NOEXCEPT {
442 __ft_ = __ft;
443 }
444
445 _LIBCPP_ALWAYS_INLINE
446 void permissions(perms __p) _NOEXCEPT {
447 __prms_ = __p;
448 }
449private:
450 file_type __ft_;
451 perms __prms_;
452};
453
454class _LIBCPP_TYPE_VIS directory_entry;
455
456template <class _Tp> struct __can_convert_char {
457 static const bool value = false;
458};
Eric Fiselier113315b2016-08-28 21:26:01 +0000459template <class _Tp> struct __can_convert_char<const _Tp>
460 : public __can_convert_char<_Tp> {
461};
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000462template <> struct __can_convert_char<char> {
463 static const bool value = true;
464 using __char_type = char;
465};
466template <> struct __can_convert_char<wchar_t> {
467 static const bool value = true;
468 using __char_type = wchar_t;
469};
470template <> struct __can_convert_char<char16_t> {
471 static const bool value = true;
472 using __char_type = char16_t;
473};
474template <> struct __can_convert_char<char32_t> {
475 static const bool value = true;
476 using __char_type = char32_t;
477};
478
479template <class _ECharT>
480typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
481__is_separator(_ECharT __e) {
482 return __e == _ECharT('/');
483};
484
485struct _NullSentinal {};
486
487template <class _Tp>
488using _Void = void;
489
490template <class _Tp, class = void>
491struct __is_pathable_string : public false_type {};
492
493template <class _ECharT, class _Traits, class _Alloc>
494struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
495 _Void<typename __can_convert_char<_ECharT>::__char_type>>
496: public __can_convert_char<_ECharT>
497{
498 using _Str = basic_string<_ECharT, _Traits, _Alloc>;
499 using _Base = __can_convert_char<_ECharT>;
500 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
501 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
502 static _ECharT __first_or_null(_Str const& __s) {
503 return __s.empty() ? _ECharT{} : __s[0];
504 }
505};
506
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000507
508template <class _ECharT, class _Traits>
509struct __is_pathable_string<basic_string_view<_ECharT, _Traits>,
510 _Void<typename __can_convert_char<_ECharT>::__char_type>>
511: public __can_convert_char<_ECharT>
512{
513 using _Str = basic_string_view<_ECharT, _Traits>;
514 using _Base = __can_convert_char<_ECharT>;
515 static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
516 static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
517 static _ECharT __first_or_null(_Str const& __s) {
518 return __s.empty() ? _ECharT{} : __s[0];
519 }
520};
521
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000522template <class _Source,
523 class _DS = typename decay<_Source>::type,
524 class _UnqualPtrType = typename remove_const<
525 typename remove_pointer<_DS>::type>::type,
526 bool _IsCharPtr = is_pointer<_DS>::value &&
527 __can_convert_char<_UnqualPtrType>::value
528 >
529struct __is_pathable_char_array : false_type {};
530
531template <class _Source, class _ECharT, class _UPtr>
532struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
533 : __can_convert_char<typename remove_const<_ECharT>::type>
534{
535 using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
536
537 static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
538 static _ECharT const* __range_end(const _ECharT* __b)
539 {
540 using _Iter = const _ECharT*;
541 const _ECharT __sentinal = _ECharT{};
542 _Iter __e = __b;
543 for (; *__e != __sentinal; ++__e)
544 ;
545 return __e;
546 }
547
548 static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
549};
550
551template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
552struct __is_pathable_iter : false_type {};
553
554template <class _Iter>
555struct __is_pathable_iter<_Iter, true,
556 _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
557 : __can_convert_char<typename iterator_traits<_Iter>::value_type>
558{
559 using _ECharT = typename iterator_traits<_Iter>::value_type;
560 using _Base = __can_convert_char<_ECharT>;
561
562 static _Iter __range_begin(_Iter __b) { return __b; }
563 static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
564
565 static _ECharT __first_or_null(_Iter __b) { return *__b; }
566};
567
568template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
569 bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
570 bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
571 >
572struct __is_pathable : false_type {
573 static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
574};
575
576template <class _Tp>
577struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
578
579
580template <class _Tp>
581struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
582
583
584template <class _Tp>
585struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
586
587
588template <class _ECharT>
589struct _PathCVT {
590 static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
591
592 typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
593
594 static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) {
595 _Narrower()(back_inserter(__dest), __b, __e);
596 }
597
598 template <class _Iter>
599 static void __append_range(string& __dest, _Iter __b, _Iter __e) {
600 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
601 if (__b == __e) return;
602 basic_string<_ECharT> __tmp(__b, __e);
603 _Narrower()(back_inserter(__dest), __tmp.data(),
604 __tmp.data() + __tmp.length());
605 }
606
607 template <class _Iter>
608 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
609 static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
610 const _ECharT __sentinal = _ECharT{};
611 if (*__b == __sentinal) return;
612 basic_string<_ECharT> __tmp;
613 for (; *__b != __sentinal; ++__b)
614 __tmp.push_back(*__b);
615 _Narrower()(back_inserter(__dest), __tmp.data(),
616 __tmp.data() + __tmp.length());
617 }
618
619 template <class _Source>
620 static void __append_source(string& __dest, _Source const& __s)
621 {
622 using _Traits = __is_pathable<_Source>;
623 __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
624 }
625};
626
627template <>
628struct _PathCVT<char> {
Eric Fiselierad1a12c2016-10-30 23:53:50 +0000629
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000630 template <class _Iter>
Eric Fiselier026d38e2016-10-31 02:46:25 +0000631 static typename enable_if<
632 __is_exactly_input_iterator<_Iter>::value
633 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
634 for (; __b != __e; ++__b)
635 __dest.push_back(*__b);
636 }
637
638 template <class _Iter>
639 static typename enable_if<
640 __is_forward_iterator<_Iter>::value
641 >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
642 __dest.__append_forward_unsafe(__b, __e);
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000643 }
644
645 template <class _Iter>
646 static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
647 const char __sentinal = char{};
648 for (; *__b != __sentinal; ++__b)
649 __dest.push_back(*__b);
650 }
651
652 template <class _Source>
653 static void __append_source(string& __dest, _Source const& __s)
654 {
655 using _Traits = __is_pathable<_Source>;
Eric Fiselierad1a12c2016-10-30 23:53:50 +0000656 __append_range(__dest, _Traits::__range_begin(__s),
657 _Traits::__range_end(__s));
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000658 }
659};
660
661
662class _LIBCPP_TYPE_VIS path
663{
664 template <class _SourceOrIter, class _Tp = path&>
665 using _EnableIfPathable = typename
666 enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
667
668 template <class _Tp>
669 using _SourceChar = typename __is_pathable<_Tp>::__char_type;
670
671 template <class _Tp>
672 using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
673
674public:
675 typedef char value_type;
676 typedef basic_string<value_type> string_type;
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000677 typedef _VSTD::string_view __string_view;
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000678 static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
679
680 // constructors and destructor
681 _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
682 _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
683 _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
684
685 _LIBCPP_INLINE_VISIBILITY
686 path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {}
687
688 template <
689 class _Source,
690 class = _EnableIfPathable<_Source, void>
691 >
692 path(const _Source& __src) {
693 _SourceCVT<_Source>::__append_source(__pn_, __src);
694 }
695
696 template <class _InputIt>
697 path(_InputIt __first, _InputIt __last) {
698 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
699 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
700 }
701
702 // TODO Implement locale conversions.
703 template <class _Source,
704 class = _EnableIfPathable<_Source, void>
705 >
706 path(const _Source& __src, const locale& __loc);
707 template <class _InputIt>
708 path(_InputIt __first, _InputIt _last, const locale& __loc);
709
710 _LIBCPP_INLINE_VISIBILITY
711 ~path() = default;
712
713 // assignments
714 _LIBCPP_INLINE_VISIBILITY
715 path& operator=(const path& __p) {
716 __pn_ = __p.__pn_;
717 return *this;
718 }
719
720 _LIBCPP_INLINE_VISIBILITY
721 path& operator=(path&& __p) _NOEXCEPT {
722 __pn_ = _VSTD::move(__p.__pn_);
723 return *this;
724 }
725
Eric Fiselierf2b48892017-01-18 05:48:55 +0000726 template <class = void>
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000727 _LIBCPP_INLINE_VISIBILITY
728 path& operator=(string_type&& __s) _NOEXCEPT {
729 __pn_ = _VSTD::move(__s);
730 return *this;
731 }
732
733 _LIBCPP_INLINE_VISIBILITY
734 path& assign(string_type&& __s) _NOEXCEPT {
735 __pn_ = _VSTD::move(__s);
736 return *this;
737 }
738
739 template <class _Source>
740 _LIBCPP_INLINE_VISIBILITY
741 _EnableIfPathable<_Source>
742 operator=(const _Source& __src)
743 { return this->assign(__src); }
744
745
746 template <class _Source>
747 _EnableIfPathable<_Source>
748 assign(const _Source& __src) {
749 __pn_.clear();
750 _SourceCVT<_Source>::__append_source(__pn_, __src);
751 return *this;
752 }
753
754 template <class _InputIt>
755 path& assign(_InputIt __first, _InputIt __last) {
756 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
757 __pn_.clear();
758 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
759 return *this;
760 }
761
762private:
763 template <class _ECharT>
764 void __append_sep_if_needed(_ECharT __first_or_null) {
765 const _ECharT __null_val = {};
766 bool __append_sep = !empty() &&
767 !__is_separator(__pn_.back()) &&
768 __first_or_null != __null_val && // non-empty
769 !__is_separator(__first_or_null);
770 if (__append_sep)
771 __pn_ += preferred_separator;
772 }
773
774public:
775 // appends
776 path& operator/=(const path& __p) {
Eric Fiselier4ca4e502016-10-15 21:29:44 +0000777 _LIBCPP_ASSERT(!__p.has_root_name(),
778 "cannot append to a path with a root name");
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000779 __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
780 __pn_ += __p.native();
781 return *this;
782 }
783
784 template <class _Source>
785 _LIBCPP_INLINE_VISIBILITY
786 _EnableIfPathable<_Source>
787 operator/=(const _Source& __src) {
788 return this->append(__src);
789 }
790
791 template <class _Source>
792 _EnableIfPathable<_Source>
793 append(const _Source& __src) {
794 using _Traits = __is_pathable<_Source>;
795 using _CVT = _PathCVT<_SourceChar<_Source>>;
796 __append_sep_if_needed(_Traits::__first_or_null(__src));
797 _CVT::__append_source(__pn_, __src);
798 return *this;
799 }
800
801 template <class _InputIt>
802 path& append(_InputIt __first, _InputIt __last) {
803 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
804 static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
805 using _CVT = _PathCVT<_ItVal>;
806 if (__first != __last) {
807 __append_sep_if_needed(*__first);
808 _CVT::__append_range(__pn_, __first, __last);
809 }
810 return *this;
811 }
812
813 // concatenation
814 _LIBCPP_INLINE_VISIBILITY
815 path& operator+=(const path& __x) {
816 __pn_ += __x.__pn_;
817 return *this;
818 }
819
820 _LIBCPP_INLINE_VISIBILITY
821 path& operator+=(const string_type& __x) {
822 __pn_ += __x;
823 return *this;
824 }
825
826 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000827 path& operator+=(__string_view __x) {
828 __pn_ += __x;
829 return *this;
830 }
831
832 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000833 path& operator+=(const value_type* __x) {
834 __pn_ += __x;
835 return *this;
836 }
837
838 _LIBCPP_INLINE_VISIBILITY
839 path& operator+=(value_type __x) {
840 __pn_ += __x;
841 return *this;
842 }
843
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000844 template <class _ECharT>
845 typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
846 operator+=(_ECharT __x)
847 {
848 basic_string<_ECharT> __tmp;
849 __tmp += __x;
850 _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
851 return *this;
852 }
853
854 template <class _Source>
855 _EnableIfPathable<_Source>
856 operator+=(const _Source& __x) {
857 return this->concat(__x);
858 }
859
860 template <class _Source>
861 _EnableIfPathable<_Source>
862 concat(const _Source& __x) {
863 _SourceCVT<_Source>::__append_source(__pn_, __x);
864 return *this;
865 }
866
867 template <class _InputIt>
868 path& concat(_InputIt __first, _InputIt __last) {
869 typedef typename iterator_traits<_InputIt>::value_type _ItVal;
870 _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
871 return *this;
872 }
873
874 // modifiers
875 _LIBCPP_INLINE_VISIBILITY
876 void clear() _NOEXCEPT {
877 __pn_.clear();
878 }
879
880 path& make_preferred() { return *this; }
Eric Fiselier620a9a52016-10-15 22:37:42 +0000881
882 _LIBCPP_INLINE_VISIBILITY
883 path& remove_filename() {
884 if (__pn_.size() == __root_path_raw().size())
885 clear();
886 else
887 __pn_ = __parent_path();
888 return *this;
889 }
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000890
891 path& replace_filename(const path& __replacement) {
892 remove_filename();
893 return (*this /= __replacement);
894 }
895
896 path& replace_extension(const path& __replacement = path());
897
898 _LIBCPP_INLINE_VISIBILITY
899 void swap(path& __rhs) _NOEXCEPT {
900 __pn_.swap(__rhs.__pn_);
901 }
902
903 // native format observers
904 _LIBCPP_INLINE_VISIBILITY
905 const string_type& native() const _NOEXCEPT {
906 return __pn_;
907 }
908
909 _LIBCPP_INLINE_VISIBILITY
910 const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
911
912 _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
913
914 template <class _ECharT, class _Traits = char_traits<_ECharT>,
915 class _Allocator = allocator<_ECharT> >
916 basic_string<_ECharT, _Traits, _Allocator>
917 string(const _Allocator& __a = _Allocator()) const {
918 using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
919 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
920 _Str __s(__a);
921 __s.reserve(__pn_.size());
922 _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
923 return __s;
924 }
925
926 _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
927 _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); }
928 _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
929 _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
930 _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
931
932 // generic format observers
933 template <class _ECharT, class _Traits = char_traits<_ECharT>,
934 class _Allocator = allocator<_ECharT>
935 >
936 basic_string<_ECharT, _Traits, _Allocator>
937 generic_string(const _Allocator& __a = _Allocator()) const {
938 return string<_ECharT, _Traits, _Allocator>(__a);
939 }
940
941 std::string generic_string() const { return __pn_; }
942 std::wstring generic_wstring() const { return string<wchar_t>(); }
943 std::string generic_u8string() const { return __pn_; }
944 std::u16string generic_u16string() const { return string<char16_t>(); }
945 std::u32string generic_u32string() const { return string<char32_t>(); }
946
947private:
Saleem Abdulrasool52241cb2017-01-30 03:58:26 +0000948 int __compare(__string_view) const;
949 __string_view __root_name() const;
950 __string_view __root_directory() const;
951 __string_view __root_path_raw() const;
952 __string_view __relative_path() const;
953 __string_view __parent_path() const;
954 __string_view __filename() const;
955 __string_view __stem() const;
956 __string_view __extension() const;
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000957
958public:
959 // compare
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000960 _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);}
961 _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); }
962 _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000963 _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); }
964
965 // decomposition
Eric Fiselier2645dbe2016-07-23 03:10:56 +0000966 _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); }
967 _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); }
968 _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); }
969 _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); }
970 _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); }
971 _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); }
972 _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());}
973 _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000974
975 // query
Marshall Clowbc6989b2017-11-16 05:48:32 +0000976 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
977 bool empty() const _NOEXCEPT { return __pn_.empty(); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000978
979 _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); }
980 _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
Eric Fiselier620a9a52016-10-15 22:37:42 +0000981 _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000982 _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); }
983 _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); }
984 _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); }
985 _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
986 _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); }
987
988 _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
989 _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
990
991 // iterators
992 class _LIBCPP_TYPE_VIS iterator;
993 typedef iterator const_iterator;
994
Saleem Abdulrasool52241cb2017-01-30 03:58:26 +0000995 iterator begin() const;
996 iterator end() const;
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000997
Eric Fiselier0b47a652018-02-04 03:10:53 +0000998
999 template <class _CharT, class _Traits>
1000 _LIBCPP_INLINE_VISIBILITY
1001 friend typename enable_if<is_same<_CharT, char>::value &&
1002 is_same<_Traits, char_traits<char>>::value,
1003 basic_ostream<_CharT, _Traits>&
1004 >::type
1005 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1006 __os << std::__quoted(__p.native());
1007 return __os;
1008 }
1009
1010 template <class _CharT, class _Traits>
1011 _LIBCPP_INLINE_VISIBILITY
1012 friend typename enable_if<!is_same<_CharT, char>::value ||
1013 !is_same<_Traits, char_traits<char>>::value,
1014 basic_ostream<_CharT, _Traits>&
1015 >::type
1016 operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1017 __os << std::__quoted(__p.string<_CharT, _Traits>());
1018 return __os;
1019 }
1020
1021 template <class _CharT, class _Traits>
1022 _LIBCPP_INLINE_VISIBILITY
1023 friend basic_istream<_CharT, _Traits>&
1024 operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
1025 {
1026 basic_string<_CharT, _Traits> __tmp;
1027 __is >> __quoted(__tmp);
1028 __p = __tmp;
1029 return __is;
1030 }
1031
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001032private:
1033 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier2645dbe2016-07-23 03:10:56 +00001034 path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; }
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001035 string_type __pn_;
1036};
1037
1038inline _LIBCPP_ALWAYS_INLINE
1039void swap(path& __lhs, path& __rhs) _NOEXCEPT {
1040 __lhs.swap(__rhs);
1041}
1042
1043_LIBCPP_FUNC_VIS
1044size_t hash_value(const path& __p) _NOEXCEPT;
1045
1046inline _LIBCPP_INLINE_VISIBILITY
1047bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
1048{ return __lhs.compare(__rhs) == 0; }
1049
1050inline _LIBCPP_INLINE_VISIBILITY
1051bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
1052{ return __lhs.compare(__rhs) != 0; }
1053
1054inline _LIBCPP_INLINE_VISIBILITY
1055bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
1056{ return __lhs.compare(__rhs) < 0; }
1057
1058inline _LIBCPP_INLINE_VISIBILITY
1059bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
1060{ return __lhs.compare(__rhs) <= 0; }
1061
1062inline _LIBCPP_INLINE_VISIBILITY
1063bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
1064{ return __lhs.compare(__rhs) > 0; }
1065
1066inline _LIBCPP_INLINE_VISIBILITY
1067bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
1068{ return __lhs.compare(__rhs) >= 0; }
1069
1070inline _LIBCPP_INLINE_VISIBILITY
1071path operator/(const path& __lhs, const path& __rhs) {
1072 return path(__lhs) /= __rhs;
1073}
1074
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001075template <class _Source>
1076_LIBCPP_INLINE_VISIBILITY
1077typename enable_if<__is_pathable<_Source>::value, path>::type
1078u8path(const _Source& __s){
1079 static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1080 "u8path(Source const&) requires Source have a character type of type 'char'");
1081 return path(__s);
1082}
1083
1084template <class _InputIt>
1085_LIBCPP_INLINE_VISIBILITY
1086typename enable_if<__is_pathable<_InputIt>::value, path>::type
1087u8path(_InputIt __f, _InputIt __l) {
1088 static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1089 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
1090 return path(__f, __l);
1091}
1092
1093class _LIBCPP_TYPE_VIS path::iterator
1094{
1095public:
1096 typedef bidirectional_iterator_tag iterator_category;
Eric Fiselier08673732017-04-04 01:05:59 +00001097
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001098 typedef path value_type;
1099 typedef std::ptrdiff_t difference_type;
1100 typedef const path* pointer;
1101 typedef const path& reference;
Eric Fiselier706e2c72017-04-13 02:54:13 +00001102
1103 typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001104public:
1105 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier271a19e2016-10-30 23:30:38 +00001106 iterator() : __stashed_elem_(), __path_ptr_(nullptr),
1107 __entry_(), __state_(__singular) {}
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001108
1109 iterator(const iterator&) = default;
1110 ~iterator() = default;
1111
1112 iterator& operator=(const iterator&) = default;
1113
1114 _LIBCPP_INLINE_VISIBILITY
1115 reference operator*() const {
Eric Fiselier271a19e2016-10-30 23:30:38 +00001116 return __stashed_elem_;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001117 }
1118
1119 _LIBCPP_INLINE_VISIBILITY
1120 pointer operator->() const {
Eric Fiselier271a19e2016-10-30 23:30:38 +00001121 return &__stashed_elem_;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001122 }
1123
1124 _LIBCPP_INLINE_VISIBILITY
1125 iterator& operator++() {
Eric Fiselier271a19e2016-10-30 23:30:38 +00001126 _LIBCPP_ASSERT(__state_ != __singular,
1127 "attempting to increment a singular iterator");
1128 _LIBCPP_ASSERT(__state_ != __at_end,
1129 "attempting to increment the end iterator");
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001130 return __increment();
1131 }
1132
1133 _LIBCPP_INLINE_VISIBILITY
1134 iterator operator++(int) {
1135 iterator __it(*this);
1136 this->operator++();
1137 return __it;
1138 }
1139
1140 _LIBCPP_INLINE_VISIBILITY
1141 iterator& operator--() {
Eric Fiselier271a19e2016-10-30 23:30:38 +00001142 _LIBCPP_ASSERT(__state_ != __singular,
1143 "attempting to decrement a singular iterator");
1144 _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1145 "attempting to decrement the begin iterator");
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001146 return __decrement();
1147 }
1148
1149 _LIBCPP_INLINE_VISIBILITY
1150 iterator operator--(int) {
1151 iterator __it(*this);
1152 this->operator--();
1153 return __it;
1154 }
1155
1156private:
1157 friend class path;
Eric Fiselier03f7d102016-09-16 00:07:16 +00001158
Eric Fiselier271a19e2016-10-30 23:30:38 +00001159 static constexpr unsigned char __singular = 0;
1160 static constexpr unsigned char __at_end = 6;
1161
Eric Fiselier03f7d102016-09-16 00:07:16 +00001162 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001163 friend bool operator==(const iterator&, const iterator&);
1164
Saleem Abdulrasool52241cb2017-01-30 03:58:26 +00001165 iterator& __increment();
1166 iterator& __decrement();
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001167
Eric Fiselier271a19e2016-10-30 23:30:38 +00001168 path __stashed_elem_;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001169 const path* __path_ptr_;
Eric Fiselier271a19e2016-10-30 23:30:38 +00001170 path::__string_view __entry_;
1171 unsigned char __state_;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001172};
1173
1174inline _LIBCPP_INLINE_VISIBILITY
1175bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
1176 return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
Eric Fiselier271a19e2016-10-30 23:30:38 +00001177 __lhs.__entry_.data() == __rhs.__entry_.data();
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001178}
1179
1180inline _LIBCPP_INLINE_VISIBILITY
1181bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1182 return !(__lhs == __rhs);
1183}
1184
1185class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
1186{
1187public:
1188 _LIBCPP_INLINE_VISIBILITY
1189 filesystem_error(const string& __what, error_code __ec)
1190 : system_error(__ec, __what),
1191 __paths_(make_shared<_Storage>(path(), path()))
1192 {}
1193
1194 _LIBCPP_INLINE_VISIBILITY
1195 filesystem_error(const string& __what, const path& __p1, error_code __ec)
1196 : system_error(__ec, __what),
1197 __paths_(make_shared<_Storage>(__p1, path()))
1198 {}
1199
1200 _LIBCPP_INLINE_VISIBILITY
1201 filesystem_error(const string& __what, const path& __p1, const path& __p2,
1202 error_code __ec)
1203 : system_error(__ec, __what),
1204 __paths_(make_shared<_Storage>(__p1, __p2))
1205 {}
1206
1207 _LIBCPP_INLINE_VISIBILITY
1208 const path& path1() const _NOEXCEPT {
1209 return __paths_->first;
1210 }
1211
1212 _LIBCPP_INLINE_VISIBILITY
1213 const path& path2() const _NOEXCEPT {
1214 return __paths_->second;
1215 }
1216
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001217 ~filesystem_error() override; // key function
1218
1219 // TODO(ericwf): Create a custom error message.
1220 //const char* what() const _NOEXCEPT;
1221
1222private:
1223 typedef pair<path, path> _Storage;
1224 shared_ptr<_Storage> __paths_;
1225};
1226
Marshall Clowe7acb0e2016-08-25 17:47:09 +00001227template <class... _Args>
1228_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001229#ifndef _LIBCPP_NO_EXCEPTIONS
Marshall Clowe7acb0e2016-08-25 17:47:09 +00001230void __throw_filesystem_error(_Args && ...__args)
1231{
Marshall Clowe7acb0e2016-08-25 17:47:09 +00001232 throw filesystem_error(std::forward<_Args>(__args)...);
Marshall Clowe7acb0e2016-08-25 17:47:09 +00001233}
Eric Fiselier0e5ebbc2016-12-23 23:37:52 +00001234#else
1235void __throw_filesystem_error(_Args&&...)
1236{
1237 _VSTD::abort();
1238}
1239#endif
1240
Marshall Clowe7acb0e2016-08-25 17:47:09 +00001241
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001242// operational functions
1243
1244_LIBCPP_FUNC_VIS
1245path __canonical(const path&, const path&, error_code *__ec=nullptr);
1246_LIBCPP_FUNC_VIS
1247void __copy(const path& __from, const path& __to, copy_options __opt,
1248 error_code *__ec=nullptr);
1249_LIBCPP_FUNC_VIS
1250bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1251 error_code *__ec=nullptr);
1252_LIBCPP_FUNC_VIS
1253void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1254 error_code *__ec=nullptr);
1255_LIBCPP_FUNC_VIS
1256bool __create_directories(const path& p, error_code *ec=nullptr);
1257_LIBCPP_FUNC_VIS
1258bool __create_directory(const path& p, error_code *ec=nullptr);
1259_LIBCPP_FUNC_VIS
1260bool __create_directory(const path& p, const path & attributes,
1261 error_code *ec=nullptr);
1262_LIBCPP_FUNC_VIS
1263void __create_directory_symlink(const path& __to, const path& __new_symlink,
1264 error_code *__ec=nullptr);
1265_LIBCPP_FUNC_VIS
1266void __create_hard_link(const path& __to, const path& __new_hard_link,
1267 error_code *__ec=nullptr);
1268_LIBCPP_FUNC_VIS
1269void __create_symlink(const path& __to, const path& __new_symlink,
1270 error_code *__ec=nullptr);
1271_LIBCPP_FUNC_VIS
1272path __current_path(error_code *__ec=nullptr);
1273_LIBCPP_FUNC_VIS
1274void __current_path(const path&, error_code *__ec=nullptr);
1275_LIBCPP_FUNC_VIS
1276bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
1277_LIBCPP_FUNC_VIS
1278uintmax_t __file_size(const path&, error_code *__ec=nullptr);
1279_LIBCPP_FUNC_VIS
1280uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
1281_LIBCPP_FUNC_VIS
1282bool __fs_is_empty(const path& p, error_code *ec=nullptr);
1283_LIBCPP_FUNC_VIS
1284file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
1285_LIBCPP_FUNC_VIS
1286void __last_write_time(const path& p, file_time_type new_time,
1287 error_code *ec=nullptr);
1288_LIBCPP_FUNC_VIS
1289void __permissions(const path& p, perms prms, error_code *ec=nullptr);
1290_LIBCPP_FUNC_VIS
1291path __read_symlink(const path& p, error_code *ec=nullptr);
1292_LIBCPP_FUNC_VIS
1293bool __remove(const path& p, error_code *ec=nullptr);
1294_LIBCPP_FUNC_VIS
1295uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
1296_LIBCPP_FUNC_VIS
1297void __rename(const path& from, const path& to, error_code *ec=nullptr);
1298_LIBCPP_FUNC_VIS
1299void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
1300_LIBCPP_FUNC_VIS
1301space_info __space(const path&, error_code *__ec=nullptr);
1302_LIBCPP_FUNC_VIS
1303file_status __status(const path&, error_code *__ec=nullptr);
1304_LIBCPP_FUNC_VIS
1305file_status __symlink_status(const path&, error_code *__ec=nullptr);
1306_LIBCPP_FUNC_VIS
1307path __system_complete(const path&, error_code *__ec=nullptr);
1308_LIBCPP_FUNC_VIS
1309path __temp_directory_path(error_code *__ec=nullptr);
1310
1311inline _LIBCPP_INLINE_VISIBILITY
1312path current_path() {
1313 return __current_path();
1314}
1315
1316inline _LIBCPP_INLINE_VISIBILITY
1317path current_path(error_code& __ec) {
1318 return __current_path(&__ec);
1319}
1320
1321inline _LIBCPP_INLINE_VISIBILITY
1322void current_path(const path& __p) {
1323 __current_path(__p);
1324}
1325
1326inline _LIBCPP_INLINE_VISIBILITY
1327void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
1328 __current_path(__p, &__ec);
1329}
1330
1331_LIBCPP_FUNC_VIS
1332path absolute(const path&, const path& __p2 = current_path());
1333
1334inline _LIBCPP_INLINE_VISIBILITY
1335path canonical(const path& __p, const path& __base = current_path()) {
1336 return __canonical(__p, __base);
1337}
1338
1339inline _LIBCPP_INLINE_VISIBILITY
1340path canonical(const path& __p, error_code& __ec) {
1341 path __base = __current_path(&__ec);
1342 if (__ec) return {};
1343 return __canonical(__p, __base, &__ec);
1344}
1345
1346inline _LIBCPP_INLINE_VISIBILITY
1347path canonical(const path& __p, const path& __base, error_code& __ec) {
1348 return __canonical(__p, __base, &__ec);
1349}
1350
1351inline _LIBCPP_INLINE_VISIBILITY
1352void copy(const path& __from, const path& __to) {
1353 __copy(__from, __to, copy_options::none);
1354}
1355
1356inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001357void copy(const path& __from, const path& __to, error_code& __ec) {
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001358 __copy(__from, __to, copy_options::none, &__ec);
1359}
1360
1361inline _LIBCPP_INLINE_VISIBILITY
1362void copy(const path& __from, const path& __to, copy_options __opt) {
1363 __copy(__from, __to, __opt);
1364}
1365
1366inline _LIBCPP_INLINE_VISIBILITY
1367void copy(const path& __from, const path& __to,
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001368 copy_options __opt, error_code& __ec) {
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001369 __copy(__from, __to, __opt, &__ec);
1370}
1371
1372inline _LIBCPP_INLINE_VISIBILITY
1373bool copy_file(const path& __from, const path& __to) {
1374 return __copy_file(__from, __to, copy_options::none);
1375}
1376
1377inline _LIBCPP_INLINE_VISIBILITY
1378bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1379 return __copy_file(__from, __to, copy_options::none, &__ec);
1380}
1381
1382inline _LIBCPP_INLINE_VISIBILITY
1383bool copy_file(const path& __from, const path& __to, copy_options __opt) {
1384 return __copy_file(__from, __to, __opt);
1385}
1386
1387inline _LIBCPP_INLINE_VISIBILITY
1388bool copy_file(const path& __from, const path& __to,
1389 copy_options __opt, error_code& __ec) _NOEXCEPT {
1390 return __copy_file(__from, __to, __opt, &__ec);
1391}
1392
1393inline _LIBCPP_INLINE_VISIBILITY
1394void copy_symlink(const path& __existing, const path& __new) {
1395 __copy_symlink(__existing, __new);
1396}
1397
1398inline _LIBCPP_INLINE_VISIBILITY
1399void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
1400 __copy_symlink(__ext, __new, &__ec);
1401}
1402
1403inline _LIBCPP_INLINE_VISIBILITY
1404bool create_directories(const path& __p) {
1405 return __create_directories(__p);
1406}
1407
1408inline _LIBCPP_INLINE_VISIBILITY
1409bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT {
1410 return __create_directories(__p, &__ec);
1411}
1412
1413inline _LIBCPP_INLINE_VISIBILITY
1414bool create_directory(const path& __p) {
1415 return __create_directory(__p);
1416}
1417
1418inline _LIBCPP_INLINE_VISIBILITY
1419bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1420 return __create_directory(__p, &__ec);
1421}
1422
1423inline _LIBCPP_INLINE_VISIBILITY
1424bool create_directory(const path& __p, const path& __attrs) {
1425 return __create_directory(__p, __attrs);
1426}
1427
1428inline _LIBCPP_INLINE_VISIBILITY
1429bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
1430 return __create_directory(__p, __attrs, &__ec);
1431}
1432
1433inline _LIBCPP_INLINE_VISIBILITY
1434void create_directory_symlink(const path& __to, const path& __new) {
1435 __create_directory_symlink(__to, __new);
1436}
1437
1438inline _LIBCPP_INLINE_VISIBILITY
1439void create_directory_symlink(const path& __to, const path& __new,
1440 error_code& __ec) _NOEXCEPT {
1441 __create_directory_symlink(__to, __new, &__ec);
1442}
1443
1444inline _LIBCPP_INLINE_VISIBILITY
1445void create_hard_link(const path& __to, const path& __new) {
1446 __create_hard_link(__to, __new);
1447}
1448
1449inline _LIBCPP_INLINE_VISIBILITY
1450void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1451 __create_hard_link(__to, __new, &__ec);
1452}
1453
1454inline _LIBCPP_INLINE_VISIBILITY
1455void create_symlink(const path& __to, const path& __new) {
1456 __create_symlink(__to, __new);
1457}
1458
1459inline _LIBCPP_INLINE_VISIBILITY
1460void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1461 return __create_symlink(__to, __new, &__ec);
1462}
1463
1464inline _LIBCPP_INLINE_VISIBILITY
1465bool status_known(file_status __s) _NOEXCEPT {
1466 return __s.type() != file_type::none;
1467}
1468
1469inline _LIBCPP_INLINE_VISIBILITY
1470bool exists(file_status __s) _NOEXCEPT {
1471 return status_known(__s) && __s.type() != file_type::not_found;
1472}
1473
1474inline _LIBCPP_INLINE_VISIBILITY
1475bool exists(const path& __p) {
1476 return exists(__status(__p));
1477}
1478
1479inline _LIBCPP_INLINE_VISIBILITY
1480bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
Eric Fiselier756a6bd2016-06-21 22:11:16 +00001481 auto __s = __status(__p, &__ec);
1482 if (status_known(__s)) __ec.clear();
1483 return exists(__s);
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001484}
1485
1486inline _LIBCPP_INLINE_VISIBILITY
1487bool equivalent(const path& __p1, const path& __p2) {
1488 return __equivalent(__p1, __p2);
1489}
1490
1491inline _LIBCPP_INLINE_VISIBILITY
1492bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
1493 return __equivalent(__p1, __p2, &__ec);
1494}
1495
1496inline _LIBCPP_INLINE_VISIBILITY
1497uintmax_t file_size(const path& __p) {
1498 return __file_size(__p);
1499}
1500
1501inline _LIBCPP_INLINE_VISIBILITY
1502uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
1503 return __file_size(__p, &__ec);
1504}
1505
1506inline _LIBCPP_INLINE_VISIBILITY
1507uintmax_t hard_link_count(const path& __p) {
1508 return __hard_link_count(__p);
1509}
1510
1511inline _LIBCPP_INLINE_VISIBILITY
1512uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
1513 return __hard_link_count(__p, &__ec);
1514}
1515
1516inline _LIBCPP_INLINE_VISIBILITY
1517bool is_block_file(file_status __s) _NOEXCEPT {
1518 return __s.type() == file_type::block;
1519}
1520
1521inline _LIBCPP_INLINE_VISIBILITY
1522bool is_block_file(const path& __p) {
1523 return is_block_file(__status(__p));
1524}
1525
1526inline _LIBCPP_INLINE_VISIBILITY
1527bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
1528 return is_block_file(__status(__p, &__ec));
1529}
1530
1531inline _LIBCPP_INLINE_VISIBILITY
1532bool is_character_file(file_status __s) _NOEXCEPT {
1533 return __s.type() == file_type::character;
1534}
1535
1536inline _LIBCPP_INLINE_VISIBILITY
1537bool is_character_file(const path& __p) {
1538 return is_character_file(__status(__p));
1539}
1540
1541inline _LIBCPP_INLINE_VISIBILITY
1542bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
1543 return is_character_file(__status(__p, &__ec));
1544}
1545
1546inline _LIBCPP_INLINE_VISIBILITY
1547bool is_directory(file_status __s) _NOEXCEPT {
1548 return __s.type() == file_type::directory;
1549}
1550
1551inline _LIBCPP_INLINE_VISIBILITY
1552bool is_directory(const path& __p) {
1553 return is_directory(__status(__p));
1554}
1555
1556inline _LIBCPP_INLINE_VISIBILITY
1557bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1558 return is_directory(__status(__p, &__ec));
1559}
1560
1561inline _LIBCPP_INLINE_VISIBILITY
1562bool is_empty(const path& __p) {
1563 return __fs_is_empty(__p);
1564}
1565
1566inline _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001567bool is_empty(const path& __p, error_code& __ec) {
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001568 return __fs_is_empty(__p, &__ec);
1569}
1570
1571inline _LIBCPP_INLINE_VISIBILITY
1572bool is_fifo(file_status __s) _NOEXCEPT {
1573 return __s.type() == file_type::fifo;
1574}
1575inline _LIBCPP_INLINE_VISIBILITY
1576bool is_fifo(const path& __p) {
1577 return is_fifo(__status(__p));
1578}
1579
1580inline _LIBCPP_INLINE_VISIBILITY
1581bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
1582 return is_fifo(__status(__p, &__ec));
1583}
1584
1585inline _LIBCPP_INLINE_VISIBILITY
1586bool is_regular_file(file_status __s) _NOEXCEPT {
1587 return __s.type() == file_type::regular;
1588}
1589
1590inline _LIBCPP_INLINE_VISIBILITY
1591bool is_regular_file(const path& __p) {
1592 return is_regular_file(__status(__p));
1593}
1594
1595inline _LIBCPP_INLINE_VISIBILITY
1596bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
1597 return is_regular_file(__status(__p, &__ec));
1598}
1599
1600inline _LIBCPP_INLINE_VISIBILITY
1601bool is_socket(file_status __s) _NOEXCEPT {
1602 return __s.type() == file_type::socket;
1603}
1604
1605inline _LIBCPP_INLINE_VISIBILITY
1606bool is_socket(const path& __p) {
1607 return is_socket(__status(__p));
1608}
1609
1610inline _LIBCPP_INLINE_VISIBILITY
1611bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
1612 return is_socket(__status(__p, &__ec));
1613}
1614
1615inline _LIBCPP_INLINE_VISIBILITY
1616bool is_symlink(file_status __s) _NOEXCEPT {
1617 return __s.type() == file_type::symlink;
1618}
1619
1620inline _LIBCPP_INLINE_VISIBILITY
1621bool is_symlink(const path& __p) {
1622 return is_symlink(__symlink_status(__p));
1623}
1624
1625inline _LIBCPP_INLINE_VISIBILITY
1626bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
1627 return is_symlink(__symlink_status(__p, &__ec));
1628}
1629
1630inline _LIBCPP_INLINE_VISIBILITY
1631bool is_other(file_status __s) _NOEXCEPT {
1632 return exists(__s)
1633 && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
1634}
1635
1636inline _LIBCPP_INLINE_VISIBILITY
1637bool is_other(const path& __p) {
1638 return is_other(__status(__p));
1639}
1640
1641inline _LIBCPP_INLINE_VISIBILITY
1642bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
1643 return is_other(__status(__p, &__ec));
1644}
1645
1646inline _LIBCPP_INLINE_VISIBILITY
1647file_time_type last_write_time(const path& __p) {
1648 return __last_write_time(__p);
1649}
1650
1651inline _LIBCPP_INLINE_VISIBILITY
1652file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
1653 return __last_write_time(__p, &__ec);
1654}
1655
1656inline _LIBCPP_INLINE_VISIBILITY
1657void last_write_time(const path& __p, file_time_type __t) {
1658 __last_write_time(__p, __t);
1659}
1660
1661inline _LIBCPP_INLINE_VISIBILITY
1662void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
1663 __last_write_time(__p, __t, &__ec);
1664}
1665
1666inline _LIBCPP_INLINE_VISIBILITY
1667void permissions(const path& __p, perms __prms) {
1668 __permissions(__p, __prms);
1669}
1670
1671inline _LIBCPP_INLINE_VISIBILITY
1672void permissions(const path& __p, perms __prms, error_code& __ec) {
1673 __permissions(__p, __prms, &__ec);
1674}
1675
1676inline _LIBCPP_INLINE_VISIBILITY
1677path read_symlink(const path& __p) {
1678 return __read_symlink(__p);
1679}
1680
1681inline _LIBCPP_INLINE_VISIBILITY
1682path read_symlink(const path& __p, error_code& __ec) {
1683 return __read_symlink(__p, &__ec);
1684}
1685
1686inline _LIBCPP_INLINE_VISIBILITY
1687bool remove(const path& __p) {
1688 return __remove(__p);
1689}
1690
1691inline _LIBCPP_INLINE_VISIBILITY
1692bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
1693 return __remove(__p, &__ec);
1694}
1695
1696inline _LIBCPP_INLINE_VISIBILITY
1697uintmax_t remove_all(const path& __p) {
1698 return __remove_all(__p);
1699}
1700
1701inline _LIBCPP_INLINE_VISIBILITY
1702uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT {
1703 return __remove_all(__p, &__ec);
1704}
1705
1706inline _LIBCPP_INLINE_VISIBILITY
1707void rename(const path& __from, const path& __to) {
1708 return __rename(__from, __to);
1709}
1710
1711inline _LIBCPP_INLINE_VISIBILITY
1712void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1713 return __rename(__from, __to, &__ec);
1714}
1715
1716inline _LIBCPP_INLINE_VISIBILITY
1717void resize_file(const path& __p, uintmax_t __ns) {
1718 return __resize_file(__p, __ns);
1719}
1720
1721inline _LIBCPP_INLINE_VISIBILITY
1722void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
1723 return __resize_file(__p, __ns, &__ec);
1724}
1725
1726inline _LIBCPP_INLINE_VISIBILITY
1727space_info space(const path& __p) {
1728 return __space(__p);
1729}
1730
1731inline _LIBCPP_INLINE_VISIBILITY
1732space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
1733 return __space(__p, &__ec);
1734}
1735
1736inline _LIBCPP_INLINE_VISIBILITY
1737file_status status(const path& __p) {
1738 return __status(__p);
1739}
1740
1741inline _LIBCPP_INLINE_VISIBILITY
1742file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
1743 return __status(__p, &__ec);
1744}
1745
1746inline _LIBCPP_INLINE_VISIBILITY
1747file_status symlink_status(const path& __p) {
1748 return __symlink_status(__p);
1749}
1750
1751inline _LIBCPP_INLINE_VISIBILITY
1752file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
1753 return __symlink_status(__p, &__ec);
1754}
1755
1756inline _LIBCPP_INLINE_VISIBILITY
1757path system_complete(const path& __p) {
1758 return __system_complete(__p);
1759}
1760
1761inline _LIBCPP_INLINE_VISIBILITY
1762path system_complete(const path& __p, error_code& __ec) {
1763 return __system_complete(__p, &__ec);
1764}
1765
1766inline _LIBCPP_INLINE_VISIBILITY
1767path temp_directory_path() {
1768 return __temp_directory_path();
1769}
1770
1771inline _LIBCPP_INLINE_VISIBILITY
1772path temp_directory_path(error_code& __ec) {
1773 return __temp_directory_path(&__ec);
1774}
1775
1776
1777class directory_entry
1778{
1779 typedef _VSTD_FS::path _Path;
1780
1781public:
1782 // constructors and destructors
1783 directory_entry() _NOEXCEPT = default;
1784 directory_entry(directory_entry const&) = default;
1785 directory_entry(directory_entry&&) _NOEXCEPT = default;
1786
1787 _LIBCPP_INLINE_VISIBILITY
1788 explicit directory_entry(_Path const& __p) : __p_(__p) {}
1789
1790 ~directory_entry() {}
1791
1792 directory_entry& operator=(directory_entry const&) = default;
1793 directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
1794
1795 _LIBCPP_INLINE_VISIBILITY
1796 void assign(_Path const& __p) {
1797 __p_ = __p;
1798 }
1799
1800 _LIBCPP_INLINE_VISIBILITY
1801 void replace_filename(_Path const& __p) {
1802 __p_ = __p_.parent_path() / __p;
1803 }
1804
1805 _LIBCPP_INLINE_VISIBILITY
1806 _Path const& path() const _NOEXCEPT {
1807 return __p_;
1808 }
1809
1810 _LIBCPP_INLINE_VISIBILITY
1811 operator const _Path&() const _NOEXCEPT {
1812 return __p_;
1813 }
1814
1815 _LIBCPP_INLINE_VISIBILITY
1816 file_status status() const {
1817 return _VSTD_FS::status(__p_);
1818 }
1819
1820 _LIBCPP_INLINE_VISIBILITY
1821 file_status status(error_code& __ec) const _NOEXCEPT {
1822 return _VSTD_FS::status(__p_, __ec);
1823 }
1824
1825 _LIBCPP_INLINE_VISIBILITY
1826 file_status symlink_status() const {
1827 return _VSTD_FS::symlink_status(__p_);
1828 }
1829
1830 _LIBCPP_INLINE_VISIBILITY
1831 file_status symlink_status(error_code& __ec) const _NOEXCEPT {
1832 return _VSTD_FS::symlink_status(__p_, __ec);
1833 }
1834
1835 _LIBCPP_INLINE_VISIBILITY
1836 bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
1837 return __p_ < __rhs.__p_;
1838 }
1839
1840 _LIBCPP_INLINE_VISIBILITY
1841 bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
1842 return __p_ == __rhs.__p_;
1843 }
1844
1845 _LIBCPP_INLINE_VISIBILITY
1846 bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
1847 return __p_ != __rhs.__p_;
1848 }
1849
1850 _LIBCPP_INLINE_VISIBILITY
1851 bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
1852 return __p_ <= __rhs.__p_;
1853 }
1854
1855 _LIBCPP_INLINE_VISIBILITY
1856 bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
1857 return __p_ > __rhs.__p_;
1858 }
1859
1860 _LIBCPP_INLINE_VISIBILITY
1861 bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
1862 return __p_ >= __rhs.__p_;
1863 }
1864private:
1865 _Path __p_;
1866};
1867
1868
1869class directory_iterator;
1870class recursive_directory_iterator;
1871class __dir_stream;
1872
1873class __dir_element_proxy {
1874public:
1875
1876 inline _LIBCPP_INLINE_VISIBILITY
1877 directory_entry operator*() { return _VSTD::move(__elem_); }
1878
1879private:
1880 friend class directory_iterator;
1881 friend class recursive_directory_iterator;
1882 explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
1883 __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
1884 directory_entry __elem_;
1885};
1886
1887class directory_iterator
1888{
1889public:
1890 typedef directory_entry value_type;
1891 typedef ptrdiff_t difference_type;
1892 typedef value_type const* pointer;
1893 typedef value_type const& reference;
1894 typedef input_iterator_tag iterator_category;
1895
1896public:
1897 //ctor & dtor
1898 directory_iterator() _NOEXCEPT
1899 { }
1900
1901 explicit directory_iterator(const path& __p)
1902 : directory_iterator(__p, nullptr)
1903 { }
1904
1905 directory_iterator(const path& __p, directory_options __opts)
1906 : directory_iterator(__p, nullptr, __opts)
1907 { }
1908
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001909 directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001910 : directory_iterator(__p, &__ec)
1911 { }
1912
1913 directory_iterator(const path& __p, directory_options __opts,
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001914 error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001915 : directory_iterator(__p, &__ec, __opts)
1916 { }
1917
1918 directory_iterator(const directory_iterator&) = default;
1919 directory_iterator(directory_iterator&&) = default;
1920 directory_iterator& operator=(const directory_iterator&) = default;
1921
1922 directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
1923 // non-default implementation provided to support self-move assign.
1924 if (this != &__o) {
1925 __imp_ = _VSTD::move(__o.__imp_);
1926 }
1927 return *this;
1928 }
1929
1930 ~directory_iterator() = default;
1931
1932 const directory_entry& operator*() const {
1933 _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00001934 return __dereference();
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001935 }
1936
1937 const directory_entry* operator->() const
1938 { return &**this; }
1939
1940 directory_iterator& operator++()
1941 { return __increment(); }
1942
1943 __dir_element_proxy operator++(int) {
1944 __dir_element_proxy __p(**this);
1945 __increment();
1946 return __p;
1947 }
1948
Eric Fiseliera4c272d2017-10-30 18:59:59 +00001949 directory_iterator& increment(error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001950 { return __increment(&__ec); }
1951
1952private:
Eric Fiselier03f7d102016-09-16 00:07:16 +00001953 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001954 friend bool operator==(const directory_iterator& __lhs,
1955 const directory_iterator& __rhs) _NOEXCEPT;
1956
1957 // construct the dir_stream
1958 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00001959 directory_iterator(const path&, error_code *,
1960 directory_options = directory_options::none);
1961
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001962 _LIBCPP_FUNC_VIS
1963 directory_iterator& __increment(error_code * __ec = nullptr);
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00001964
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001965 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00001966 const directory_entry& __dereference() const;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00001967
1968private:
1969 shared_ptr<__dir_stream> __imp_;
1970};
1971
1972
1973inline _LIBCPP_INLINE_VISIBILITY
1974bool operator==(const directory_iterator& __lhs,
1975 const directory_iterator& __rhs) _NOEXCEPT {
1976 return __lhs.__imp_ == __rhs.__imp_;
1977}
1978
1979inline _LIBCPP_INLINE_VISIBILITY
1980bool operator!=(const directory_iterator& __lhs,
1981 const directory_iterator& __rhs) _NOEXCEPT {
1982 return !(__lhs == __rhs);
1983}
1984
1985// enable directory_iterator range-based for statements
1986inline _LIBCPP_INLINE_VISIBILITY
1987directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
1988 return __iter;
1989}
1990
1991inline _LIBCPP_INLINE_VISIBILITY
1992directory_iterator end(const directory_iterator&) _NOEXCEPT {
1993 return directory_iterator();
1994}
1995
1996class recursive_directory_iterator {
1997public:
1998 using value_type = directory_entry;
1999 using difference_type = std::ptrdiff_t;
2000 using pointer = directory_entry const *;
2001 using reference = directory_entry const &;
2002 using iterator_category = std::input_iterator_tag;
2003
2004public:
2005 // constructors and destructor
2006 _LIBCPP_INLINE_VISIBILITY
2007 recursive_directory_iterator() _NOEXCEPT
2008 : __rec_(false)
2009 {}
2010
2011 _LIBCPP_INLINE_VISIBILITY
2012 explicit recursive_directory_iterator(const path& __p,
2013 directory_options __xoptions = directory_options::none)
2014 : recursive_directory_iterator(__p, __xoptions, nullptr)
2015 { }
2016
2017 _LIBCPP_INLINE_VISIBILITY
2018 recursive_directory_iterator(const path& __p,
Eric Fiseliera4c272d2017-10-30 18:59:59 +00002019 directory_options __xoptions, error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002020 : recursive_directory_iterator(__p, __xoptions, &__ec)
2021 { }
2022
2023 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera4c272d2017-10-30 18:59:59 +00002024 recursive_directory_iterator(const path& __p, error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002025 : recursive_directory_iterator(__p, directory_options::none, &__ec)
2026 { }
2027
2028 recursive_directory_iterator(const recursive_directory_iterator&) = default;
2029 recursive_directory_iterator(recursive_directory_iterator&&) = default;
2030
2031 recursive_directory_iterator &
2032 operator=(const recursive_directory_iterator&) = default;
2033
2034 _LIBCPP_INLINE_VISIBILITY
2035 recursive_directory_iterator &
2036 operator=(recursive_directory_iterator&& __o) noexcept {
2037 // non-default implementation provided to support self-move assign.
2038 if (this != &__o) {
2039 __imp_ = _VSTD::move(__o.__imp_);
2040 __rec_ = __o.__rec_;
2041 }
2042 return *this;
2043 }
2044
2045 ~recursive_directory_iterator() = default;
2046
2047 _LIBCPP_INLINE_VISIBILITY
2048 const directory_entry& operator*() const
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00002049 { return __dereference(); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002050
2051 _LIBCPP_INLINE_VISIBILITY
2052 const directory_entry* operator->() const
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00002053 { return &__dereference(); }
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002054
2055 recursive_directory_iterator& operator++()
2056 { return __increment(); }
2057
2058 _LIBCPP_INLINE_VISIBILITY
2059 __dir_element_proxy operator++(int) {
2060 __dir_element_proxy __p(**this);
2061 __increment();
2062 return __p;
2063 }
2064
2065 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera4c272d2017-10-30 18:59:59 +00002066 recursive_directory_iterator& increment(error_code& __ec)
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002067 { return __increment(&__ec); }
2068
2069 _LIBCPP_FUNC_VIS directory_options options() const;
2070 _LIBCPP_FUNC_VIS int depth() const;
2071
2072 _LIBCPP_INLINE_VISIBILITY
2073 void pop() { __pop(); }
2074
2075 _LIBCPP_INLINE_VISIBILITY
2076 void pop(error_code& __ec)
2077 { __pop(&__ec); }
2078
2079 _LIBCPP_INLINE_VISIBILITY
2080 bool recursion_pending() const
2081 { return __rec_; }
2082
2083 _LIBCPP_INLINE_VISIBILITY
2084 void disable_recursion_pending()
2085 { __rec_ = false; }
2086
2087private:
2088 recursive_directory_iterator(const path& __p, directory_options __opt,
2089 error_code *__ec);
2090
2091 _LIBCPP_FUNC_VIS
Saleem Abdulrasoolb35cd982017-01-30 00:15:47 +00002092 const directory_entry& __dereference() const;
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002093
2094 _LIBCPP_FUNC_VIS
2095 bool __try_recursion(error_code* __ec);
2096
2097 _LIBCPP_FUNC_VIS
2098 void __advance(error_code* __ec=nullptr);
2099
2100 _LIBCPP_FUNC_VIS
2101 recursive_directory_iterator& __increment(error_code *__ec=nullptr);
2102
2103 _LIBCPP_FUNC_VIS
2104 void __pop(error_code* __ec=nullptr);
2105
Eric Fiselier03f7d102016-09-16 00:07:16 +00002106 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002107 friend bool operator==(const recursive_directory_iterator&,
2108 const recursive_directory_iterator&) _NOEXCEPT;
2109
2110 struct __shared_imp;
2111 shared_ptr<__shared_imp> __imp_;
2112 bool __rec_;
2113}; // class recursive_directory_iterator
2114
2115
Eric Fiselier03f7d102016-09-16 00:07:16 +00002116inline _LIBCPP_INLINE_VISIBILITY
2117bool operator==(const recursive_directory_iterator& __lhs,
2118 const recursive_directory_iterator& __rhs) _NOEXCEPT
Eric Fiselier6e9a6942016-06-17 19:46:40 +00002119{
2120 return __lhs.__imp_ == __rhs.__imp_;
2121}
2122
2123_LIBCPP_INLINE_VISIBILITY
2124inline bool operator!=(const recursive_directory_iterator& __lhs,
2125 const recursive_directory_iterator& __rhs) _NOEXCEPT
2126{
2127 return !(__lhs == __rhs);
2128}
2129// enable recursive_directory_iterator range-based for statements
2130inline _LIBCPP_INLINE_VISIBILITY
2131recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
2132 return __iter;
2133}
2134
2135inline _LIBCPP_INLINE_VISIBILITY
2136recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
2137 return recursive_directory_iterator();
2138}
2139
2140_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
2141
2142#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM