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