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