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