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