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