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