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