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