1// -*- C++ -*-
2//===--------------------------- filesystem -------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10#ifndef _LIBCPP_EXPERIMENTAL_FILESYSTEM
11#define _LIBCPP_EXPERIMENTAL_FILESYSTEM
12/*
13    filesystem synopsis
14
15    namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
16
17    class path;
18
19    void swap(path& lhs, path& rhs) _NOEXCEPT;
20    size_t hash_value(const path& p) _NOEXCEPT;
21
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    bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT;
28
29    path operator/ (const path& lhs, const path& rhs);
30
31    // fs.path.io operators are friends of path.
32    template <class charT, class traits>
33    friend basic_ostream<charT, traits>&
34    operator<<(basic_ostream<charT, traits>& os, const path& p);
35
36    template <class charT, class traits>
37    friend basic_istream<charT, traits>&
38    operator>>(basic_istream<charT, traits>& is, path& p);
39
40    template <class Source>
41      path u8path(const Source& source);
42    template <class InputIterator>
43      path u8path(InputIterator first, InputIterator last);
44
45    class filesystem_error;
46    class directory_entry;
47
48    class directory_iterator;
49
50    // enable directory_iterator range-based for statements
51    directory_iterator begin(directory_iterator iter) noexcept;
52    directory_iterator end(const directory_iterator&) noexcept;
53
54    class recursive_directory_iterator;
55
56    // enable recursive_directory_iterator range-based for statements
57    recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
58    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
59
60    class file_status;
61
62    struct space_info
63    {
64      uintmax_t capacity;
65      uintmax_t free;
66      uintmax_t available;
67    };
68
69    enum class file_type;
70    enum class perms;
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, const path& base=current_path());
79
80    path canonical(const path& p, const path& base = current_path());
81    path canonical(const path& p, error_code& ec);
82    path canonical(const path& p, const path& base, 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    void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT;
183
184    path read_symlink(const path& p);
185    path read_symlink(const path& p, error_code& ec);
186
187    bool remove(const path& p);
188    bool remove(const path& p, error_code& ec) _NOEXCEPT;
189
190    uintmax_t    remove_all(const path& p);
191    uintmax_t    remove_all(const path& p, error_code& ec);
192
193    void rename(const path& from, const path& to);
194    void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT;
195
196    void resize_file(const path& p, uintmax_t size);
197    void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT;
198
199    space_info   space(const path& p);
200    space_info   space(const path& p, error_code& ec) _NOEXCEPT;
201
202    file_status  status(const path& p);
203    file_status  status(const path& p, error_code& ec) _NOEXCEPT;
204
205    bool status_known(file_status s) _NOEXCEPT;
206
207    file_status  symlink_status(const path& p);
208    file_status  symlink_status(const path& p, error_code& ec) _NOEXCEPT;
209
210    path system_complete(const path& p);
211    path system_complete(const path& p, error_code& ec);
212
213    path temp_directory_path();
214    path temp_directory_path(error_code& ec);
215
216} } } }  // namespaces std::experimental::filesystem::v1
217
218*/
219
220#include <experimental/__config>
221#include <cstddef>
222#include <chrono>
223#include <iterator>
224#include <iosfwd>
225#include <locale>
226#include <memory>
227#include <stack>
228#include <string>
229#include <system_error>
230#include <utility>
231#include <iomanip> // for quoted
232#include <string_view>
233
234#include <__debug>
235
236#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
237#pragma GCC system_header
238#endif
239
240#define __cpp_lib_experimental_filesystem 201406
241
242_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
243
244typedef chrono::time_point<std::chrono::system_clock>  file_time_type;
245
246struct _LIBCPP_TYPE_VIS space_info
247{
248  uintmax_t capacity;
249  uintmax_t free;
250  uintmax_t available;
251};
252
253enum class _LIBCPP_ENUM_VIS file_type : signed char
254{
255    none       = 0,
256    not_found  = -1,
257    regular    = 1,
258    directory  = 2,
259    symlink    = 3,
260    block      = 4,
261    character  = 5,
262    fifo       = 6,
263    socket     = 7,
264    unknown    = 8
265};
266
267enum class _LIBCPP_ENUM_VIS perms : unsigned
268{
269    none         = 0,
270
271    owner_read   = 0400,
272    owner_write  = 0200,
273    owner_exec   = 0100,
274    owner_all    = 0700,
275
276    group_read   = 040,
277    group_write  = 020,
278    group_exec   = 010,
279    group_all    = 070,
280
281    others_read  = 04,
282    others_write = 02,
283    others_exec  = 01,
284    others_all   = 07,
285
286    all          = 0777,
287
288    set_uid      = 04000,
289    set_gid      = 02000,
290    sticky_bit   = 01000,
291    mask         = 07777,
292    unknown      = 0xFFFF,
293
294    add_perms        = 0x10000,
295    remove_perms     = 0x20000,
296    symlink_nofollow = 0x40000
297};
298
299_LIBCPP_INLINE_VISIBILITY
300inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS)
301{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
302
303_LIBCPP_INLINE_VISIBILITY
304inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS)
305{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
306
307_LIBCPP_INLINE_VISIBILITY
308inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS)
309{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
310
311_LIBCPP_INLINE_VISIBILITY
312inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS)
313{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); }
314
315_LIBCPP_INLINE_VISIBILITY
316inline perms& operator&=(perms& _LHS, perms _RHS)
317{ return _LHS = _LHS & _RHS; }
318
319_LIBCPP_INLINE_VISIBILITY
320inline perms& operator|=(perms& _LHS, perms _RHS)
321{ return _LHS = _LHS | _RHS; }
322
323_LIBCPP_INLINE_VISIBILITY
324inline perms& operator^=(perms& _LHS, perms _RHS)
325{ return _LHS = _LHS ^ _RHS; }
326
327enum class _LIBCPP_ENUM_VIS copy_options : unsigned short
328{
329    none               = 0,
330    skip_existing      = 1,
331    overwrite_existing = 2,
332    update_existing    = 4,
333    recursive          = 8,
334    copy_symlinks      = 16,
335    skip_symlinks      = 32,
336    directories_only   = 64,
337    create_symlinks    = 128,
338    create_hard_links  = 256,
339    __in_recursive_copy = 512,
340};
341
342_LIBCPP_INLINE_VISIBILITY
343inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS)
344{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); }
345
346_LIBCPP_INLINE_VISIBILITY
347inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS)
348{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); }
349
350_LIBCPP_INLINE_VISIBILITY
351inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS)
352{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); }
353
354_LIBCPP_INLINE_VISIBILITY
355inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS)
356{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); }
357
358_LIBCPP_INLINE_VISIBILITY
359inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS)
360{ return _LHS = _LHS & _RHS; }
361
362_LIBCPP_INLINE_VISIBILITY
363inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS)
364{ return _LHS = _LHS | _RHS; }
365
366_LIBCPP_INLINE_VISIBILITY
367inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS)
368{ return _LHS = _LHS ^ _RHS; }
369
370
371enum class _LIBCPP_ENUM_VIS directory_options : unsigned char
372{
373    none                     = 0,
374    follow_directory_symlink = 1,
375    skip_permission_denied   = 2
376};
377
378_LIBCPP_INLINE_VISIBILITY
379inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS)
380{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); }
381
382_LIBCPP_INLINE_VISIBILITY
383inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS)
384{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); }
385
386_LIBCPP_INLINE_VISIBILITY
387inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS)
388{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); }
389
390_LIBCPP_INLINE_VISIBILITY
391inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS)
392{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); }
393
394_LIBCPP_INLINE_VISIBILITY
395inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS)
396{ return _LHS = _LHS & _RHS; }
397
398_LIBCPP_INLINE_VISIBILITY
399inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS)
400{ return _LHS = _LHS | _RHS; }
401
402_LIBCPP_INLINE_VISIBILITY
403inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS)
404{ return _LHS = _LHS ^ _RHS; }
405
406
407class _LIBCPP_TYPE_VIS file_status
408{
409public:
410    // constructors
411    _LIBCPP_INLINE_VISIBILITY
412    file_status() _NOEXCEPT : file_status(file_type::none) {}
413    _LIBCPP_INLINE_VISIBILITY
414    explicit file_status(file_type __ft,
415                         perms __prms = perms::unknown) _NOEXCEPT
416      : __ft_(__ft), __prms_(__prms)
417    {}
418
419    file_status(const file_status&) _NOEXCEPT = default;
420    file_status(file_status&&) _NOEXCEPT = default;
421
422    _LIBCPP_INLINE_VISIBILITY
423    ~file_status() {}
424
425    file_status& operator=(const file_status&) _NOEXCEPT = default;
426    file_status& operator=(file_status&&) _NOEXCEPT = default;
427
428    // observers
429    _LIBCPP_ALWAYS_INLINE
430    file_type type() const _NOEXCEPT {
431        return __ft_;
432    }
433
434    _LIBCPP_ALWAYS_INLINE
435    perms permissions() const _NOEXCEPT {
436        return __prms_;
437    }
438
439    // modifiers
440    _LIBCPP_ALWAYS_INLINE
441    void type(file_type __ft) _NOEXCEPT {
442        __ft_ = __ft;
443    }
444
445    _LIBCPP_ALWAYS_INLINE
446    void permissions(perms __p) _NOEXCEPT {
447        __prms_ = __p;
448    }
449private:
450    file_type __ft_;
451    perms __prms_;
452};
453
454class _LIBCPP_TYPE_VIS directory_entry;
455
456template <class _Tp> struct __can_convert_char {
457  static const bool value = false;
458};
459template <class _Tp> struct __can_convert_char<const _Tp>
460    : public __can_convert_char<_Tp> {
461};
462template <> struct __can_convert_char<char> {
463    static const bool value = true;
464    using __char_type = char;
465};
466template <> struct __can_convert_char<wchar_t>  {
467    static const bool value = true;
468    using __char_type = wchar_t;
469};
470template <> struct __can_convert_char<char16_t> {
471    static const bool value = true;
472    using __char_type = char16_t;
473};
474template <> struct __can_convert_char<char32_t> {
475    static const bool value = true;
476    using __char_type = char32_t;
477};
478
479template <class _ECharT>
480typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
481__is_separator(_ECharT __e) {
482    return __e == _ECharT('/');
483};
484
485struct _NullSentinal {};
486
487template <class _Tp>
488using _Void = void;
489
490template <class _Tp, class = void>
491struct __is_pathable_string : public false_type {};
492
493template <class _ECharT, class _Traits, class _Alloc>
494struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>,
495                            _Void<typename __can_convert_char<_ECharT>::__char_type>>
496: public __can_convert_char<_ECharT>
497{
498    using _Str = basic_string<_ECharT, _Traits, _Alloc>;
499    using _Base = __can_convert_char<_ECharT>;
500    static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
501    static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
502    static _ECharT __first_or_null(_Str const& __s) {
503        return __s.empty() ? _ECharT{} : __s[0];
504    }
505};
506
507
508template <class _ECharT, class _Traits>
509struct __is_pathable_string<basic_string_view<_ECharT, _Traits>,
510                            _Void<typename __can_convert_char<_ECharT>::__char_type>>
511: public __can_convert_char<_ECharT>
512{
513    using _Str = basic_string_view<_ECharT, _Traits>;
514    using _Base = __can_convert_char<_ECharT>;
515    static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
516    static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); }
517    static _ECharT __first_or_null(_Str const& __s) {
518        return __s.empty() ? _ECharT{} : __s[0];
519    }
520};
521
522template <class _Source,
523          class _DS = typename decay<_Source>::type,
524          class _UnqualPtrType = typename remove_const<
525              typename remove_pointer<_DS>::type>::type,
526          bool _IsCharPtr = is_pointer<_DS>::value &&
527                            __can_convert_char<_UnqualPtrType>::value
528        >
529struct __is_pathable_char_array : false_type {};
530
531template <class _Source, class _ECharT, class _UPtr>
532struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
533        : __can_convert_char<typename remove_const<_ECharT>::type>
534{
535  using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
536
537  static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
538  static _ECharT const* __range_end(const _ECharT* __b)
539  {
540      using _Iter = const _ECharT*;
541      const _ECharT __sentinal = _ECharT{};
542      _Iter __e = __b;
543      for (; *__e != __sentinal; ++__e)
544          ;
545      return __e;
546  }
547
548  static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
549};
550
551template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void>
552struct __is_pathable_iter : false_type {};
553
554template <class _Iter>
555struct __is_pathable_iter<_Iter, true,
556        _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>>
557        : __can_convert_char<typename iterator_traits<_Iter>::value_type>
558{
559  using _ECharT = typename iterator_traits<_Iter>::value_type;
560  using _Base = __can_convert_char<_ECharT>;
561
562  static _Iter         __range_begin(_Iter __b) { return __b; }
563  static _NullSentinal __range_end(_Iter)       { return _NullSentinal{}; }
564
565  static _ECharT __first_or_null(_Iter __b) { return *__b; }
566};
567
568template <class _Tp, bool _IsStringT =  __is_pathable_string<_Tp>::value,
569                     bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
570                     bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value
571         >
572struct __is_pathable : false_type {
573  static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
574};
575
576template <class _Tp>
577struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
578
579
580template <class _Tp>
581struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {};
582
583
584template <class _Tp>
585struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
586
587
588template <class _ECharT>
589struct _PathCVT {
590    static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible");
591
592    typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower;
593
594    static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e)  {
595        _Narrower()(back_inserter(__dest), __b, __e);
596    }
597
598    template <class _Iter>
599    static void __append_range(string& __dest, _Iter __b, _Iter __e) {
600        static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
601        if (__b == __e) return;
602        basic_string<_ECharT> __tmp(__b, __e);
603        _Narrower()(back_inserter(__dest), __tmp.data(),
604                    __tmp.data() + __tmp.length());
605    }
606
607    template <class _Iter>
608    static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
609        static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
610        const _ECharT __sentinal = _ECharT{};
611        if (*__b == __sentinal) return;
612        basic_string<_ECharT> __tmp;
613        for (; *__b != __sentinal; ++__b)
614            __tmp.push_back(*__b);
615        _Narrower()(back_inserter(__dest), __tmp.data(),
616                    __tmp.data() + __tmp.length());
617    }
618
619    template <class _Source>
620    static void __append_source(string& __dest, _Source const& __s)
621    {
622        using _Traits = __is_pathable<_Source>;
623        __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s));
624    }
625};
626
627template <>
628struct _PathCVT<char> {
629
630    template <class _Iter>
631    static typename enable_if<
632        __is_exactly_input_iterator<_Iter>::value
633    >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
634        for (; __b != __e; ++__b)
635            __dest.push_back(*__b);
636    }
637
638    template <class _Iter>
639    static typename enable_if<
640        __is_forward_iterator<_Iter>::value
641    >::type __append_range(string& __dest, _Iter __b, _Iter __e) {
642        __dest.__append_forward_unsafe(__b, __e);
643    }
644
645    template <class _Iter>
646    static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
647        const char __sentinal = char{};
648        for (; *__b != __sentinal; ++__b)
649            __dest.push_back(*__b);
650    }
651
652    template <class _Source>
653    static void __append_source(string& __dest, _Source const& __s)
654    {
655        using _Traits = __is_pathable<_Source>;
656        __append_range(__dest, _Traits::__range_begin(__s),
657                               _Traits::__range_end(__s));
658    }
659};
660
661
662class _LIBCPP_TYPE_VIS path
663{
664    template <class _SourceOrIter, class _Tp = path&>
665    using _EnableIfPathable = typename
666        enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
667
668    template <class _Tp>
669    using _SourceChar = typename __is_pathable<_Tp>::__char_type;
670
671    template <class _Tp>
672    using _SourceCVT = _PathCVT<_SourceChar<_Tp>>;
673
674public:
675    typedef char value_type;
676    typedef basic_string<value_type> string_type;
677    typedef _VSTD::string_view __string_view;
678    static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
679
680    // constructors and destructor
681    _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
682    _LIBCPP_INLINE_VISIBILITY path(const path& __p)      : __pn_(__p.__pn_) {}
683    _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
684
685    _LIBCPP_INLINE_VISIBILITY
686    path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {}
687
688    template <
689        class _Source,
690        class = _EnableIfPathable<_Source, void>
691        >
692    path(const _Source& __src) {
693        _SourceCVT<_Source>::__append_source(__pn_, __src);
694    }
695
696    template <class _InputIt>
697    path(_InputIt __first, _InputIt __last) {
698        typedef typename iterator_traits<_InputIt>::value_type _ItVal;
699        _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
700    }
701
702    // TODO Implement locale conversions.
703    template <class _Source,
704              class = _EnableIfPathable<_Source, void>
705             >
706        path(const _Source& __src, const locale& __loc);
707    template <class _InputIt>
708        path(_InputIt __first, _InputIt _last, const locale& __loc);
709
710    _LIBCPP_INLINE_VISIBILITY
711    ~path() = default;
712
713    // assignments
714    _LIBCPP_INLINE_VISIBILITY
715    path& operator=(const path& __p) {
716        __pn_ = __p.__pn_;
717        return *this;
718    }
719
720    _LIBCPP_INLINE_VISIBILITY
721    path& operator=(path&& __p) _NOEXCEPT {
722        __pn_ = _VSTD::move(__p.__pn_);
723        return *this;
724    }
725
726    template <class = void>
727    _LIBCPP_INLINE_VISIBILITY
728    path& operator=(string_type&& __s) _NOEXCEPT {
729        __pn_ = _VSTD::move(__s);
730        return *this;
731    }
732
733    _LIBCPP_INLINE_VISIBILITY
734    path& assign(string_type&& __s) _NOEXCEPT {
735        __pn_ = _VSTD::move(__s);
736        return *this;
737    }
738
739    template <class _Source>
740    _LIBCPP_INLINE_VISIBILITY
741    _EnableIfPathable<_Source>
742    operator=(const _Source& __src)
743    { return this->assign(__src); }
744
745
746    template <class _Source>
747    _EnableIfPathable<_Source>
748    assign(const _Source& __src) {
749        __pn_.clear();
750        _SourceCVT<_Source>::__append_source(__pn_, __src);
751        return *this;
752    }
753
754    template <class _InputIt>
755    path& assign(_InputIt __first, _InputIt __last) {
756        typedef typename iterator_traits<_InputIt>::value_type _ItVal;
757        __pn_.clear();
758        _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
759        return *this;
760    }
761
762private:
763    template <class _ECharT>
764    void __append_sep_if_needed(_ECharT __first_or_null) {
765        const _ECharT __null_val = {};
766        bool __append_sep = !empty()                       &&
767                            !__is_separator(__pn_.back())  &&
768                            __first_or_null != __null_val  && // non-empty
769                            !__is_separator(__first_or_null);
770        if (__append_sep)
771            __pn_ += preferred_separator;
772    }
773
774public:
775    // appends
776    path& operator/=(const path& __p) {
777        _LIBCPP_ASSERT(!__p.has_root_name(),
778                      "cannot append to a path with a root name");
779        __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
780        __pn_ += __p.native();
781        return *this;
782    }
783
784    template <class _Source>
785    _LIBCPP_INLINE_VISIBILITY
786    _EnableIfPathable<_Source>
787    operator/=(const _Source& __src) {
788        return this->append(__src);
789    }
790
791    template <class _Source>
792    _EnableIfPathable<_Source>
793    append(const _Source& __src) {
794        using _Traits = __is_pathable<_Source>;
795        using _CVT = _PathCVT<_SourceChar<_Source>>;
796        __append_sep_if_needed(_Traits::__first_or_null(__src));
797        _CVT::__append_source(__pn_, __src);
798        return *this;
799    }
800
801    template <class _InputIt>
802    path& append(_InputIt __first, _InputIt __last) {
803        typedef typename iterator_traits<_InputIt>::value_type _ItVal;
804        static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
805        using _CVT = _PathCVT<_ItVal>;
806        if (__first != __last) {
807            __append_sep_if_needed(*__first);
808            _CVT::__append_range(__pn_, __first, __last);
809        }
810        return *this;
811    }
812
813    // concatenation
814    _LIBCPP_INLINE_VISIBILITY
815    path& operator+=(const path& __x) {
816        __pn_ += __x.__pn_;
817        return *this;
818    }
819
820    _LIBCPP_INLINE_VISIBILITY
821    path& operator+=(const string_type& __x) {
822        __pn_ += __x;
823        return *this;
824    }
825
826    _LIBCPP_INLINE_VISIBILITY
827    path& operator+=(__string_view __x) {
828        __pn_ += __x;
829        return *this;
830    }
831
832    _LIBCPP_INLINE_VISIBILITY
833    path& operator+=(const value_type* __x) {
834        __pn_ += __x;
835        return *this;
836    }
837
838    _LIBCPP_INLINE_VISIBILITY
839    path& operator+=(value_type __x) {
840        __pn_ += __x;
841        return *this;
842    }
843
844    template <class _ECharT>
845    typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
846    operator+=(_ECharT __x)
847    {
848        basic_string<_ECharT> __tmp;
849        __tmp += __x;
850        _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
851        return *this;
852    }
853
854    template <class _Source>
855    _EnableIfPathable<_Source>
856    operator+=(const _Source& __x) {
857       return this->concat(__x);
858    }
859
860    template <class _Source>
861    _EnableIfPathable<_Source>
862    concat(const _Source& __x) {
863         _SourceCVT<_Source>::__append_source(__pn_, __x);
864        return *this;
865    }
866
867    template <class _InputIt>
868    path& concat(_InputIt __first, _InputIt __last) {
869        typedef typename iterator_traits<_InputIt>::value_type _ItVal;
870        _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
871        return *this;
872    }
873
874    // modifiers
875    _LIBCPP_INLINE_VISIBILITY
876    void clear() _NOEXCEPT {
877        __pn_.clear();
878    }
879
880    path& make_preferred() { return *this; }
881
882    _LIBCPP_INLINE_VISIBILITY
883    path& remove_filename() {
884      if (__pn_.size() == __root_path_raw().size())
885        clear();
886      else
887        __pn_ = __parent_path();
888      return *this;
889    }
890
891    path& replace_filename(const path& __replacement) {
892        remove_filename();
893        return (*this /= __replacement);
894    }
895
896    path& replace_extension(const path& __replacement = path());
897
898    _LIBCPP_INLINE_VISIBILITY
899    void  swap(path& __rhs) _NOEXCEPT {
900        __pn_.swap(__rhs.__pn_);
901    }
902
903    // native format observers
904    _LIBCPP_INLINE_VISIBILITY
905    const string_type& native() const _NOEXCEPT {
906        return __pn_;
907    }
908
909    _LIBCPP_INLINE_VISIBILITY
910    const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); }
911
912    _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_;  }
913
914    template <class _ECharT, class _Traits = char_traits<_ECharT>,
915              class _Allocator = allocator<_ECharT> >
916    basic_string<_ECharT, _Traits, _Allocator>
917    string(const _Allocator& __a = _Allocator()) const {
918        using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>;
919        using _Str = basic_string<_ECharT, _Traits, _Allocator>;
920        _Str __s(__a);
921        __s.reserve(__pn_.size());
922        _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
923        return __s;
924    }
925
926    _LIBCPP_INLINE_VISIBILITY std::string    string()    const { return __pn_; }
927    _LIBCPP_INLINE_VISIBILITY std::wstring   wstring()   const { return string<wchar_t>(); }
928    _LIBCPP_INLINE_VISIBILITY std::string    u8string()  const { return __pn_; }
929    _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); }
930    _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); }
931
932    // generic format observers
933    template <class _ECharT, class _Traits = char_traits<_ECharT>,
934              class _Allocator = allocator<_ECharT>
935    >
936    basic_string<_ECharT, _Traits, _Allocator>
937    generic_string(const _Allocator& __a = _Allocator()) const {
938        return string<_ECharT, _Traits, _Allocator>(__a);
939    }
940
941    std::string    generic_string()    const { return __pn_; }
942    std::wstring   generic_wstring()   const { return string<wchar_t>(); }
943    std::string    generic_u8string()  const { return __pn_; }
944    std::u16string generic_u16string() const { return string<char16_t>(); }
945    std::u32string generic_u32string() const { return string<char32_t>(); }
946
947private:
948    int __compare(__string_view) const;
949    __string_view __root_name() const;
950    __string_view __root_directory() const;
951    __string_view __root_path_raw() const;
952    __string_view __relative_path() const;
953    __string_view __parent_path() const;
954    __string_view __filename() const;
955    __string_view __stem() const;
956    __string_view __extension() const;
957
958public:
959    // compare
960    _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);}
961    _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); }
962    _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); }
963    _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const  { return __compare(__s); }
964
965    // decomposition
966    _LIBCPP_INLINE_VISIBILITY path root_name()      const { return  string_type(__root_name()); }
967    _LIBCPP_INLINE_VISIBILITY path root_directory() const { return  string_type(__root_directory()); }
968    _LIBCPP_INLINE_VISIBILITY path root_path()      const { return root_name().append(string_type(__root_directory())); }
969    _LIBCPP_INLINE_VISIBILITY path relative_path()  const { return string_type(__relative_path()); }
970    _LIBCPP_INLINE_VISIBILITY path parent_path()    const { return string_type(__parent_path()); }
971    _LIBCPP_INLINE_VISIBILITY path filename()       const { return string_type(__filename()); }
972    _LIBCPP_INLINE_VISIBILITY path stem()           const { return string_type(__stem());}
973    _LIBCPP_INLINE_VISIBILITY path extension()      const { return string_type(__extension()); }
974
975    // query
976    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
977    bool empty() const _NOEXCEPT { return __pn_.empty(); }
978
979    _LIBCPP_INLINE_VISIBILITY bool has_root_name()      const { return !__root_name().empty(); }
980    _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); }
981    _LIBCPP_INLINE_VISIBILITY bool has_root_path()      const { return !__root_path_raw().empty(); }
982    _LIBCPP_INLINE_VISIBILITY bool has_relative_path()  const { return !__relative_path().empty(); }
983    _LIBCPP_INLINE_VISIBILITY bool has_parent_path()    const { return !__parent_path().empty(); }
984    _LIBCPP_INLINE_VISIBILITY bool has_filename()       const { return !__filename().empty(); }
985    _LIBCPP_INLINE_VISIBILITY bool has_stem()           const { return !__stem().empty(); }
986    _LIBCPP_INLINE_VISIBILITY bool has_extension()      const { return !__extension().empty(); }
987
988    _LIBCPP_INLINE_VISIBILITY bool is_absolute()        const { return has_root_directory(); }
989    _LIBCPP_INLINE_VISIBILITY bool is_relative()        const { return !is_absolute(); }
990
991    // iterators
992    class _LIBCPP_TYPE_VIS iterator;
993    typedef iterator const_iterator;
994
995    iterator begin() const;
996    iterator end() const;
997
998
999    template <class _CharT, class _Traits>
1000    _LIBCPP_INLINE_VISIBILITY
1001    friend typename enable_if<is_same<_CharT, char>::value &&
1002                       is_same<_Traits, char_traits<char>>::value,
1003                       basic_ostream<_CharT, _Traits>&
1004    >::type
1005    operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1006        __os << std::__quoted(__p.native());
1007        return __os;
1008    }
1009
1010    template <class _CharT, class _Traits>
1011    _LIBCPP_INLINE_VISIBILITY
1012    friend typename enable_if<!is_same<_CharT, char>::value ||
1013                       !is_same<_Traits, char_traits<char>>::value,
1014                       basic_ostream<_CharT, _Traits>&
1015    >::type
1016    operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1017        __os << std::__quoted(__p.string<_CharT, _Traits>());
1018        return __os;
1019    }
1020
1021    template <class _CharT, class _Traits>
1022    _LIBCPP_INLINE_VISIBILITY
1023    friend basic_istream<_CharT, _Traits>&
1024    operator>>(basic_istream<_CharT, _Traits>& __is, path& __p)
1025    {
1026        basic_string<_CharT, _Traits> __tmp;
1027        __is >> __quoted(__tmp);
1028        __p = __tmp;
1029        return __is;
1030    }
1031
1032private:
1033    inline _LIBCPP_INLINE_VISIBILITY
1034    path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; }
1035    string_type __pn_;
1036};
1037
1038inline _LIBCPP_ALWAYS_INLINE
1039void swap(path& __lhs, path& __rhs) _NOEXCEPT {
1040    __lhs.swap(__rhs);
1041}
1042
1043_LIBCPP_FUNC_VIS
1044size_t hash_value(const path& __p) _NOEXCEPT;
1045
1046inline _LIBCPP_INLINE_VISIBILITY
1047bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT
1048{ return __lhs.compare(__rhs) == 0; }
1049
1050inline _LIBCPP_INLINE_VISIBILITY
1051bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT
1052{ return __lhs.compare(__rhs) != 0; }
1053
1054inline _LIBCPP_INLINE_VISIBILITY
1055bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT
1056{ return __lhs.compare(__rhs) < 0; }
1057
1058inline _LIBCPP_INLINE_VISIBILITY
1059bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT
1060{ return __lhs.compare(__rhs) <= 0; }
1061
1062inline _LIBCPP_INLINE_VISIBILITY
1063bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT
1064{ return __lhs.compare(__rhs) > 0; }
1065
1066inline _LIBCPP_INLINE_VISIBILITY
1067bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
1068{ return __lhs.compare(__rhs) >= 0; }
1069
1070inline _LIBCPP_INLINE_VISIBILITY
1071path operator/(const path& __lhs, const path& __rhs) {
1072    return path(__lhs) /= __rhs;
1073}
1074
1075template <class _Source>
1076_LIBCPP_INLINE_VISIBILITY
1077typename enable_if<__is_pathable<_Source>::value, path>::type
1078u8path(const _Source& __s){
1079    static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1080        "u8path(Source const&) requires Source have a character type of type 'char'");
1081    return path(__s);
1082}
1083
1084template <class _InputIt>
1085_LIBCPP_INLINE_VISIBILITY
1086typename enable_if<__is_pathable<_InputIt>::value, path>::type
1087u8path(_InputIt __f, _InputIt __l) {
1088    static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1089        "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
1090    return path(__f, __l);
1091}
1092
1093class _LIBCPP_TYPE_VIS path::iterator
1094{
1095public:
1096    typedef bidirectional_iterator_tag iterator_category;
1097
1098    typedef path                       value_type;
1099    typedef std::ptrdiff_t             difference_type;
1100    typedef const path*                pointer;
1101    typedef const path&                reference;
1102
1103    typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
1104public:
1105    _LIBCPP_INLINE_VISIBILITY
1106    iterator() : __stashed_elem_(), __path_ptr_(nullptr),
1107                 __entry_(), __state_(__singular) {}
1108
1109    iterator(const iterator&) = default;
1110    ~iterator() = default;
1111
1112    iterator& operator=(const iterator&) = default;
1113
1114    _LIBCPP_INLINE_VISIBILITY
1115    reference operator*() const {
1116        return __stashed_elem_;
1117    }
1118
1119    _LIBCPP_INLINE_VISIBILITY
1120    pointer operator->() const {
1121        return &__stashed_elem_;
1122    }
1123
1124    _LIBCPP_INLINE_VISIBILITY
1125    iterator& operator++() {
1126        _LIBCPP_ASSERT(__state_ != __singular,
1127                       "attempting to increment a singular iterator");
1128        _LIBCPP_ASSERT(__state_ != __at_end,
1129                      "attempting to increment the end iterator");
1130        return __increment();
1131    }
1132
1133    _LIBCPP_INLINE_VISIBILITY
1134    iterator operator++(int) {
1135        iterator __it(*this);
1136        this->operator++();
1137        return __it;
1138    }
1139
1140    _LIBCPP_INLINE_VISIBILITY
1141    iterator& operator--() {
1142        _LIBCPP_ASSERT(__state_ != __singular,
1143                       "attempting to decrement a singular iterator");
1144        _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
1145                       "attempting to decrement the begin iterator");
1146        return __decrement();
1147    }
1148
1149    _LIBCPP_INLINE_VISIBILITY
1150    iterator operator--(int) {
1151        iterator __it(*this);
1152        this->operator--();
1153        return __it;
1154    }
1155
1156private:
1157    friend class path;
1158
1159    static constexpr unsigned char __singular = 0;
1160    static constexpr unsigned char __at_end = 6;
1161
1162    inline _LIBCPP_INLINE_VISIBILITY
1163    friend bool operator==(const iterator&, const iterator&);
1164
1165    iterator& __increment();
1166    iterator& __decrement();
1167
1168    path __stashed_elem_;
1169    const path* __path_ptr_;
1170    path::__string_view __entry_;
1171    unsigned char __state_;
1172};
1173
1174inline _LIBCPP_INLINE_VISIBILITY
1175bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
1176    return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
1177           __lhs.__entry_.data() == __rhs.__entry_.data();
1178}
1179
1180inline _LIBCPP_INLINE_VISIBILITY
1181bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
1182    return !(__lhs == __rhs);
1183}
1184
1185class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
1186{
1187public:
1188    _LIBCPP_INLINE_VISIBILITY
1189    filesystem_error(const string& __what, error_code __ec)
1190        : system_error(__ec, __what),
1191          __paths_(make_shared<_Storage>(path(), path()))
1192    {}
1193
1194    _LIBCPP_INLINE_VISIBILITY
1195    filesystem_error(const string& __what, const path& __p1, error_code __ec)
1196        : system_error(__ec, __what),
1197        __paths_(make_shared<_Storage>(__p1, path()))
1198    {}
1199
1200    _LIBCPP_INLINE_VISIBILITY
1201    filesystem_error(const string& __what, const path& __p1, const path& __p2,
1202                     error_code __ec)
1203        : system_error(__ec, __what),
1204          __paths_(make_shared<_Storage>(__p1, __p2))
1205    {}
1206
1207    _LIBCPP_INLINE_VISIBILITY
1208    const path& path1() const _NOEXCEPT {
1209        return __paths_->first;
1210    }
1211
1212    _LIBCPP_INLINE_VISIBILITY
1213    const path& path2() const _NOEXCEPT {
1214        return __paths_->second;
1215    }
1216
1217    ~filesystem_error() override; // key function
1218
1219    // TODO(ericwf): Create a custom error message.
1220    //const char* what() const _NOEXCEPT;
1221
1222private:
1223    typedef pair<path, path> _Storage;
1224    shared_ptr<_Storage> __paths_;
1225};
1226
1227template <class... _Args>
1228_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
1229#ifndef _LIBCPP_NO_EXCEPTIONS
1230void __throw_filesystem_error(_Args && ...__args)
1231{
1232    throw filesystem_error(std::forward<_Args>(__args)...);
1233}
1234#else
1235void __throw_filesystem_error(_Args&&...)
1236{
1237    _VSTD::abort();
1238}
1239#endif
1240
1241
1242// operational functions
1243
1244_LIBCPP_FUNC_VIS
1245path __canonical(const path&, const path&, error_code *__ec=nullptr);
1246_LIBCPP_FUNC_VIS
1247void __copy(const path& __from, const path& __to, copy_options __opt,
1248        error_code *__ec=nullptr);
1249_LIBCPP_FUNC_VIS
1250bool __copy_file(const path& __from, const path& __to, copy_options __opt,
1251        error_code *__ec=nullptr);
1252_LIBCPP_FUNC_VIS
1253void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
1254        error_code *__ec=nullptr);
1255_LIBCPP_FUNC_VIS
1256bool __create_directories(const path& p, error_code *ec=nullptr);
1257_LIBCPP_FUNC_VIS
1258bool __create_directory(const path& p, error_code *ec=nullptr);
1259_LIBCPP_FUNC_VIS
1260bool __create_directory(const path& p, const path & attributes,
1261        error_code *ec=nullptr);
1262_LIBCPP_FUNC_VIS
1263void __create_directory_symlink(const path& __to, const path& __new_symlink,
1264        error_code *__ec=nullptr);
1265_LIBCPP_FUNC_VIS
1266void __create_hard_link(const path& __to, const path& __new_hard_link,
1267        error_code *__ec=nullptr);
1268_LIBCPP_FUNC_VIS
1269void __create_symlink(const path& __to, const path& __new_symlink,
1270        error_code *__ec=nullptr);
1271_LIBCPP_FUNC_VIS
1272path __current_path(error_code *__ec=nullptr);
1273_LIBCPP_FUNC_VIS
1274void __current_path(const path&, error_code *__ec=nullptr);
1275_LIBCPP_FUNC_VIS
1276bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
1277_LIBCPP_FUNC_VIS
1278uintmax_t __file_size(const path&, error_code *__ec=nullptr);
1279_LIBCPP_FUNC_VIS
1280uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
1281_LIBCPP_FUNC_VIS
1282bool __fs_is_empty(const path& p, error_code *ec=nullptr);
1283_LIBCPP_FUNC_VIS
1284file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
1285_LIBCPP_FUNC_VIS
1286void __last_write_time(const path& p, file_time_type new_time,
1287        error_code *ec=nullptr);
1288_LIBCPP_FUNC_VIS
1289void __permissions(const path& p, perms prms, error_code *ec=nullptr);
1290_LIBCPP_FUNC_VIS
1291path __read_symlink(const path& p, error_code *ec=nullptr);
1292_LIBCPP_FUNC_VIS
1293bool __remove(const path& p, error_code *ec=nullptr);
1294_LIBCPP_FUNC_VIS
1295uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
1296_LIBCPP_FUNC_VIS
1297void __rename(const path& from, const path& to, error_code *ec=nullptr);
1298_LIBCPP_FUNC_VIS
1299void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
1300_LIBCPP_FUNC_VIS
1301space_info __space(const path&, error_code *__ec=nullptr);
1302_LIBCPP_FUNC_VIS
1303file_status __status(const path&, error_code *__ec=nullptr);
1304_LIBCPP_FUNC_VIS
1305file_status __symlink_status(const path&, error_code *__ec=nullptr);
1306_LIBCPP_FUNC_VIS
1307path __system_complete(const path&, error_code *__ec=nullptr);
1308_LIBCPP_FUNC_VIS
1309path __temp_directory_path(error_code *__ec=nullptr);
1310
1311inline _LIBCPP_INLINE_VISIBILITY
1312path current_path() {
1313    return __current_path();
1314}
1315
1316inline _LIBCPP_INLINE_VISIBILITY
1317path current_path(error_code& __ec) {
1318    return __current_path(&__ec);
1319}
1320
1321inline _LIBCPP_INLINE_VISIBILITY
1322void current_path(const path& __p) {
1323    __current_path(__p);
1324}
1325
1326inline _LIBCPP_INLINE_VISIBILITY
1327void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
1328    __current_path(__p, &__ec);
1329}
1330
1331_LIBCPP_FUNC_VIS
1332path absolute(const path&, const path& __p2 = current_path());
1333
1334inline _LIBCPP_INLINE_VISIBILITY
1335path canonical(const path& __p, const path& __base = current_path()) {
1336    return __canonical(__p, __base);
1337}
1338
1339inline _LIBCPP_INLINE_VISIBILITY
1340path canonical(const path& __p, error_code& __ec) {
1341    path __base = __current_path(&__ec);
1342    if (__ec) return {};
1343    return __canonical(__p, __base, &__ec);
1344}
1345
1346inline _LIBCPP_INLINE_VISIBILITY
1347path canonical(const path& __p, const path& __base, error_code& __ec) {
1348    return __canonical(__p, __base, &__ec);
1349}
1350
1351inline _LIBCPP_INLINE_VISIBILITY
1352void copy(const path& __from, const path& __to) {
1353    __copy(__from, __to, copy_options::none);
1354}
1355
1356inline _LIBCPP_INLINE_VISIBILITY
1357void copy(const path& __from, const path& __to, error_code& __ec) {
1358    __copy(__from, __to, copy_options::none, &__ec);
1359}
1360
1361inline _LIBCPP_INLINE_VISIBILITY
1362void copy(const path& __from, const path& __to, copy_options __opt) {
1363    __copy(__from, __to, __opt);
1364}
1365
1366inline _LIBCPP_INLINE_VISIBILITY
1367void copy(const path& __from, const path& __to,
1368          copy_options __opt, error_code& __ec) {
1369    __copy(__from, __to, __opt, &__ec);
1370}
1371
1372inline _LIBCPP_INLINE_VISIBILITY
1373bool copy_file(const path& __from, const path& __to) {
1374    return __copy_file(__from, __to, copy_options::none);
1375}
1376
1377inline _LIBCPP_INLINE_VISIBILITY
1378bool copy_file(const path& __from, const path& __to, error_code& __ec) {
1379    return __copy_file(__from, __to, copy_options::none, &__ec);
1380}
1381
1382inline _LIBCPP_INLINE_VISIBILITY
1383bool copy_file(const path& __from, const path& __to, copy_options __opt) {
1384    return __copy_file(__from, __to, __opt);
1385}
1386
1387inline _LIBCPP_INLINE_VISIBILITY
1388bool copy_file(const path& __from, const path& __to,
1389               copy_options __opt, error_code& __ec){
1390    return __copy_file(__from, __to, __opt, &__ec);
1391}
1392
1393inline _LIBCPP_INLINE_VISIBILITY
1394void copy_symlink(const path& __existing, const path& __new) {
1395    __copy_symlink(__existing, __new);
1396}
1397
1398inline _LIBCPP_INLINE_VISIBILITY
1399void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
1400    __copy_symlink(__ext, __new, &__ec);
1401}
1402
1403inline _LIBCPP_INLINE_VISIBILITY
1404bool create_directories(const path& __p) {
1405    return __create_directories(__p);
1406}
1407
1408inline _LIBCPP_INLINE_VISIBILITY
1409bool create_directories(const path& __p, error_code& __ec) {
1410    return __create_directories(__p, &__ec);
1411}
1412
1413inline _LIBCPP_INLINE_VISIBILITY
1414bool create_directory(const path& __p) {
1415    return __create_directory(__p);
1416}
1417
1418inline _LIBCPP_INLINE_VISIBILITY
1419bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1420    return __create_directory(__p, &__ec);
1421}
1422
1423inline _LIBCPP_INLINE_VISIBILITY
1424bool create_directory(const path& __p, const path& __attrs) {
1425    return __create_directory(__p, __attrs);
1426}
1427
1428inline _LIBCPP_INLINE_VISIBILITY
1429bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
1430    return __create_directory(__p, __attrs, &__ec);
1431}
1432
1433inline _LIBCPP_INLINE_VISIBILITY
1434void create_directory_symlink(const path& __to, const path& __new) {
1435    __create_directory_symlink(__to, __new);
1436}
1437
1438inline _LIBCPP_INLINE_VISIBILITY
1439void create_directory_symlink(const path& __to, const path& __new,
1440                              error_code& __ec) _NOEXCEPT {
1441    __create_directory_symlink(__to, __new, &__ec);
1442}
1443
1444inline _LIBCPP_INLINE_VISIBILITY
1445void create_hard_link(const path& __to, const path& __new) {
1446    __create_hard_link(__to, __new);
1447}
1448
1449inline _LIBCPP_INLINE_VISIBILITY
1450void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1451    __create_hard_link(__to, __new, &__ec);
1452}
1453
1454inline _LIBCPP_INLINE_VISIBILITY
1455void create_symlink(const path& __to, const path& __new) {
1456    __create_symlink(__to, __new);
1457}
1458
1459inline _LIBCPP_INLINE_VISIBILITY
1460void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
1461    return __create_symlink(__to, __new, &__ec);
1462}
1463
1464inline _LIBCPP_INLINE_VISIBILITY
1465bool status_known(file_status __s) _NOEXCEPT {
1466    return __s.type() != file_type::none;
1467}
1468
1469inline _LIBCPP_INLINE_VISIBILITY
1470bool exists(file_status __s) _NOEXCEPT {
1471    return status_known(__s) && __s.type() != file_type::not_found;
1472}
1473
1474inline _LIBCPP_INLINE_VISIBILITY
1475bool exists(const path& __p) {
1476    return exists(__status(__p));
1477}
1478
1479inline _LIBCPP_INLINE_VISIBILITY
1480bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
1481    auto __s = __status(__p, &__ec);
1482    if (status_known(__s)) __ec.clear();
1483    return exists(__s);
1484}
1485
1486inline _LIBCPP_INLINE_VISIBILITY
1487bool equivalent(const path& __p1, const path& __p2) {
1488    return __equivalent(__p1, __p2);
1489}
1490
1491inline _LIBCPP_INLINE_VISIBILITY
1492bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
1493    return __equivalent(__p1, __p2, &__ec);
1494}
1495
1496inline _LIBCPP_INLINE_VISIBILITY
1497uintmax_t file_size(const path& __p) {
1498    return __file_size(__p);
1499}
1500
1501inline _LIBCPP_INLINE_VISIBILITY
1502uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
1503    return __file_size(__p, &__ec);
1504}
1505
1506inline _LIBCPP_INLINE_VISIBILITY
1507uintmax_t hard_link_count(const path& __p) {
1508    return __hard_link_count(__p);
1509}
1510
1511inline _LIBCPP_INLINE_VISIBILITY
1512uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
1513    return __hard_link_count(__p, &__ec);
1514}
1515
1516inline _LIBCPP_INLINE_VISIBILITY
1517bool is_block_file(file_status __s) _NOEXCEPT {
1518    return __s.type() == file_type::block;
1519}
1520
1521inline _LIBCPP_INLINE_VISIBILITY
1522bool is_block_file(const path& __p) {
1523    return is_block_file(__status(__p));
1524}
1525
1526inline _LIBCPP_INLINE_VISIBILITY
1527bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
1528    return is_block_file(__status(__p, &__ec));
1529}
1530
1531inline _LIBCPP_INLINE_VISIBILITY
1532bool is_character_file(file_status __s) _NOEXCEPT {
1533    return __s.type() == file_type::character;
1534}
1535
1536inline _LIBCPP_INLINE_VISIBILITY
1537bool is_character_file(const path& __p) {
1538    return is_character_file(__status(__p));
1539}
1540
1541inline _LIBCPP_INLINE_VISIBILITY
1542bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
1543    return is_character_file(__status(__p, &__ec));
1544}
1545
1546inline _LIBCPP_INLINE_VISIBILITY
1547bool is_directory(file_status __s) _NOEXCEPT {
1548    return __s.type() == file_type::directory;
1549}
1550
1551inline _LIBCPP_INLINE_VISIBILITY
1552bool is_directory(const path& __p) {
1553    return is_directory(__status(__p));
1554}
1555
1556inline _LIBCPP_INLINE_VISIBILITY
1557bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
1558    return is_directory(__status(__p, &__ec));
1559}
1560
1561inline _LIBCPP_INLINE_VISIBILITY
1562bool is_empty(const path& __p) {
1563    return __fs_is_empty(__p);
1564}
1565
1566inline _LIBCPP_INLINE_VISIBILITY
1567bool is_empty(const path& __p, error_code& __ec) {
1568    return __fs_is_empty(__p, &__ec);
1569}
1570
1571inline _LIBCPP_INLINE_VISIBILITY
1572bool is_fifo(file_status __s) _NOEXCEPT {
1573    return __s.type() == file_type::fifo;
1574}
1575inline _LIBCPP_INLINE_VISIBILITY
1576bool is_fifo(const path& __p) {
1577    return is_fifo(__status(__p));
1578}
1579
1580inline _LIBCPP_INLINE_VISIBILITY
1581bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
1582    return is_fifo(__status(__p, &__ec));
1583}
1584
1585inline _LIBCPP_INLINE_VISIBILITY
1586bool is_regular_file(file_status __s) _NOEXCEPT {
1587    return __s.type() == file_type::regular;
1588}
1589
1590inline _LIBCPP_INLINE_VISIBILITY
1591bool is_regular_file(const path& __p) {
1592    return is_regular_file(__status(__p));
1593}
1594
1595inline _LIBCPP_INLINE_VISIBILITY
1596bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
1597    return is_regular_file(__status(__p, &__ec));
1598}
1599
1600inline _LIBCPP_INLINE_VISIBILITY
1601bool is_socket(file_status __s) _NOEXCEPT {
1602    return __s.type() == file_type::socket;
1603}
1604
1605inline _LIBCPP_INLINE_VISIBILITY
1606bool is_socket(const path& __p) {
1607    return is_socket(__status(__p));
1608}
1609
1610inline _LIBCPP_INLINE_VISIBILITY
1611bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
1612    return is_socket(__status(__p, &__ec));
1613}
1614
1615inline _LIBCPP_INLINE_VISIBILITY
1616bool is_symlink(file_status __s) _NOEXCEPT {
1617    return __s.type() == file_type::symlink;
1618}
1619
1620inline _LIBCPP_INLINE_VISIBILITY
1621bool is_symlink(const path& __p) {
1622    return is_symlink(__symlink_status(__p));
1623}
1624
1625inline _LIBCPP_INLINE_VISIBILITY
1626bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
1627    return is_symlink(__symlink_status(__p, &__ec));
1628}
1629
1630inline _LIBCPP_INLINE_VISIBILITY
1631bool is_other(file_status __s) _NOEXCEPT {
1632    return exists(__s)
1633        && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
1634}
1635
1636inline _LIBCPP_INLINE_VISIBILITY
1637bool is_other(const path& __p) {
1638    return is_other(__status(__p));
1639}
1640
1641inline _LIBCPP_INLINE_VISIBILITY
1642bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
1643    return is_other(__status(__p, &__ec));
1644}
1645
1646inline _LIBCPP_INLINE_VISIBILITY
1647file_time_type last_write_time(const path& __p) {
1648    return __last_write_time(__p);
1649}
1650
1651inline _LIBCPP_INLINE_VISIBILITY
1652file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
1653    return __last_write_time(__p, &__ec);
1654}
1655
1656inline _LIBCPP_INLINE_VISIBILITY
1657void last_write_time(const path& __p, file_time_type __t) {
1658    __last_write_time(__p, __t);
1659}
1660
1661inline _LIBCPP_INLINE_VISIBILITY
1662void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
1663    __last_write_time(__p, __t, &__ec);
1664}
1665
1666inline _LIBCPP_INLINE_VISIBILITY
1667void permissions(const path& __p, perms __prms) {
1668    __permissions(__p, __prms);
1669}
1670
1671inline _LIBCPP_INLINE_VISIBILITY
1672void permissions(const path& __p, perms __prms, error_code& __ec)  {
1673    __permissions(__p, __prms, &__ec);
1674}
1675
1676inline _LIBCPP_INLINE_VISIBILITY
1677path read_symlink(const path& __p) {
1678    return __read_symlink(__p);
1679}
1680
1681inline _LIBCPP_INLINE_VISIBILITY
1682path read_symlink(const path& __p, error_code& __ec) {
1683    return __read_symlink(__p, &__ec);
1684}
1685
1686inline _LIBCPP_INLINE_VISIBILITY
1687bool remove(const path& __p) {
1688    return __remove(__p);
1689}
1690
1691inline _LIBCPP_INLINE_VISIBILITY
1692bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
1693    return __remove(__p, &__ec);
1694}
1695
1696inline _LIBCPP_INLINE_VISIBILITY
1697uintmax_t remove_all(const path& __p) {
1698    return __remove_all(__p);
1699}
1700
1701inline _LIBCPP_INLINE_VISIBILITY
1702uintmax_t remove_all(const path& __p, error_code& __ec) {
1703    return __remove_all(__p, &__ec);
1704}
1705
1706inline _LIBCPP_INLINE_VISIBILITY
1707void rename(const path& __from, const path& __to) {
1708    return __rename(__from, __to);
1709}
1710
1711inline _LIBCPP_INLINE_VISIBILITY
1712void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
1713    return __rename(__from, __to, &__ec);
1714}
1715
1716inline _LIBCPP_INLINE_VISIBILITY
1717void resize_file(const path& __p, uintmax_t __ns) {
1718    return __resize_file(__p, __ns);
1719}
1720
1721inline _LIBCPP_INLINE_VISIBILITY
1722void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
1723    return __resize_file(__p, __ns, &__ec);
1724}
1725
1726inline _LIBCPP_INLINE_VISIBILITY
1727space_info space(const path& __p) {
1728    return __space(__p);
1729}
1730
1731inline _LIBCPP_INLINE_VISIBILITY
1732space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
1733    return __space(__p, &__ec);
1734}
1735
1736inline _LIBCPP_INLINE_VISIBILITY
1737file_status status(const path& __p) {
1738    return __status(__p);
1739}
1740
1741inline _LIBCPP_INLINE_VISIBILITY
1742file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
1743    return __status(__p, &__ec);
1744}
1745
1746inline _LIBCPP_INLINE_VISIBILITY
1747file_status symlink_status(const path& __p) {
1748    return __symlink_status(__p);
1749}
1750
1751inline _LIBCPP_INLINE_VISIBILITY
1752file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
1753    return __symlink_status(__p, &__ec);
1754}
1755
1756inline _LIBCPP_INLINE_VISIBILITY
1757path system_complete(const path& __p) {
1758    return __system_complete(__p);
1759}
1760
1761inline _LIBCPP_INLINE_VISIBILITY
1762path system_complete(const path& __p, error_code& __ec) {
1763    return __system_complete(__p, &__ec);
1764}
1765
1766inline _LIBCPP_INLINE_VISIBILITY
1767path temp_directory_path() {
1768    return __temp_directory_path();
1769}
1770
1771inline _LIBCPP_INLINE_VISIBILITY
1772path temp_directory_path(error_code& __ec) {
1773    return __temp_directory_path(&__ec);
1774}
1775
1776
1777class directory_entry
1778{
1779    typedef _VSTD_FS::path _Path;
1780
1781public:
1782    // constructors and destructors
1783    directory_entry() _NOEXCEPT = default;
1784    directory_entry(directory_entry const&) = default;
1785    directory_entry(directory_entry&&) _NOEXCEPT = default;
1786
1787    _LIBCPP_INLINE_VISIBILITY
1788    explicit directory_entry(_Path const& __p) : __p_(__p) {}
1789
1790    ~directory_entry() {}
1791
1792    directory_entry& operator=(directory_entry const&) = default;
1793    directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
1794
1795    _LIBCPP_INLINE_VISIBILITY
1796    void assign(_Path const& __p) {
1797        __p_ = __p;
1798    }
1799
1800    _LIBCPP_INLINE_VISIBILITY
1801    void replace_filename(_Path const& __p) {
1802        __p_ = __p_.parent_path() / __p;
1803    }
1804
1805    _LIBCPP_INLINE_VISIBILITY
1806    _Path const& path() const _NOEXCEPT {
1807        return __p_;
1808    }
1809
1810    _LIBCPP_INLINE_VISIBILITY
1811    operator const _Path&() const _NOEXCEPT {
1812        return __p_;
1813    }
1814
1815    _LIBCPP_INLINE_VISIBILITY
1816    file_status status() const {
1817        return _VSTD_FS::status(__p_);
1818    }
1819
1820    _LIBCPP_INLINE_VISIBILITY
1821    file_status status(error_code& __ec) const _NOEXCEPT {
1822        return _VSTD_FS::status(__p_, __ec);
1823    }
1824
1825    _LIBCPP_INLINE_VISIBILITY
1826    file_status symlink_status() const {
1827        return _VSTD_FS::symlink_status(__p_);
1828    }
1829
1830    _LIBCPP_INLINE_VISIBILITY
1831    file_status symlink_status(error_code& __ec) const _NOEXCEPT {
1832        return _VSTD_FS::symlink_status(__p_, __ec);
1833    }
1834
1835    _LIBCPP_INLINE_VISIBILITY
1836    bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
1837        return __p_ < __rhs.__p_;
1838    }
1839
1840    _LIBCPP_INLINE_VISIBILITY
1841    bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
1842        return __p_ == __rhs.__p_;
1843    }
1844
1845    _LIBCPP_INLINE_VISIBILITY
1846    bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
1847        return __p_ != __rhs.__p_;
1848    }
1849
1850    _LIBCPP_INLINE_VISIBILITY
1851    bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
1852        return __p_ <= __rhs.__p_;
1853    }
1854
1855    _LIBCPP_INLINE_VISIBILITY
1856    bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
1857        return __p_ > __rhs.__p_;
1858    }
1859
1860    _LIBCPP_INLINE_VISIBILITY
1861    bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
1862        return __p_ >= __rhs.__p_;
1863    }
1864private:
1865    _Path __p_;
1866};
1867
1868
1869class directory_iterator;
1870class recursive_directory_iterator;
1871class __dir_stream;
1872
1873class __dir_element_proxy {
1874public:
1875
1876    inline _LIBCPP_INLINE_VISIBILITY
1877    directory_entry operator*() { return _VSTD::move(__elem_); }
1878
1879private:
1880    friend class directory_iterator;
1881    friend class recursive_directory_iterator;
1882    explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
1883    __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
1884    directory_entry __elem_;
1885};
1886
1887class directory_iterator
1888{
1889public:
1890    typedef directory_entry value_type;
1891    typedef ptrdiff_t difference_type;
1892    typedef value_type const* pointer;
1893    typedef value_type const& reference;
1894    typedef input_iterator_tag iterator_category;
1895
1896public:
1897    //ctor & dtor
1898    directory_iterator() _NOEXCEPT
1899    { }
1900
1901    explicit directory_iterator(const path& __p)
1902        : directory_iterator(__p, nullptr)
1903    { }
1904
1905    directory_iterator(const path& __p, directory_options __opts)
1906        : directory_iterator(__p, nullptr, __opts)
1907    { }
1908
1909    directory_iterator(const path& __p, error_code& __ec)
1910        : directory_iterator(__p, &__ec)
1911    { }
1912
1913    directory_iterator(const path& __p, directory_options __opts,
1914                       error_code& __ec)
1915        : directory_iterator(__p, &__ec, __opts)
1916    { }
1917
1918    directory_iterator(const directory_iterator&) = default;
1919    directory_iterator(directory_iterator&&) = default;
1920    directory_iterator& operator=(const directory_iterator&) = default;
1921
1922    directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
1923        // non-default implementation provided to support self-move assign.
1924        if (this != &__o) {
1925            __imp_ = _VSTD::move(__o.__imp_);
1926        }
1927        return *this;
1928    }
1929
1930    ~directory_iterator() = default;
1931
1932    const directory_entry& operator*() const {
1933        _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
1934        return __dereference();
1935    }
1936
1937    const directory_entry* operator->() const
1938    { return &**this; }
1939
1940    directory_iterator& operator++()
1941    { return __increment(); }
1942
1943    __dir_element_proxy operator++(int) {
1944        __dir_element_proxy __p(**this);
1945        __increment();
1946        return __p;
1947    }
1948
1949    directory_iterator& increment(error_code& __ec)
1950    { return __increment(&__ec); }
1951
1952private:
1953    inline _LIBCPP_INLINE_VISIBILITY
1954    friend bool operator==(const directory_iterator& __lhs,
1955                           const directory_iterator& __rhs) _NOEXCEPT;
1956
1957    // construct the dir_stream
1958    _LIBCPP_FUNC_VIS
1959    directory_iterator(const path&, error_code *,
1960                       directory_options = directory_options::none);
1961
1962    _LIBCPP_FUNC_VIS
1963    directory_iterator& __increment(error_code * __ec = nullptr);
1964
1965    _LIBCPP_FUNC_VIS
1966    const directory_entry& __dereference() const;
1967
1968private:
1969    shared_ptr<__dir_stream> __imp_;
1970};
1971
1972
1973inline _LIBCPP_INLINE_VISIBILITY
1974bool operator==(const directory_iterator& __lhs,
1975                const directory_iterator& __rhs) _NOEXCEPT {
1976    return __lhs.__imp_ == __rhs.__imp_;
1977}
1978
1979inline _LIBCPP_INLINE_VISIBILITY
1980bool operator!=(const directory_iterator& __lhs,
1981                const directory_iterator& __rhs) _NOEXCEPT {
1982    return !(__lhs == __rhs);
1983}
1984
1985// enable directory_iterator range-based for statements
1986inline _LIBCPP_INLINE_VISIBILITY
1987directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
1988    return __iter;
1989}
1990
1991inline _LIBCPP_INLINE_VISIBILITY
1992directory_iterator end(const directory_iterator&) _NOEXCEPT {
1993    return directory_iterator();
1994}
1995
1996class recursive_directory_iterator {
1997public:
1998    using value_type = directory_entry;
1999    using difference_type = std::ptrdiff_t;
2000    using pointer = directory_entry const *;
2001    using reference = directory_entry const &;
2002    using iterator_category = std::input_iterator_tag;
2003
2004public:
2005    // constructors and destructor
2006    _LIBCPP_INLINE_VISIBILITY
2007    recursive_directory_iterator()  _NOEXCEPT
2008        : __rec_(false)
2009    {}
2010
2011    _LIBCPP_INLINE_VISIBILITY
2012    explicit recursive_directory_iterator(const path& __p,
2013                directory_options __xoptions = directory_options::none)
2014        : recursive_directory_iterator(__p, __xoptions,  nullptr)
2015    { }
2016
2017    _LIBCPP_INLINE_VISIBILITY
2018    recursive_directory_iterator(const path& __p,
2019        directory_options __xoptions, error_code& __ec)
2020        : recursive_directory_iterator(__p, __xoptions, &__ec)
2021    { }
2022
2023    _LIBCPP_INLINE_VISIBILITY
2024    recursive_directory_iterator(const path& __p, error_code& __ec)
2025        : recursive_directory_iterator(__p, directory_options::none,  &__ec)
2026    { }
2027
2028    recursive_directory_iterator(const recursive_directory_iterator&) = default;
2029    recursive_directory_iterator(recursive_directory_iterator&&) = default;
2030
2031    recursive_directory_iterator &
2032    operator=(const recursive_directory_iterator&) = default;
2033
2034    _LIBCPP_INLINE_VISIBILITY
2035    recursive_directory_iterator &
2036    operator=(recursive_directory_iterator&& __o) noexcept {
2037        // non-default implementation provided to support self-move assign.
2038        if (this != &__o) {
2039            __imp_ = _VSTD::move(__o.__imp_);
2040            __rec_ = __o.__rec_;
2041        }
2042        return *this;
2043    }
2044
2045    ~recursive_directory_iterator() = default;
2046
2047    _LIBCPP_INLINE_VISIBILITY
2048    const directory_entry& operator*() const
2049    { return __dereference(); }
2050
2051    _LIBCPP_INLINE_VISIBILITY
2052    const directory_entry* operator->() const
2053    { return &__dereference(); }
2054
2055    recursive_directory_iterator& operator++()
2056    { return __increment(); }
2057
2058    _LIBCPP_INLINE_VISIBILITY
2059    __dir_element_proxy operator++(int) {
2060        __dir_element_proxy __p(**this);
2061        __increment();
2062        return __p;
2063    }
2064
2065    _LIBCPP_INLINE_VISIBILITY
2066    recursive_directory_iterator& increment(error_code& __ec)
2067    { return __increment(&__ec); }
2068
2069    _LIBCPP_FUNC_VIS directory_options options() const;
2070    _LIBCPP_FUNC_VIS int  depth() const;
2071
2072    _LIBCPP_INLINE_VISIBILITY
2073    void pop() { __pop(); }
2074
2075    _LIBCPP_INLINE_VISIBILITY
2076    void pop(error_code& __ec)
2077    { __pop(&__ec); }
2078
2079    _LIBCPP_INLINE_VISIBILITY
2080    bool recursion_pending() const
2081    { return __rec_; }
2082
2083    _LIBCPP_INLINE_VISIBILITY
2084    void disable_recursion_pending()
2085    { __rec_ = false; }
2086
2087private:
2088    recursive_directory_iterator(const path& __p, directory_options __opt,
2089                                 error_code *__ec);
2090
2091    _LIBCPP_FUNC_VIS
2092    const directory_entry& __dereference() const;
2093
2094    _LIBCPP_FUNC_VIS
2095    bool __try_recursion(error_code* __ec);
2096
2097    _LIBCPP_FUNC_VIS
2098    void __advance(error_code* __ec=nullptr);
2099
2100    _LIBCPP_FUNC_VIS
2101    recursive_directory_iterator& __increment(error_code *__ec=nullptr);
2102
2103    _LIBCPP_FUNC_VIS
2104    void __pop(error_code* __ec=nullptr);
2105
2106    inline _LIBCPP_INLINE_VISIBILITY
2107    friend bool operator==(const recursive_directory_iterator&,
2108                           const recursive_directory_iterator&) _NOEXCEPT;
2109
2110    struct __shared_imp;
2111    shared_ptr<__shared_imp> __imp_;
2112    bool __rec_;
2113};                                     // class recursive_directory_iterator
2114
2115
2116inline _LIBCPP_INLINE_VISIBILITY
2117bool operator==(const recursive_directory_iterator& __lhs,
2118                const recursive_directory_iterator& __rhs) _NOEXCEPT
2119{
2120    return __lhs.__imp_ == __rhs.__imp_;
2121}
2122
2123_LIBCPP_INLINE_VISIBILITY
2124inline bool operator!=(const recursive_directory_iterator& __lhs,
2125                        const recursive_directory_iterator& __rhs) _NOEXCEPT
2126{
2127    return !(__lhs == __rhs);
2128}
2129// enable recursive_directory_iterator range-based for statements
2130inline _LIBCPP_INLINE_VISIBILITY
2131recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
2132    return __iter;
2133}
2134
2135inline _LIBCPP_INLINE_VISIBILITY
2136recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
2137    return recursive_directory_iterator();
2138}
2139
2140_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
2141
2142#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM
2143