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 
   1095     typedef path                       value_type;
   1096     typedef std::ptrdiff_t             difference_type;
   1097     typedef const path*                pointer;
   1098     typedef const path&                reference;
   1099 
   1100     typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
   1101 public:
   1102     _LIBCPP_INLINE_VISIBILITY
   1103     iterator() : __stashed_elem_(), __path_ptr_(nullptr),
   1104                  __entry_(), __state_(__singular) {}
   1105 
   1106     iterator(const iterator&) = default;
   1107     ~iterator() = default;
   1108 
   1109     iterator& operator=(const iterator&) = default;
   1110 
   1111     _LIBCPP_INLINE_VISIBILITY
   1112     reference operator*() const {
   1113         return __stashed_elem_;
   1114     }
   1115 
   1116     _LIBCPP_INLINE_VISIBILITY
   1117     pointer operator->() const {
   1118         return &__stashed_elem_;
   1119     }
   1120 
   1121     _LIBCPP_INLINE_VISIBILITY
   1122     iterator& operator++() {
   1123         _LIBCPP_ASSERT(__state_ != __singular,
   1124                        "attempting to increment a singular iterator");
   1125         _LIBCPP_ASSERT(__state_ != __at_end,
   1126                       "attempting to increment the end iterator");
   1127         return __increment();
   1128     }
   1129 
   1130     _LIBCPP_INLINE_VISIBILITY
   1131     iterator operator++(int) {
   1132         iterator __it(*this);
   1133         this->operator++();
   1134         return __it;
   1135     }
   1136 
   1137     _LIBCPP_INLINE_VISIBILITY
   1138     iterator& operator--() {
   1139         _LIBCPP_ASSERT(__state_ != __singular,
   1140                        "attempting to decrement a singular iterator");
   1141         _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
   1142                        "attempting to decrement the begin iterator");
   1143         return __decrement();
   1144     }
   1145 
   1146     _LIBCPP_INLINE_VISIBILITY
   1147     iterator operator--(int) {
   1148         iterator __it(*this);
   1149         this->operator--();
   1150         return __it;
   1151     }
   1152 
   1153 private:
   1154     friend class path;
   1155 
   1156     static constexpr unsigned char __singular = 0;
   1157     static constexpr unsigned char __at_end = 6;
   1158 
   1159     inline _LIBCPP_INLINE_VISIBILITY
   1160     friend bool operator==(const iterator&, const iterator&);
   1161 
   1162     iterator& __increment();
   1163     iterator& __decrement();
   1164 
   1165     path __stashed_elem_;
   1166     const path* __path_ptr_;
   1167     path::__string_view __entry_;
   1168     unsigned char __state_;
   1169 };
   1170 
   1171 inline _LIBCPP_INLINE_VISIBILITY
   1172 bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
   1173     return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
   1174            __lhs.__entry_.data() == __rhs.__entry_.data();
   1175 }
   1176 
   1177 inline _LIBCPP_INLINE_VISIBILITY
   1178 bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
   1179     return !(__lhs == __rhs);
   1180 }
   1181 
   1182 class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error
   1183 {
   1184 public:
   1185     _LIBCPP_INLINE_VISIBILITY
   1186     filesystem_error(const string& __what, error_code __ec)
   1187         : system_error(__ec, __what),
   1188           __paths_(make_shared<_Storage>(path(), path()))
   1189     {}
   1190 
   1191     _LIBCPP_INLINE_VISIBILITY
   1192     filesystem_error(const string& __what, const path& __p1, error_code __ec)
   1193         : system_error(__ec, __what),
   1194         __paths_(make_shared<_Storage>(__p1, path()))
   1195     {}
   1196 
   1197     _LIBCPP_INLINE_VISIBILITY
   1198     filesystem_error(const string& __what, const path& __p1, const path& __p2,
   1199                      error_code __ec)
   1200         : system_error(__ec, __what),
   1201           __paths_(make_shared<_Storage>(__p1, __p2))
   1202     {}
   1203 
   1204     _LIBCPP_INLINE_VISIBILITY
   1205     const path& path1() const _NOEXCEPT {
   1206         return __paths_->first;
   1207     }
   1208 
   1209     _LIBCPP_INLINE_VISIBILITY
   1210     const path& path2() const _NOEXCEPT {
   1211         return __paths_->second;
   1212     }
   1213 
   1214     ~filesystem_error() override; // key function
   1215 
   1216     // TODO(ericwf): Create a custom error message.
   1217     //const char* what() const _NOEXCEPT;
   1218 
   1219 private:
   1220     typedef pair<path, path> _Storage;
   1221     shared_ptr<_Storage> __paths_;
   1222 };
   1223 
   1224 template <class... _Args>
   1225 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
   1226 #ifndef _LIBCPP_NO_EXCEPTIONS
   1227 void __throw_filesystem_error(_Args && ...__args)
   1228 {
   1229     throw filesystem_error(std::forward<_Args>(__args)...);
   1230 }
   1231 #else
   1232 void __throw_filesystem_error(_Args&&...)
   1233 {
   1234     _VSTD::abort();
   1235 }
   1236 #endif
   1237 
   1238 
   1239 // operational functions
   1240 
   1241 _LIBCPP_FUNC_VIS
   1242 path __canonical(const path&, const path&, error_code *__ec=nullptr);
   1243 _LIBCPP_FUNC_VIS
   1244 void __copy(const path& __from, const path& __to, copy_options __opt,
   1245         error_code *__ec=nullptr);
   1246 _LIBCPP_FUNC_VIS
   1247 bool __copy_file(const path& __from, const path& __to, copy_options __opt,
   1248         error_code *__ec=nullptr);
   1249 _LIBCPP_FUNC_VIS
   1250 void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
   1251         error_code *__ec=nullptr);
   1252 _LIBCPP_FUNC_VIS
   1253 bool __create_directories(const path& p, error_code *ec=nullptr);
   1254 _LIBCPP_FUNC_VIS
   1255 bool __create_directory(const path& p, error_code *ec=nullptr);
   1256 _LIBCPP_FUNC_VIS
   1257 bool __create_directory(const path& p, const path & attributes,
   1258         error_code *ec=nullptr);
   1259 _LIBCPP_FUNC_VIS
   1260 void __create_directory_symlink(const path& __to, const path& __new_symlink,
   1261         error_code *__ec=nullptr);
   1262 _LIBCPP_FUNC_VIS
   1263 void __create_hard_link(const path& __to, const path& __new_hard_link,
   1264         error_code *__ec=nullptr);
   1265 _LIBCPP_FUNC_VIS
   1266 void __create_symlink(const path& __to, const path& __new_symlink,
   1267         error_code *__ec=nullptr);
   1268 _LIBCPP_FUNC_VIS
   1269 path __current_path(error_code *__ec=nullptr);
   1270 _LIBCPP_FUNC_VIS
   1271 void __current_path(const path&, error_code *__ec=nullptr);
   1272 _LIBCPP_FUNC_VIS
   1273 bool __equivalent(const path&, const path&, error_code *__ec=nullptr);
   1274 _LIBCPP_FUNC_VIS
   1275 uintmax_t __file_size(const path&, error_code *__ec=nullptr);
   1276 _LIBCPP_FUNC_VIS
   1277 uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr);
   1278 _LIBCPP_FUNC_VIS
   1279 bool __fs_is_empty(const path& p, error_code *ec=nullptr);
   1280 _LIBCPP_FUNC_VIS
   1281 file_time_type __last_write_time(const path& p, error_code *ec=nullptr);
   1282 _LIBCPP_FUNC_VIS
   1283 void __last_write_time(const path& p, file_time_type new_time,
   1284         error_code *ec=nullptr);
   1285 _LIBCPP_FUNC_VIS
   1286 void __permissions(const path& p, perms prms, error_code *ec=nullptr);
   1287 _LIBCPP_FUNC_VIS
   1288 path __read_symlink(const path& p, error_code *ec=nullptr);
   1289 _LIBCPP_FUNC_VIS
   1290 bool __remove(const path& p, error_code *ec=nullptr);
   1291 _LIBCPP_FUNC_VIS
   1292 uintmax_t __remove_all(const path& p, error_code *ec=nullptr);
   1293 _LIBCPP_FUNC_VIS
   1294 void __rename(const path& from, const path& to, error_code *ec=nullptr);
   1295 _LIBCPP_FUNC_VIS
   1296 void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr);
   1297 _LIBCPP_FUNC_VIS
   1298 space_info __space(const path&, error_code *__ec=nullptr);
   1299 _LIBCPP_FUNC_VIS
   1300 file_status __status(const path&, error_code *__ec=nullptr);
   1301 _LIBCPP_FUNC_VIS
   1302 file_status __symlink_status(const path&, error_code *__ec=nullptr);
   1303 _LIBCPP_FUNC_VIS
   1304 path __system_complete(const path&, error_code *__ec=nullptr);
   1305 _LIBCPP_FUNC_VIS
   1306 path __temp_directory_path(error_code *__ec=nullptr);
   1307 
   1308 inline _LIBCPP_INLINE_VISIBILITY
   1309 path current_path() {
   1310     return __current_path();
   1311 }
   1312 
   1313 inline _LIBCPP_INLINE_VISIBILITY
   1314 path current_path(error_code& __ec) {
   1315     return __current_path(&__ec);
   1316 }
   1317 
   1318 inline _LIBCPP_INLINE_VISIBILITY
   1319 void current_path(const path& __p) {
   1320     __current_path(__p);
   1321 }
   1322 
   1323 inline _LIBCPP_INLINE_VISIBILITY
   1324 void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
   1325     __current_path(__p, &__ec);
   1326 }
   1327 
   1328 _LIBCPP_FUNC_VIS
   1329 path absolute(const path&, const path& __p2 = current_path());
   1330 
   1331 inline _LIBCPP_INLINE_VISIBILITY
   1332 path canonical(const path& __p, const path& __base = current_path()) {
   1333     return __canonical(__p, __base);
   1334 }
   1335 
   1336 inline _LIBCPP_INLINE_VISIBILITY
   1337 path canonical(const path& __p, error_code& __ec) {
   1338     path __base = __current_path(&__ec);
   1339     if (__ec) return {};
   1340     return __canonical(__p, __base, &__ec);
   1341 }
   1342 
   1343 inline _LIBCPP_INLINE_VISIBILITY
   1344 path canonical(const path& __p, const path& __base, error_code& __ec) {
   1345     return __canonical(__p, __base, &__ec);
   1346 }
   1347 
   1348 inline _LIBCPP_INLINE_VISIBILITY
   1349 void copy(const path& __from, const path& __to) {
   1350     __copy(__from, __to, copy_options::none);
   1351 }
   1352 
   1353 inline _LIBCPP_INLINE_VISIBILITY
   1354 void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
   1355     __copy(__from, __to, copy_options::none, &__ec);
   1356 }
   1357 
   1358 inline _LIBCPP_INLINE_VISIBILITY
   1359 void copy(const path& __from, const path& __to, copy_options __opt) {
   1360     __copy(__from, __to, __opt);
   1361 }
   1362 
   1363 inline _LIBCPP_INLINE_VISIBILITY
   1364 void copy(const path& __from, const path& __to,
   1365           copy_options __opt, error_code& __ec) _NOEXCEPT {
   1366     __copy(__from, __to, __opt, &__ec);
   1367 }
   1368 
   1369 inline _LIBCPP_INLINE_VISIBILITY
   1370 bool copy_file(const path& __from, const path& __to) {
   1371     return __copy_file(__from, __to, copy_options::none);
   1372 }
   1373 
   1374 inline _LIBCPP_INLINE_VISIBILITY
   1375 bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
   1376     return __copy_file(__from, __to, copy_options::none, &__ec);
   1377 }
   1378 
   1379 inline _LIBCPP_INLINE_VISIBILITY
   1380 bool copy_file(const path& __from, const path& __to, copy_options __opt) {
   1381     return __copy_file(__from, __to, __opt);
   1382 }
   1383 
   1384 inline _LIBCPP_INLINE_VISIBILITY
   1385 bool copy_file(const path& __from, const path& __to,
   1386                copy_options __opt, error_code& __ec) _NOEXCEPT {
   1387     return __copy_file(__from, __to, __opt, &__ec);
   1388 }
   1389 
   1390 inline _LIBCPP_INLINE_VISIBILITY
   1391 void copy_symlink(const path& __existing, const path& __new) {
   1392     __copy_symlink(__existing, __new);
   1393 }
   1394 
   1395 inline _LIBCPP_INLINE_VISIBILITY
   1396 void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT {
   1397     __copy_symlink(__ext, __new, &__ec);
   1398 }
   1399 
   1400 inline _LIBCPP_INLINE_VISIBILITY
   1401 bool create_directories(const path& __p) {
   1402     return __create_directories(__p);
   1403 }
   1404 
   1405 inline _LIBCPP_INLINE_VISIBILITY
   1406 bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT {
   1407     return __create_directories(__p, &__ec);
   1408 }
   1409 
   1410 inline _LIBCPP_INLINE_VISIBILITY
   1411 bool create_directory(const path& __p) {
   1412     return __create_directory(__p);
   1413 }
   1414 
   1415 inline _LIBCPP_INLINE_VISIBILITY
   1416 bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT {
   1417     return __create_directory(__p, &__ec);
   1418 }
   1419 
   1420 inline _LIBCPP_INLINE_VISIBILITY
   1421 bool create_directory(const path& __p, const path& __attrs) {
   1422     return __create_directory(__p, __attrs);
   1423 }
   1424 
   1425 inline _LIBCPP_INLINE_VISIBILITY
   1426 bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT {
   1427     return __create_directory(__p, __attrs, &__ec);
   1428 }
   1429 
   1430 inline _LIBCPP_INLINE_VISIBILITY
   1431 void create_directory_symlink(const path& __to, const path& __new) {
   1432     __create_directory_symlink(__to, __new);
   1433 }
   1434 
   1435 inline _LIBCPP_INLINE_VISIBILITY
   1436 void create_directory_symlink(const path& __to, const path& __new,
   1437                               error_code& __ec) _NOEXCEPT {
   1438     __create_directory_symlink(__to, __new, &__ec);
   1439 }
   1440 
   1441 inline _LIBCPP_INLINE_VISIBILITY
   1442 void create_hard_link(const path& __to, const path& __new) {
   1443     __create_hard_link(__to, __new);
   1444 }
   1445 
   1446 inline _LIBCPP_INLINE_VISIBILITY
   1447 void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
   1448     __create_hard_link(__to, __new, &__ec);
   1449 }
   1450 
   1451 inline _LIBCPP_INLINE_VISIBILITY
   1452 void create_symlink(const path& __to, const path& __new) {
   1453     __create_symlink(__to, __new);
   1454 }
   1455 
   1456 inline _LIBCPP_INLINE_VISIBILITY
   1457 void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
   1458     return __create_symlink(__to, __new, &__ec);
   1459 }
   1460 
   1461 inline _LIBCPP_INLINE_VISIBILITY
   1462 bool status_known(file_status __s) _NOEXCEPT {
   1463     return __s.type() != file_type::none;
   1464 }
   1465 
   1466 inline _LIBCPP_INLINE_VISIBILITY
   1467 bool exists(file_status __s) _NOEXCEPT {
   1468     return status_known(__s) && __s.type() != file_type::not_found;
   1469 }
   1470 
   1471 inline _LIBCPP_INLINE_VISIBILITY
   1472 bool exists(const path& __p) {
   1473     return exists(__status(__p));
   1474 }
   1475 
   1476 inline _LIBCPP_INLINE_VISIBILITY
   1477 bool exists(const path& __p, error_code& __ec) _NOEXCEPT {
   1478     auto __s = __status(__p, &__ec);
   1479     if (status_known(__s)) __ec.clear();
   1480     return exists(__s);
   1481 }
   1482 
   1483 inline _LIBCPP_INLINE_VISIBILITY
   1484 bool equivalent(const path& __p1, const path& __p2) {
   1485     return __equivalent(__p1, __p2);
   1486 }
   1487 
   1488 inline _LIBCPP_INLINE_VISIBILITY
   1489 bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT {
   1490     return __equivalent(__p1, __p2, &__ec);
   1491 }
   1492 
   1493 inline _LIBCPP_INLINE_VISIBILITY
   1494 uintmax_t file_size(const path& __p) {
   1495     return __file_size(__p);
   1496 }
   1497 
   1498 inline _LIBCPP_INLINE_VISIBILITY
   1499 uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT {
   1500     return __file_size(__p, &__ec);
   1501 }
   1502 
   1503 inline _LIBCPP_INLINE_VISIBILITY
   1504 uintmax_t hard_link_count(const path& __p) {
   1505     return __hard_link_count(__p);
   1506 }
   1507 
   1508 inline _LIBCPP_INLINE_VISIBILITY
   1509 uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT {
   1510     return __hard_link_count(__p, &__ec);
   1511 }
   1512 
   1513 inline _LIBCPP_INLINE_VISIBILITY
   1514 bool is_block_file(file_status __s) _NOEXCEPT {
   1515     return __s.type() == file_type::block;
   1516 }
   1517 
   1518 inline _LIBCPP_INLINE_VISIBILITY
   1519 bool is_block_file(const path& __p) {
   1520     return is_block_file(__status(__p));
   1521 }
   1522 
   1523 inline _LIBCPP_INLINE_VISIBILITY
   1524 bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT {
   1525     return is_block_file(__status(__p, &__ec));
   1526 }
   1527 
   1528 inline _LIBCPP_INLINE_VISIBILITY
   1529 bool is_character_file(file_status __s) _NOEXCEPT {
   1530     return __s.type() == file_type::character;
   1531 }
   1532 
   1533 inline _LIBCPP_INLINE_VISIBILITY
   1534 bool is_character_file(const path& __p) {
   1535     return is_character_file(__status(__p));
   1536 }
   1537 
   1538 inline _LIBCPP_INLINE_VISIBILITY
   1539 bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT {
   1540     return is_character_file(__status(__p, &__ec));
   1541 }
   1542 
   1543 inline _LIBCPP_INLINE_VISIBILITY
   1544 bool is_directory(file_status __s) _NOEXCEPT {
   1545     return __s.type() == file_type::directory;
   1546 }
   1547 
   1548 inline _LIBCPP_INLINE_VISIBILITY
   1549 bool is_directory(const path& __p) {
   1550     return is_directory(__status(__p));
   1551 }
   1552 
   1553 inline _LIBCPP_INLINE_VISIBILITY
   1554 bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT {
   1555     return is_directory(__status(__p, &__ec));
   1556 }
   1557 
   1558 inline _LIBCPP_INLINE_VISIBILITY
   1559 bool is_empty(const path& __p) {
   1560     return __fs_is_empty(__p);
   1561 }
   1562 
   1563 inline _LIBCPP_INLINE_VISIBILITY
   1564 bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT {
   1565     return __fs_is_empty(__p, &__ec);
   1566 }
   1567 
   1568 inline _LIBCPP_INLINE_VISIBILITY
   1569 bool is_fifo(file_status __s) _NOEXCEPT {
   1570     return __s.type() == file_type::fifo;
   1571 }
   1572 inline _LIBCPP_INLINE_VISIBILITY
   1573 bool is_fifo(const path& __p) {
   1574     return is_fifo(__status(__p));
   1575 }
   1576 
   1577 inline _LIBCPP_INLINE_VISIBILITY
   1578 bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT {
   1579     return is_fifo(__status(__p, &__ec));
   1580 }
   1581 
   1582 inline _LIBCPP_INLINE_VISIBILITY
   1583 bool is_regular_file(file_status __s) _NOEXCEPT {
   1584     return __s.type() == file_type::regular;
   1585 }
   1586 
   1587 inline _LIBCPP_INLINE_VISIBILITY
   1588 bool is_regular_file(const path& __p) {
   1589     return is_regular_file(__status(__p));
   1590 }
   1591 
   1592 inline _LIBCPP_INLINE_VISIBILITY
   1593 bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT {
   1594     return is_regular_file(__status(__p, &__ec));
   1595 }
   1596 
   1597 inline _LIBCPP_INLINE_VISIBILITY
   1598 bool is_socket(file_status __s) _NOEXCEPT {
   1599     return __s.type() == file_type::socket;
   1600 }
   1601 
   1602 inline _LIBCPP_INLINE_VISIBILITY
   1603 bool is_socket(const path& __p) {
   1604     return is_socket(__status(__p));
   1605 }
   1606 
   1607 inline _LIBCPP_INLINE_VISIBILITY
   1608 bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT {
   1609     return is_socket(__status(__p, &__ec));
   1610 }
   1611 
   1612 inline _LIBCPP_INLINE_VISIBILITY
   1613 bool is_symlink(file_status __s) _NOEXCEPT {
   1614     return __s.type() == file_type::symlink;
   1615 }
   1616 
   1617 inline _LIBCPP_INLINE_VISIBILITY
   1618 bool is_symlink(const path& __p) {
   1619     return is_symlink(__symlink_status(__p));
   1620 }
   1621 
   1622 inline _LIBCPP_INLINE_VISIBILITY
   1623 bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT {
   1624     return is_symlink(__symlink_status(__p, &__ec));
   1625 }
   1626 
   1627 inline _LIBCPP_INLINE_VISIBILITY
   1628 bool is_other(file_status __s) _NOEXCEPT {
   1629     return exists(__s)
   1630         && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
   1631 }
   1632 
   1633 inline _LIBCPP_INLINE_VISIBILITY
   1634 bool is_other(const path& __p) {
   1635     return is_other(__status(__p));
   1636 }
   1637 
   1638 inline _LIBCPP_INLINE_VISIBILITY
   1639 bool is_other(const path& __p, error_code& __ec) _NOEXCEPT {
   1640     return is_other(__status(__p, &__ec));
   1641 }
   1642 
   1643 inline _LIBCPP_INLINE_VISIBILITY
   1644 file_time_type last_write_time(const path& __p) {
   1645     return __last_write_time(__p);
   1646 }
   1647 
   1648 inline _LIBCPP_INLINE_VISIBILITY
   1649 file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT {
   1650     return __last_write_time(__p, &__ec);
   1651 }
   1652 
   1653 inline _LIBCPP_INLINE_VISIBILITY
   1654 void last_write_time(const path& __p, file_time_type __t) {
   1655     __last_write_time(__p, __t);
   1656 }
   1657 
   1658 inline _LIBCPP_INLINE_VISIBILITY
   1659 void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT {
   1660     __last_write_time(__p, __t, &__ec);
   1661 }
   1662 
   1663 inline _LIBCPP_INLINE_VISIBILITY
   1664 void permissions(const path& __p, perms __prms) {
   1665     __permissions(__p, __prms);
   1666 }
   1667 
   1668 inline _LIBCPP_INLINE_VISIBILITY
   1669 void permissions(const path& __p, perms __prms, error_code& __ec)  {
   1670     __permissions(__p, __prms, &__ec);
   1671 }
   1672 
   1673 inline _LIBCPP_INLINE_VISIBILITY
   1674 path read_symlink(const path& __p) {
   1675     return __read_symlink(__p);
   1676 }
   1677 
   1678 inline _LIBCPP_INLINE_VISIBILITY
   1679 path read_symlink(const path& __p, error_code& __ec) {
   1680     return __read_symlink(__p, &__ec);
   1681 }
   1682 
   1683 inline _LIBCPP_INLINE_VISIBILITY
   1684 bool remove(const path& __p) {
   1685     return __remove(__p);
   1686 }
   1687 
   1688 inline _LIBCPP_INLINE_VISIBILITY
   1689 bool remove(const path& __p, error_code& __ec) _NOEXCEPT {
   1690     return __remove(__p, &__ec);
   1691 }
   1692 
   1693 inline _LIBCPP_INLINE_VISIBILITY
   1694 uintmax_t remove_all(const path& __p) {
   1695     return __remove_all(__p);
   1696 }
   1697 
   1698 inline _LIBCPP_INLINE_VISIBILITY
   1699 uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT {
   1700     return __remove_all(__p, &__ec);
   1701 }
   1702 
   1703 inline _LIBCPP_INLINE_VISIBILITY
   1704 void rename(const path& __from, const path& __to) {
   1705     return __rename(__from, __to);
   1706 }
   1707 
   1708 inline _LIBCPP_INLINE_VISIBILITY
   1709 void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
   1710     return __rename(__from, __to, &__ec);
   1711 }
   1712 
   1713 inline _LIBCPP_INLINE_VISIBILITY
   1714 void resize_file(const path& __p, uintmax_t __ns) {
   1715     return __resize_file(__p, __ns);
   1716 }
   1717 
   1718 inline _LIBCPP_INLINE_VISIBILITY
   1719 void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT {
   1720     return __resize_file(__p, __ns, &__ec);
   1721 }
   1722 
   1723 inline _LIBCPP_INLINE_VISIBILITY
   1724 space_info space(const path& __p) {
   1725     return __space(__p);
   1726 }
   1727 
   1728 inline _LIBCPP_INLINE_VISIBILITY
   1729 space_info space(const path& __p, error_code& __ec) _NOEXCEPT {
   1730     return __space(__p, &__ec);
   1731 }
   1732 
   1733 inline _LIBCPP_INLINE_VISIBILITY
   1734 file_status status(const path& __p) {
   1735     return __status(__p);
   1736 }
   1737 
   1738 inline _LIBCPP_INLINE_VISIBILITY
   1739 file_status status(const path& __p, error_code& __ec) _NOEXCEPT {
   1740     return __status(__p, &__ec);
   1741 }
   1742 
   1743 inline _LIBCPP_INLINE_VISIBILITY
   1744 file_status symlink_status(const path& __p) {
   1745     return __symlink_status(__p);
   1746 }
   1747 
   1748 inline _LIBCPP_INLINE_VISIBILITY
   1749 file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
   1750     return __symlink_status(__p, &__ec);
   1751 }
   1752 
   1753 inline _LIBCPP_INLINE_VISIBILITY
   1754 path system_complete(const path& __p) {
   1755     return __system_complete(__p);
   1756 }
   1757 
   1758 inline _LIBCPP_INLINE_VISIBILITY
   1759 path system_complete(const path& __p, error_code& __ec) {
   1760     return __system_complete(__p, &__ec);
   1761 }
   1762 
   1763 inline _LIBCPP_INLINE_VISIBILITY
   1764 path temp_directory_path() {
   1765     return __temp_directory_path();
   1766 }
   1767 
   1768 inline _LIBCPP_INLINE_VISIBILITY
   1769 path temp_directory_path(error_code& __ec) {
   1770     return __temp_directory_path(&__ec);
   1771 }
   1772 
   1773 
   1774 class directory_entry
   1775 {
   1776     typedef _VSTD_FS::path _Path;
   1777 
   1778 public:
   1779     // constructors and destructors
   1780     directory_entry() _NOEXCEPT = default;
   1781     directory_entry(directory_entry const&) = default;
   1782     directory_entry(directory_entry&&) _NOEXCEPT = default;
   1783 
   1784     _LIBCPP_INLINE_VISIBILITY
   1785     explicit directory_entry(_Path const& __p) : __p_(__p) {}
   1786 
   1787     ~directory_entry() {}
   1788 
   1789     directory_entry& operator=(directory_entry const&) = default;
   1790     directory_entry& operator=(directory_entry&&) _NOEXCEPT = default;
   1791 
   1792     _LIBCPP_INLINE_VISIBILITY
   1793     void assign(_Path const& __p) {
   1794         __p_ = __p;
   1795     }
   1796 
   1797     _LIBCPP_INLINE_VISIBILITY
   1798     void replace_filename(_Path const& __p) {
   1799         __p_ = __p_.parent_path() / __p;
   1800     }
   1801 
   1802     _LIBCPP_INLINE_VISIBILITY
   1803     _Path const& path() const _NOEXCEPT {
   1804         return __p_;
   1805     }
   1806 
   1807     _LIBCPP_INLINE_VISIBILITY
   1808     operator const _Path&() const _NOEXCEPT {
   1809         return __p_;
   1810     }
   1811 
   1812     _LIBCPP_INLINE_VISIBILITY
   1813     file_status status() const {
   1814         return _VSTD_FS::status(__p_);
   1815     }
   1816 
   1817     _LIBCPP_INLINE_VISIBILITY
   1818     file_status status(error_code& __ec) const _NOEXCEPT {
   1819         return _VSTD_FS::status(__p_, __ec);
   1820     }
   1821 
   1822     _LIBCPP_INLINE_VISIBILITY
   1823     file_status symlink_status() const {
   1824         return _VSTD_FS::symlink_status(__p_);
   1825     }
   1826 
   1827     _LIBCPP_INLINE_VISIBILITY
   1828     file_status symlink_status(error_code& __ec) const _NOEXCEPT {
   1829         return _VSTD_FS::symlink_status(__p_, __ec);
   1830     }
   1831 
   1832     _LIBCPP_INLINE_VISIBILITY
   1833     bool operator< (directory_entry const& __rhs) const _NOEXCEPT {
   1834         return __p_ < __rhs.__p_;
   1835     }
   1836 
   1837     _LIBCPP_INLINE_VISIBILITY
   1838     bool operator==(directory_entry const& __rhs) const _NOEXCEPT {
   1839         return __p_ == __rhs.__p_;
   1840     }
   1841 
   1842     _LIBCPP_INLINE_VISIBILITY
   1843     bool operator!=(directory_entry const& __rhs) const _NOEXCEPT {
   1844         return __p_ != __rhs.__p_;
   1845     }
   1846 
   1847     _LIBCPP_INLINE_VISIBILITY
   1848     bool operator<=(directory_entry const& __rhs) const _NOEXCEPT {
   1849         return __p_ <= __rhs.__p_;
   1850     }
   1851 
   1852     _LIBCPP_INLINE_VISIBILITY
   1853     bool operator> (directory_entry const& __rhs) const _NOEXCEPT {
   1854         return __p_ > __rhs.__p_;
   1855     }
   1856 
   1857     _LIBCPP_INLINE_VISIBILITY
   1858     bool operator>=(directory_entry const& __rhs) const _NOEXCEPT {
   1859         return __p_ >= __rhs.__p_;
   1860     }
   1861 private:
   1862     _Path __p_;
   1863 };
   1864 
   1865 
   1866 class directory_iterator;
   1867 class recursive_directory_iterator;
   1868 class __dir_stream;
   1869 
   1870 class __dir_element_proxy {
   1871 public:
   1872 
   1873     inline _LIBCPP_INLINE_VISIBILITY
   1874     directory_entry operator*() { return _VSTD::move(__elem_); }
   1875 
   1876 private:
   1877     friend class directory_iterator;
   1878     friend class recursive_directory_iterator;
   1879     explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
   1880     __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {}
   1881     directory_entry __elem_;
   1882 };
   1883 
   1884 class directory_iterator
   1885 {
   1886 public:
   1887     typedef directory_entry value_type;
   1888     typedef ptrdiff_t difference_type;
   1889     typedef value_type const* pointer;
   1890     typedef value_type const& reference;
   1891     typedef input_iterator_tag iterator_category;
   1892 
   1893 public:
   1894     //ctor & dtor
   1895     directory_iterator() _NOEXCEPT
   1896     { }
   1897 
   1898     explicit directory_iterator(const path& __p)
   1899         : directory_iterator(__p, nullptr)
   1900     { }
   1901 
   1902     directory_iterator(const path& __p, directory_options __opts)
   1903         : directory_iterator(__p, nullptr, __opts)
   1904     { }
   1905 
   1906     directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
   1907         : directory_iterator(__p, &__ec)
   1908     { }
   1909 
   1910     directory_iterator(const path& __p, directory_options __opts,
   1911                        error_code& __ec) _NOEXCEPT
   1912         : directory_iterator(__p, &__ec, __opts)
   1913     { }
   1914 
   1915     directory_iterator(const directory_iterator&) = default;
   1916     directory_iterator(directory_iterator&&) = default;
   1917     directory_iterator& operator=(const directory_iterator&) = default;
   1918 
   1919     directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT {
   1920         // non-default implementation provided to support self-move assign.
   1921         if (this != &__o) {
   1922             __imp_ = _VSTD::move(__o.__imp_);
   1923         }
   1924         return *this;
   1925     }
   1926 
   1927     ~directory_iterator() = default;
   1928 
   1929     const directory_entry& operator*() const {
   1930         _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
   1931         return __dereference();
   1932     }
   1933 
   1934     const directory_entry* operator->() const
   1935     { return &**this; }
   1936 
   1937     directory_iterator& operator++()
   1938     { return __increment(); }
   1939 
   1940     __dir_element_proxy operator++(int) {
   1941         __dir_element_proxy __p(**this);
   1942         __increment();
   1943         return __p;
   1944     }
   1945 
   1946     directory_iterator& increment(error_code& __ec) _NOEXCEPT
   1947     { return __increment(&__ec); }
   1948 
   1949 private:
   1950     inline _LIBCPP_INLINE_VISIBILITY
   1951     friend bool operator==(const directory_iterator& __lhs,
   1952                            const directory_iterator& __rhs) _NOEXCEPT;
   1953 
   1954     // construct the dir_stream
   1955     _LIBCPP_FUNC_VIS
   1956     directory_iterator(const path&, error_code *,
   1957                        directory_options = directory_options::none);
   1958 
   1959     _LIBCPP_FUNC_VIS
   1960     directory_iterator& __increment(error_code * __ec = nullptr);
   1961 
   1962     _LIBCPP_FUNC_VIS
   1963     const directory_entry& __dereference() const;
   1964 
   1965 private:
   1966     shared_ptr<__dir_stream> __imp_;
   1967 };
   1968 
   1969 
   1970 inline _LIBCPP_INLINE_VISIBILITY
   1971 bool operator==(const directory_iterator& __lhs,
   1972                 const directory_iterator& __rhs) _NOEXCEPT {
   1973     return __lhs.__imp_ == __rhs.__imp_;
   1974 }
   1975 
   1976 inline _LIBCPP_INLINE_VISIBILITY
   1977 bool operator!=(const directory_iterator& __lhs,
   1978                 const directory_iterator& __rhs) _NOEXCEPT {
   1979     return !(__lhs == __rhs);
   1980 }
   1981 
   1982 // enable directory_iterator range-based for statements
   1983 inline _LIBCPP_INLINE_VISIBILITY
   1984 directory_iterator begin(directory_iterator __iter) _NOEXCEPT {
   1985     return __iter;
   1986 }
   1987 
   1988 inline _LIBCPP_INLINE_VISIBILITY
   1989 directory_iterator end(const directory_iterator&) _NOEXCEPT {
   1990     return directory_iterator();
   1991 }
   1992 
   1993 class recursive_directory_iterator {
   1994 public:
   1995     using value_type = directory_entry;
   1996     using difference_type = std::ptrdiff_t;
   1997     using pointer = directory_entry const *;
   1998     using reference = directory_entry const &;
   1999     using iterator_category = std::input_iterator_tag;
   2000 
   2001 public:
   2002     // constructors and destructor
   2003     _LIBCPP_INLINE_VISIBILITY
   2004     recursive_directory_iterator()  _NOEXCEPT
   2005         : __rec_(false)
   2006     {}
   2007 
   2008     _LIBCPP_INLINE_VISIBILITY
   2009     explicit recursive_directory_iterator(const path& __p,
   2010                 directory_options __xoptions = directory_options::none)
   2011         : recursive_directory_iterator(__p, __xoptions,  nullptr)
   2012     { }
   2013 
   2014     _LIBCPP_INLINE_VISIBILITY
   2015     recursive_directory_iterator(const path& __p,
   2016         directory_options __xoptions, error_code& __ec) _NOEXCEPT
   2017         : recursive_directory_iterator(__p, __xoptions, &__ec)
   2018     { }
   2019 
   2020     _LIBCPP_INLINE_VISIBILITY
   2021     recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
   2022         : recursive_directory_iterator(__p, directory_options::none,  &__ec)
   2023     { }
   2024 
   2025     recursive_directory_iterator(const recursive_directory_iterator&) = default;
   2026     recursive_directory_iterator(recursive_directory_iterator&&) = default;
   2027 
   2028     recursive_directory_iterator &
   2029     operator=(const recursive_directory_iterator&) = default;
   2030 
   2031     _LIBCPP_INLINE_VISIBILITY
   2032     recursive_directory_iterator &
   2033     operator=(recursive_directory_iterator&& __o) noexcept {
   2034         // non-default implementation provided to support self-move assign.
   2035         if (this != &__o) {
   2036             __imp_ = _VSTD::move(__o.__imp_);
   2037             __rec_ = __o.__rec_;
   2038         }
   2039         return *this;
   2040     }
   2041 
   2042     ~recursive_directory_iterator() = default;
   2043 
   2044     _LIBCPP_INLINE_VISIBILITY
   2045     const directory_entry& operator*() const
   2046     { return __dereference(); }
   2047 
   2048     _LIBCPP_INLINE_VISIBILITY
   2049     const directory_entry* operator->() const
   2050     { return &__dereference(); }
   2051 
   2052     recursive_directory_iterator& operator++()
   2053     { return __increment(); }
   2054 
   2055     _LIBCPP_INLINE_VISIBILITY
   2056     __dir_element_proxy operator++(int) {
   2057         __dir_element_proxy __p(**this);
   2058         __increment();
   2059         return __p;
   2060     }
   2061 
   2062     _LIBCPP_INLINE_VISIBILITY
   2063     recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT
   2064     { return __increment(&__ec); }
   2065 
   2066     _LIBCPP_FUNC_VIS directory_options options() const;
   2067     _LIBCPP_FUNC_VIS int  depth() const;
   2068 
   2069     _LIBCPP_INLINE_VISIBILITY
   2070     void pop() { __pop(); }
   2071 
   2072     _LIBCPP_INLINE_VISIBILITY
   2073     void pop(error_code& __ec)
   2074     { __pop(&__ec); }
   2075 
   2076     _LIBCPP_INLINE_VISIBILITY
   2077     bool recursion_pending() const
   2078     { return __rec_; }
   2079 
   2080     _LIBCPP_INLINE_VISIBILITY
   2081     void disable_recursion_pending()
   2082     { __rec_ = false; }
   2083 
   2084 private:
   2085     recursive_directory_iterator(const path& __p, directory_options __opt,
   2086                                  error_code *__ec);
   2087 
   2088     _LIBCPP_FUNC_VIS
   2089     const directory_entry& __dereference() const;
   2090 
   2091     _LIBCPP_FUNC_VIS
   2092     bool __try_recursion(error_code* __ec);
   2093 
   2094     _LIBCPP_FUNC_VIS
   2095     void __advance(error_code* __ec=nullptr);
   2096 
   2097     _LIBCPP_FUNC_VIS
   2098     recursive_directory_iterator& __increment(error_code *__ec=nullptr);
   2099 
   2100     _LIBCPP_FUNC_VIS
   2101     void __pop(error_code* __ec=nullptr);
   2102 
   2103     inline _LIBCPP_INLINE_VISIBILITY
   2104     friend bool operator==(const recursive_directory_iterator&,
   2105                            const recursive_directory_iterator&) _NOEXCEPT;
   2106 
   2107     struct __shared_imp;
   2108     shared_ptr<__shared_imp> __imp_;
   2109     bool __rec_;
   2110 };                                     // class recursive_directory_iterator
   2111 
   2112 
   2113 inline _LIBCPP_INLINE_VISIBILITY
   2114 bool operator==(const recursive_directory_iterator& __lhs,
   2115                 const recursive_directory_iterator& __rhs) _NOEXCEPT
   2116 {
   2117     return __lhs.__imp_ == __rhs.__imp_;
   2118 }
   2119 
   2120 _LIBCPP_INLINE_VISIBILITY
   2121 inline bool operator!=(const recursive_directory_iterator& __lhs,
   2122                         const recursive_directory_iterator& __rhs) _NOEXCEPT
   2123 {
   2124     return !(__lhs == __rhs);
   2125 }
   2126 // enable recursive_directory_iterator range-based for statements
   2127 inline _LIBCPP_INLINE_VISIBILITY
   2128 recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT {
   2129     return __iter;
   2130 }
   2131 
   2132 inline _LIBCPP_INLINE_VISIBILITY
   2133 recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT {
   2134     return recursive_directory_iterator();
   2135 }
   2136 
   2137 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
   2138 
   2139 #endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM
   2140