1// -*- C++ -*-
2//===--------------------------- filesystem -------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9#ifndef _LIBCPP_FILESYSTEM
10#define _LIBCPP_FILESYSTEM
11/*
12    filesystem synopsis
13
14    namespace std::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#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
970  // TODO Implement locale conversions.
971  template <class _Source, class = _EnableIfPathable<_Source, void> >
972  path(const _Source& __src, const locale& __loc, format = format::auto_format);
973  template <class _InputIt>
974  path(_InputIt __first, _InputIt _last, const locale& __loc,
975       format = format::auto_format);
976#endif
977
978  _LIBCPP_INLINE_VISIBILITY
979  ~path() = default;
980
981  // assignments
982  _LIBCPP_INLINE_VISIBILITY
983  path& operator=(const path& __p) {
984    __pn_ = __p.__pn_;
985    return *this;
986  }
987
988  _LIBCPP_INLINE_VISIBILITY
989  path& operator=(path&& __p) noexcept {
990    __pn_ = _VSTD::move(__p.__pn_);
991    return *this;
992  }
993
994  _LIBCPP_INLINE_VISIBILITY
995  path& operator=(string_type&& __s) noexcept {
996    __pn_ = _VSTD::move(__s);
997    return *this;
998  }
999
1000  _LIBCPP_INLINE_VISIBILITY
1001  path& assign(string_type&& __s) noexcept {
1002    __pn_ = _VSTD::move(__s);
1003    return *this;
1004  }
1005
1006  template <class _Source>
1007  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1008  operator=(const _Source& __src) {
1009    return this->assign(__src);
1010  }
1011
1012  template <class _Source>
1013  _EnableIfPathable<_Source> assign(const _Source& __src) {
1014    __pn_.clear();
1015    _SourceCVT<_Source>::__append_source(__pn_, __src);
1016    return *this;
1017  }
1018
1019  template <class _InputIt>
1020  path& assign(_InputIt __first, _InputIt __last) {
1021    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1022    __pn_.clear();
1023    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1024    return *this;
1025  }
1026
1027public:
1028  // appends
1029#if defined(_LIBCPP_WIN32API)
1030  path& operator/=(const path& __p) {
1031    auto __p_root_name = __p.__root_name();
1032    auto __p_root_name_size = __p_root_name.size();
1033    if (__p.is_absolute() ||
1034        (!__p_root_name.empty() && __p_root_name != root_name())) {
1035      __pn_ = __p.__pn_;
1036      return *this;
1037    }
1038    if (__p.has_root_directory()) {
1039      path __root_name_str = root_name();
1040      __pn_ = __root_name_str.native();
1041      __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1042      return *this;
1043    }
1044    if (has_filename() || (!has_root_directory() && is_absolute()))
1045      __pn_ += preferred_separator;
1046    __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1047    return *this;
1048  }
1049  template <class _Source>
1050  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1051  operator/=(const _Source& __src) {
1052    return operator/=(path(__src));
1053  }
1054
1055  template <class _Source>
1056  _EnableIfPathable<_Source> append(const _Source& __src) {
1057    return operator/=(path(__src));
1058  }
1059
1060  template <class _InputIt>
1061  path& append(_InputIt __first, _InputIt __last) {
1062    return operator/=(path(__first, __last));
1063  }
1064#else
1065  path& operator/=(const path& __p) {
1066    if (__p.is_absolute()) {
1067      __pn_ = __p.__pn_;
1068      return *this;
1069    }
1070    if (has_filename())
1071      __pn_ += preferred_separator;
1072    __pn_ += __p.native();
1073    return *this;
1074  }
1075
1076  // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
1077  // is known at compile time to be "/' since the user almost certainly intended
1078  // to append a separator instead of overwriting the path with "/"
1079  template <class _Source>
1080  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1081  operator/=(const _Source& __src) {
1082    return this->append(__src);
1083  }
1084
1085  template <class _Source>
1086  _EnableIfPathable<_Source> append(const _Source& __src) {
1087    using _Traits = __is_pathable<_Source>;
1088    using _CVT = _PathCVT<_SourceChar<_Source> >;
1089    bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
1090    if (__source_is_absolute)
1091      __pn_.clear();
1092    else if (has_filename())
1093      __pn_ += preferred_separator;
1094    _CVT::__append_source(__pn_, __src);
1095    return *this;
1096  }
1097
1098  template <class _InputIt>
1099  path& append(_InputIt __first, _InputIt __last) {
1100    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1101    static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
1102    using _CVT = _PathCVT<_ItVal>;
1103    if (__first != __last && __is_separator(*__first))
1104      __pn_.clear();
1105    else if (has_filename())
1106      __pn_ += preferred_separator;
1107    _CVT::__append_range(__pn_, __first, __last);
1108    return *this;
1109  }
1110#endif
1111
1112  // concatenation
1113  _LIBCPP_INLINE_VISIBILITY
1114  path& operator+=(const path& __x) {
1115    __pn_ += __x.__pn_;
1116    return *this;
1117  }
1118
1119  _LIBCPP_INLINE_VISIBILITY
1120  path& operator+=(const string_type& __x) {
1121    __pn_ += __x;
1122    return *this;
1123  }
1124
1125  _LIBCPP_INLINE_VISIBILITY
1126  path& operator+=(__string_view __x) {
1127    __pn_ += __x;
1128    return *this;
1129  }
1130
1131  _LIBCPP_INLINE_VISIBILITY
1132  path& operator+=(const value_type* __x) {
1133    __pn_ += __x;
1134    return *this;
1135  }
1136
1137  _LIBCPP_INLINE_VISIBILITY
1138  path& operator+=(value_type __x) {
1139    __pn_ += __x;
1140    return *this;
1141  }
1142
1143  template <class _ECharT>
1144  typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
1145  operator+=(_ECharT __x) {
1146    _PathCVT<_ECharT>::__append_source(__pn_,
1147                                       basic_string_view<_ECharT>(&__x, 1));
1148    return *this;
1149  }
1150
1151  template <class _Source>
1152  _EnableIfPathable<_Source> operator+=(const _Source& __x) {
1153    return this->concat(__x);
1154  }
1155
1156  template <class _Source>
1157  _EnableIfPathable<_Source> concat(const _Source& __x) {
1158    _SourceCVT<_Source>::__append_source(__pn_, __x);
1159    return *this;
1160  }
1161
1162  template <class _InputIt>
1163  path& concat(_InputIt __first, _InputIt __last) {
1164    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
1165    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
1166    return *this;
1167  }
1168
1169  // modifiers
1170  _LIBCPP_INLINE_VISIBILITY
1171  void clear() noexcept { __pn_.clear(); }
1172
1173  path& make_preferred() {
1174#if defined(_LIBCPP_WIN32API)
1175    _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
1176#endif
1177    return *this;
1178  }
1179
1180  _LIBCPP_INLINE_VISIBILITY
1181  path& remove_filename() {
1182    auto __fname = __filename();
1183    if (!__fname.empty())
1184      __pn_.erase(__fname.data() - __pn_.data());
1185    return *this;
1186  }
1187
1188  path& replace_filename(const path& __replacement) {
1189    remove_filename();
1190    return (*this /= __replacement);
1191  }
1192
1193  path& replace_extension(const path& __replacement = path());
1194
1195  _LIBCPP_INLINE_VISIBILITY
1196  void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
1197
1198  // private helper to allow reserving memory in the path
1199  _LIBCPP_INLINE_VISIBILITY
1200  void __reserve(size_t __s) { __pn_.reserve(__s); }
1201
1202  // native format observers
1203  _LIBCPP_INLINE_VISIBILITY
1204  const string_type& native() const noexcept { return __pn_; }
1205
1206  _LIBCPP_INLINE_VISIBILITY
1207  const value_type* c_str() const noexcept { return __pn_.c_str(); }
1208
1209  _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
1210
1211#if defined(_LIBCPP_WIN32API)
1212  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
1213
1214  _VSTD::wstring generic_wstring() const {
1215    _VSTD::wstring __s;
1216    __s.resize(__pn_.size());
1217    _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
1218    return __s;
1219  }
1220
1221#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1222  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1223            class _Allocator = allocator<_ECharT> >
1224  basic_string<_ECharT, _Traits, _Allocator>
1225  string(const _Allocator& __a = _Allocator()) const {
1226    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1227    _Str __s(__a);
1228    __s.reserve(__pn_.size());
1229    _PathExport<_ECharT>::__append(__s, __pn_);
1230    return __s;
1231  }
1232
1233  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
1234    return string<char>();
1235  }
1236  _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
1237    using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1238    __u8_string __s;
1239    __s.reserve(__pn_.size());
1240    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1241    return __s;
1242  }
1243
1244  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1245    return string<char16_t>();
1246  }
1247  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1248    return string<char32_t>();
1249  }
1250
1251  // generic format observers
1252  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1253            class _Allocator = allocator<_ECharT> >
1254  basic_string<_ECharT, _Traits, _Allocator>
1255  generic_string(const _Allocator& __a = _Allocator()) const {
1256    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1257    _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
1258    // Note: This (and generic_u8string below) is slightly suboptimal as
1259    // it iterates twice over the string; once to convert it to the right
1260    // character type, and once to replace path delimiters.
1261    _VSTD::replace(__s.begin(), __s.end(),
1262                   static_cast<_ECharT>('\\'), static_cast<_ECharT>('/'));
1263    return __s;
1264  }
1265
1266  _VSTD::string generic_string() const { return generic_string<char>(); }
1267  _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
1268  _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1269  __u8_string generic_u8string() const {
1270    __u8_string __s = u8string();
1271    _VSTD::replace(__s.begin(), __s.end(), '\\', '/');
1272    return __s;
1273  }
1274#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1275#else /* _LIBCPP_WIN32API */
1276
1277  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
1278#ifndef _LIBCPP_HAS_NO_CHAR8_T
1279  _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1280#else
1281  _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
1282#endif
1283
1284#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1285  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1286            class _Allocator = allocator<_ECharT> >
1287  basic_string<_ECharT, _Traits, _Allocator>
1288  string(const _Allocator& __a = _Allocator()) const {
1289    using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
1290    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1291    _Str __s(__a);
1292    __s.reserve(__pn_.size());
1293    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1294    return __s;
1295  }
1296
1297#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1298  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
1299    return string<wchar_t>();
1300  }
1301#endif
1302  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1303    return string<char16_t>();
1304  }
1305  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1306    return string<char32_t>();
1307  }
1308#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1309
1310  // generic format observers
1311  _VSTD::string generic_string() const { return __pn_; }
1312#ifndef _LIBCPP_HAS_NO_CHAR8_T
1313  _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1314#else
1315  _VSTD::string generic_u8string() const { return __pn_; }
1316#endif
1317
1318#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1319  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1320            class _Allocator = allocator<_ECharT> >
1321  basic_string<_ECharT, _Traits, _Allocator>
1322  generic_string(const _Allocator& __a = _Allocator()) const {
1323    return string<_ECharT, _Traits, _Allocator>(__a);
1324  }
1325
1326#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1327  _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
1328#endif
1329  _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
1330  _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
1331#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1332#endif /* !_LIBCPP_WIN32API */
1333
1334private:
1335  int __compare(__string_view) const;
1336  __string_view __root_name() const;
1337  __string_view __root_directory() const;
1338  __string_view __root_path_raw() const;
1339  __string_view __relative_path() const;
1340  __string_view __parent_path() const;
1341  __string_view __filename() const;
1342  __string_view __stem() const;
1343  __string_view __extension() const;
1344
1345public:
1346  // compare
1347  _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
1348    return __compare(__p.__pn_);
1349  }
1350  _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
1351    return __compare(__s);
1352  }
1353  _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
1354    return __compare(__s);
1355  }
1356  _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
1357    return __compare(__s);
1358  }
1359
1360  // decomposition
1361  _LIBCPP_INLINE_VISIBILITY path root_name() const {
1362    return string_type(__root_name());
1363  }
1364  _LIBCPP_INLINE_VISIBILITY path root_directory() const {
1365    return string_type(__root_directory());
1366  }
1367  _LIBCPP_INLINE_VISIBILITY path root_path() const {
1368#if defined(_LIBCPP_WIN32API)
1369    return string_type(__root_path_raw());
1370#else
1371    return root_name().append(string_type(__root_directory()));
1372#endif
1373  }
1374  _LIBCPP_INLINE_VISIBILITY path relative_path() const {
1375    return string_type(__relative_path());
1376  }
1377  _LIBCPP_INLINE_VISIBILITY path parent_path() const {
1378    return string_type(__parent_path());
1379  }
1380  _LIBCPP_INLINE_VISIBILITY path filename() const {
1381    return string_type(__filename());
1382  }
1383  _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
1384  _LIBCPP_INLINE_VISIBILITY path extension() const {
1385    return string_type(__extension());
1386  }
1387
1388  // query
1389  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
1390  empty() const noexcept {
1391    return __pn_.empty();
1392  }
1393
1394  _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
1395    return !__root_name().empty();
1396  }
1397  _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
1398    return !__root_directory().empty();
1399  }
1400  _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
1401    return !__root_path_raw().empty();
1402  }
1403  _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
1404    return !__relative_path().empty();
1405  }
1406  _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
1407    return !__parent_path().empty();
1408  }
1409  _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
1410    return !__filename().empty();
1411  }
1412  _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
1413  _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
1414    return !__extension().empty();
1415  }
1416
1417  _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1418#if defined(_LIBCPP_WIN32API)
1419    __string_view __root_name_str = __root_name();
1420    __string_view __root_dir = __root_directory();
1421    if (__root_name_str.size() == 2 && __root_name_str[1] == ':') {
1422      // A drive letter with no root directory is relative, e.g. x:example.
1423      return !__root_dir.empty();
1424    }
1425    // If no root name, it's relative, e.g. \example is relative to the current drive
1426    if (__root_name_str.empty())
1427      return false;
1428    if (__root_name_str.size() < 3)
1429      return false;
1430    // A server root name, like \\server, is always absolute
1431    if (__root_name_str[0] != '/' && __root_name_str[0] != '\\')
1432      return false;
1433    if (__root_name_str[1] != '/' && __root_name_str[1] != '\\')
1434      return false;
1435    // Seems to be a server root name
1436    return true;
1437#else
1438    return has_root_directory();
1439#endif
1440  }
1441  _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
1442
1443  // relative paths
1444  path lexically_normal() const;
1445  path lexically_relative(const path& __base) const;
1446
1447  _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
1448    path __result = this->lexically_relative(__base);
1449    if (__result.native().empty())
1450      return *this;
1451    return __result;
1452  }
1453
1454  // iterators
1455  class _LIBCPP_TYPE_VIS iterator;
1456  typedef iterator const_iterator;
1457
1458  iterator begin() const;
1459  iterator end() const;
1460
1461#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1462  template <class _CharT, class _Traits>
1463  _LIBCPP_INLINE_VISIBILITY friend
1464      typename enable_if<is_same<_CharT, value_type>::value &&
1465                             is_same<_Traits, char_traits<value_type> >::value,
1466                         basic_ostream<_CharT, _Traits>&>::type
1467      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1468    __os << _VSTD::__quoted(__p.native());
1469    return __os;
1470  }
1471
1472  template <class _CharT, class _Traits>
1473  _LIBCPP_INLINE_VISIBILITY friend
1474      typename enable_if<!is_same<_CharT, value_type>::value ||
1475                             !is_same<_Traits, char_traits<value_type> >::value,
1476                         basic_ostream<_CharT, _Traits>&>::type
1477      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1478    __os << _VSTD::__quoted(__p.string<_CharT, _Traits>());
1479    return __os;
1480  }
1481
1482  template <class _CharT, class _Traits>
1483  _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
1484  operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
1485    basic_string<_CharT, _Traits> __tmp;
1486    __is >> __quoted(__tmp);
1487    __p = __tmp;
1488    return __is;
1489  }
1490#endif // !_LIBCPP_HAS_NO_LOCALIZATION
1491
1492  friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
1493    return __lhs.compare(__rhs) == 0;
1494  }
1495  friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
1496    return __lhs.compare(__rhs) != 0;
1497  }
1498  friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
1499    return __lhs.compare(__rhs) < 0;
1500  }
1501  friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
1502    return __lhs.compare(__rhs) <= 0;
1503  }
1504  friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
1505    return __lhs.compare(__rhs) > 0;
1506  }
1507  friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
1508    return __lhs.compare(__rhs) >= 0;
1509  }
1510
1511  friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1512                                                  const path& __rhs) {
1513    path __result(__lhs);
1514    __result /= __rhs;
1515    return __result;
1516  }
1517private:
1518  inline _LIBCPP_INLINE_VISIBILITY path&
1519  __assign_view(__string_view const& __s) noexcept {
1520    __pn_ = string_type(__s);
1521    return *this;
1522  }
1523  string_type __pn_;
1524};
1525
1526inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
1527  __lhs.swap(__rhs);
1528}
1529
1530_LIBCPP_FUNC_VIS
1531size_t hash_value(const path& __p) noexcept;
1532
1533template <class _InputIt>
1534_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1535    typename enable_if<__is_pathable<_InputIt>::value, path>::type
1536    u8path(_InputIt __f, _InputIt __l) {
1537  static_assert(
1538#ifndef _LIBCPP_HAS_NO_CHAR8_T
1539      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1540#endif
1541      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1542      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1543      " or 'char8_t'");
1544#if defined(_LIBCPP_WIN32API)
1545  string __tmp(__f, __l);
1546  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1547  _VSTD::wstring __w;
1548  __w.reserve(__tmp.size());
1549  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1550  return path(__w);
1551#else
1552  return path(__f, __l);
1553#endif /* !_LIBCPP_WIN32API */
1554}
1555
1556#if defined(_LIBCPP_WIN32API)
1557template <class _InputIt>
1558_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1559    typename enable_if<__is_pathable<_InputIt>::value, path>::type
1560    u8path(_InputIt __f, _NullSentinel) {
1561  static_assert(
1562#ifndef _LIBCPP_HAS_NO_CHAR8_T
1563      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1564#endif
1565      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1566      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1567      " or 'char8_t'");
1568  string __tmp;
1569  const char __sentinel = char{};
1570  for (; *__f != __sentinel; ++__f)
1571    __tmp.push_back(*__f);
1572  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1573  _VSTD::wstring __w;
1574  __w.reserve(__tmp.size());
1575  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1576  return path(__w);
1577}
1578#endif /* _LIBCPP_WIN32API */
1579
1580template <class _Source>
1581_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1582    typename enable_if<__is_pathable<_Source>::value, path>::type
1583    u8path(const _Source& __s) {
1584  static_assert(
1585#ifndef _LIBCPP_HAS_NO_CHAR8_T
1586      is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
1587#endif
1588      is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1589      "u8path(Source const&) requires Source have a character type of type "
1590      "'char' or 'char8_t'");
1591#if defined(_LIBCPP_WIN32API)
1592  using _Traits = __is_pathable<_Source>;
1593  return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s)));
1594#else
1595  return path(__s);
1596#endif
1597}
1598
1599class _LIBCPP_TYPE_VIS path::iterator {
1600public:
1601  enum _ParserState : unsigned char {
1602    _Singular,
1603    _BeforeBegin,
1604    _InRootName,
1605    _InRootDir,
1606    _InFilenames,
1607    _InTrailingSep,
1608    _AtEnd
1609  };
1610
1611public:
1612  typedef bidirectional_iterator_tag iterator_category;
1613
1614  typedef path value_type;
1615  typedef ptrdiff_t difference_type;
1616  typedef const path* pointer;
1617  typedef const path& reference;
1618
1619  typedef void
1620      __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1621
1622public:
1623  _LIBCPP_INLINE_VISIBILITY
1624  iterator()
1625      : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
1626        __state_(_Singular) {}
1627
1628  iterator(const iterator&) = default;
1629  ~iterator() = default;
1630
1631  iterator& operator=(const iterator&) = default;
1632
1633  _LIBCPP_INLINE_VISIBILITY
1634  reference operator*() const { return __stashed_elem_; }
1635
1636  _LIBCPP_INLINE_VISIBILITY
1637  pointer operator->() const { return &__stashed_elem_; }
1638
1639  _LIBCPP_INLINE_VISIBILITY
1640  iterator& operator++() {
1641    _LIBCPP_ASSERT(__state_ != _Singular,
1642                   "attempting to increment a singular iterator");
1643    _LIBCPP_ASSERT(__state_ != _AtEnd,
1644                   "attempting to increment the end iterator");
1645    return __increment();
1646  }
1647
1648  _LIBCPP_INLINE_VISIBILITY
1649  iterator operator++(int) {
1650    iterator __it(*this);
1651    this->operator++();
1652    return __it;
1653  }
1654
1655  _LIBCPP_INLINE_VISIBILITY
1656  iterator& operator--() {
1657    _LIBCPP_ASSERT(__state_ != _Singular,
1658                   "attempting to decrement a singular iterator");
1659    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1660                   "attempting to decrement the begin iterator");
1661    return __decrement();
1662  }
1663
1664  _LIBCPP_INLINE_VISIBILITY
1665  iterator operator--(int) {
1666    iterator __it(*this);
1667    this->operator--();
1668    return __it;
1669  }
1670
1671private:
1672  friend class path;
1673
1674  inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
1675                                                          const iterator&);
1676
1677  iterator& __increment();
1678  iterator& __decrement();
1679
1680  path __stashed_elem_;
1681  const path* __path_ptr_;
1682  path::__string_view __entry_;
1683  _ParserState __state_;
1684};
1685
1686inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
1687                                                 const path::iterator& __rhs) {
1688  return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1689         __lhs.__entry_.data() == __rhs.__entry_.data();
1690}
1691
1692inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
1693                                                 const path::iterator& __rhs) {
1694  return !(__lhs == __rhs);
1695}
1696
1697// TODO(ldionne): We need to pop the pragma and push it again after
1698//                filesystem_error to work around PR41078.
1699_LIBCPP_AVAILABILITY_FILESYSTEM_POP
1700
1701class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
1702public:
1703  _LIBCPP_INLINE_VISIBILITY
1704  filesystem_error(const string& __what, error_code __ec)
1705      : system_error(__ec, __what),
1706        __storage_(make_shared<_Storage>(path(), path())) {
1707    __create_what(0);
1708  }
1709
1710  _LIBCPP_INLINE_VISIBILITY
1711  filesystem_error(const string& __what, const path& __p1, error_code __ec)
1712      : system_error(__ec, __what),
1713        __storage_(make_shared<_Storage>(__p1, path())) {
1714    __create_what(1);
1715  }
1716
1717  _LIBCPP_INLINE_VISIBILITY
1718  filesystem_error(const string& __what, const path& __p1, const path& __p2,
1719                   error_code __ec)
1720      : system_error(__ec, __what),
1721        __storage_(make_shared<_Storage>(__p1, __p2)) {
1722    __create_what(2);
1723  }
1724
1725  _LIBCPP_INLINE_VISIBILITY
1726  const path& path1() const noexcept { return __storage_->__p1_; }
1727
1728  _LIBCPP_INLINE_VISIBILITY
1729  const path& path2() const noexcept { return __storage_->__p2_; }
1730
1731  filesystem_error(const filesystem_error&) = default;
1732  ~filesystem_error() override; // key function
1733
1734  _LIBCPP_INLINE_VISIBILITY
1735  const char* what() const noexcept override {
1736    return __storage_->__what_.c_str();
1737  }
1738
1739  void __create_what(int __num_paths);
1740
1741private:
1742  struct _LIBCPP_HIDDEN _Storage {
1743    _LIBCPP_INLINE_VISIBILITY
1744    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
1745
1746    path __p1_;
1747    path __p2_;
1748    string __what_;
1749  };
1750  shared_ptr<_Storage> __storage_;
1751};
1752
1753_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
1754
1755template <class... _Args>
1756_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1757#ifndef _LIBCPP_NO_EXCEPTIONS
1758void __throw_filesystem_error(_Args&&... __args) {
1759  throw filesystem_error(_VSTD::forward<_Args>(__args)...);
1760}
1761#else
1762void __throw_filesystem_error(_Args&&...) {
1763  _VSTD::abort();
1764}
1765#endif
1766
1767// operational functions
1768
1769_LIBCPP_FUNC_VIS
1770path __absolute(const path&, error_code* __ec = nullptr);
1771_LIBCPP_FUNC_VIS
1772path __canonical(const path&, error_code* __ec = nullptr);
1773_LIBCPP_FUNC_VIS
1774void __copy(const path& __from, const path& __to, copy_options __opt,
1775            error_code* __ec = nullptr);
1776_LIBCPP_FUNC_VIS
1777bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1778                 error_code* __ec = nullptr);
1779_LIBCPP_FUNC_VIS
1780void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1781                    error_code* __ec = nullptr);
1782_LIBCPP_FUNC_VIS
1783bool __create_directories(const path& p, error_code* ec = nullptr);
1784_LIBCPP_FUNC_VIS
1785bool __create_directory(const path& p, error_code* ec = nullptr);
1786_LIBCPP_FUNC_VIS
1787bool __create_directory(const path& p, const path& attributes,
1788                        error_code* ec = nullptr);
1789_LIBCPP_FUNC_VIS
1790void __create_directory_symlink(const path& __to, const path& __new_symlink,
1791                                error_code* __ec = nullptr);
1792_LIBCPP_FUNC_VIS
1793void __create_hard_link(const path& __to, const path& __new_hard_link,
1794                        error_code* __ec = nullptr);
1795_LIBCPP_FUNC_VIS
1796void __create_symlink(const path& __to, const path& __new_symlink,
1797                      error_code* __ec = nullptr);
1798_LIBCPP_FUNC_VIS
1799path __current_path(error_code* __ec = nullptr);
1800_LIBCPP_FUNC_VIS
1801void __current_path(const path&, error_code* __ec = nullptr);
1802_LIBCPP_FUNC_VIS
1803bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
1804_LIBCPP_FUNC_VIS
1805uintmax_t __file_size(const path&, error_code* __ec = nullptr);
1806_LIBCPP_FUNC_VIS
1807uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
1808_LIBCPP_FUNC_VIS
1809bool __fs_is_empty(const path& p, error_code* ec = nullptr);
1810_LIBCPP_FUNC_VIS
1811file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
1812_LIBCPP_FUNC_VIS
1813void __last_write_time(const path& p, file_time_type new_time,
1814                       error_code* ec = nullptr);
1815_LIBCPP_FUNC_VIS
1816void __permissions(const path&, perms, perm_options, error_code* = nullptr);
1817_LIBCPP_FUNC_VIS
1818path __read_symlink(const path& p, error_code* ec = nullptr);
1819_LIBCPP_FUNC_VIS
1820bool __remove(const path& p, error_code* ec = nullptr);
1821_LIBCPP_FUNC_VIS
1822uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
1823_LIBCPP_FUNC_VIS
1824void __rename(const path& from, const path& to, error_code* ec = nullptr);
1825_LIBCPP_FUNC_VIS
1826void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
1827_LIBCPP_FUNC_VIS
1828space_info __space(const path&, error_code* __ec = nullptr);
1829_LIBCPP_FUNC_VIS
1830file_status __status(const path&, error_code* __ec = nullptr);
1831_LIBCPP_FUNC_VIS
1832file_status __symlink_status(const path&, error_code* __ec = nullptr);
1833_LIBCPP_FUNC_VIS
1834path __system_complete(const path&, error_code* __ec = nullptr);
1835_LIBCPP_FUNC_VIS
1836path __temp_directory_path(error_code* __ec = nullptr);
1837_LIBCPP_FUNC_VIS
1838path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
1839
1840inline _LIBCPP_INLINE_VISIBILITY path current_path() {
1841  return __current_path();
1842}
1843
1844inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
1845  return __current_path(&__ec);
1846}
1847
1848inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
1849  __current_path(__p);
1850}
1851
1852inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
1853                                                   error_code& __ec) noexcept {
1854  __current_path(__p, &__ec);
1855}
1856
1857inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
1858  return __absolute(__p);
1859}
1860
1861inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
1862                                               error_code& __ec) {
1863  return __absolute(__p, &__ec);
1864}
1865
1866inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
1867  return __canonical(__p);
1868}
1869
1870inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
1871                                                error_code& __ec) {
1872  return __canonical(__p, &__ec);
1873}
1874
1875inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
1876                                           const path& __to) {
1877  __copy(__from, __to, copy_options::none);
1878}
1879
1880inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1881                                           error_code& __ec) {
1882  __copy(__from, __to, copy_options::none, &__ec);
1883}
1884
1885inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1886                                           copy_options __opt) {
1887  __copy(__from, __to, __opt);
1888}
1889
1890inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
1891                                           copy_options __opt,
1892                                           error_code& __ec) {
1893  __copy(__from, __to, __opt, &__ec);
1894}
1895
1896inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1897                                                const path& __to) {
1898  return __copy_file(__from, __to, copy_options::none);
1899}
1900
1901inline _LIBCPP_INLINE_VISIBILITY bool
1902copy_file(const path& __from, const path& __to, error_code& __ec) {
1903  return __copy_file(__from, __to, copy_options::none, &__ec);
1904}
1905
1906inline _LIBCPP_INLINE_VISIBILITY bool
1907copy_file(const path& __from, const path& __to, copy_options __opt) {
1908  return __copy_file(__from, __to, __opt);
1909}
1910
1911inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
1912                                                const path& __to,
1913                                                copy_options __opt,
1914                                                error_code& __ec) {
1915  return __copy_file(__from, __to, __opt, &__ec);
1916}
1917
1918inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
1919                                                   const path& __new) {
1920  __copy_symlink(__existing, __new);
1921}
1922
1923inline _LIBCPP_INLINE_VISIBILITY void
1924copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
1925  __copy_symlink(__ext, __new, &__ec);
1926}
1927
1928inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
1929  return __create_directories(__p);
1930}
1931
1932inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
1933                                                         error_code& __ec) {
1934  return __create_directories(__p, &__ec);
1935}
1936
1937inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
1938  return __create_directory(__p);
1939}
1940
1941inline _LIBCPP_INLINE_VISIBILITY bool
1942create_directory(const path& __p, error_code& __ec) noexcept {
1943  return __create_directory(__p, &__ec);
1944}
1945
1946inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
1947                                                       const path& __attrs) {
1948  return __create_directory(__p, __attrs);
1949}
1950
1951inline _LIBCPP_INLINE_VISIBILITY bool
1952create_directory(const path& __p, const path& __attrs,
1953                 error_code& __ec) noexcept {
1954  return __create_directory(__p, __attrs, &__ec);
1955}
1956
1957inline _LIBCPP_INLINE_VISIBILITY void
1958create_directory_symlink(const path& __to, const path& __new) {
1959  __create_directory_symlink(__to, __new);
1960}
1961
1962inline _LIBCPP_INLINE_VISIBILITY void
1963create_directory_symlink(const path& __to, const path& __new,
1964                         error_code& __ec) noexcept {
1965  __create_directory_symlink(__to, __new, &__ec);
1966}
1967
1968inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
1969                                                       const path& __new) {
1970  __create_hard_link(__to, __new);
1971}
1972
1973inline _LIBCPP_INLINE_VISIBILITY void
1974create_hard_link(const path& __to, const path& __new,
1975                 error_code& __ec) noexcept {
1976  __create_hard_link(__to, __new, &__ec);
1977}
1978
1979inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
1980                                                     const path& __new) {
1981  __create_symlink(__to, __new);
1982}
1983
1984inline _LIBCPP_INLINE_VISIBILITY void
1985create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
1986  return __create_symlink(__to, __new, &__ec);
1987}
1988
1989inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
1990  return __s.type() != file_type::none;
1991}
1992
1993inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
1994  return status_known(__s) && __s.type() != file_type::not_found;
1995}
1996
1997inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
1998  return exists(__status(__p));
1999}
2000
2001inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
2002                                             error_code& __ec) noexcept {
2003  auto __s = __status(__p, &__ec);
2004  if (status_known(__s))
2005    __ec.clear();
2006  return exists(__s);
2007}
2008
2009inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
2010                                                 const path& __p2) {
2011  return __equivalent(__p1, __p2);
2012}
2013
2014inline _LIBCPP_INLINE_VISIBILITY bool
2015equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
2016  return __equivalent(__p1, __p2, &__ec);
2017}
2018
2019inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
2020  return __file_size(__p);
2021}
2022
2023inline _LIBCPP_INLINE_VISIBILITY uintmax_t
2024file_size(const path& __p, error_code& __ec) noexcept {
2025  return __file_size(__p, &__ec);
2026}
2027
2028inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
2029  return __hard_link_count(__p);
2030}
2031
2032inline _LIBCPP_INLINE_VISIBILITY uintmax_t
2033hard_link_count(const path& __p, error_code& __ec) noexcept {
2034  return __hard_link_count(__p, &__ec);
2035}
2036
2037inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
2038  return __s.type() == file_type::block;
2039}
2040
2041inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
2042  return is_block_file(__status(__p));
2043}
2044
2045inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
2046                                                    error_code& __ec) noexcept {
2047  return is_block_file(__status(__p, &__ec));
2048}
2049
2050inline _LIBCPP_INLINE_VISIBILITY bool
2051is_character_file(file_status __s) noexcept {
2052  return __s.type() == file_type::character;
2053}
2054
2055inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
2056  return is_character_file(__status(__p));
2057}
2058
2059inline _LIBCPP_INLINE_VISIBILITY bool
2060is_character_file(const path& __p, error_code& __ec) noexcept {
2061  return is_character_file(__status(__p, &__ec));
2062}
2063
2064inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
2065  return __s.type() == file_type::directory;
2066}
2067
2068inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
2069  return is_directory(__status(__p));
2070}
2071
2072inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
2073                                                   error_code& __ec) noexcept {
2074  return is_directory(__status(__p, &__ec));
2075}
2076
2077inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
2078  return __fs_is_empty(__p);
2079}
2080
2081inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
2082                                               error_code& __ec) {
2083  return __fs_is_empty(__p, &__ec);
2084}
2085
2086inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
2087  return __s.type() == file_type::fifo;
2088}
2089inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
2090  return is_fifo(__status(__p));
2091}
2092
2093inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
2094                                              error_code& __ec) noexcept {
2095  return is_fifo(__status(__p, &__ec));
2096}
2097
2098inline _LIBCPP_INLINE_VISIBILITY bool
2099is_regular_file(file_status __s) noexcept {
2100  return __s.type() == file_type::regular;
2101}
2102
2103inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
2104  return is_regular_file(__status(__p));
2105}
2106
2107inline _LIBCPP_INLINE_VISIBILITY bool
2108is_regular_file(const path& __p, error_code& __ec) noexcept {
2109  return is_regular_file(__status(__p, &__ec));
2110}
2111
2112inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
2113  return __s.type() == file_type::socket;
2114}
2115
2116inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
2117  return is_socket(__status(__p));
2118}
2119
2120inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
2121                                                error_code& __ec) noexcept {
2122  return is_socket(__status(__p, &__ec));
2123}
2124
2125inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
2126  return __s.type() == file_type::symlink;
2127}
2128
2129inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
2130  return is_symlink(__symlink_status(__p));
2131}
2132
2133inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
2134                                                 error_code& __ec) noexcept {
2135  return is_symlink(__symlink_status(__p, &__ec));
2136}
2137
2138inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
2139  return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
2140         !is_symlink(__s);
2141}
2142
2143inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
2144  return is_other(__status(__p));
2145}
2146
2147inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
2148                                               error_code& __ec) noexcept {
2149  return is_other(__status(__p, &__ec));
2150}
2151
2152inline _LIBCPP_INLINE_VISIBILITY file_time_type
2153last_write_time(const path& __p) {
2154  return __last_write_time(__p);
2155}
2156
2157inline _LIBCPP_INLINE_VISIBILITY file_time_type
2158last_write_time(const path& __p, error_code& __ec) noexcept {
2159  return __last_write_time(__p, &__ec);
2160}
2161
2162inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
2163                                                      file_time_type __t) {
2164  __last_write_time(__p, __t);
2165}
2166
2167inline _LIBCPP_INLINE_VISIBILITY void
2168last_write_time(const path& __p, file_time_type __t,
2169                error_code& __ec) noexcept {
2170  __last_write_time(__p, __t, &__ec);
2171}
2172
2173inline _LIBCPP_INLINE_VISIBILITY void
2174permissions(const path& __p, perms __prms,
2175            perm_options __opts = perm_options::replace) {
2176  __permissions(__p, __prms, __opts);
2177}
2178
2179inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2180                                                  error_code& __ec) noexcept {
2181  __permissions(__p, __prms, perm_options::replace, &__ec);
2182}
2183
2184inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
2185                                                  perm_options __opts,
2186                                                  error_code& __ec) {
2187  __permissions(__p, __prms, __opts, &__ec);
2188}
2189
2190inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2191                                                const path& __base,
2192                                                error_code& __ec) {
2193  path __tmp = __weakly_canonical(__p, &__ec);
2194  if (__ec)
2195    return {};
2196  path __tmp_base = __weakly_canonical(__base, &__ec);
2197  if (__ec)
2198    return {};
2199  return __tmp.lexically_proximate(__tmp_base);
2200}
2201
2202inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
2203                                                error_code& __ec) {
2204  return proximate(__p, current_path(), __ec);
2205}
2206
2207inline _LIBCPP_INLINE_VISIBILITY path
2208proximate(const path& __p, const path& __base = current_path()) {
2209  return __weakly_canonical(__p).lexically_proximate(
2210      __weakly_canonical(__base));
2211}
2212
2213inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
2214  return __read_symlink(__p);
2215}
2216
2217inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
2218                                                   error_code& __ec) {
2219  return __read_symlink(__p, &__ec);
2220}
2221
2222inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2223                                               const path& __base,
2224                                               error_code& __ec) {
2225  path __tmp = __weakly_canonical(__p, &__ec);
2226  if (__ec)
2227    return path();
2228  path __tmpbase = __weakly_canonical(__base, &__ec);
2229  if (__ec)
2230    return path();
2231  return __tmp.lexically_relative(__tmpbase);
2232}
2233
2234inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
2235                                               error_code& __ec) {
2236  return relative(__p, current_path(), __ec);
2237}
2238
2239inline _LIBCPP_INLINE_VISIBILITY path
2240relative(const path& __p, const path& __base = current_path()) {
2241  return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
2242}
2243
2244inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
2245  return __remove(__p);
2246}
2247
2248inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
2249                                             error_code& __ec) noexcept {
2250  return __remove(__p, &__ec);
2251}
2252
2253inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
2254  return __remove_all(__p);
2255}
2256
2257inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
2258                                                      error_code& __ec) {
2259  return __remove_all(__p, &__ec);
2260}
2261
2262inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
2263                                             const path& __to) {
2264  return __rename(__from, __to);
2265}
2266
2267inline _LIBCPP_INLINE_VISIBILITY void
2268rename(const path& __from, const path& __to, error_code& __ec) noexcept {
2269  return __rename(__from, __to, &__ec);
2270}
2271
2272inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
2273                                                  uintmax_t __ns) {
2274  return __resize_file(__p, __ns);
2275}
2276
2277inline _LIBCPP_INLINE_VISIBILITY void
2278resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
2279  return __resize_file(__p, __ns, &__ec);
2280}
2281
2282inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
2283  return __space(__p);
2284}
2285
2286inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
2287                                                  error_code& __ec) noexcept {
2288  return __space(__p, &__ec);
2289}
2290
2291inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
2292  return __status(__p);
2293}
2294
2295inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
2296                                                    error_code& __ec) noexcept {
2297  return __status(__p, &__ec);
2298}
2299
2300inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
2301  return __symlink_status(__p);
2302}
2303
2304inline _LIBCPP_INLINE_VISIBILITY file_status
2305symlink_status(const path& __p, error_code& __ec) noexcept {
2306  return __symlink_status(__p, &__ec);
2307}
2308
2309inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
2310  return __temp_directory_path();
2311}
2312
2313inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
2314  return __temp_directory_path(&__ec);
2315}
2316
2317inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
2318  return __weakly_canonical(__p);
2319}
2320
2321inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
2322                                                       error_code& __ec) {
2323  return __weakly_canonical(__p, &__ec);
2324}
2325
2326class directory_iterator;
2327class recursive_directory_iterator;
2328class _LIBCPP_HIDDEN __dir_stream;
2329
2330class directory_entry {
2331  typedef _VSTD_FS::path _Path;
2332
2333public:
2334  // constructors and destructors
2335  directory_entry() noexcept = default;
2336  directory_entry(directory_entry const&) = default;
2337  directory_entry(directory_entry&&) noexcept = default;
2338
2339  _LIBCPP_INLINE_VISIBILITY
2340  explicit directory_entry(_Path const& __p) : __p_(__p) {
2341    error_code __ec;
2342    __refresh(&__ec);
2343  }
2344
2345  _LIBCPP_INLINE_VISIBILITY
2346  directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
2347    __refresh(&__ec);
2348  }
2349
2350  ~directory_entry() {}
2351
2352  directory_entry& operator=(directory_entry const&) = default;
2353  directory_entry& operator=(directory_entry&&) noexcept = default;
2354
2355  _LIBCPP_INLINE_VISIBILITY
2356  void assign(_Path const& __p) {
2357    __p_ = __p;
2358    error_code __ec;
2359    __refresh(&__ec);
2360  }
2361
2362  _LIBCPP_INLINE_VISIBILITY
2363  void assign(_Path const& __p, error_code& __ec) {
2364    __p_ = __p;
2365    __refresh(&__ec);
2366  }
2367
2368  _LIBCPP_INLINE_VISIBILITY
2369  void replace_filename(_Path const& __p) {
2370    __p_.replace_filename(__p);
2371    error_code __ec;
2372    __refresh(&__ec);
2373  }
2374
2375  _LIBCPP_INLINE_VISIBILITY
2376  void replace_filename(_Path const& __p, error_code& __ec) {
2377    __p_ = __p_.parent_path() / __p;
2378    __refresh(&__ec);
2379  }
2380
2381  _LIBCPP_INLINE_VISIBILITY
2382  void refresh() { __refresh(); }
2383
2384  _LIBCPP_INLINE_VISIBILITY
2385  void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
2386
2387  _LIBCPP_INLINE_VISIBILITY
2388  _Path const& path() const noexcept { return __p_; }
2389
2390  _LIBCPP_INLINE_VISIBILITY
2391  operator const _Path&() const noexcept { return __p_; }
2392
2393  _LIBCPP_INLINE_VISIBILITY
2394  bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
2395
2396  _LIBCPP_INLINE_VISIBILITY
2397  bool exists(error_code& __ec) const noexcept {
2398    return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
2399  }
2400
2401  _LIBCPP_INLINE_VISIBILITY
2402  bool is_block_file() const { return __get_ft() == file_type::block; }
2403
2404  _LIBCPP_INLINE_VISIBILITY
2405  bool is_block_file(error_code& __ec) const noexcept {
2406    return __get_ft(&__ec) == file_type::block;
2407  }
2408
2409  _LIBCPP_INLINE_VISIBILITY
2410  bool is_character_file() const { return __get_ft() == file_type::character; }
2411
2412  _LIBCPP_INLINE_VISIBILITY
2413  bool is_character_file(error_code& __ec) const noexcept {
2414    return __get_ft(&__ec) == file_type::character;
2415  }
2416
2417  _LIBCPP_INLINE_VISIBILITY
2418  bool is_directory() const { return __get_ft() == file_type::directory; }
2419
2420  _LIBCPP_INLINE_VISIBILITY
2421  bool is_directory(error_code& __ec) const noexcept {
2422    return __get_ft(&__ec) == file_type::directory;
2423  }
2424
2425  _LIBCPP_INLINE_VISIBILITY
2426  bool is_fifo() const { return __get_ft() == file_type::fifo; }
2427
2428  _LIBCPP_INLINE_VISIBILITY
2429  bool is_fifo(error_code& __ec) const noexcept {
2430    return __get_ft(&__ec) == file_type::fifo;
2431  }
2432
2433  _LIBCPP_INLINE_VISIBILITY
2434  bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
2435
2436  _LIBCPP_INLINE_VISIBILITY
2437  bool is_other(error_code& __ec) const noexcept {
2438    return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
2439  }
2440
2441  _LIBCPP_INLINE_VISIBILITY
2442  bool is_regular_file() const { return __get_ft() == file_type::regular; }
2443
2444  _LIBCPP_INLINE_VISIBILITY
2445  bool is_regular_file(error_code& __ec) const noexcept {
2446    return __get_ft(&__ec) == file_type::regular;
2447  }
2448
2449  _LIBCPP_INLINE_VISIBILITY
2450  bool is_socket() const { return __get_ft() == file_type::socket; }
2451
2452  _LIBCPP_INLINE_VISIBILITY
2453  bool is_socket(error_code& __ec) const noexcept {
2454    return __get_ft(&__ec) == file_type::socket;
2455  }
2456
2457  _LIBCPP_INLINE_VISIBILITY
2458  bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
2459
2460  _LIBCPP_INLINE_VISIBILITY
2461  bool is_symlink(error_code& __ec) const noexcept {
2462    return __get_sym_ft(&__ec) == file_type::symlink;
2463  }
2464  _LIBCPP_INLINE_VISIBILITY
2465  uintmax_t file_size() const { return __get_size(); }
2466
2467  _LIBCPP_INLINE_VISIBILITY
2468  uintmax_t file_size(error_code& __ec) const noexcept {
2469    return __get_size(&__ec);
2470  }
2471
2472  _LIBCPP_INLINE_VISIBILITY
2473  uintmax_t hard_link_count() const { return __get_nlink(); }
2474
2475  _LIBCPP_INLINE_VISIBILITY
2476  uintmax_t hard_link_count(error_code& __ec) const noexcept {
2477    return __get_nlink(&__ec);
2478  }
2479
2480  _LIBCPP_INLINE_VISIBILITY
2481  file_time_type last_write_time() const { return __get_write_time(); }
2482
2483  _LIBCPP_INLINE_VISIBILITY
2484  file_time_type last_write_time(error_code& __ec) const noexcept {
2485    return __get_write_time(&__ec);
2486  }
2487
2488  _LIBCPP_INLINE_VISIBILITY
2489  file_status status() const { return __get_status(); }
2490
2491  _LIBCPP_INLINE_VISIBILITY
2492  file_status status(error_code& __ec) const noexcept {
2493    return __get_status(&__ec);
2494  }
2495
2496  _LIBCPP_INLINE_VISIBILITY
2497  file_status symlink_status() const { return __get_symlink_status(); }
2498
2499  _LIBCPP_INLINE_VISIBILITY
2500  file_status symlink_status(error_code& __ec) const noexcept {
2501    return __get_symlink_status(&__ec);
2502  }
2503
2504  _LIBCPP_INLINE_VISIBILITY
2505  bool operator<(directory_entry const& __rhs) const noexcept {
2506    return __p_ < __rhs.__p_;
2507  }
2508
2509  _LIBCPP_INLINE_VISIBILITY
2510  bool operator==(directory_entry const& __rhs) const noexcept {
2511    return __p_ == __rhs.__p_;
2512  }
2513
2514  _LIBCPP_INLINE_VISIBILITY
2515  bool operator!=(directory_entry const& __rhs) const noexcept {
2516    return __p_ != __rhs.__p_;
2517  }
2518
2519  _LIBCPP_INLINE_VISIBILITY
2520  bool operator<=(directory_entry const& __rhs) const noexcept {
2521    return __p_ <= __rhs.__p_;
2522  }
2523
2524  _LIBCPP_INLINE_VISIBILITY
2525  bool operator>(directory_entry const& __rhs) const noexcept {
2526    return __p_ > __rhs.__p_;
2527  }
2528
2529  _LIBCPP_INLINE_VISIBILITY
2530  bool operator>=(directory_entry const& __rhs) const noexcept {
2531    return __p_ >= __rhs.__p_;
2532  }
2533
2534private:
2535  friend class directory_iterator;
2536  friend class recursive_directory_iterator;
2537  friend class __dir_stream;
2538
2539  enum _CacheType : unsigned char {
2540    _Empty,
2541    _IterSymlink,
2542    _IterNonSymlink,
2543    _RefreshSymlink,
2544    _RefreshSymlinkUnresolved,
2545    _RefreshNonSymlink
2546  };
2547
2548  struct __cached_data {
2549    uintmax_t __size_;
2550    uintmax_t __nlink_;
2551    file_time_type __write_time_;
2552    perms __sym_perms_;
2553    perms __non_sym_perms_;
2554    file_type __type_;
2555    _CacheType __cache_type_;
2556
2557    _LIBCPP_INLINE_VISIBILITY
2558    __cached_data() noexcept { __reset(); }
2559
2560    _LIBCPP_INLINE_VISIBILITY
2561    void __reset() {
2562      __cache_type_ = _Empty;
2563      __type_ = file_type::none;
2564      __sym_perms_ = __non_sym_perms_ = perms::unknown;
2565      __size_ = __nlink_ = uintmax_t(-1);
2566      __write_time_ = file_time_type::min();
2567    }
2568  };
2569
2570  _LIBCPP_INLINE_VISIBILITY
2571  static __cached_data __create_iter_result(file_type __ft) {
2572    __cached_data __data;
2573    __data.__type_ = __ft;
2574    __data.__cache_type_ = [&]() {
2575      switch (__ft) {
2576      case file_type::none:
2577        return _Empty;
2578      case file_type::symlink:
2579        return _IterSymlink;
2580      default:
2581        return _IterNonSymlink;
2582      }
2583    }();
2584    return __data;
2585  }
2586
2587  _LIBCPP_INLINE_VISIBILITY
2588  void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2589    __p_ = _VSTD::move(__p);
2590    __data_ = __dt;
2591  }
2592
2593  _LIBCPP_FUNC_VIS
2594  error_code __do_refresh() noexcept;
2595
2596  _LIBCPP_INLINE_VISIBILITY
2597  static bool __is_dne_error(error_code const& __ec) {
2598    if (!__ec)
2599      return true;
2600    switch (static_cast<errc>(__ec.value())) {
2601    case errc::no_such_file_or_directory:
2602    case errc::not_a_directory:
2603      return true;
2604    default:
2605      return false;
2606    }
2607  }
2608
2609  _LIBCPP_INLINE_VISIBILITY
2610  void __handle_error(const char* __msg, error_code* __dest_ec,
2611                      error_code const& __ec, bool __allow_dne = false) const {
2612    if (__dest_ec) {
2613      *__dest_ec = __ec;
2614      return;
2615    }
2616    if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2617      __throw_filesystem_error(__msg, __p_, __ec);
2618  }
2619
2620  _LIBCPP_INLINE_VISIBILITY
2621  void __refresh(error_code* __ec = nullptr) {
2622    __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
2623                   /*allow_dne*/ true);
2624  }
2625
2626  _LIBCPP_INLINE_VISIBILITY
2627  file_type __get_sym_ft(error_code* __ec = nullptr) const {
2628    switch (__data_.__cache_type_) {
2629    case _Empty:
2630      return __symlink_status(__p_, __ec).type();
2631    case _IterSymlink:
2632    case _RefreshSymlink:
2633    case _RefreshSymlinkUnresolved:
2634      if (__ec)
2635        __ec->clear();
2636      return file_type::symlink;
2637    case _IterNonSymlink:
2638    case _RefreshNonSymlink:
2639      file_status __st(__data_.__type_);
2640      if (__ec && !_VSTD_FS::exists(__st))
2641        *__ec = make_error_code(errc::no_such_file_or_directory);
2642      else if (__ec)
2643        __ec->clear();
2644      return __data_.__type_;
2645    }
2646    _LIBCPP_UNREACHABLE();
2647  }
2648
2649  _LIBCPP_INLINE_VISIBILITY
2650  file_type __get_ft(error_code* __ec = nullptr) const {
2651    switch (__data_.__cache_type_) {
2652    case _Empty:
2653    case _IterSymlink:
2654    case _RefreshSymlinkUnresolved:
2655      return __status(__p_, __ec).type();
2656    case _IterNonSymlink:
2657    case _RefreshNonSymlink:
2658    case _RefreshSymlink: {
2659      file_status __st(__data_.__type_);
2660      if (__ec && !_VSTD_FS::exists(__st))
2661        *__ec = make_error_code(errc::no_such_file_or_directory);
2662      else if (__ec)
2663        __ec->clear();
2664      return __data_.__type_;
2665    }
2666    }
2667    _LIBCPP_UNREACHABLE();
2668  }
2669
2670  _LIBCPP_INLINE_VISIBILITY
2671  file_status __get_status(error_code* __ec = nullptr) const {
2672    switch (__data_.__cache_type_) {
2673    case _Empty:
2674    case _IterNonSymlink:
2675    case _IterSymlink:
2676    case _RefreshSymlinkUnresolved:
2677      return __status(__p_, __ec);
2678    case _RefreshNonSymlink:
2679    case _RefreshSymlink:
2680      return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
2681    }
2682    _LIBCPP_UNREACHABLE();
2683  }
2684
2685  _LIBCPP_INLINE_VISIBILITY
2686  file_status __get_symlink_status(error_code* __ec = nullptr) const {
2687    switch (__data_.__cache_type_) {
2688    case _Empty:
2689    case _IterNonSymlink:
2690    case _IterSymlink:
2691      return __symlink_status(__p_, __ec);
2692    case _RefreshNonSymlink:
2693      return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
2694    case _RefreshSymlink:
2695    case _RefreshSymlinkUnresolved:
2696      return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
2697    }
2698    _LIBCPP_UNREACHABLE();
2699  }
2700
2701  _LIBCPP_INLINE_VISIBILITY
2702  uintmax_t __get_size(error_code* __ec = nullptr) const {
2703    switch (__data_.__cache_type_) {
2704    case _Empty:
2705    case _IterNonSymlink:
2706    case _IterSymlink:
2707    case _RefreshSymlinkUnresolved:
2708      return _VSTD_FS::__file_size(__p_, __ec);
2709    case _RefreshSymlink:
2710    case _RefreshNonSymlink: {
2711      error_code __m_ec;
2712      file_status __st(__get_ft(&__m_ec));
2713      __handle_error("in directory_entry::file_size", __ec, __m_ec);
2714      if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
2715        errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
2716                                                       : errc::not_supported;
2717        __handle_error("in directory_entry::file_size", __ec,
2718                       make_error_code(__err_kind));
2719      }
2720      return __data_.__size_;
2721    }
2722    }
2723    _LIBCPP_UNREACHABLE();
2724  }
2725
2726  _LIBCPP_INLINE_VISIBILITY
2727  uintmax_t __get_nlink(error_code* __ec = nullptr) const {
2728    switch (__data_.__cache_type_) {
2729    case _Empty:
2730    case _IterNonSymlink:
2731    case _IterSymlink:
2732    case _RefreshSymlinkUnresolved:
2733      return _VSTD_FS::__hard_link_count(__p_, __ec);
2734    case _RefreshSymlink:
2735    case _RefreshNonSymlink: {
2736      error_code __m_ec;
2737      (void)__get_ft(&__m_ec);
2738      __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
2739      return __data_.__nlink_;
2740    }
2741    }
2742    _LIBCPP_UNREACHABLE();
2743  }
2744
2745  _LIBCPP_INLINE_VISIBILITY
2746  file_time_type __get_write_time(error_code* __ec = nullptr) const {
2747    switch (__data_.__cache_type_) {
2748    case _Empty:
2749    case _IterNonSymlink:
2750    case _IterSymlink:
2751    case _RefreshSymlinkUnresolved:
2752      return _VSTD_FS::__last_write_time(__p_, __ec);
2753    case _RefreshSymlink:
2754    case _RefreshNonSymlink: {
2755      error_code __m_ec;
2756      file_status __st(__get_ft(&__m_ec));
2757      __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
2758      if (_VSTD_FS::exists(__st) &&
2759          __data_.__write_time_ == file_time_type::min())
2760        __handle_error("in directory_entry::last_write_time", __ec,
2761                       make_error_code(errc::value_too_large));
2762      return __data_.__write_time_;
2763    }
2764    }
2765    _LIBCPP_UNREACHABLE();
2766  }
2767
2768private:
2769  _Path __p_;
2770  __cached_data __data_;
2771};
2772
2773class __dir_element_proxy {
2774public:
2775  inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
2776    return _VSTD::move(__elem_);
2777  }
2778
2779private:
2780  friend class directory_iterator;
2781  friend class recursive_directory_iterator;
2782  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
2783  __dir_element_proxy(__dir_element_proxy&& __o)
2784      : __elem_(_VSTD::move(__o.__elem_)) {}
2785  directory_entry __elem_;
2786};
2787
2788class directory_iterator {
2789public:
2790  typedef directory_entry value_type;
2791  typedef ptrdiff_t difference_type;
2792  typedef value_type const* pointer;
2793  typedef value_type const& reference;
2794  typedef input_iterator_tag iterator_category;
2795
2796public:
2797  //ctor & dtor
2798  directory_iterator() noexcept {}
2799
2800  explicit directory_iterator(const path& __p)
2801      : directory_iterator(__p, nullptr) {}
2802
2803  directory_iterator(const path& __p, directory_options __opts)
2804      : directory_iterator(__p, nullptr, __opts) {}
2805
2806  directory_iterator(const path& __p, error_code& __ec)
2807      : directory_iterator(__p, &__ec) {}
2808
2809  directory_iterator(const path& __p, directory_options __opts,
2810                     error_code& __ec)
2811      : directory_iterator(__p, &__ec, __opts) {}
2812
2813  directory_iterator(const directory_iterator&) = default;
2814  directory_iterator(directory_iterator&&) = default;
2815  directory_iterator& operator=(const directory_iterator&) = default;
2816
2817  directory_iterator& operator=(directory_iterator&& __o) noexcept {
2818    // non-default implementation provided to support self-move assign.
2819    if (this != &__o) {
2820      __imp_ = _VSTD::move(__o.__imp_);
2821    }
2822    return *this;
2823  }
2824
2825  ~directory_iterator() = default;
2826
2827  const directory_entry& operator*() const {
2828    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
2829    return __dereference();
2830  }
2831
2832  const directory_entry* operator->() const { return &**this; }
2833
2834  directory_iterator& operator++() { return __increment(); }
2835
2836  __dir_element_proxy operator++(int) {
2837    __dir_element_proxy __p(**this);
2838    __increment();
2839    return __p;
2840  }
2841
2842  directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
2843
2844private:
2845  inline _LIBCPP_INLINE_VISIBILITY friend bool
2846  operator==(const directory_iterator& __lhs,
2847             const directory_iterator& __rhs) noexcept;
2848
2849  // construct the dir_stream
2850  _LIBCPP_FUNC_VIS
2851  directory_iterator(const path&, error_code*,
2852                     directory_options = directory_options::none);
2853
2854  _LIBCPP_FUNC_VIS
2855  directory_iterator& __increment(error_code* __ec = nullptr);
2856
2857  _LIBCPP_FUNC_VIS
2858  const directory_entry& __dereference() const;
2859
2860private:
2861  shared_ptr<__dir_stream> __imp_;
2862};
2863
2864inline _LIBCPP_INLINE_VISIBILITY bool
2865operator==(const directory_iterator& __lhs,
2866           const directory_iterator& __rhs) noexcept {
2867  return __lhs.__imp_ == __rhs.__imp_;
2868}
2869
2870inline _LIBCPP_INLINE_VISIBILITY bool
2871operator!=(const directory_iterator& __lhs,
2872           const directory_iterator& __rhs) noexcept {
2873  return !(__lhs == __rhs);
2874}
2875
2876// enable directory_iterator range-based for statements
2877inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2878begin(directory_iterator __iter) noexcept {
2879  return __iter;
2880}
2881
2882inline _LIBCPP_INLINE_VISIBILITY directory_iterator
2883end(directory_iterator) noexcept {
2884  return directory_iterator();
2885}
2886
2887class recursive_directory_iterator {
2888public:
2889  using value_type = directory_entry;
2890  using difference_type = ptrdiff_t;
2891  using pointer = directory_entry const*;
2892  using reference = directory_entry const&;
2893  using iterator_category = input_iterator_tag;
2894
2895public:
2896  // constructors and destructor
2897  _LIBCPP_INLINE_VISIBILITY
2898  recursive_directory_iterator() noexcept : __rec_(false) {}
2899
2900  _LIBCPP_INLINE_VISIBILITY
2901  explicit recursive_directory_iterator(
2902      const path& __p, directory_options __xoptions = directory_options::none)
2903      : recursive_directory_iterator(__p, __xoptions, nullptr) {}
2904
2905  _LIBCPP_INLINE_VISIBILITY
2906  recursive_directory_iterator(const path& __p, directory_options __xoptions,
2907                               error_code& __ec)
2908      : recursive_directory_iterator(__p, __xoptions, &__ec) {}
2909
2910  _LIBCPP_INLINE_VISIBILITY
2911  recursive_directory_iterator(const path& __p, error_code& __ec)
2912      : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
2913
2914  recursive_directory_iterator(const recursive_directory_iterator&) = default;
2915  recursive_directory_iterator(recursive_directory_iterator&&) = default;
2916
2917  recursive_directory_iterator&
2918  operator=(const recursive_directory_iterator&) = default;
2919
2920  _LIBCPP_INLINE_VISIBILITY
2921  recursive_directory_iterator&
2922  operator=(recursive_directory_iterator&& __o) noexcept {
2923    // non-default implementation provided to support self-move assign.
2924    if (this != &__o) {
2925      __imp_ = _VSTD::move(__o.__imp_);
2926      __rec_ = __o.__rec_;
2927    }
2928    return *this;
2929  }
2930
2931  ~recursive_directory_iterator() = default;
2932
2933  _LIBCPP_INLINE_VISIBILITY
2934  const directory_entry& operator*() const { return __dereference(); }
2935
2936  _LIBCPP_INLINE_VISIBILITY
2937  const directory_entry* operator->() const { return &__dereference(); }
2938
2939  recursive_directory_iterator& operator++() { return __increment(); }
2940
2941  _LIBCPP_INLINE_VISIBILITY
2942  __dir_element_proxy operator++(int) {
2943    __dir_element_proxy __p(**this);
2944    __increment();
2945    return __p;
2946  }
2947
2948  _LIBCPP_INLINE_VISIBILITY
2949  recursive_directory_iterator& increment(error_code& __ec) {
2950    return __increment(&__ec);
2951  }
2952
2953  _LIBCPP_FUNC_VIS directory_options options() const;
2954  _LIBCPP_FUNC_VIS int depth() const;
2955
2956  _LIBCPP_INLINE_VISIBILITY
2957  void pop() { __pop(); }
2958
2959  _LIBCPP_INLINE_VISIBILITY
2960  void pop(error_code& __ec) { __pop(&__ec); }
2961
2962  _LIBCPP_INLINE_VISIBILITY
2963  bool recursion_pending() const { return __rec_; }
2964
2965  _LIBCPP_INLINE_VISIBILITY
2966  void disable_recursion_pending() { __rec_ = false; }
2967
2968private:
2969  _LIBCPP_FUNC_VIS
2970  recursive_directory_iterator(const path& __p, directory_options __opt,
2971                               error_code* __ec);
2972
2973  _LIBCPP_FUNC_VIS
2974  const directory_entry& __dereference() const;
2975
2976  _LIBCPP_FUNC_VIS
2977  bool __try_recursion(error_code* __ec);
2978
2979  _LIBCPP_FUNC_VIS
2980  void __advance(error_code* __ec = nullptr);
2981
2982  _LIBCPP_FUNC_VIS
2983  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
2984
2985  _LIBCPP_FUNC_VIS
2986  void __pop(error_code* __ec = nullptr);
2987
2988  inline _LIBCPP_INLINE_VISIBILITY friend bool
2989  operator==(const recursive_directory_iterator&,
2990             const recursive_directory_iterator&) noexcept;
2991
2992  struct _LIBCPP_HIDDEN __shared_imp;
2993  shared_ptr<__shared_imp> __imp_;
2994  bool __rec_;
2995}; // class recursive_directory_iterator
2996
2997inline _LIBCPP_INLINE_VISIBILITY bool
2998operator==(const recursive_directory_iterator& __lhs,
2999           const recursive_directory_iterator& __rhs) noexcept {
3000  return __lhs.__imp_ == __rhs.__imp_;
3001}
3002
3003_LIBCPP_INLINE_VISIBILITY
3004inline bool operator!=(const recursive_directory_iterator& __lhs,
3005                       const recursive_directory_iterator& __rhs) noexcept {
3006  return !(__lhs == __rhs);
3007}
3008// enable recursive_directory_iterator range-based for statements
3009inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
3010begin(recursive_directory_iterator __iter) noexcept {
3011  return __iter;
3012}
3013
3014inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
3015end(recursive_directory_iterator) noexcept {
3016  return recursive_directory_iterator();
3017}
3018
3019_LIBCPP_AVAILABILITY_FILESYSTEM_POP
3020
3021_LIBCPP_END_NAMESPACE_FILESYSTEM
3022
3023#if !defined(_LIBCPP_HAS_NO_RANGES)
3024template <>
3025inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true;
3026template <>
3027inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true;
3028
3029template <>
3030inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
3031template <>
3032inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
3033#endif
3034
3035#endif // !_LIBCPP_CXX03_LANG
3036
3037_LIBCPP_POP_MACROS
3038
3039#endif // _LIBCPP_FILESYSTEM
3040