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