xref: /freebsd/contrib/llvm-project/libcxx/include/filesystem (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===--------------------------- filesystem -------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric#ifndef _LIBCPP_FILESYSTEM
100b57cec5SDimitry Andric#define _LIBCPP_FILESYSTEM
110b57cec5SDimitry Andric/*
120b57cec5SDimitry Andric    filesystem synopsis
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric    namespace std { namespace filesystem {
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric    class path;
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric    void swap(path& lhs, path& rhs) noexcept;
190b57cec5SDimitry Andric    size_t hash_value(const path& p) noexcept;
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric    bool operator==(const path& lhs, const path& rhs) noexcept;
220b57cec5SDimitry Andric    bool operator!=(const path& lhs, const path& rhs) noexcept;
230b57cec5SDimitry Andric    bool operator< (const path& lhs, const path& rhs) noexcept;
240b57cec5SDimitry Andric    bool operator<=(const path& lhs, const path& rhs) noexcept;
250b57cec5SDimitry Andric    bool operator> (const path& lhs, const path& rhs) noexcept;
260b57cec5SDimitry Andric    bool operator>=(const path& lhs, const path& rhs) noexcept;
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric    path operator/ (const path& lhs, const path& rhs);
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric    // fs.path.io operators are friends of path.
310b57cec5SDimitry Andric    template <class charT, class traits>
320b57cec5SDimitry Andric    friend basic_ostream<charT, traits>&
330b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os, const path& p);
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric    template <class charT, class traits>
360b57cec5SDimitry Andric    friend basic_istream<charT, traits>&
370b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is, path& p);
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric    template <class Source>
400b57cec5SDimitry Andric      path u8path(const Source& source);
410b57cec5SDimitry Andric    template <class InputIterator>
420b57cec5SDimitry Andric      path u8path(InputIterator first, InputIterator last);
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric    class filesystem_error;
450b57cec5SDimitry Andric    class directory_entry;
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric    class directory_iterator;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric    // enable directory_iterator range-based for statements
500b57cec5SDimitry Andric    directory_iterator begin(directory_iterator iter) noexcept;
510b57cec5SDimitry Andric    directory_iterator end(const directory_iterator&) noexcept;
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric    class recursive_directory_iterator;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric    // enable recursive_directory_iterator range-based for statements
560b57cec5SDimitry Andric    recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
570b57cec5SDimitry Andric    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    class file_status;
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric    struct space_info
620b57cec5SDimitry Andric    {
630b57cec5SDimitry Andric      uintmax_t capacity;
640b57cec5SDimitry Andric      uintmax_t free;
650b57cec5SDimitry Andric      uintmax_t available;
660b57cec5SDimitry Andric    };
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric    enum class file_type;
690b57cec5SDimitry Andric    enum class perms;
700b57cec5SDimitry Andric    enum class perm_options;
710b57cec5SDimitry Andric    enum class copy_options;
720b57cec5SDimitry Andric    enum class directory_options;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric    typedef chrono::time_point<trivial-clock>  file_time_type;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric    // operational functions
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric    path absolute(const path& p);
790b57cec5SDimitry Andric    path absolute(const path& p, error_code &ec);
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric    path canonical(const path& p);
820b57cec5SDimitry Andric    path canonical(const path& p, error_code& ec);
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    void copy(const path& from, const path& to);
850b57cec5SDimitry Andric    void copy(const path& from, const path& to, error_code& ec);
860b57cec5SDimitry Andric    void copy(const path& from, const path& to, copy_options options);
870b57cec5SDimitry Andric    void copy(const path& from, const path& to, copy_options options,
880b57cec5SDimitry Andric                   error_code& ec);
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric    bool copy_file(const path& from, const path& to);
910b57cec5SDimitry Andric    bool copy_file(const path& from, const path& to, error_code& ec);
920b57cec5SDimitry Andric    bool copy_file(const path& from, const path& to, copy_options option);
930b57cec5SDimitry Andric    bool copy_file(const path& from, const path& to, copy_options option,
940b57cec5SDimitry Andric                           error_code& ec);
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric    void copy_symlink(const path& existing_symlink, const path& new_symlink);
970b57cec5SDimitry Andric    void copy_symlink(const path& existing_symlink, const path& new_symlink,
980b57cec5SDimitry Andric                              error_code& ec) noexcept;
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric    bool create_directories(const path& p);
1010b57cec5SDimitry Andric    bool create_directories(const path& p, error_code& ec);
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric    bool create_directory(const path& p);
1040b57cec5SDimitry Andric    bool create_directory(const path& p, error_code& ec) noexcept;
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric    bool create_directory(const path& p, const path& attributes);
1070b57cec5SDimitry Andric    bool create_directory(const path& p, const path& attributes,
1080b57cec5SDimitry Andric                                  error_code& ec) noexcept;
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric    void create_directory_symlink(const path& to, const path& new_symlink);
1110b57cec5SDimitry Andric    void create_directory_symlink(const path& to, const path& new_symlink,
1120b57cec5SDimitry Andric                                          error_code& ec) noexcept;
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric    void create_hard_link(const path& to, const path& new_hard_link);
1150b57cec5SDimitry Andric    void create_hard_link(const path& to, const path& new_hard_link,
1160b57cec5SDimitry Andric                                  error_code& ec) noexcept;
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric    void create_symlink(const path& to, const path& new_symlink);
1190b57cec5SDimitry Andric    void create_symlink(const path& to, const path& new_symlink,
1200b57cec5SDimitry Andric                                error_code& ec) noexcept;
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric    path current_path();
1230b57cec5SDimitry Andric    path current_path(error_code& ec);
1240b57cec5SDimitry Andric    void current_path(const path& p);
1250b57cec5SDimitry Andric    void current_path(const path& p, error_code& ec) noexcept;
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    bool exists(file_status s) noexcept;
1280b57cec5SDimitry Andric    bool exists(const path& p);
1290b57cec5SDimitry Andric    bool exists(const path& p, error_code& ec) noexcept;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric    bool equivalent(const path& p1, const path& p2);
1320b57cec5SDimitry Andric    bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric    uintmax_t    file_size(const path& p);
1350b57cec5SDimitry Andric    uintmax_t    file_size(const path& p, error_code& ec) noexcept;
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric    uintmax_t    hard_link_count(const path& p);
1380b57cec5SDimitry Andric    uintmax_t    hard_link_count(const path& p, error_code& ec) noexcept;
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andric    bool is_block_file(file_status s) noexcept;
1410b57cec5SDimitry Andric    bool is_block_file(const path& p);
1420b57cec5SDimitry Andric    bool is_block_file(const path& p, error_code& ec) noexcept;
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andric    bool is_character_file(file_status s) noexcept;
1450b57cec5SDimitry Andric    bool is_character_file(const path& p);
1460b57cec5SDimitry Andric    bool is_character_file(const path& p, error_code& ec) noexcept;
1470b57cec5SDimitry Andric
1480b57cec5SDimitry Andric    bool is_directory(file_status s) noexcept;
1490b57cec5SDimitry Andric    bool is_directory(const path& p);
1500b57cec5SDimitry Andric    bool is_directory(const path& p, error_code& ec) noexcept;
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric    bool is_empty(const path& p);
1530b57cec5SDimitry Andric    bool is_empty(const path& p, error_code& ec) noexcept;
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric    bool is_fifo(file_status s) noexcept;
1560b57cec5SDimitry Andric    bool is_fifo(const path& p);
1570b57cec5SDimitry Andric    bool is_fifo(const path& p, error_code& ec) noexcept;
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric    bool is_other(file_status s) noexcept;
1600b57cec5SDimitry Andric    bool is_other(const path& p);
1610b57cec5SDimitry Andric    bool is_other(const path& p, error_code& ec) noexcept;
1620b57cec5SDimitry Andric
1630b57cec5SDimitry Andric    bool is_regular_file(file_status s) noexcept;
1640b57cec5SDimitry Andric    bool is_regular_file(const path& p);
1650b57cec5SDimitry Andric    bool is_regular_file(const path& p, error_code& ec) noexcept;
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric    bool is_socket(file_status s) noexcept;
1680b57cec5SDimitry Andric    bool is_socket(const path& p);
1690b57cec5SDimitry Andric    bool is_socket(const path& p, error_code& ec) noexcept;
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric    bool is_symlink(file_status s) noexcept;
1720b57cec5SDimitry Andric    bool is_symlink(const path& p);
1730b57cec5SDimitry Andric    bool is_symlink(const path& p, error_code& ec) noexcept;
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric    file_time_type  last_write_time(const path& p);
1760b57cec5SDimitry Andric    file_time_type  last_write_time(const path& p, error_code& ec) noexcept;
1770b57cec5SDimitry Andric    void last_write_time(const path& p, file_time_type new_time);
1780b57cec5SDimitry Andric    void last_write_time(const path& p, file_time_type new_time,
1790b57cec5SDimitry Andric                                 error_code& ec) noexcept;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric    void permissions(const path& p, perms prms,
1820b57cec5SDimitry Andric                     perm_options opts=perm_options::replace);
1830b57cec5SDimitry Andric    void permissions(const path& p, perms prms, error_code& ec) noexcept;
1840b57cec5SDimitry Andric    void permissions(const path& p, perms prms, perm_options opts,
1850b57cec5SDimitry Andric                     error_code& ec);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric    path proximate(const path& p, error_code& ec);
1880b57cec5SDimitry Andric    path proximate(const path& p, const path& base = current_path());
1890b57cec5SDimitry Andric    path proximate(const path& p, const path& base, error_code &ec);
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric    path read_symlink(const path& p);
1920b57cec5SDimitry Andric    path read_symlink(const path& p, error_code& ec);
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric    path relative(const path& p, error_code& ec);
1950b57cec5SDimitry Andric    path relative(const path& p, const path& base=current_path());
1960b57cec5SDimitry Andric    path relative(const path& p, const path& base, error_code& ec);
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric    bool remove(const path& p);
1990b57cec5SDimitry Andric    bool remove(const path& p, error_code& ec) noexcept;
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric    uintmax_t    remove_all(const path& p);
2020b57cec5SDimitry Andric    uintmax_t    remove_all(const path& p, error_code& ec);
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric    void rename(const path& from, const path& to);
2050b57cec5SDimitry Andric    void rename(const path& from, const path& to, error_code& ec) noexcept;
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andric    void resize_file(const path& p, uintmax_t size);
2080b57cec5SDimitry Andric    void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric    space_info   space(const path& p);
2110b57cec5SDimitry Andric    space_info   space(const path& p, error_code& ec) noexcept;
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andric    file_status  status(const path& p);
2140b57cec5SDimitry Andric    file_status  status(const path& p, error_code& ec) noexcept;
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric    bool status_known(file_status s) noexcept;
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric    file_status  symlink_status(const path& p);
2190b57cec5SDimitry Andric    file_status  symlink_status(const path& p, error_code& ec) noexcept;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric    path temp_directory_path();
2220b57cec5SDimitry Andric    path temp_directory_path(error_code& ec);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric    path weakly_canonical(path const& p);
2250b57cec5SDimitry Andric    path weakly_canonical(path const& p, error_code& ec);
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric} }  // namespaces std::filesystem
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric*/
2310b57cec5SDimitry Andric
232e8d8bef9SDimitry Andric#include <__availability>
233*fe6060f1SDimitry Andric#include <__config>
234*fe6060f1SDimitry Andric#include <__debug>
235*fe6060f1SDimitry Andric#include <__utility/forward.h>
236*fe6060f1SDimitry Andric#include <chrono>
237*fe6060f1SDimitry Andric#include <compare>
2380b57cec5SDimitry Andric#include <cstddef>
2390b57cec5SDimitry Andric#include <cstdlib>
2400b57cec5SDimitry Andric#include <iosfwd>
241*fe6060f1SDimitry Andric#include <iterator>
2420b57cec5SDimitry Andric#include <memory>
2430b57cec5SDimitry Andric#include <stack>
2440b57cec5SDimitry Andric#include <string>
245*fe6060f1SDimitry Andric#include <string_view>
2460b57cec5SDimitry Andric#include <system_error>
2470b57cec5SDimitry Andric#include <utility>
2480b57cec5SDimitry Andric#include <version>
2490b57cec5SDimitry Andric
250e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
251e8d8bef9SDimitry Andric# include <locale>
252e8d8bef9SDimitry Andric# include <iomanip> // for quoted
253e8d8bef9SDimitry Andric#endif
254e8d8bef9SDimitry Andric
255e8d8bef9SDimitry Andric#if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
256e8d8bef9SDimitry Andric# error "The Filesystem library is not supported by this configuration of libc++"
257e8d8bef9SDimitry Andric#endif
258e8d8bef9SDimitry Andric
2590b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2600b57cec5SDimitry Andric#pragma GCC system_header
2610b57cec5SDimitry Andric#endif
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2640b57cec5SDimitry Andric#include <__undef_macros>
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andrictypedef chrono::time_point<_FilesystemClock> file_time_type;
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS space_info {
2750b57cec5SDimitry Andric  uintmax_t capacity;
2760b57cec5SDimitry Andric  uintmax_t free;
2770b57cec5SDimitry Andric  uintmax_t available;
2780b57cec5SDimitry Andric};
2790b57cec5SDimitry Andric
280*fe6060f1SDimitry Andric// On Windows, the library never identifies files as  block, character, fifo
281*fe6060f1SDimitry Andric// or socket.
2820b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS file_type : signed char {
2830b57cec5SDimitry Andric  none = 0,
2840b57cec5SDimitry Andric  not_found = -1,
2850b57cec5SDimitry Andric  regular = 1,
2860b57cec5SDimitry Andric  directory = 2,
2870b57cec5SDimitry Andric  symlink = 3,
2880b57cec5SDimitry Andric  block = 4,
2890b57cec5SDimitry Andric  character = 5,
2900b57cec5SDimitry Andric  fifo = 6,
2910b57cec5SDimitry Andric  socket = 7,
2920b57cec5SDimitry Andric  unknown = 8
2930b57cec5SDimitry Andric};
2940b57cec5SDimitry Andric
295*fe6060f1SDimitry Andric// On Windows, these permission bits map to one single readonly flag per
296*fe6060f1SDimitry Andric// file, and the executable bit is always returned as set. When setting
297*fe6060f1SDimitry Andric// permissions, as long as the write bit is set for either owner, group or
298*fe6060f1SDimitry Andric// others, the readonly flag is cleared.
2990b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS perms : unsigned {
3000b57cec5SDimitry Andric  none = 0,
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric  owner_read = 0400,
3030b57cec5SDimitry Andric  owner_write = 0200,
3040b57cec5SDimitry Andric  owner_exec = 0100,
3050b57cec5SDimitry Andric  owner_all = 0700,
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric  group_read = 040,
3080b57cec5SDimitry Andric  group_write = 020,
3090b57cec5SDimitry Andric  group_exec = 010,
3100b57cec5SDimitry Andric  group_all = 070,
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric  others_read = 04,
3130b57cec5SDimitry Andric  others_write = 02,
3140b57cec5SDimitry Andric  others_exec = 01,
3150b57cec5SDimitry Andric  others_all = 07,
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andric  all = 0777,
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric  set_uid = 04000,
3200b57cec5SDimitry Andric  set_gid = 02000,
3210b57cec5SDimitry Andric  sticky_bit = 01000,
3220b57cec5SDimitry Andric  mask = 07777,
3230b57cec5SDimitry Andric  unknown = 0xFFFF,
3240b57cec5SDimitry Andric};
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3270b57cec5SDimitry Andricinline constexpr perms operator&(perms _LHS, perms _RHS) {
3280b57cec5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) &
3290b57cec5SDimitry Andric                            static_cast<unsigned>(_RHS));
3300b57cec5SDimitry Andric}
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3330b57cec5SDimitry Andricinline constexpr perms operator|(perms _LHS, perms _RHS) {
3340b57cec5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) |
3350b57cec5SDimitry Andric                            static_cast<unsigned>(_RHS));
3360b57cec5SDimitry Andric}
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3390b57cec5SDimitry Andricinline constexpr perms operator^(perms _LHS, perms _RHS) {
3400b57cec5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) ^
3410b57cec5SDimitry Andric                            static_cast<unsigned>(_RHS));
3420b57cec5SDimitry Andric}
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3450b57cec5SDimitry Andricinline constexpr perms operator~(perms _LHS) {
3460b57cec5SDimitry Andric  return static_cast<perms>(~static_cast<unsigned>(_LHS));
3470b57cec5SDimitry Andric}
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3500b57cec5SDimitry Andricinline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3530b57cec5SDimitry Andricinline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3560b57cec5SDimitry Andricinline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
3590b57cec5SDimitry Andric  replace = 1,
3600b57cec5SDimitry Andric  add = 2,
3610b57cec5SDimitry Andric  remove = 4,
3620b57cec5SDimitry Andric  nofollow = 8
3630b57cec5SDimitry Andric};
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3660b57cec5SDimitry Andricinline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
3670b57cec5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
3680b57cec5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3690b57cec5SDimitry Andric}
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3720b57cec5SDimitry Andricinline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
3730b57cec5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
3740b57cec5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3750b57cec5SDimitry Andric}
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3780b57cec5SDimitry Andricinline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
3790b57cec5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
3800b57cec5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3810b57cec5SDimitry Andric}
3820b57cec5SDimitry Andric
3830b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3840b57cec5SDimitry Andricinline constexpr perm_options operator~(perm_options _LHS) {
3850b57cec5SDimitry Andric  return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
3860b57cec5SDimitry Andric}
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3890b57cec5SDimitry Andricinline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
3900b57cec5SDimitry Andric  return _LHS = _LHS & _RHS;
3910b57cec5SDimitry Andric}
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3940b57cec5SDimitry Andricinline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
3950b57cec5SDimitry Andric  return _LHS = _LHS | _RHS;
3960b57cec5SDimitry Andric}
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3990b57cec5SDimitry Andricinline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
4000b57cec5SDimitry Andric  return _LHS = _LHS ^ _RHS;
4010b57cec5SDimitry Andric}
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
4040b57cec5SDimitry Andric  none = 0,
4050b57cec5SDimitry Andric  skip_existing = 1,
4060b57cec5SDimitry Andric  overwrite_existing = 2,
4070b57cec5SDimitry Andric  update_existing = 4,
4080b57cec5SDimitry Andric  recursive = 8,
4090b57cec5SDimitry Andric  copy_symlinks = 16,
4100b57cec5SDimitry Andric  skip_symlinks = 32,
4110b57cec5SDimitry Andric  directories_only = 64,
4120b57cec5SDimitry Andric  create_symlinks = 128,
4130b57cec5SDimitry Andric  create_hard_links = 256,
4140b57cec5SDimitry Andric  __in_recursive_copy = 512,
4150b57cec5SDimitry Andric};
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4180b57cec5SDimitry Andricinline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
4190b57cec5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
4200b57cec5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4210b57cec5SDimitry Andric}
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4240b57cec5SDimitry Andricinline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
4250b57cec5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
4260b57cec5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4270b57cec5SDimitry Andric}
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4300b57cec5SDimitry Andricinline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
4310b57cec5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
4320b57cec5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4330b57cec5SDimitry Andric}
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4360b57cec5SDimitry Andricinline constexpr copy_options operator~(copy_options _LHS) {
4370b57cec5SDimitry Andric  return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
4380b57cec5SDimitry Andric}
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4410b57cec5SDimitry Andricinline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
4420b57cec5SDimitry Andric  return _LHS = _LHS & _RHS;
4430b57cec5SDimitry Andric}
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4460b57cec5SDimitry Andricinline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
4470b57cec5SDimitry Andric  return _LHS = _LHS | _RHS;
4480b57cec5SDimitry Andric}
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4510b57cec5SDimitry Andricinline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
4520b57cec5SDimitry Andric  return _LHS = _LHS ^ _RHS;
4530b57cec5SDimitry Andric}
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andricenum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
4560b57cec5SDimitry Andric  none = 0,
4570b57cec5SDimitry Andric  follow_directory_symlink = 1,
4580b57cec5SDimitry Andric  skip_permission_denied = 2
4590b57cec5SDimitry Andric};
4600b57cec5SDimitry Andric
4610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4620b57cec5SDimitry Andricinline constexpr directory_options operator&(directory_options _LHS,
4630b57cec5SDimitry Andric                                             directory_options _RHS) {
4640b57cec5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
4650b57cec5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4660b57cec5SDimitry Andric}
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4690b57cec5SDimitry Andricinline constexpr directory_options operator|(directory_options _LHS,
4700b57cec5SDimitry Andric                                             directory_options _RHS) {
4710b57cec5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
4720b57cec5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4730b57cec5SDimitry Andric}
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4760b57cec5SDimitry Andricinline constexpr directory_options operator^(directory_options _LHS,
4770b57cec5SDimitry Andric                                             directory_options _RHS) {
4780b57cec5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
4790b57cec5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4800b57cec5SDimitry Andric}
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4830b57cec5SDimitry Andricinline constexpr directory_options operator~(directory_options _LHS) {
4840b57cec5SDimitry Andric  return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
4850b57cec5SDimitry Andric}
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4880b57cec5SDimitry Andricinline directory_options& operator&=(directory_options& _LHS,
4890b57cec5SDimitry Andric                                     directory_options _RHS) {
4900b57cec5SDimitry Andric  return _LHS = _LHS & _RHS;
4910b57cec5SDimitry Andric}
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4940b57cec5SDimitry Andricinline directory_options& operator|=(directory_options& _LHS,
4950b57cec5SDimitry Andric                                     directory_options _RHS) {
4960b57cec5SDimitry Andric  return _LHS = _LHS | _RHS;
4970b57cec5SDimitry Andric}
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
5000b57cec5SDimitry Andricinline directory_options& operator^=(directory_options& _LHS,
5010b57cec5SDimitry Andric                                     directory_options _RHS) {
5020b57cec5SDimitry Andric  return _LHS = _LHS ^ _RHS;
5030b57cec5SDimitry Andric}
5040b57cec5SDimitry Andric
5050b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS file_status {
5060b57cec5SDimitry Andricpublic:
5070b57cec5SDimitry Andric  // constructors
5080b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5090b57cec5SDimitry Andric  file_status() noexcept : file_status(file_type::none) {}
5100b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5110b57cec5SDimitry Andric  explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
5120b57cec5SDimitry Andric      : __ft_(__ft),
5130b57cec5SDimitry Andric        __prms_(__prms) {}
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric  file_status(const file_status&) noexcept = default;
5160b57cec5SDimitry Andric  file_status(file_status&&) noexcept = default;
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5190b57cec5SDimitry Andric  ~file_status() {}
5200b57cec5SDimitry Andric
5210b57cec5SDimitry Andric  file_status& operator=(const file_status&) noexcept = default;
5220b57cec5SDimitry Andric  file_status& operator=(file_status&&) noexcept = default;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric  // observers
5250b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5260b57cec5SDimitry Andric  file_type type() const noexcept { return __ft_; }
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5290b57cec5SDimitry Andric  perms permissions() const noexcept { return __prms_; }
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric  // modifiers
5320b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5330b57cec5SDimitry Andric  void type(file_type __ft) noexcept { __ft_ = __ft; }
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5360b57cec5SDimitry Andric  void permissions(perms __p) noexcept { __prms_ = __p; }
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andricprivate:
5390b57cec5SDimitry Andric  file_type __ft_;
5400b57cec5SDimitry Andric  perms __prms_;
5410b57cec5SDimitry Andric};
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS directory_entry;
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andrictemplate <class _Tp>
5460b57cec5SDimitry Andricstruct __can_convert_char {
5470b57cec5SDimitry Andric  static const bool value = false;
5480b57cec5SDimitry Andric};
5490b57cec5SDimitry Andrictemplate <class _Tp>
5500b57cec5SDimitry Andricstruct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
5510b57cec5SDimitry Andrictemplate <>
5520b57cec5SDimitry Andricstruct __can_convert_char<char> {
5530b57cec5SDimitry Andric  static const bool value = true;
5540b57cec5SDimitry Andric  using __char_type = char;
5550b57cec5SDimitry Andric};
5560b57cec5SDimitry Andrictemplate <>
5570b57cec5SDimitry Andricstruct __can_convert_char<wchar_t> {
5580b57cec5SDimitry Andric  static const bool value = true;
5590b57cec5SDimitry Andric  using __char_type = wchar_t;
5600b57cec5SDimitry Andric};
561*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
562e8d8bef9SDimitry Andrictemplate <>
563e8d8bef9SDimitry Andricstruct __can_convert_char<char8_t> {
564e8d8bef9SDimitry Andric  static const bool value = true;
565e8d8bef9SDimitry Andric  using __char_type = char8_t;
566e8d8bef9SDimitry Andric};
567e8d8bef9SDimitry Andric#endif
5680b57cec5SDimitry Andrictemplate <>
5690b57cec5SDimitry Andricstruct __can_convert_char<char16_t> {
5700b57cec5SDimitry Andric  static const bool value = true;
5710b57cec5SDimitry Andric  using __char_type = char16_t;
5720b57cec5SDimitry Andric};
5730b57cec5SDimitry Andrictemplate <>
5740b57cec5SDimitry Andricstruct __can_convert_char<char32_t> {
5750b57cec5SDimitry Andric  static const bool value = true;
5760b57cec5SDimitry Andric  using __char_type = char32_t;
5770b57cec5SDimitry Andric};
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andrictemplate <class _ECharT>
5800b57cec5SDimitry Andrictypename enable_if<__can_convert_char<_ECharT>::value, bool>::type
5810b57cec5SDimitry Andric__is_separator(_ECharT __e) {
582e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
583e8d8bef9SDimitry Andric  return __e == _ECharT('/') || __e == _ECharT('\\');
584e8d8bef9SDimitry Andric#else
5850b57cec5SDimitry Andric  return __e == _ECharT('/');
586e8d8bef9SDimitry Andric#endif
5870b57cec5SDimitry Andric}
5880b57cec5SDimitry Andric
589*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
590e8d8bef9SDimitry Andrictypedef u8string __u8_string;
591e8d8bef9SDimitry Andric#else
592e8d8bef9SDimitry Andrictypedef string __u8_string;
593e8d8bef9SDimitry Andric#endif
594e8d8bef9SDimitry Andric
595e8d8bef9SDimitry Andricstruct _NullSentinel {};
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andrictemplate <class _Tp>
5980b57cec5SDimitry Andricusing _Void = void;
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andrictemplate <class _Tp, class = void>
6010b57cec5SDimitry Andricstruct __is_pathable_string : public false_type {};
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andrictemplate <class _ECharT, class _Traits, class _Alloc>
6040b57cec5SDimitry Andricstruct __is_pathable_string<
6050b57cec5SDimitry Andric    basic_string<_ECharT, _Traits, _Alloc>,
6060b57cec5SDimitry Andric    _Void<typename __can_convert_char<_ECharT>::__char_type> >
6070b57cec5SDimitry Andric    : public __can_convert_char<_ECharT> {
6080b57cec5SDimitry Andric  using _Str = basic_string<_ECharT, _Traits, _Alloc>;
6090b57cec5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
6100b57cec5SDimitry Andric  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
6110b57cec5SDimitry Andric  static _ECharT const* __range_end(_Str const& __s) {
6120b57cec5SDimitry Andric    return __s.data() + __s.length();
6130b57cec5SDimitry Andric  }
6140b57cec5SDimitry Andric  static _ECharT __first_or_null(_Str const& __s) {
6150b57cec5SDimitry Andric    return __s.empty() ? _ECharT{} : __s[0];
6160b57cec5SDimitry Andric  }
6170b57cec5SDimitry Andric};
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andrictemplate <class _ECharT, class _Traits>
6200b57cec5SDimitry Andricstruct __is_pathable_string<
6210b57cec5SDimitry Andric    basic_string_view<_ECharT, _Traits>,
6220b57cec5SDimitry Andric    _Void<typename __can_convert_char<_ECharT>::__char_type> >
6230b57cec5SDimitry Andric    : public __can_convert_char<_ECharT> {
6240b57cec5SDimitry Andric  using _Str = basic_string_view<_ECharT, _Traits>;
6250b57cec5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
6260b57cec5SDimitry Andric  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
6270b57cec5SDimitry Andric  static _ECharT const* __range_end(_Str const& __s) {
6280b57cec5SDimitry Andric    return __s.data() + __s.length();
6290b57cec5SDimitry Andric  }
6300b57cec5SDimitry Andric  static _ECharT __first_or_null(_Str const& __s) {
6310b57cec5SDimitry Andric    return __s.empty() ? _ECharT{} : __s[0];
6320b57cec5SDimitry Andric  }
6330b57cec5SDimitry Andric};
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andrictemplate <class _Source, class _DS = typename decay<_Source>::type,
6360b57cec5SDimitry Andric          class _UnqualPtrType =
6370b57cec5SDimitry Andric              typename remove_const<typename remove_pointer<_DS>::type>::type,
6380b57cec5SDimitry Andric          bool _IsCharPtr = is_pointer<_DS>::value&&
6390b57cec5SDimitry Andric              __can_convert_char<_UnqualPtrType>::value>
6400b57cec5SDimitry Andricstruct __is_pathable_char_array : false_type {};
6410b57cec5SDimitry Andric
6420b57cec5SDimitry Andrictemplate <class _Source, class _ECharT, class _UPtr>
6430b57cec5SDimitry Andricstruct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
6440b57cec5SDimitry Andric    : __can_convert_char<typename remove_const<_ECharT>::type> {
6450b57cec5SDimitry Andric  using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric  static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
6480b57cec5SDimitry Andric  static _ECharT const* __range_end(const _ECharT* __b) {
6490b57cec5SDimitry Andric    using _Iter = const _ECharT*;
650e8d8bef9SDimitry Andric    const _ECharT __sentinel = _ECharT{};
6510b57cec5SDimitry Andric    _Iter __e = __b;
652e8d8bef9SDimitry Andric    for (; *__e != __sentinel; ++__e)
6530b57cec5SDimitry Andric      ;
6540b57cec5SDimitry Andric    return __e;
6550b57cec5SDimitry Andric  }
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andric  static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
6580b57cec5SDimitry Andric};
6590b57cec5SDimitry Andric
660480093f4SDimitry Andrictemplate <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value,
6610b57cec5SDimitry Andric          class = void>
6620b57cec5SDimitry Andricstruct __is_pathable_iter : false_type {};
6630b57cec5SDimitry Andric
6640b57cec5SDimitry Andrictemplate <class _Iter>
6650b57cec5SDimitry Andricstruct __is_pathable_iter<
6660b57cec5SDimitry Andric    _Iter, true,
6670b57cec5SDimitry Andric    _Void<typename __can_convert_char<
6680b57cec5SDimitry Andric        typename iterator_traits<_Iter>::value_type>::__char_type> >
6690b57cec5SDimitry Andric    : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
6700b57cec5SDimitry Andric  using _ECharT = typename iterator_traits<_Iter>::value_type;
6710b57cec5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric  static _Iter __range_begin(_Iter __b) { return __b; }
674e8d8bef9SDimitry Andric  static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; }
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andric  static _ECharT __first_or_null(_Iter __b) { return *__b; }
6770b57cec5SDimitry Andric};
6780b57cec5SDimitry Andric
6790b57cec5SDimitry Andrictemplate <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
6800b57cec5SDimitry Andric          bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
6810b57cec5SDimitry Andric          bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
6820b57cec5SDimitry Andricstruct __is_pathable : false_type {
6830b57cec5SDimitry Andric  static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
6840b57cec5SDimitry Andric};
6850b57cec5SDimitry Andric
6860b57cec5SDimitry Andrictemplate <class _Tp>
6870b57cec5SDimitry Andricstruct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
6880b57cec5SDimitry Andric
6890b57cec5SDimitry Andrictemplate <class _Tp>
6900b57cec5SDimitry Andricstruct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
6910b57cec5SDimitry Andric};
6920b57cec5SDimitry Andric
6930b57cec5SDimitry Andrictemplate <class _Tp>
6940b57cec5SDimitry Andricstruct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
6950b57cec5SDimitry Andric
696e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
697e8d8bef9SDimitry Andrictypedef wstring __path_string;
698e8d8bef9SDimitry Andrictypedef wchar_t __path_value;
699e8d8bef9SDimitry Andric#else
700e8d8bef9SDimitry Andrictypedef string __path_string;
701e8d8bef9SDimitry Andrictypedef char __path_value;
702e8d8bef9SDimitry Andric#endif
703e8d8bef9SDimitry Andric
704e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
705e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS
706e8d8bef9SDimitry Andricsize_t __wide_to_char(const wstring&, char*, size_t);
707e8d8bef9SDimitry Andric_LIBCPP_FUNC_VIS
708e8d8bef9SDimitry Andricsize_t __char_to_wide(const string&, wchar_t*, size_t);
709e8d8bef9SDimitry Andric#endif
710e8d8bef9SDimitry Andric
711e8d8bef9SDimitry Andrictemplate <class _ECharT>
712e8d8bef9SDimitry Andricstruct _PathCVT;
713e8d8bef9SDimitry Andric
714e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
7150b57cec5SDimitry Andrictemplate <class _ECharT>
7160b57cec5SDimitry Andricstruct _PathCVT {
7170b57cec5SDimitry Andric  static_assert(__can_convert_char<_ECharT>::value,
7180b57cec5SDimitry Andric                "Char type not convertible");
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andric  typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
721e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
722e8d8bef9SDimitry Andric  typedef __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Widener;
723e8d8bef9SDimitry Andric#endif
7240b57cec5SDimitry Andric
725e8d8bef9SDimitry Andric  static void __append_range(__path_string& __dest, _ECharT const* __b,
7260b57cec5SDimitry Andric                             _ECharT const* __e) {
727e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
728e8d8bef9SDimitry Andric    string __utf8;
729e8d8bef9SDimitry Andric    _Narrower()(back_inserter(__utf8), __b, __e);
730e8d8bef9SDimitry Andric    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
731e8d8bef9SDimitry Andric#else
7320b57cec5SDimitry Andric    _Narrower()(back_inserter(__dest), __b, __e);
733e8d8bef9SDimitry Andric#endif
7340b57cec5SDimitry Andric  }
7350b57cec5SDimitry Andric
7360b57cec5SDimitry Andric  template <class _Iter>
737e8d8bef9SDimitry Andric  static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
7380b57cec5SDimitry Andric    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
7390b57cec5SDimitry Andric    if (__b == __e)
7400b57cec5SDimitry Andric      return;
7410b57cec5SDimitry Andric    basic_string<_ECharT> __tmp(__b, __e);
742e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
743e8d8bef9SDimitry Andric    string __utf8;
744e8d8bef9SDimitry Andric    _Narrower()(back_inserter(__utf8), __tmp.data(),
745e8d8bef9SDimitry Andric                __tmp.data() + __tmp.length());
746e8d8bef9SDimitry Andric    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
747e8d8bef9SDimitry Andric#else
7480b57cec5SDimitry Andric    _Narrower()(back_inserter(__dest), __tmp.data(),
7490b57cec5SDimitry Andric                __tmp.data() + __tmp.length());
750e8d8bef9SDimitry Andric#endif
7510b57cec5SDimitry Andric  }
7520b57cec5SDimitry Andric
7530b57cec5SDimitry Andric  template <class _Iter>
754e8d8bef9SDimitry Andric  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
7550b57cec5SDimitry Andric    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
756e8d8bef9SDimitry Andric    const _ECharT __sentinel = _ECharT{};
757e8d8bef9SDimitry Andric    if (*__b == __sentinel)
7580b57cec5SDimitry Andric      return;
7590b57cec5SDimitry Andric    basic_string<_ECharT> __tmp;
760e8d8bef9SDimitry Andric    for (; *__b != __sentinel; ++__b)
7610b57cec5SDimitry Andric      __tmp.push_back(*__b);
762e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
763e8d8bef9SDimitry Andric    string __utf8;
764e8d8bef9SDimitry Andric    _Narrower()(back_inserter(__utf8), __tmp.data(),
765e8d8bef9SDimitry Andric                __tmp.data() + __tmp.length());
766e8d8bef9SDimitry Andric    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
767e8d8bef9SDimitry Andric#else
7680b57cec5SDimitry Andric    _Narrower()(back_inserter(__dest), __tmp.data(),
7690b57cec5SDimitry Andric                __tmp.data() + __tmp.length());
770e8d8bef9SDimitry Andric#endif
7710b57cec5SDimitry Andric  }
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric  template <class _Source>
774e8d8bef9SDimitry Andric  static void __append_source(__path_string& __dest, _Source const& __s) {
7750b57cec5SDimitry Andric    using _Traits = __is_pathable<_Source>;
7760b57cec5SDimitry Andric    __append_range(__dest, _Traits::__range_begin(__s),
7770b57cec5SDimitry Andric                   _Traits::__range_end(__s));
7780b57cec5SDimitry Andric  }
7790b57cec5SDimitry Andric};
780e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andrictemplate <>
783e8d8bef9SDimitry Andricstruct _PathCVT<__path_value> {
7840b57cec5SDimitry Andric
7850b57cec5SDimitry Andric  template <class _Iter>
786480093f4SDimitry Andric  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
787e8d8bef9SDimitry Andric  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
7880b57cec5SDimitry Andric    for (; __b != __e; ++__b)
7890b57cec5SDimitry Andric      __dest.push_back(*__b);
7900b57cec5SDimitry Andric  }
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric  template <class _Iter>
793480093f4SDimitry Andric  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
794e8d8bef9SDimitry Andric  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
795*fe6060f1SDimitry Andric    __dest.append(__b, __e);
7960b57cec5SDimitry Andric  }
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric  template <class _Iter>
799e8d8bef9SDimitry Andric  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
800e8d8bef9SDimitry Andric    const char __sentinel = char{};
801e8d8bef9SDimitry Andric    for (; *__b != __sentinel; ++__b)
8020b57cec5SDimitry Andric      __dest.push_back(*__b);
8030b57cec5SDimitry Andric  }
8040b57cec5SDimitry Andric
8050b57cec5SDimitry Andric  template <class _Source>
806e8d8bef9SDimitry Andric  static void __append_source(__path_string& __dest, _Source const& __s) {
8070b57cec5SDimitry Andric    using _Traits = __is_pathable<_Source>;
8080b57cec5SDimitry Andric    __append_range(__dest, _Traits::__range_begin(__s),
8090b57cec5SDimitry Andric                   _Traits::__range_end(__s));
8100b57cec5SDimitry Andric  }
8110b57cec5SDimitry Andric};
8120b57cec5SDimitry Andric
813e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
814e8d8bef9SDimitry Andrictemplate <>
815e8d8bef9SDimitry Andricstruct _PathCVT<char> {
816e8d8bef9SDimitry Andric
817e8d8bef9SDimitry Andric  static void
818e8d8bef9SDimitry Andric  __append_string(__path_string& __dest, const basic_string<char> &__str) {
819e8d8bef9SDimitry Andric      size_t __size = __char_to_wide(__str, nullptr, 0);
820e8d8bef9SDimitry Andric      size_t __pos = __dest.size();
821e8d8bef9SDimitry Andric      __dest.resize(__pos + __size);
822e8d8bef9SDimitry Andric      __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size);
823e8d8bef9SDimitry Andric  }
824e8d8bef9SDimitry Andric
825e8d8bef9SDimitry Andric  template <class _Iter>
826e8d8bef9SDimitry Andric  static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type
827e8d8bef9SDimitry Andric  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
828e8d8bef9SDimitry Andric    basic_string<char> __tmp(__b, __e);
829e8d8bef9SDimitry Andric    __append_string(__dest, __tmp);
830e8d8bef9SDimitry Andric  }
831e8d8bef9SDimitry Andric
832e8d8bef9SDimitry Andric  template <class _Iter>
833e8d8bef9SDimitry Andric  static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type
834e8d8bef9SDimitry Andric  __append_range(__path_string& __dest, _Iter __b, _Iter __e) {
835e8d8bef9SDimitry Andric    basic_string<char> __tmp(__b, __e);
836e8d8bef9SDimitry Andric    __append_string(__dest, __tmp);
837e8d8bef9SDimitry Andric  }
838e8d8bef9SDimitry Andric
839e8d8bef9SDimitry Andric  template <class _Iter>
840e8d8bef9SDimitry Andric  static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) {
841e8d8bef9SDimitry Andric    const char __sentinel = char{};
842e8d8bef9SDimitry Andric    basic_string<char> __tmp;
843e8d8bef9SDimitry Andric    for (; *__b != __sentinel; ++__b)
844e8d8bef9SDimitry Andric      __tmp.push_back(*__b);
845e8d8bef9SDimitry Andric    __append_string(__dest, __tmp);
846e8d8bef9SDimitry Andric  }
847e8d8bef9SDimitry Andric
848e8d8bef9SDimitry Andric  template <class _Source>
849e8d8bef9SDimitry Andric  static void __append_source(__path_string& __dest, _Source const& __s) {
850e8d8bef9SDimitry Andric    using _Traits = __is_pathable<_Source>;
851e8d8bef9SDimitry Andric    __append_range(__dest, _Traits::__range_begin(__s),
852e8d8bef9SDimitry Andric                   _Traits::__range_end(__s));
853e8d8bef9SDimitry Andric  }
854e8d8bef9SDimitry Andric};
855e8d8bef9SDimitry Andric
856e8d8bef9SDimitry Andrictemplate <class _ECharT>
857e8d8bef9SDimitry Andricstruct _PathExport {
858e8d8bef9SDimitry Andric  typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
859e8d8bef9SDimitry Andric  typedef __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Widener;
860e8d8bef9SDimitry Andric
861e8d8bef9SDimitry Andric  template <class _Str>
862e8d8bef9SDimitry Andric  static void __append(_Str& __dest, const __path_string& __src) {
863e8d8bef9SDimitry Andric    string __utf8;
864e8d8bef9SDimitry Andric    _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size());
865e8d8bef9SDimitry Andric    _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size());
866e8d8bef9SDimitry Andric  }
867e8d8bef9SDimitry Andric};
868e8d8bef9SDimitry Andric
869e8d8bef9SDimitry Andrictemplate <>
870e8d8bef9SDimitry Andricstruct _PathExport<char> {
871e8d8bef9SDimitry Andric  template <class _Str>
872e8d8bef9SDimitry Andric  static void __append(_Str& __dest, const __path_string& __src) {
873e8d8bef9SDimitry Andric    size_t __size = __wide_to_char(__src, nullptr, 0);
874e8d8bef9SDimitry Andric    size_t __pos = __dest.size();
875e8d8bef9SDimitry Andric    __dest.resize(__size);
876e8d8bef9SDimitry Andric    __wide_to_char(__src, const_cast<char*>(__dest.data()) + __pos, __size);
877e8d8bef9SDimitry Andric  }
878e8d8bef9SDimitry Andric};
879e8d8bef9SDimitry Andric
880e8d8bef9SDimitry Andrictemplate <>
881e8d8bef9SDimitry Andricstruct _PathExport<wchar_t> {
882e8d8bef9SDimitry Andric  template <class _Str>
883e8d8bef9SDimitry Andric  static void __append(_Str& __dest, const __path_string& __src) {
884e8d8bef9SDimitry Andric    __dest.append(__src.begin(), __src.end());
885e8d8bef9SDimitry Andric  }
886e8d8bef9SDimitry Andric};
887e8d8bef9SDimitry Andric
888e8d8bef9SDimitry Andrictemplate <>
889e8d8bef9SDimitry Andricstruct _PathExport<char16_t> {
890e8d8bef9SDimitry Andric  template <class _Str>
891e8d8bef9SDimitry Andric  static void __append(_Str& __dest, const __path_string& __src) {
892e8d8bef9SDimitry Andric    __dest.append(__src.begin(), __src.end());
893e8d8bef9SDimitry Andric  }
894e8d8bef9SDimitry Andric};
895e8d8bef9SDimitry Andric
896*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
897e8d8bef9SDimitry Andrictemplate <>
898e8d8bef9SDimitry Andricstruct _PathExport<char8_t> {
899e8d8bef9SDimitry Andric  typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
900e8d8bef9SDimitry Andric
901e8d8bef9SDimitry Andric  template <class _Str>
902e8d8bef9SDimitry Andric  static void __append(_Str& __dest, const __path_string& __src) {
903e8d8bef9SDimitry Andric    _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
904e8d8bef9SDimitry Andric  }
905e8d8bef9SDimitry Andric};
906*fe6060f1SDimitry Andric#endif /* !_LIBCPP_HAS_NO_CHAR8_T */
907e8d8bef9SDimitry Andric#endif /* _LIBCPP_WIN32API */
908e8d8bef9SDimitry Andric
9090b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS path {
9100b57cec5SDimitry Andric  template <class _SourceOrIter, class _Tp = path&>
9110b57cec5SDimitry Andric  using _EnableIfPathable =
9120b57cec5SDimitry Andric      typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andric  template <class _Tp>
9150b57cec5SDimitry Andric  using _SourceChar = typename __is_pathable<_Tp>::__char_type;
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric  template <class _Tp>
9180b57cec5SDimitry Andric  using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
9190b57cec5SDimitry Andric
9200b57cec5SDimitry Andricpublic:
921e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
922e8d8bef9SDimitry Andric  typedef wchar_t value_type;
923e8d8bef9SDimitry Andric  static constexpr value_type preferred_separator = L'\\';
924e8d8bef9SDimitry Andric#else
9250b57cec5SDimitry Andric  typedef char value_type;
9260b57cec5SDimitry Andric  static constexpr value_type preferred_separator = '/';
927e8d8bef9SDimitry Andric#endif
928e8d8bef9SDimitry Andric  typedef basic_string<value_type> string_type;
929e8d8bef9SDimitry Andric  typedef basic_string_view<value_type> __string_view;
9300b57cec5SDimitry Andric
931*fe6060f1SDimitry Andric  enum _LIBCPP_ENUM_VIS format : unsigned char {
9320b57cec5SDimitry Andric    auto_format,
9330b57cec5SDimitry Andric    native_format,
9340b57cec5SDimitry Andric    generic_format
9350b57cec5SDimitry Andric  };
9360b57cec5SDimitry Andric
9370b57cec5SDimitry Andric  // constructors and destructor
9380b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path() noexcept {}
9390b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
9400b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
9410b57cec5SDimitry Andric      : __pn_(_VSTD::move(__p.__pn_)) {}
9420b57cec5SDimitry Andric
9430b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9440b57cec5SDimitry Andric  path(string_type&& __s, format = format::auto_format) noexcept
9450b57cec5SDimitry Andric      : __pn_(_VSTD::move(__s)) {}
9460b57cec5SDimitry Andric
9470b57cec5SDimitry Andric  template <class _Source, class = _EnableIfPathable<_Source, void> >
9480b57cec5SDimitry Andric  path(const _Source& __src, format = format::auto_format) {
9490b57cec5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __src);
9500b57cec5SDimitry Andric  }
9510b57cec5SDimitry Andric
9520b57cec5SDimitry Andric  template <class _InputIt>
9530b57cec5SDimitry Andric  path(_InputIt __first, _InputIt __last, format = format::auto_format) {
9540b57cec5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
9550b57cec5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
9560b57cec5SDimitry Andric  }
9570b57cec5SDimitry Andric
958e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
9590b57cec5SDimitry Andric  // TODO Implement locale conversions.
9600b57cec5SDimitry Andric  template <class _Source, class = _EnableIfPathable<_Source, void> >
9610b57cec5SDimitry Andric  path(const _Source& __src, const locale& __loc, format = format::auto_format);
9620b57cec5SDimitry Andric  template <class _InputIt>
9630b57cec5SDimitry Andric  path(_InputIt __first, _InputIt _last, const locale& __loc,
9640b57cec5SDimitry Andric       format = format::auto_format);
965e8d8bef9SDimitry Andric#endif
9660b57cec5SDimitry Andric
9670b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9680b57cec5SDimitry Andric  ~path() = default;
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andric  // assignments
9710b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9720b57cec5SDimitry Andric  path& operator=(const path& __p) {
9730b57cec5SDimitry Andric    __pn_ = __p.__pn_;
9740b57cec5SDimitry Andric    return *this;
9750b57cec5SDimitry Andric  }
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9780b57cec5SDimitry Andric  path& operator=(path&& __p) noexcept {
9790b57cec5SDimitry Andric    __pn_ = _VSTD::move(__p.__pn_);
9800b57cec5SDimitry Andric    return *this;
9810b57cec5SDimitry Andric  }
9820b57cec5SDimitry Andric
983*fe6060f1SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
984*fe6060f1SDimitry Andric  path& operator=(string_type&& __s) noexcept {
9850b57cec5SDimitry Andric    __pn_ = _VSTD::move(__s);
9860b57cec5SDimitry Andric    return *this;
9870b57cec5SDimitry Andric  }
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9900b57cec5SDimitry Andric  path& assign(string_type&& __s) noexcept {
9910b57cec5SDimitry Andric    __pn_ = _VSTD::move(__s);
9920b57cec5SDimitry Andric    return *this;
9930b57cec5SDimitry Andric  }
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andric  template <class _Source>
9960b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
9970b57cec5SDimitry Andric  operator=(const _Source& __src) {
9980b57cec5SDimitry Andric    return this->assign(__src);
9990b57cec5SDimitry Andric  }
10000b57cec5SDimitry Andric
10010b57cec5SDimitry Andric  template <class _Source>
10020b57cec5SDimitry Andric  _EnableIfPathable<_Source> assign(const _Source& __src) {
10030b57cec5SDimitry Andric    __pn_.clear();
10040b57cec5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __src);
10050b57cec5SDimitry Andric    return *this;
10060b57cec5SDimitry Andric  }
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andric  template <class _InputIt>
10090b57cec5SDimitry Andric  path& assign(_InputIt __first, _InputIt __last) {
10100b57cec5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
10110b57cec5SDimitry Andric    __pn_.clear();
10120b57cec5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
10130b57cec5SDimitry Andric    return *this;
10140b57cec5SDimitry Andric  }
10150b57cec5SDimitry Andric
10160b57cec5SDimitry Andricpublic:
10170b57cec5SDimitry Andric  // appends
1018*fe6060f1SDimitry Andric#if defined(_LIBCPP_WIN32API)
1019*fe6060f1SDimitry Andric  path& operator/=(const path& __p) {
1020*fe6060f1SDimitry Andric    auto __p_root_name = __p.__root_name();
1021*fe6060f1SDimitry Andric    auto __p_root_name_size = __p_root_name.size();
1022*fe6060f1SDimitry Andric    if (__p.is_absolute() ||
1023*fe6060f1SDimitry Andric        (!__p_root_name.empty() && __p_root_name != root_name())) {
1024*fe6060f1SDimitry Andric      __pn_ = __p.__pn_;
1025*fe6060f1SDimitry Andric      return *this;
1026*fe6060f1SDimitry Andric    }
1027*fe6060f1SDimitry Andric    if (__p.has_root_directory()) {
1028*fe6060f1SDimitry Andric      path __root_name_str = root_name();
1029*fe6060f1SDimitry Andric      __pn_ = __root_name_str.native();
1030*fe6060f1SDimitry Andric      __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1031*fe6060f1SDimitry Andric      return *this;
1032*fe6060f1SDimitry Andric    }
1033*fe6060f1SDimitry Andric    if (has_filename() || (!has_root_directory() && is_absolute()))
1034*fe6060f1SDimitry Andric      __pn_ += preferred_separator;
1035*fe6060f1SDimitry Andric    __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size);
1036*fe6060f1SDimitry Andric    return *this;
1037*fe6060f1SDimitry Andric  }
1038*fe6060f1SDimitry Andric  template <class _Source>
1039*fe6060f1SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
1040*fe6060f1SDimitry Andric  operator/=(const _Source& __src) {
1041*fe6060f1SDimitry Andric    return operator/=(path(__src));
1042*fe6060f1SDimitry Andric  }
1043*fe6060f1SDimitry Andric
1044*fe6060f1SDimitry Andric  template <class _Source>
1045*fe6060f1SDimitry Andric  _EnableIfPathable<_Source> append(const _Source& __src) {
1046*fe6060f1SDimitry Andric    return operator/=(path(__src));
1047*fe6060f1SDimitry Andric  }
1048*fe6060f1SDimitry Andric
1049*fe6060f1SDimitry Andric  template <class _InputIt>
1050*fe6060f1SDimitry Andric  path& append(_InputIt __first, _InputIt __last) {
1051*fe6060f1SDimitry Andric    return operator/=(path(__first, __last));
1052*fe6060f1SDimitry Andric  }
1053*fe6060f1SDimitry Andric#else
10540b57cec5SDimitry Andric  path& operator/=(const path& __p) {
10550b57cec5SDimitry Andric    if (__p.is_absolute()) {
10560b57cec5SDimitry Andric      __pn_ = __p.__pn_;
10570b57cec5SDimitry Andric      return *this;
10580b57cec5SDimitry Andric    }
10590b57cec5SDimitry Andric    if (has_filename())
10600b57cec5SDimitry Andric      __pn_ += preferred_separator;
10610b57cec5SDimitry Andric    __pn_ += __p.native();
10620b57cec5SDimitry Andric    return *this;
10630b57cec5SDimitry Andric  }
10640b57cec5SDimitry Andric
10650b57cec5SDimitry Andric  // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
10660b57cec5SDimitry Andric  // is known at compile time to be "/' since the user almost certainly intended
10670b57cec5SDimitry Andric  // to append a separator instead of overwriting the path with "/"
10680b57cec5SDimitry Andric  template <class _Source>
10690b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
10700b57cec5SDimitry Andric  operator/=(const _Source& __src) {
10710b57cec5SDimitry Andric    return this->append(__src);
10720b57cec5SDimitry Andric  }
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric  template <class _Source>
10750b57cec5SDimitry Andric  _EnableIfPathable<_Source> append(const _Source& __src) {
10760b57cec5SDimitry Andric    using _Traits = __is_pathable<_Source>;
10770b57cec5SDimitry Andric    using _CVT = _PathCVT<_SourceChar<_Source> >;
1078*fe6060f1SDimitry Andric    bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
1079*fe6060f1SDimitry Andric    if (__source_is_absolute)
10800b57cec5SDimitry Andric      __pn_.clear();
10810b57cec5SDimitry Andric    else if (has_filename())
10820b57cec5SDimitry Andric      __pn_ += preferred_separator;
10830b57cec5SDimitry Andric    _CVT::__append_source(__pn_, __src);
10840b57cec5SDimitry Andric    return *this;
10850b57cec5SDimitry Andric  }
10860b57cec5SDimitry Andric
10870b57cec5SDimitry Andric  template <class _InputIt>
10880b57cec5SDimitry Andric  path& append(_InputIt __first, _InputIt __last) {
10890b57cec5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
10900b57cec5SDimitry Andric    static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
10910b57cec5SDimitry Andric    using _CVT = _PathCVT<_ItVal>;
1092*fe6060f1SDimitry Andric    if (__first != __last && __is_separator(*__first))
10930b57cec5SDimitry Andric      __pn_.clear();
10940b57cec5SDimitry Andric    else if (has_filename())
10950b57cec5SDimitry Andric      __pn_ += preferred_separator;
10960b57cec5SDimitry Andric    _CVT::__append_range(__pn_, __first, __last);
10970b57cec5SDimitry Andric    return *this;
10980b57cec5SDimitry Andric  }
1099*fe6060f1SDimitry Andric#endif
11000b57cec5SDimitry Andric
11010b57cec5SDimitry Andric  // concatenation
11020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11030b57cec5SDimitry Andric  path& operator+=(const path& __x) {
11040b57cec5SDimitry Andric    __pn_ += __x.__pn_;
11050b57cec5SDimitry Andric    return *this;
11060b57cec5SDimitry Andric  }
11070b57cec5SDimitry Andric
11080b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11090b57cec5SDimitry Andric  path& operator+=(const string_type& __x) {
11100b57cec5SDimitry Andric    __pn_ += __x;
11110b57cec5SDimitry Andric    return *this;
11120b57cec5SDimitry Andric  }
11130b57cec5SDimitry Andric
11140b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11150b57cec5SDimitry Andric  path& operator+=(__string_view __x) {
11160b57cec5SDimitry Andric    __pn_ += __x;
11170b57cec5SDimitry Andric    return *this;
11180b57cec5SDimitry Andric  }
11190b57cec5SDimitry Andric
11200b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11210b57cec5SDimitry Andric  path& operator+=(const value_type* __x) {
11220b57cec5SDimitry Andric    __pn_ += __x;
11230b57cec5SDimitry Andric    return *this;
11240b57cec5SDimitry Andric  }
11250b57cec5SDimitry Andric
11260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11270b57cec5SDimitry Andric  path& operator+=(value_type __x) {
11280b57cec5SDimitry Andric    __pn_ += __x;
11290b57cec5SDimitry Andric    return *this;
11300b57cec5SDimitry Andric  }
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric  template <class _ECharT>
11330b57cec5SDimitry Andric  typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
11340b57cec5SDimitry Andric  operator+=(_ECharT __x) {
1135e8d8bef9SDimitry Andric    _PathCVT<_ECharT>::__append_source(__pn_,
1136e8d8bef9SDimitry Andric                                       basic_string_view<_ECharT>(&__x, 1));
11370b57cec5SDimitry Andric    return *this;
11380b57cec5SDimitry Andric  }
11390b57cec5SDimitry Andric
11400b57cec5SDimitry Andric  template <class _Source>
11410b57cec5SDimitry Andric  _EnableIfPathable<_Source> operator+=(const _Source& __x) {
11420b57cec5SDimitry Andric    return this->concat(__x);
11430b57cec5SDimitry Andric  }
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andric  template <class _Source>
11460b57cec5SDimitry Andric  _EnableIfPathable<_Source> concat(const _Source& __x) {
11470b57cec5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __x);
11480b57cec5SDimitry Andric    return *this;
11490b57cec5SDimitry Andric  }
11500b57cec5SDimitry Andric
11510b57cec5SDimitry Andric  template <class _InputIt>
11520b57cec5SDimitry Andric  path& concat(_InputIt __first, _InputIt __last) {
11530b57cec5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
11540b57cec5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
11550b57cec5SDimitry Andric    return *this;
11560b57cec5SDimitry Andric  }
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andric  // modifiers
11590b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11600b57cec5SDimitry Andric  void clear() noexcept { __pn_.clear(); }
11610b57cec5SDimitry Andric
1162e8d8bef9SDimitry Andric  path& make_preferred() {
1163e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
1164e8d8bef9SDimitry Andric    _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
1165e8d8bef9SDimitry Andric#endif
1166e8d8bef9SDimitry Andric    return *this;
1167e8d8bef9SDimitry Andric  }
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11700b57cec5SDimitry Andric  path& remove_filename() {
11710b57cec5SDimitry Andric    auto __fname = __filename();
11720b57cec5SDimitry Andric    if (!__fname.empty())
11730b57cec5SDimitry Andric      __pn_.erase(__fname.data() - __pn_.data());
11740b57cec5SDimitry Andric    return *this;
11750b57cec5SDimitry Andric  }
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andric  path& replace_filename(const path& __replacement) {
11780b57cec5SDimitry Andric    remove_filename();
11790b57cec5SDimitry Andric    return (*this /= __replacement);
11800b57cec5SDimitry Andric  }
11810b57cec5SDimitry Andric
11820b57cec5SDimitry Andric  path& replace_extension(const path& __replacement = path());
11830b57cec5SDimitry Andric
11840b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11850b57cec5SDimitry Andric  void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
11860b57cec5SDimitry Andric
11870b57cec5SDimitry Andric  // private helper to allow reserving memory in the path
11880b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11890b57cec5SDimitry Andric  void __reserve(size_t __s) { __pn_.reserve(__s); }
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric  // native format observers
11920b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11930b57cec5SDimitry Andric  const string_type& native() const noexcept { return __pn_; }
11940b57cec5SDimitry Andric
11950b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11960b57cec5SDimitry Andric  const value_type* c_str() const noexcept { return __pn_.c_str(); }
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
11990b57cec5SDimitry Andric
1200e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
1201e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; }
1202e8d8bef9SDimitry Andric
1203*fe6060f1SDimitry Andric  _VSTD::wstring generic_wstring() const {
1204*fe6060f1SDimitry Andric    _VSTD::wstring __s;
1205*fe6060f1SDimitry Andric    __s.resize(__pn_.size());
1206*fe6060f1SDimitry Andric    _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
1207*fe6060f1SDimitry Andric    return __s;
1208*fe6060f1SDimitry Andric  }
1209e8d8bef9SDimitry Andric
1210e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
1211e8d8bef9SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1212e8d8bef9SDimitry Andric            class _Allocator = allocator<_ECharT> >
1213e8d8bef9SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
1214e8d8bef9SDimitry Andric  string(const _Allocator& __a = _Allocator()) const {
1215e8d8bef9SDimitry Andric    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1216e8d8bef9SDimitry Andric    _Str __s(__a);
1217e8d8bef9SDimitry Andric    __s.reserve(__pn_.size());
1218e8d8bef9SDimitry Andric    _PathExport<_ECharT>::__append(__s, __pn_);
1219e8d8bef9SDimitry Andric    return __s;
1220e8d8bef9SDimitry Andric  }
1221e8d8bef9SDimitry Andric
1222e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const {
1223e8d8bef9SDimitry Andric    return string<char>();
1224e8d8bef9SDimitry Andric  }
1225e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const {
1226e8d8bef9SDimitry Andric    using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1227e8d8bef9SDimitry Andric    __u8_string __s;
1228e8d8bef9SDimitry Andric    __s.reserve(__pn_.size());
1229e8d8bef9SDimitry Andric    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
1230e8d8bef9SDimitry Andric    return __s;
1231e8d8bef9SDimitry Andric  }
1232e8d8bef9SDimitry Andric
1233e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
1234e8d8bef9SDimitry Andric    return string<char16_t>();
1235e8d8bef9SDimitry Andric  }
1236e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
1237e8d8bef9SDimitry Andric    return string<char32_t>();
1238e8d8bef9SDimitry Andric  }
1239e8d8bef9SDimitry Andric
1240e8d8bef9SDimitry Andric  // generic format observers
1241e8d8bef9SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
1242e8d8bef9SDimitry Andric            class _Allocator = allocator<_ECharT> >
1243e8d8bef9SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
1244e8d8bef9SDimitry Andric  generic_string(const _Allocator& __a = _Allocator()) const {
1245*fe6060f1SDimitry Andric    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
1246*fe6060f1SDimitry Andric    _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
1247*fe6060f1SDimitry Andric    // Note: This (and generic_u8string below) is slightly suboptimal as
1248*fe6060f1SDimitry Andric    // it iterates twice over the string; once to convert it to the right
1249*fe6060f1SDimitry Andric    // character type, and once to replace path delimiters.
1250*fe6060f1SDimitry Andric    _VSTD::replace(__s.begin(), __s.end(),
1251*fe6060f1SDimitry Andric                   static_cast<_ECharT>('\\'), static_cast<_ECharT>('/'));
1252*fe6060f1SDimitry Andric    return __s;
1253e8d8bef9SDimitry Andric  }
1254e8d8bef9SDimitry Andric
1255e8d8bef9SDimitry Andric  _VSTD::string generic_string() const { return generic_string<char>(); }
1256e8d8bef9SDimitry Andric  _VSTD::u16string generic_u16string() const { return generic_string<char16_t>(); }
1257e8d8bef9SDimitry Andric  _VSTD::u32string generic_u32string() const { return generic_string<char32_t>(); }
1258*fe6060f1SDimitry Andric  __u8_string generic_u8string() const {
1259*fe6060f1SDimitry Andric    __u8_string __s = u8string();
1260*fe6060f1SDimitry Andric    _VSTD::replace(__s.begin(), __s.end(), '\\', '/');
1261*fe6060f1SDimitry Andric    return __s;
1262*fe6060f1SDimitry Andric  }
1263e8d8bef9SDimitry Andric#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1264e8d8bef9SDimitry Andric#else /* _LIBCPP_WIN32API */
1265e8d8bef9SDimitry Andric
1266e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
1267*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1268e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1269e8d8bef9SDimitry Andric#else
1270e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
1271e8d8bef9SDimitry Andric#endif
1272e8d8bef9SDimitry Andric
1273e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
12740b57cec5SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
12750b57cec5SDimitry Andric            class _Allocator = allocator<_ECharT> >
12760b57cec5SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
12770b57cec5SDimitry Andric  string(const _Allocator& __a = _Allocator()) const {
12780b57cec5SDimitry Andric    using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
12790b57cec5SDimitry Andric    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
12800b57cec5SDimitry Andric    _Str __s(__a);
12810b57cec5SDimitry Andric    __s.reserve(__pn_.size());
12820b57cec5SDimitry Andric    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
12830b57cec5SDimitry Andric    return __s;
12840b57cec5SDimitry Andric  }
12850b57cec5SDimitry Andric
1286e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const {
12870b57cec5SDimitry Andric    return string<wchar_t>();
12880b57cec5SDimitry Andric  }
1289e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const {
12900b57cec5SDimitry Andric    return string<char16_t>();
12910b57cec5SDimitry Andric  }
1292e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const {
12930b57cec5SDimitry Andric    return string<char32_t>();
12940b57cec5SDimitry Andric  }
1295e8d8bef9SDimitry Andric#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric  // generic format observers
1298e8d8bef9SDimitry Andric  _VSTD::string generic_string() const { return __pn_; }
1299*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1300e8d8bef9SDimitry Andric  _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
1301e8d8bef9SDimitry Andric#else
1302e8d8bef9SDimitry Andric  _VSTD::string generic_u8string() const { return __pn_; }
1303e8d8bef9SDimitry Andric#endif
1304e8d8bef9SDimitry Andric
1305e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
13060b57cec5SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
13070b57cec5SDimitry Andric            class _Allocator = allocator<_ECharT> >
13080b57cec5SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
13090b57cec5SDimitry Andric  generic_string(const _Allocator& __a = _Allocator()) const {
13100b57cec5SDimitry Andric    return string<_ECharT, _Traits, _Allocator>(__a);
13110b57cec5SDimitry Andric  }
13120b57cec5SDimitry Andric
1313e8d8bef9SDimitry Andric  _VSTD::wstring generic_wstring() const { return string<wchar_t>(); }
1314e8d8bef9SDimitry Andric  _VSTD::u16string generic_u16string() const { return string<char16_t>(); }
1315e8d8bef9SDimitry Andric  _VSTD::u32string generic_u32string() const { return string<char32_t>(); }
1316e8d8bef9SDimitry Andric#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */
1317e8d8bef9SDimitry Andric#endif /* !_LIBCPP_WIN32API */
13180b57cec5SDimitry Andric
13190b57cec5SDimitry Andricprivate:
13200b57cec5SDimitry Andric  int __compare(__string_view) const;
13210b57cec5SDimitry Andric  __string_view __root_name() const;
13220b57cec5SDimitry Andric  __string_view __root_directory() const;
13230b57cec5SDimitry Andric  __string_view __root_path_raw() const;
13240b57cec5SDimitry Andric  __string_view __relative_path() const;
13250b57cec5SDimitry Andric  __string_view __parent_path() const;
13260b57cec5SDimitry Andric  __string_view __filename() const;
13270b57cec5SDimitry Andric  __string_view __stem() const;
13280b57cec5SDimitry Andric  __string_view __extension() const;
13290b57cec5SDimitry Andric
13300b57cec5SDimitry Andricpublic:
13310b57cec5SDimitry Andric  // compare
13320b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
13330b57cec5SDimitry Andric    return __compare(__p.__pn_);
13340b57cec5SDimitry Andric  }
13350b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
13360b57cec5SDimitry Andric    return __compare(__s);
13370b57cec5SDimitry Andric  }
13380b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
13390b57cec5SDimitry Andric    return __compare(__s);
13400b57cec5SDimitry Andric  }
13410b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
13420b57cec5SDimitry Andric    return __compare(__s);
13430b57cec5SDimitry Andric  }
13440b57cec5SDimitry Andric
13450b57cec5SDimitry Andric  // decomposition
13460b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_name() const {
13470b57cec5SDimitry Andric    return string_type(__root_name());
13480b57cec5SDimitry Andric  }
13490b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_directory() const {
13500b57cec5SDimitry Andric    return string_type(__root_directory());
13510b57cec5SDimitry Andric  }
13520b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_path() const {
1353*fe6060f1SDimitry Andric#if defined(_LIBCPP_WIN32API)
1354*fe6060f1SDimitry Andric    return string_type(__root_path_raw());
1355*fe6060f1SDimitry Andric#else
13560b57cec5SDimitry Andric    return root_name().append(string_type(__root_directory()));
1357*fe6060f1SDimitry Andric#endif
13580b57cec5SDimitry Andric  }
13590b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path relative_path() const {
13600b57cec5SDimitry Andric    return string_type(__relative_path());
13610b57cec5SDimitry Andric  }
13620b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path parent_path() const {
13630b57cec5SDimitry Andric    return string_type(__parent_path());
13640b57cec5SDimitry Andric  }
13650b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path filename() const {
13660b57cec5SDimitry Andric    return string_type(__filename());
13670b57cec5SDimitry Andric  }
13680b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
13690b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path extension() const {
13700b57cec5SDimitry Andric    return string_type(__extension());
13710b57cec5SDimitry Andric  }
13720b57cec5SDimitry Andric
13730b57cec5SDimitry Andric  // query
13740b57cec5SDimitry Andric  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
13750b57cec5SDimitry Andric  empty() const noexcept {
13760b57cec5SDimitry Andric    return __pn_.empty();
13770b57cec5SDimitry Andric  }
13780b57cec5SDimitry Andric
13790b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
13800b57cec5SDimitry Andric    return !__root_name().empty();
13810b57cec5SDimitry Andric  }
13820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
13830b57cec5SDimitry Andric    return !__root_directory().empty();
13840b57cec5SDimitry Andric  }
13850b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
13860b57cec5SDimitry Andric    return !__root_path_raw().empty();
13870b57cec5SDimitry Andric  }
13880b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
13890b57cec5SDimitry Andric    return !__relative_path().empty();
13900b57cec5SDimitry Andric  }
13910b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
13920b57cec5SDimitry Andric    return !__parent_path().empty();
13930b57cec5SDimitry Andric  }
13940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
13950b57cec5SDimitry Andric    return !__filename().empty();
13960b57cec5SDimitry Andric  }
13970b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
13980b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
13990b57cec5SDimitry Andric    return !__extension().empty();
14000b57cec5SDimitry Andric  }
14010b57cec5SDimitry Andric
14020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
1403*fe6060f1SDimitry Andric#if defined(_LIBCPP_WIN32API)
1404*fe6060f1SDimitry Andric    __string_view __root_name_str = __root_name();
1405*fe6060f1SDimitry Andric    __string_view __root_dir = __root_directory();
1406*fe6060f1SDimitry Andric    if (__root_name_str.size() == 2 && __root_name_str[1] == ':') {
1407*fe6060f1SDimitry Andric      // A drive letter with no root directory is relative, e.g. x:example.
1408*fe6060f1SDimitry Andric      return !__root_dir.empty();
1409*fe6060f1SDimitry Andric    }
1410*fe6060f1SDimitry Andric    // If no root name, it's relative, e.g. \example is relative to the current drive
1411*fe6060f1SDimitry Andric    if (__root_name_str.empty())
1412*fe6060f1SDimitry Andric      return false;
1413*fe6060f1SDimitry Andric    if (__root_name_str.size() < 3)
1414*fe6060f1SDimitry Andric      return false;
1415*fe6060f1SDimitry Andric    // A server root name, like \\server, is always absolute
1416*fe6060f1SDimitry Andric    if (__root_name_str[0] != '/' && __root_name_str[0] != '\\')
1417*fe6060f1SDimitry Andric      return false;
1418*fe6060f1SDimitry Andric    if (__root_name_str[1] != '/' && __root_name_str[1] != '\\')
1419*fe6060f1SDimitry Andric      return false;
1420*fe6060f1SDimitry Andric    // Seems to be a server root name
1421*fe6060f1SDimitry Andric    return true;
1422*fe6060f1SDimitry Andric#else
14230b57cec5SDimitry Andric    return has_root_directory();
1424*fe6060f1SDimitry Andric#endif
14250b57cec5SDimitry Andric  }
14260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
14270b57cec5SDimitry Andric
14280b57cec5SDimitry Andric  // relative paths
14290b57cec5SDimitry Andric  path lexically_normal() const;
14300b57cec5SDimitry Andric  path lexically_relative(const path& __base) const;
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
14330b57cec5SDimitry Andric    path __result = this->lexically_relative(__base);
14340b57cec5SDimitry Andric    if (__result.native().empty())
14350b57cec5SDimitry Andric      return *this;
14360b57cec5SDimitry Andric    return __result;
14370b57cec5SDimitry Andric  }
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andric  // iterators
14400b57cec5SDimitry Andric  class _LIBCPP_TYPE_VIS iterator;
14410b57cec5SDimitry Andric  typedef iterator const_iterator;
14420b57cec5SDimitry Andric
14430b57cec5SDimitry Andric  iterator begin() const;
14440b57cec5SDimitry Andric  iterator end() const;
14450b57cec5SDimitry Andric
1446e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
14470b57cec5SDimitry Andric  template <class _CharT, class _Traits>
14480b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend
1449e8d8bef9SDimitry Andric      typename enable_if<is_same<_CharT, value_type>::value &&
1450e8d8bef9SDimitry Andric                             is_same<_Traits, char_traits<value_type> >::value,
14510b57cec5SDimitry Andric                         basic_ostream<_CharT, _Traits>&>::type
14520b57cec5SDimitry Andric      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1453e8d8bef9SDimitry Andric    __os << _VSTD::__quoted(__p.native());
14540b57cec5SDimitry Andric    return __os;
14550b57cec5SDimitry Andric  }
14560b57cec5SDimitry Andric
14570b57cec5SDimitry Andric  template <class _CharT, class _Traits>
14580b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend
1459e8d8bef9SDimitry Andric      typename enable_if<!is_same<_CharT, value_type>::value ||
1460e8d8bef9SDimitry Andric                             !is_same<_Traits, char_traits<value_type> >::value,
14610b57cec5SDimitry Andric                         basic_ostream<_CharT, _Traits>&>::type
14620b57cec5SDimitry Andric      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
1463e8d8bef9SDimitry Andric    __os << _VSTD::__quoted(__p.string<_CharT, _Traits>());
14640b57cec5SDimitry Andric    return __os;
14650b57cec5SDimitry Andric  }
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric  template <class _CharT, class _Traits>
14680b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
14690b57cec5SDimitry Andric  operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
14700b57cec5SDimitry Andric    basic_string<_CharT, _Traits> __tmp;
14710b57cec5SDimitry Andric    __is >> __quoted(__tmp);
14720b57cec5SDimitry Andric    __p = __tmp;
14730b57cec5SDimitry Andric    return __is;
14740b57cec5SDimitry Andric  }
1475e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
14780b57cec5SDimitry Andric    return __lhs.compare(__rhs) == 0;
14790b57cec5SDimitry Andric  }
14800b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
14810b57cec5SDimitry Andric    return __lhs.compare(__rhs) != 0;
14820b57cec5SDimitry Andric  }
14830b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
14840b57cec5SDimitry Andric    return __lhs.compare(__rhs) < 0;
14850b57cec5SDimitry Andric  }
14860b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
14870b57cec5SDimitry Andric    return __lhs.compare(__rhs) <= 0;
14880b57cec5SDimitry Andric  }
14890b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
14900b57cec5SDimitry Andric    return __lhs.compare(__rhs) > 0;
14910b57cec5SDimitry Andric  }
14920b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
14930b57cec5SDimitry Andric    return __lhs.compare(__rhs) >= 0;
14940b57cec5SDimitry Andric  }
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
14970b57cec5SDimitry Andric                                                  const path& __rhs) {
14980b57cec5SDimitry Andric    path __result(__lhs);
14990b57cec5SDimitry Andric    __result /= __rhs;
15000b57cec5SDimitry Andric    return __result;
15010b57cec5SDimitry Andric  }
15020b57cec5SDimitry Andricprivate:
15030b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY path&
15040b57cec5SDimitry Andric  __assign_view(__string_view const& __s) noexcept {
15050b57cec5SDimitry Andric    __pn_ = string_type(__s);
15060b57cec5SDimitry Andric    return *this;
15070b57cec5SDimitry Andric  }
15080b57cec5SDimitry Andric  string_type __pn_;
15090b57cec5SDimitry Andric};
15100b57cec5SDimitry Andric
15110b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
15120b57cec5SDimitry Andric  __lhs.swap(__rhs);
15130b57cec5SDimitry Andric}
15140b57cec5SDimitry Andric
15150b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
15160b57cec5SDimitry Andricsize_t hash_value(const path& __p) noexcept;
15170b57cec5SDimitry Andric
15180b57cec5SDimitry Andrictemplate <class _InputIt>
1519e8d8bef9SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
15200b57cec5SDimitry Andric    typename enable_if<__is_pathable<_InputIt>::value, path>::type
15210b57cec5SDimitry Andric    u8path(_InputIt __f, _InputIt __l) {
15220b57cec5SDimitry Andric  static_assert(
1523*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1524e8d8bef9SDimitry Andric      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1525e8d8bef9SDimitry Andric#endif
15260b57cec5SDimitry Andric      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1527e8d8bef9SDimitry Andric      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1528e8d8bef9SDimitry Andric      " or 'char8_t'");
1529e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
1530e8d8bef9SDimitry Andric  string __tmp(__f, __l);
1531e8d8bef9SDimitry Andric  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1532e8d8bef9SDimitry Andric  _VSTD::wstring __w;
1533e8d8bef9SDimitry Andric  __w.reserve(__tmp.size());
1534e8d8bef9SDimitry Andric  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1535e8d8bef9SDimitry Andric  return path(__w);
1536e8d8bef9SDimitry Andric#else
15370b57cec5SDimitry Andric  return path(__f, __l);
1538e8d8bef9SDimitry Andric#endif /* !_LIBCPP_WIN32API */
1539e8d8bef9SDimitry Andric}
1540e8d8bef9SDimitry Andric
1541e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
1542e8d8bef9SDimitry Andrictemplate <class _InputIt>
1543e8d8bef9SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1544e8d8bef9SDimitry Andric    typename enable_if<__is_pathable<_InputIt>::value, path>::type
1545e8d8bef9SDimitry Andric    u8path(_InputIt __f, _NullSentinel) {
1546e8d8bef9SDimitry Andric  static_assert(
1547*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1548e8d8bef9SDimitry Andric      is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
1549e8d8bef9SDimitry Andric#endif
1550e8d8bef9SDimitry Andric      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
1551e8d8bef9SDimitry Andric      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
1552e8d8bef9SDimitry Andric      " or 'char8_t'");
1553e8d8bef9SDimitry Andric  string __tmp;
1554e8d8bef9SDimitry Andric  const char __sentinel = char{};
1555e8d8bef9SDimitry Andric  for (; *__f != __sentinel; ++__f)
1556e8d8bef9SDimitry Andric    __tmp.push_back(*__f);
1557e8d8bef9SDimitry Andric  using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
1558e8d8bef9SDimitry Andric  _VSTD::wstring __w;
1559e8d8bef9SDimitry Andric  __w.reserve(__tmp.size());
1560e8d8bef9SDimitry Andric  _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
1561e8d8bef9SDimitry Andric  return path(__w);
1562e8d8bef9SDimitry Andric}
1563e8d8bef9SDimitry Andric#endif /* _LIBCPP_WIN32API */
1564e8d8bef9SDimitry Andric
1565e8d8bef9SDimitry Andrictemplate <class _Source>
1566e8d8bef9SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
1567e8d8bef9SDimitry Andric    typename enable_if<__is_pathable<_Source>::value, path>::type
1568e8d8bef9SDimitry Andric    u8path(const _Source& __s) {
1569e8d8bef9SDimitry Andric  static_assert(
1570*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1571e8d8bef9SDimitry Andric      is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
1572e8d8bef9SDimitry Andric#endif
1573e8d8bef9SDimitry Andric      is_same<typename __is_pathable<_Source>::__char_type, char>::value,
1574e8d8bef9SDimitry Andric      "u8path(Source const&) requires Source have a character type of type "
1575e8d8bef9SDimitry Andric      "'char' or 'char8_t'");
1576e8d8bef9SDimitry Andric#if defined(_LIBCPP_WIN32API)
1577e8d8bef9SDimitry Andric  using _Traits = __is_pathable<_Source>;
1578*fe6060f1SDimitry Andric  return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s)));
1579e8d8bef9SDimitry Andric#else
1580e8d8bef9SDimitry Andric  return path(__s);
1581e8d8bef9SDimitry Andric#endif
15820b57cec5SDimitry Andric}
15830b57cec5SDimitry Andric
15840b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS path::iterator {
15850b57cec5SDimitry Andricpublic:
15860b57cec5SDimitry Andric  enum _ParserState : unsigned char {
15870b57cec5SDimitry Andric    _Singular,
15880b57cec5SDimitry Andric    _BeforeBegin,
15890b57cec5SDimitry Andric    _InRootName,
15900b57cec5SDimitry Andric    _InRootDir,
15910b57cec5SDimitry Andric    _InFilenames,
15920b57cec5SDimitry Andric    _InTrailingSep,
15930b57cec5SDimitry Andric    _AtEnd
15940b57cec5SDimitry Andric  };
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andricpublic:
15970b57cec5SDimitry Andric  typedef bidirectional_iterator_tag iterator_category;
15980b57cec5SDimitry Andric
15990b57cec5SDimitry Andric  typedef path value_type;
1600e8d8bef9SDimitry Andric  typedef ptrdiff_t difference_type;
16010b57cec5SDimitry Andric  typedef const path* pointer;
16020b57cec5SDimitry Andric  typedef const path& reference;
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric  typedef void
16050b57cec5SDimitry Andric      __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andricpublic:
16080b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16090b57cec5SDimitry Andric  iterator()
16100b57cec5SDimitry Andric      : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
16110b57cec5SDimitry Andric        __state_(_Singular) {}
16120b57cec5SDimitry Andric
16130b57cec5SDimitry Andric  iterator(const iterator&) = default;
16140b57cec5SDimitry Andric  ~iterator() = default;
16150b57cec5SDimitry Andric
16160b57cec5SDimitry Andric  iterator& operator=(const iterator&) = default;
16170b57cec5SDimitry Andric
16180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16190b57cec5SDimitry Andric  reference operator*() const { return __stashed_elem_; }
16200b57cec5SDimitry Andric
16210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16220b57cec5SDimitry Andric  pointer operator->() const { return &__stashed_elem_; }
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16250b57cec5SDimitry Andric  iterator& operator++() {
16260b57cec5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _Singular,
16270b57cec5SDimitry Andric                   "attempting to increment a singular iterator");
16280b57cec5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _AtEnd,
16290b57cec5SDimitry Andric                   "attempting to increment the end iterator");
16300b57cec5SDimitry Andric    return __increment();
16310b57cec5SDimitry Andric  }
16320b57cec5SDimitry Andric
16330b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16340b57cec5SDimitry Andric  iterator operator++(int) {
16350b57cec5SDimitry Andric    iterator __it(*this);
16360b57cec5SDimitry Andric    this->operator++();
16370b57cec5SDimitry Andric    return __it;
16380b57cec5SDimitry Andric  }
16390b57cec5SDimitry Andric
16400b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16410b57cec5SDimitry Andric  iterator& operator--() {
16420b57cec5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _Singular,
16430b57cec5SDimitry Andric                   "attempting to decrement a singular iterator");
16440b57cec5SDimitry Andric    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
16450b57cec5SDimitry Andric                   "attempting to decrement the begin iterator");
16460b57cec5SDimitry Andric    return __decrement();
16470b57cec5SDimitry Andric  }
16480b57cec5SDimitry Andric
16490b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16500b57cec5SDimitry Andric  iterator operator--(int) {
16510b57cec5SDimitry Andric    iterator __it(*this);
16520b57cec5SDimitry Andric    this->operator--();
16530b57cec5SDimitry Andric    return __it;
16540b57cec5SDimitry Andric  }
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andricprivate:
16570b57cec5SDimitry Andric  friend class path;
16580b57cec5SDimitry Andric
16590b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
16600b57cec5SDimitry Andric                                                          const iterator&);
16610b57cec5SDimitry Andric
16620b57cec5SDimitry Andric  iterator& __increment();
16630b57cec5SDimitry Andric  iterator& __decrement();
16640b57cec5SDimitry Andric
16650b57cec5SDimitry Andric  path __stashed_elem_;
16660b57cec5SDimitry Andric  const path* __path_ptr_;
16670b57cec5SDimitry Andric  path::__string_view __entry_;
16680b57cec5SDimitry Andric  _ParserState __state_;
16690b57cec5SDimitry Andric};
16700b57cec5SDimitry Andric
16710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
16720b57cec5SDimitry Andric                                                 const path::iterator& __rhs) {
16730b57cec5SDimitry Andric  return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
16740b57cec5SDimitry Andric         __lhs.__entry_.data() == __rhs.__entry_.data();
16750b57cec5SDimitry Andric}
16760b57cec5SDimitry Andric
16770b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
16780b57cec5SDimitry Andric                                                 const path::iterator& __rhs) {
16790b57cec5SDimitry Andric  return !(__lhs == __rhs);
16800b57cec5SDimitry Andric}
16810b57cec5SDimitry Andric
16820b57cec5SDimitry Andric// TODO(ldionne): We need to pop the pragma and push it again after
16830b57cec5SDimitry Andric//                filesystem_error to work around PR41078.
16840b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FILESYSTEM_POP
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
16870b57cec5SDimitry Andricpublic:
16880b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16890b57cec5SDimitry Andric  filesystem_error(const string& __what, error_code __ec)
16900b57cec5SDimitry Andric      : system_error(__ec, __what),
16910b57cec5SDimitry Andric        __storage_(make_shared<_Storage>(path(), path())) {
16920b57cec5SDimitry Andric    __create_what(0);
16930b57cec5SDimitry Andric  }
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16960b57cec5SDimitry Andric  filesystem_error(const string& __what, const path& __p1, error_code __ec)
16970b57cec5SDimitry Andric      : system_error(__ec, __what),
16980b57cec5SDimitry Andric        __storage_(make_shared<_Storage>(__p1, path())) {
16990b57cec5SDimitry Andric    __create_what(1);
17000b57cec5SDimitry Andric  }
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17030b57cec5SDimitry Andric  filesystem_error(const string& __what, const path& __p1, const path& __p2,
17040b57cec5SDimitry Andric                   error_code __ec)
17050b57cec5SDimitry Andric      : system_error(__ec, __what),
17060b57cec5SDimitry Andric        __storage_(make_shared<_Storage>(__p1, __p2)) {
17070b57cec5SDimitry Andric    __create_what(2);
17080b57cec5SDimitry Andric  }
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17110b57cec5SDimitry Andric  const path& path1() const noexcept { return __storage_->__p1_; }
17120b57cec5SDimitry Andric
17130b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17140b57cec5SDimitry Andric  const path& path2() const noexcept { return __storage_->__p2_; }
17150b57cec5SDimitry Andric
17169ec406dcSDimitry Andric  filesystem_error(const filesystem_error&) = default;
17170b57cec5SDimitry Andric  ~filesystem_error() override; // key function
17180b57cec5SDimitry Andric
17190b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17200b57cec5SDimitry Andric  const char* what() const noexcept override {
17210b57cec5SDimitry Andric    return __storage_->__what_.c_str();
17220b57cec5SDimitry Andric  }
17230b57cec5SDimitry Andric
17240b57cec5SDimitry Andric  void __create_what(int __num_paths);
17250b57cec5SDimitry Andric
17260b57cec5SDimitry Andricprivate:
17270b57cec5SDimitry Andric  struct _LIBCPP_HIDDEN _Storage {
17280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17290b57cec5SDimitry Andric    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
17300b57cec5SDimitry Andric
17310b57cec5SDimitry Andric    path __p1_;
17320b57cec5SDimitry Andric    path __p2_;
17330b57cec5SDimitry Andric    string __what_;
17340b57cec5SDimitry Andric  };
17350b57cec5SDimitry Andric  shared_ptr<_Storage> __storage_;
17360b57cec5SDimitry Andric};
17370b57cec5SDimitry Andric
17380b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andrictemplate <class... _Args>
17410b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
17420b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
17430b57cec5SDimitry Andricvoid __throw_filesystem_error(_Args&&... __args) {
1744e8d8bef9SDimitry Andric  throw filesystem_error(_VSTD::forward<_Args>(__args)...);
17450b57cec5SDimitry Andric}
17460b57cec5SDimitry Andric#else
17470b57cec5SDimitry Andricvoid __throw_filesystem_error(_Args&&...) {
17480b57cec5SDimitry Andric  _VSTD::abort();
17490b57cec5SDimitry Andric}
17500b57cec5SDimitry Andric#endif
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andric// operational functions
17530b57cec5SDimitry Andric
17540b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17550b57cec5SDimitry Andricpath __absolute(const path&, error_code* __ec = nullptr);
17560b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17570b57cec5SDimitry Andricpath __canonical(const path&, error_code* __ec = nullptr);
17580b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17590b57cec5SDimitry Andricvoid __copy(const path& __from, const path& __to, copy_options __opt,
17600b57cec5SDimitry Andric            error_code* __ec = nullptr);
17610b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17620b57cec5SDimitry Andricbool __copy_file(const path& __from, const path& __to, copy_options __opt,
17630b57cec5SDimitry Andric                 error_code* __ec = nullptr);
17640b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17650b57cec5SDimitry Andricvoid __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
17660b57cec5SDimitry Andric                    error_code* __ec = nullptr);
17670b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17680b57cec5SDimitry Andricbool __create_directories(const path& p, error_code* ec = nullptr);
17690b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17700b57cec5SDimitry Andricbool __create_directory(const path& p, error_code* ec = nullptr);
17710b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17720b57cec5SDimitry Andricbool __create_directory(const path& p, const path& attributes,
17730b57cec5SDimitry Andric                        error_code* ec = nullptr);
17740b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17750b57cec5SDimitry Andricvoid __create_directory_symlink(const path& __to, const path& __new_symlink,
17760b57cec5SDimitry Andric                                error_code* __ec = nullptr);
17770b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17780b57cec5SDimitry Andricvoid __create_hard_link(const path& __to, const path& __new_hard_link,
17790b57cec5SDimitry Andric                        error_code* __ec = nullptr);
17800b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17810b57cec5SDimitry Andricvoid __create_symlink(const path& __to, const path& __new_symlink,
17820b57cec5SDimitry Andric                      error_code* __ec = nullptr);
17830b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17840b57cec5SDimitry Andricpath __current_path(error_code* __ec = nullptr);
17850b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17860b57cec5SDimitry Andricvoid __current_path(const path&, error_code* __ec = nullptr);
17870b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17880b57cec5SDimitry Andricbool __equivalent(const path&, const path&, error_code* __ec = nullptr);
17890b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17900b57cec5SDimitry Andricuintmax_t __file_size(const path&, error_code* __ec = nullptr);
17910b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17920b57cec5SDimitry Andricuintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
17930b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17940b57cec5SDimitry Andricbool __fs_is_empty(const path& p, error_code* ec = nullptr);
17950b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17960b57cec5SDimitry Andricfile_time_type __last_write_time(const path& p, error_code* ec = nullptr);
17970b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
17980b57cec5SDimitry Andricvoid __last_write_time(const path& p, file_time_type new_time,
17990b57cec5SDimitry Andric                       error_code* ec = nullptr);
18000b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18010b57cec5SDimitry Andricvoid __permissions(const path&, perms, perm_options, error_code* = nullptr);
18020b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18030b57cec5SDimitry Andricpath __read_symlink(const path& p, error_code* ec = nullptr);
18040b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18050b57cec5SDimitry Andricbool __remove(const path& p, error_code* ec = nullptr);
18060b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18070b57cec5SDimitry Andricuintmax_t __remove_all(const path& p, error_code* ec = nullptr);
18080b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18090b57cec5SDimitry Andricvoid __rename(const path& from, const path& to, error_code* ec = nullptr);
18100b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18110b57cec5SDimitry Andricvoid __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
18120b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18130b57cec5SDimitry Andricspace_info __space(const path&, error_code* __ec = nullptr);
18140b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18150b57cec5SDimitry Andricfile_status __status(const path&, error_code* __ec = nullptr);
18160b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18170b57cec5SDimitry Andricfile_status __symlink_status(const path&, error_code* __ec = nullptr);
18180b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18190b57cec5SDimitry Andricpath __system_complete(const path&, error_code* __ec = nullptr);
18200b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18210b57cec5SDimitry Andricpath __temp_directory_path(error_code* __ec = nullptr);
18220b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
18230b57cec5SDimitry Andricpath __weakly_canonical(path const& __p, error_code* __ec = nullptr);
18240b57cec5SDimitry Andric
18250b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path current_path() {
18260b57cec5SDimitry Andric  return __current_path();
18270b57cec5SDimitry Andric}
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
18300b57cec5SDimitry Andric  return __current_path(&__ec);
18310b57cec5SDimitry Andric}
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
18340b57cec5SDimitry Andric  __current_path(__p);
18350b57cec5SDimitry Andric}
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
18380b57cec5SDimitry Andric                                                   error_code& __ec) noexcept {
18390b57cec5SDimitry Andric  __current_path(__p, &__ec);
18400b57cec5SDimitry Andric}
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
18430b57cec5SDimitry Andric  return __absolute(__p);
18440b57cec5SDimitry Andric}
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
18470b57cec5SDimitry Andric                                               error_code& __ec) {
18480b57cec5SDimitry Andric  return __absolute(__p, &__ec);
18490b57cec5SDimitry Andric}
18500b57cec5SDimitry Andric
18510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
18520b57cec5SDimitry Andric  return __canonical(__p);
18530b57cec5SDimitry Andric}
18540b57cec5SDimitry Andric
18550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
18560b57cec5SDimitry Andric                                                error_code& __ec) {
18570b57cec5SDimitry Andric  return __canonical(__p, &__ec);
18580b57cec5SDimitry Andric}
18590b57cec5SDimitry Andric
18600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
18610b57cec5SDimitry Andric                                           const path& __to) {
18620b57cec5SDimitry Andric  __copy(__from, __to, copy_options::none);
18630b57cec5SDimitry Andric}
18640b57cec5SDimitry Andric
18650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
18660b57cec5SDimitry Andric                                           error_code& __ec) {
18670b57cec5SDimitry Andric  __copy(__from, __to, copy_options::none, &__ec);
18680b57cec5SDimitry Andric}
18690b57cec5SDimitry Andric
18700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
18710b57cec5SDimitry Andric                                           copy_options __opt) {
18720b57cec5SDimitry Andric  __copy(__from, __to, __opt);
18730b57cec5SDimitry Andric}
18740b57cec5SDimitry Andric
18750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
18760b57cec5SDimitry Andric                                           copy_options __opt,
18770b57cec5SDimitry Andric                                           error_code& __ec) {
18780b57cec5SDimitry Andric  __copy(__from, __to, __opt, &__ec);
18790b57cec5SDimitry Andric}
18800b57cec5SDimitry Andric
18810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
18820b57cec5SDimitry Andric                                                const path& __to) {
18830b57cec5SDimitry Andric  return __copy_file(__from, __to, copy_options::none);
18840b57cec5SDimitry Andric}
18850b57cec5SDimitry Andric
18860b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
18870b57cec5SDimitry Andriccopy_file(const path& __from, const path& __to, error_code& __ec) {
18880b57cec5SDimitry Andric  return __copy_file(__from, __to, copy_options::none, &__ec);
18890b57cec5SDimitry Andric}
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
18920b57cec5SDimitry Andriccopy_file(const path& __from, const path& __to, copy_options __opt) {
18930b57cec5SDimitry Andric  return __copy_file(__from, __to, __opt);
18940b57cec5SDimitry Andric}
18950b57cec5SDimitry Andric
18960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
18970b57cec5SDimitry Andric                                                const path& __to,
18980b57cec5SDimitry Andric                                                copy_options __opt,
18990b57cec5SDimitry Andric                                                error_code& __ec) {
19000b57cec5SDimitry Andric  return __copy_file(__from, __to, __opt, &__ec);
19010b57cec5SDimitry Andric}
19020b57cec5SDimitry Andric
19030b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
19040b57cec5SDimitry Andric                                                   const path& __new) {
19050b57cec5SDimitry Andric  __copy_symlink(__existing, __new);
19060b57cec5SDimitry Andric}
19070b57cec5SDimitry Andric
19080b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
19090b57cec5SDimitry Andriccopy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
19100b57cec5SDimitry Andric  __copy_symlink(__ext, __new, &__ec);
19110b57cec5SDimitry Andric}
19120b57cec5SDimitry Andric
19130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
19140b57cec5SDimitry Andric  return __create_directories(__p);
19150b57cec5SDimitry Andric}
19160b57cec5SDimitry Andric
19170b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
19180b57cec5SDimitry Andric                                                         error_code& __ec) {
19190b57cec5SDimitry Andric  return __create_directories(__p, &__ec);
19200b57cec5SDimitry Andric}
19210b57cec5SDimitry Andric
19220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
19230b57cec5SDimitry Andric  return __create_directory(__p);
19240b57cec5SDimitry Andric}
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
19270b57cec5SDimitry Andriccreate_directory(const path& __p, error_code& __ec) noexcept {
19280b57cec5SDimitry Andric  return __create_directory(__p, &__ec);
19290b57cec5SDimitry Andric}
19300b57cec5SDimitry Andric
19310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
19320b57cec5SDimitry Andric                                                       const path& __attrs) {
19330b57cec5SDimitry Andric  return __create_directory(__p, __attrs);
19340b57cec5SDimitry Andric}
19350b57cec5SDimitry Andric
19360b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
19370b57cec5SDimitry Andriccreate_directory(const path& __p, const path& __attrs,
19380b57cec5SDimitry Andric                 error_code& __ec) noexcept {
19390b57cec5SDimitry Andric  return __create_directory(__p, __attrs, &__ec);
19400b57cec5SDimitry Andric}
19410b57cec5SDimitry Andric
19420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
19430b57cec5SDimitry Andriccreate_directory_symlink(const path& __to, const path& __new) {
19440b57cec5SDimitry Andric  __create_directory_symlink(__to, __new);
19450b57cec5SDimitry Andric}
19460b57cec5SDimitry Andric
19470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
19480b57cec5SDimitry Andriccreate_directory_symlink(const path& __to, const path& __new,
19490b57cec5SDimitry Andric                         error_code& __ec) noexcept {
19500b57cec5SDimitry Andric  __create_directory_symlink(__to, __new, &__ec);
19510b57cec5SDimitry Andric}
19520b57cec5SDimitry Andric
19530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
19540b57cec5SDimitry Andric                                                       const path& __new) {
19550b57cec5SDimitry Andric  __create_hard_link(__to, __new);
19560b57cec5SDimitry Andric}
19570b57cec5SDimitry Andric
19580b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
19590b57cec5SDimitry Andriccreate_hard_link(const path& __to, const path& __new,
19600b57cec5SDimitry Andric                 error_code& __ec) noexcept {
19610b57cec5SDimitry Andric  __create_hard_link(__to, __new, &__ec);
19620b57cec5SDimitry Andric}
19630b57cec5SDimitry Andric
19640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
19650b57cec5SDimitry Andric                                                     const path& __new) {
19660b57cec5SDimitry Andric  __create_symlink(__to, __new);
19670b57cec5SDimitry Andric}
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
19700b57cec5SDimitry Andriccreate_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
19710b57cec5SDimitry Andric  return __create_symlink(__to, __new, &__ec);
19720b57cec5SDimitry Andric}
19730b57cec5SDimitry Andric
19740b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
19750b57cec5SDimitry Andric  return __s.type() != file_type::none;
19760b57cec5SDimitry Andric}
19770b57cec5SDimitry Andric
19780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
19790b57cec5SDimitry Andric  return status_known(__s) && __s.type() != file_type::not_found;
19800b57cec5SDimitry Andric}
19810b57cec5SDimitry Andric
19820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
19830b57cec5SDimitry Andric  return exists(__status(__p));
19840b57cec5SDimitry Andric}
19850b57cec5SDimitry Andric
19860b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
19870b57cec5SDimitry Andric                                             error_code& __ec) noexcept {
19880b57cec5SDimitry Andric  auto __s = __status(__p, &__ec);
19890b57cec5SDimitry Andric  if (status_known(__s))
19900b57cec5SDimitry Andric    __ec.clear();
19910b57cec5SDimitry Andric  return exists(__s);
19920b57cec5SDimitry Andric}
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
19950b57cec5SDimitry Andric                                                 const path& __p2) {
19960b57cec5SDimitry Andric  return __equivalent(__p1, __p2);
19970b57cec5SDimitry Andric}
19980b57cec5SDimitry Andric
19990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
20000b57cec5SDimitry Andricequivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
20010b57cec5SDimitry Andric  return __equivalent(__p1, __p2, &__ec);
20020b57cec5SDimitry Andric}
20030b57cec5SDimitry Andric
20040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
20050b57cec5SDimitry Andric  return __file_size(__p);
20060b57cec5SDimitry Andric}
20070b57cec5SDimitry Andric
20080b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t
20090b57cec5SDimitry Andricfile_size(const path& __p, error_code& __ec) noexcept {
20100b57cec5SDimitry Andric  return __file_size(__p, &__ec);
20110b57cec5SDimitry Andric}
20120b57cec5SDimitry Andric
20130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
20140b57cec5SDimitry Andric  return __hard_link_count(__p);
20150b57cec5SDimitry Andric}
20160b57cec5SDimitry Andric
20170b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t
20180b57cec5SDimitry Andrichard_link_count(const path& __p, error_code& __ec) noexcept {
20190b57cec5SDimitry Andric  return __hard_link_count(__p, &__ec);
20200b57cec5SDimitry Andric}
20210b57cec5SDimitry Andric
20220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
20230b57cec5SDimitry Andric  return __s.type() == file_type::block;
20240b57cec5SDimitry Andric}
20250b57cec5SDimitry Andric
20260b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
20270b57cec5SDimitry Andric  return is_block_file(__status(__p));
20280b57cec5SDimitry Andric}
20290b57cec5SDimitry Andric
20300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
20310b57cec5SDimitry Andric                                                    error_code& __ec) noexcept {
20320b57cec5SDimitry Andric  return is_block_file(__status(__p, &__ec));
20330b57cec5SDimitry Andric}
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
20360b57cec5SDimitry Andricis_character_file(file_status __s) noexcept {
20370b57cec5SDimitry Andric  return __s.type() == file_type::character;
20380b57cec5SDimitry Andric}
20390b57cec5SDimitry Andric
20400b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
20410b57cec5SDimitry Andric  return is_character_file(__status(__p));
20420b57cec5SDimitry Andric}
20430b57cec5SDimitry Andric
20440b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
20450b57cec5SDimitry Andricis_character_file(const path& __p, error_code& __ec) noexcept {
20460b57cec5SDimitry Andric  return is_character_file(__status(__p, &__ec));
20470b57cec5SDimitry Andric}
20480b57cec5SDimitry Andric
20490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
20500b57cec5SDimitry Andric  return __s.type() == file_type::directory;
20510b57cec5SDimitry Andric}
20520b57cec5SDimitry Andric
20530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
20540b57cec5SDimitry Andric  return is_directory(__status(__p));
20550b57cec5SDimitry Andric}
20560b57cec5SDimitry Andric
20570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
20580b57cec5SDimitry Andric                                                   error_code& __ec) noexcept {
20590b57cec5SDimitry Andric  return is_directory(__status(__p, &__ec));
20600b57cec5SDimitry Andric}
20610b57cec5SDimitry Andric
20620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
20630b57cec5SDimitry Andric  return __fs_is_empty(__p);
20640b57cec5SDimitry Andric}
20650b57cec5SDimitry Andric
20660b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
20670b57cec5SDimitry Andric                                               error_code& __ec) {
20680b57cec5SDimitry Andric  return __fs_is_empty(__p, &__ec);
20690b57cec5SDimitry Andric}
20700b57cec5SDimitry Andric
20710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
20720b57cec5SDimitry Andric  return __s.type() == file_type::fifo;
20730b57cec5SDimitry Andric}
20740b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
20750b57cec5SDimitry Andric  return is_fifo(__status(__p));
20760b57cec5SDimitry Andric}
20770b57cec5SDimitry Andric
20780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
20790b57cec5SDimitry Andric                                              error_code& __ec) noexcept {
20800b57cec5SDimitry Andric  return is_fifo(__status(__p, &__ec));
20810b57cec5SDimitry Andric}
20820b57cec5SDimitry Andric
20830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
20840b57cec5SDimitry Andricis_regular_file(file_status __s) noexcept {
20850b57cec5SDimitry Andric  return __s.type() == file_type::regular;
20860b57cec5SDimitry Andric}
20870b57cec5SDimitry Andric
20880b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
20890b57cec5SDimitry Andric  return is_regular_file(__status(__p));
20900b57cec5SDimitry Andric}
20910b57cec5SDimitry Andric
20920b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
20930b57cec5SDimitry Andricis_regular_file(const path& __p, error_code& __ec) noexcept {
20940b57cec5SDimitry Andric  return is_regular_file(__status(__p, &__ec));
20950b57cec5SDimitry Andric}
20960b57cec5SDimitry Andric
20970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
20980b57cec5SDimitry Andric  return __s.type() == file_type::socket;
20990b57cec5SDimitry Andric}
21000b57cec5SDimitry Andric
21010b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
21020b57cec5SDimitry Andric  return is_socket(__status(__p));
21030b57cec5SDimitry Andric}
21040b57cec5SDimitry Andric
21050b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
21060b57cec5SDimitry Andric                                                error_code& __ec) noexcept {
21070b57cec5SDimitry Andric  return is_socket(__status(__p, &__ec));
21080b57cec5SDimitry Andric}
21090b57cec5SDimitry Andric
21100b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
21110b57cec5SDimitry Andric  return __s.type() == file_type::symlink;
21120b57cec5SDimitry Andric}
21130b57cec5SDimitry Andric
21140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
21150b57cec5SDimitry Andric  return is_symlink(__symlink_status(__p));
21160b57cec5SDimitry Andric}
21170b57cec5SDimitry Andric
21180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
21190b57cec5SDimitry Andric                                                 error_code& __ec) noexcept {
21200b57cec5SDimitry Andric  return is_symlink(__symlink_status(__p, &__ec));
21210b57cec5SDimitry Andric}
21220b57cec5SDimitry Andric
21230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
21240b57cec5SDimitry Andric  return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
21250b57cec5SDimitry Andric         !is_symlink(__s);
21260b57cec5SDimitry Andric}
21270b57cec5SDimitry Andric
21280b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
21290b57cec5SDimitry Andric  return is_other(__status(__p));
21300b57cec5SDimitry Andric}
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
21330b57cec5SDimitry Andric                                               error_code& __ec) noexcept {
21340b57cec5SDimitry Andric  return is_other(__status(__p, &__ec));
21350b57cec5SDimitry Andric}
21360b57cec5SDimitry Andric
21370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_time_type
21380b57cec5SDimitry Andriclast_write_time(const path& __p) {
21390b57cec5SDimitry Andric  return __last_write_time(__p);
21400b57cec5SDimitry Andric}
21410b57cec5SDimitry Andric
21420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_time_type
21430b57cec5SDimitry Andriclast_write_time(const path& __p, error_code& __ec) noexcept {
21440b57cec5SDimitry Andric  return __last_write_time(__p, &__ec);
21450b57cec5SDimitry Andric}
21460b57cec5SDimitry Andric
21470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
21480b57cec5SDimitry Andric                                                      file_time_type __t) {
21490b57cec5SDimitry Andric  __last_write_time(__p, __t);
21500b57cec5SDimitry Andric}
21510b57cec5SDimitry Andric
21520b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
21530b57cec5SDimitry Andriclast_write_time(const path& __p, file_time_type __t,
21540b57cec5SDimitry Andric                error_code& __ec) noexcept {
21550b57cec5SDimitry Andric  __last_write_time(__p, __t, &__ec);
21560b57cec5SDimitry Andric}
21570b57cec5SDimitry Andric
21580b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
21590b57cec5SDimitry Andricpermissions(const path& __p, perms __prms,
21600b57cec5SDimitry Andric            perm_options __opts = perm_options::replace) {
21610b57cec5SDimitry Andric  __permissions(__p, __prms, __opts);
21620b57cec5SDimitry Andric}
21630b57cec5SDimitry Andric
21640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
21650b57cec5SDimitry Andric                                                  error_code& __ec) noexcept {
21660b57cec5SDimitry Andric  __permissions(__p, __prms, perm_options::replace, &__ec);
21670b57cec5SDimitry Andric}
21680b57cec5SDimitry Andric
21690b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
21700b57cec5SDimitry Andric                                                  perm_options __opts,
21710b57cec5SDimitry Andric                                                  error_code& __ec) {
21720b57cec5SDimitry Andric  __permissions(__p, __prms, __opts, &__ec);
21730b57cec5SDimitry Andric}
21740b57cec5SDimitry Andric
21750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
21760b57cec5SDimitry Andric                                                const path& __base,
21770b57cec5SDimitry Andric                                                error_code& __ec) {
21780b57cec5SDimitry Andric  path __tmp = __weakly_canonical(__p, &__ec);
21790b57cec5SDimitry Andric  if (__ec)
21800b57cec5SDimitry Andric    return {};
21810b57cec5SDimitry Andric  path __tmp_base = __weakly_canonical(__base, &__ec);
21820b57cec5SDimitry Andric  if (__ec)
21830b57cec5SDimitry Andric    return {};
21840b57cec5SDimitry Andric  return __tmp.lexically_proximate(__tmp_base);
21850b57cec5SDimitry Andric}
21860b57cec5SDimitry Andric
21870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
21880b57cec5SDimitry Andric                                                error_code& __ec) {
21890b57cec5SDimitry Andric  return proximate(__p, current_path(), __ec);
21900b57cec5SDimitry Andric}
21910b57cec5SDimitry Andric
21920b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path
21930b57cec5SDimitry Andricproximate(const path& __p, const path& __base = current_path()) {
21940b57cec5SDimitry Andric  return __weakly_canonical(__p).lexically_proximate(
21950b57cec5SDimitry Andric      __weakly_canonical(__base));
21960b57cec5SDimitry Andric}
21970b57cec5SDimitry Andric
21980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
21990b57cec5SDimitry Andric  return __read_symlink(__p);
22000b57cec5SDimitry Andric}
22010b57cec5SDimitry Andric
22020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
22030b57cec5SDimitry Andric                                                   error_code& __ec) {
22040b57cec5SDimitry Andric  return __read_symlink(__p, &__ec);
22050b57cec5SDimitry Andric}
22060b57cec5SDimitry Andric
22070b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
22080b57cec5SDimitry Andric                                               const path& __base,
22090b57cec5SDimitry Andric                                               error_code& __ec) {
22100b57cec5SDimitry Andric  path __tmp = __weakly_canonical(__p, &__ec);
22110b57cec5SDimitry Andric  if (__ec)
22120b57cec5SDimitry Andric    return path();
22130b57cec5SDimitry Andric  path __tmpbase = __weakly_canonical(__base, &__ec);
22140b57cec5SDimitry Andric  if (__ec)
22150b57cec5SDimitry Andric    return path();
22160b57cec5SDimitry Andric  return __tmp.lexically_relative(__tmpbase);
22170b57cec5SDimitry Andric}
22180b57cec5SDimitry Andric
22190b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
22200b57cec5SDimitry Andric                                               error_code& __ec) {
22210b57cec5SDimitry Andric  return relative(__p, current_path(), __ec);
22220b57cec5SDimitry Andric}
22230b57cec5SDimitry Andric
22240b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path
22250b57cec5SDimitry Andricrelative(const path& __p, const path& __base = current_path()) {
22260b57cec5SDimitry Andric  return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
22270b57cec5SDimitry Andric}
22280b57cec5SDimitry Andric
22290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
22300b57cec5SDimitry Andric  return __remove(__p);
22310b57cec5SDimitry Andric}
22320b57cec5SDimitry Andric
22330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
22340b57cec5SDimitry Andric                                             error_code& __ec) noexcept {
22350b57cec5SDimitry Andric  return __remove(__p, &__ec);
22360b57cec5SDimitry Andric}
22370b57cec5SDimitry Andric
22380b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
22390b57cec5SDimitry Andric  return __remove_all(__p);
22400b57cec5SDimitry Andric}
22410b57cec5SDimitry Andric
22420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
22430b57cec5SDimitry Andric                                                      error_code& __ec) {
22440b57cec5SDimitry Andric  return __remove_all(__p, &__ec);
22450b57cec5SDimitry Andric}
22460b57cec5SDimitry Andric
22470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
22480b57cec5SDimitry Andric                                             const path& __to) {
22490b57cec5SDimitry Andric  return __rename(__from, __to);
22500b57cec5SDimitry Andric}
22510b57cec5SDimitry Andric
22520b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
22530b57cec5SDimitry Andricrename(const path& __from, const path& __to, error_code& __ec) noexcept {
22540b57cec5SDimitry Andric  return __rename(__from, __to, &__ec);
22550b57cec5SDimitry Andric}
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
22580b57cec5SDimitry Andric                                                  uintmax_t __ns) {
22590b57cec5SDimitry Andric  return __resize_file(__p, __ns);
22600b57cec5SDimitry Andric}
22610b57cec5SDimitry Andric
22620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
22630b57cec5SDimitry Andricresize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
22640b57cec5SDimitry Andric  return __resize_file(__p, __ns, &__ec);
22650b57cec5SDimitry Andric}
22660b57cec5SDimitry Andric
22670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
22680b57cec5SDimitry Andric  return __space(__p);
22690b57cec5SDimitry Andric}
22700b57cec5SDimitry Andric
22710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
22720b57cec5SDimitry Andric                                                  error_code& __ec) noexcept {
22730b57cec5SDimitry Andric  return __space(__p, &__ec);
22740b57cec5SDimitry Andric}
22750b57cec5SDimitry Andric
22760b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
22770b57cec5SDimitry Andric  return __status(__p);
22780b57cec5SDimitry Andric}
22790b57cec5SDimitry Andric
22800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
22810b57cec5SDimitry Andric                                                    error_code& __ec) noexcept {
22820b57cec5SDimitry Andric  return __status(__p, &__ec);
22830b57cec5SDimitry Andric}
22840b57cec5SDimitry Andric
22850b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
22860b57cec5SDimitry Andric  return __symlink_status(__p);
22870b57cec5SDimitry Andric}
22880b57cec5SDimitry Andric
22890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status
22900b57cec5SDimitry Andricsymlink_status(const path& __p, error_code& __ec) noexcept {
22910b57cec5SDimitry Andric  return __symlink_status(__p, &__ec);
22920b57cec5SDimitry Andric}
22930b57cec5SDimitry Andric
22940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
22950b57cec5SDimitry Andric  return __temp_directory_path();
22960b57cec5SDimitry Andric}
22970b57cec5SDimitry Andric
22980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
22990b57cec5SDimitry Andric  return __temp_directory_path(&__ec);
23000b57cec5SDimitry Andric}
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
23030b57cec5SDimitry Andric  return __weakly_canonical(__p);
23040b57cec5SDimitry Andric}
23050b57cec5SDimitry Andric
23060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
23070b57cec5SDimitry Andric                                                       error_code& __ec) {
23080b57cec5SDimitry Andric  return __weakly_canonical(__p, &__ec);
23090b57cec5SDimitry Andric}
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andricclass directory_iterator;
23120b57cec5SDimitry Andricclass recursive_directory_iterator;
23130b57cec5SDimitry Andricclass _LIBCPP_HIDDEN __dir_stream;
23140b57cec5SDimitry Andric
23150b57cec5SDimitry Andricclass directory_entry {
23160b57cec5SDimitry Andric  typedef _VSTD_FS::path _Path;
23170b57cec5SDimitry Andric
23180b57cec5SDimitry Andricpublic:
23190b57cec5SDimitry Andric  // constructors and destructors
23200b57cec5SDimitry Andric  directory_entry() noexcept = default;
23210b57cec5SDimitry Andric  directory_entry(directory_entry const&) = default;
23220b57cec5SDimitry Andric  directory_entry(directory_entry&&) noexcept = default;
23230b57cec5SDimitry Andric
23240b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23250b57cec5SDimitry Andric  explicit directory_entry(_Path const& __p) : __p_(__p) {
23260b57cec5SDimitry Andric    error_code __ec;
23270b57cec5SDimitry Andric    __refresh(&__ec);
23280b57cec5SDimitry Andric  }
23290b57cec5SDimitry Andric
23300b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23310b57cec5SDimitry Andric  directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
23320b57cec5SDimitry Andric    __refresh(&__ec);
23330b57cec5SDimitry Andric  }
23340b57cec5SDimitry Andric
23350b57cec5SDimitry Andric  ~directory_entry() {}
23360b57cec5SDimitry Andric
23370b57cec5SDimitry Andric  directory_entry& operator=(directory_entry const&) = default;
23380b57cec5SDimitry Andric  directory_entry& operator=(directory_entry&&) noexcept = default;
23390b57cec5SDimitry Andric
23400b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23410b57cec5SDimitry Andric  void assign(_Path const& __p) {
23420b57cec5SDimitry Andric    __p_ = __p;
23430b57cec5SDimitry Andric    error_code __ec;
23440b57cec5SDimitry Andric    __refresh(&__ec);
23450b57cec5SDimitry Andric  }
23460b57cec5SDimitry Andric
23470b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23480b57cec5SDimitry Andric  void assign(_Path const& __p, error_code& __ec) {
23490b57cec5SDimitry Andric    __p_ = __p;
23500b57cec5SDimitry Andric    __refresh(&__ec);
23510b57cec5SDimitry Andric  }
23520b57cec5SDimitry Andric
23530b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23540b57cec5SDimitry Andric  void replace_filename(_Path const& __p) {
23550b57cec5SDimitry Andric    __p_.replace_filename(__p);
23560b57cec5SDimitry Andric    error_code __ec;
23570b57cec5SDimitry Andric    __refresh(&__ec);
23580b57cec5SDimitry Andric  }
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23610b57cec5SDimitry Andric  void replace_filename(_Path const& __p, error_code& __ec) {
23620b57cec5SDimitry Andric    __p_ = __p_.parent_path() / __p;
23630b57cec5SDimitry Andric    __refresh(&__ec);
23640b57cec5SDimitry Andric  }
23650b57cec5SDimitry Andric
23660b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23670b57cec5SDimitry Andric  void refresh() { __refresh(); }
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23700b57cec5SDimitry Andric  void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23730b57cec5SDimitry Andric  _Path const& path() const noexcept { return __p_; }
23740b57cec5SDimitry Andric
23750b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23760b57cec5SDimitry Andric  operator const _Path&() const noexcept { return __p_; }
23770b57cec5SDimitry Andric
23780b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23790b57cec5SDimitry Andric  bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
23800b57cec5SDimitry Andric
23810b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23820b57cec5SDimitry Andric  bool exists(error_code& __ec) const noexcept {
23830b57cec5SDimitry Andric    return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
23840b57cec5SDimitry Andric  }
23850b57cec5SDimitry Andric
23860b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23870b57cec5SDimitry Andric  bool is_block_file() const { return __get_ft() == file_type::block; }
23880b57cec5SDimitry Andric
23890b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23900b57cec5SDimitry Andric  bool is_block_file(error_code& __ec) const noexcept {
23910b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::block;
23920b57cec5SDimitry Andric  }
23930b57cec5SDimitry Andric
23940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23950b57cec5SDimitry Andric  bool is_character_file() const { return __get_ft() == file_type::character; }
23960b57cec5SDimitry Andric
23970b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23980b57cec5SDimitry Andric  bool is_character_file(error_code& __ec) const noexcept {
23990b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::character;
24000b57cec5SDimitry Andric  }
24010b57cec5SDimitry Andric
24020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24030b57cec5SDimitry Andric  bool is_directory() const { return __get_ft() == file_type::directory; }
24040b57cec5SDimitry Andric
24050b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24060b57cec5SDimitry Andric  bool is_directory(error_code& __ec) const noexcept {
24070b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::directory;
24080b57cec5SDimitry Andric  }
24090b57cec5SDimitry Andric
24100b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24110b57cec5SDimitry Andric  bool is_fifo() const { return __get_ft() == file_type::fifo; }
24120b57cec5SDimitry Andric
24130b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24140b57cec5SDimitry Andric  bool is_fifo(error_code& __ec) const noexcept {
24150b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::fifo;
24160b57cec5SDimitry Andric  }
24170b57cec5SDimitry Andric
24180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24190b57cec5SDimitry Andric  bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
24200b57cec5SDimitry Andric
24210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24220b57cec5SDimitry Andric  bool is_other(error_code& __ec) const noexcept {
24230b57cec5SDimitry Andric    return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
24240b57cec5SDimitry Andric  }
24250b57cec5SDimitry Andric
24260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24270b57cec5SDimitry Andric  bool is_regular_file() const { return __get_ft() == file_type::regular; }
24280b57cec5SDimitry Andric
24290b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24300b57cec5SDimitry Andric  bool is_regular_file(error_code& __ec) const noexcept {
24310b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::regular;
24320b57cec5SDimitry Andric  }
24330b57cec5SDimitry Andric
24340b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24350b57cec5SDimitry Andric  bool is_socket() const { return __get_ft() == file_type::socket; }
24360b57cec5SDimitry Andric
24370b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24380b57cec5SDimitry Andric  bool is_socket(error_code& __ec) const noexcept {
24390b57cec5SDimitry Andric    return __get_ft(&__ec) == file_type::socket;
24400b57cec5SDimitry Andric  }
24410b57cec5SDimitry Andric
24420b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24430b57cec5SDimitry Andric  bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
24440b57cec5SDimitry Andric
24450b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24460b57cec5SDimitry Andric  bool is_symlink(error_code& __ec) const noexcept {
24470b57cec5SDimitry Andric    return __get_sym_ft(&__ec) == file_type::symlink;
24480b57cec5SDimitry Andric  }
24490b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24500b57cec5SDimitry Andric  uintmax_t file_size() const { return __get_size(); }
24510b57cec5SDimitry Andric
24520b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24530b57cec5SDimitry Andric  uintmax_t file_size(error_code& __ec) const noexcept {
24540b57cec5SDimitry Andric    return __get_size(&__ec);
24550b57cec5SDimitry Andric  }
24560b57cec5SDimitry Andric
24570b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24580b57cec5SDimitry Andric  uintmax_t hard_link_count() const { return __get_nlink(); }
24590b57cec5SDimitry Andric
24600b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24610b57cec5SDimitry Andric  uintmax_t hard_link_count(error_code& __ec) const noexcept {
24620b57cec5SDimitry Andric    return __get_nlink(&__ec);
24630b57cec5SDimitry Andric  }
24640b57cec5SDimitry Andric
24650b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24660b57cec5SDimitry Andric  file_time_type last_write_time() const { return __get_write_time(); }
24670b57cec5SDimitry Andric
24680b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24690b57cec5SDimitry Andric  file_time_type last_write_time(error_code& __ec) const noexcept {
24700b57cec5SDimitry Andric    return __get_write_time(&__ec);
24710b57cec5SDimitry Andric  }
24720b57cec5SDimitry Andric
24730b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24740b57cec5SDimitry Andric  file_status status() const { return __get_status(); }
24750b57cec5SDimitry Andric
24760b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24770b57cec5SDimitry Andric  file_status status(error_code& __ec) const noexcept {
24780b57cec5SDimitry Andric    return __get_status(&__ec);
24790b57cec5SDimitry Andric  }
24800b57cec5SDimitry Andric
24810b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24820b57cec5SDimitry Andric  file_status symlink_status() const { return __get_symlink_status(); }
24830b57cec5SDimitry Andric
24840b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24850b57cec5SDimitry Andric  file_status symlink_status(error_code& __ec) const noexcept {
24860b57cec5SDimitry Andric    return __get_symlink_status(&__ec);
24870b57cec5SDimitry Andric  }
24880b57cec5SDimitry Andric
24890b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24900b57cec5SDimitry Andric  bool operator<(directory_entry const& __rhs) const noexcept {
24910b57cec5SDimitry Andric    return __p_ < __rhs.__p_;
24920b57cec5SDimitry Andric  }
24930b57cec5SDimitry Andric
24940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24950b57cec5SDimitry Andric  bool operator==(directory_entry const& __rhs) const noexcept {
24960b57cec5SDimitry Andric    return __p_ == __rhs.__p_;
24970b57cec5SDimitry Andric  }
24980b57cec5SDimitry Andric
24990b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25000b57cec5SDimitry Andric  bool operator!=(directory_entry const& __rhs) const noexcept {
25010b57cec5SDimitry Andric    return __p_ != __rhs.__p_;
25020b57cec5SDimitry Andric  }
25030b57cec5SDimitry Andric
25040b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25050b57cec5SDimitry Andric  bool operator<=(directory_entry const& __rhs) const noexcept {
25060b57cec5SDimitry Andric    return __p_ <= __rhs.__p_;
25070b57cec5SDimitry Andric  }
25080b57cec5SDimitry Andric
25090b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25100b57cec5SDimitry Andric  bool operator>(directory_entry const& __rhs) const noexcept {
25110b57cec5SDimitry Andric    return __p_ > __rhs.__p_;
25120b57cec5SDimitry Andric  }
25130b57cec5SDimitry Andric
25140b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25150b57cec5SDimitry Andric  bool operator>=(directory_entry const& __rhs) const noexcept {
25160b57cec5SDimitry Andric    return __p_ >= __rhs.__p_;
25170b57cec5SDimitry Andric  }
25180b57cec5SDimitry Andric
25190b57cec5SDimitry Andricprivate:
25200b57cec5SDimitry Andric  friend class directory_iterator;
25210b57cec5SDimitry Andric  friend class recursive_directory_iterator;
25220b57cec5SDimitry Andric  friend class __dir_stream;
25230b57cec5SDimitry Andric
25240b57cec5SDimitry Andric  enum _CacheType : unsigned char {
25250b57cec5SDimitry Andric    _Empty,
25260b57cec5SDimitry Andric    _IterSymlink,
25270b57cec5SDimitry Andric    _IterNonSymlink,
25280b57cec5SDimitry Andric    _RefreshSymlink,
25290b57cec5SDimitry Andric    _RefreshSymlinkUnresolved,
25300b57cec5SDimitry Andric    _RefreshNonSymlink
25310b57cec5SDimitry Andric  };
25320b57cec5SDimitry Andric
25330b57cec5SDimitry Andric  struct __cached_data {
25340b57cec5SDimitry Andric    uintmax_t __size_;
25350b57cec5SDimitry Andric    uintmax_t __nlink_;
25360b57cec5SDimitry Andric    file_time_type __write_time_;
25370b57cec5SDimitry Andric    perms __sym_perms_;
25380b57cec5SDimitry Andric    perms __non_sym_perms_;
25390b57cec5SDimitry Andric    file_type __type_;
25400b57cec5SDimitry Andric    _CacheType __cache_type_;
25410b57cec5SDimitry Andric
25420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25430b57cec5SDimitry Andric    __cached_data() noexcept { __reset(); }
25440b57cec5SDimitry Andric
25450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25460b57cec5SDimitry Andric    void __reset() {
25470b57cec5SDimitry Andric      __cache_type_ = _Empty;
25480b57cec5SDimitry Andric      __type_ = file_type::none;
25490b57cec5SDimitry Andric      __sym_perms_ = __non_sym_perms_ = perms::unknown;
25500b57cec5SDimitry Andric      __size_ = __nlink_ = uintmax_t(-1);
25510b57cec5SDimitry Andric      __write_time_ = file_time_type::min();
25520b57cec5SDimitry Andric    }
25530b57cec5SDimitry Andric  };
25540b57cec5SDimitry Andric
25550b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25560b57cec5SDimitry Andric  static __cached_data __create_iter_result(file_type __ft) {
25570b57cec5SDimitry Andric    __cached_data __data;
25580b57cec5SDimitry Andric    __data.__type_ = __ft;
25590b57cec5SDimitry Andric    __data.__cache_type_ = [&]() {
25600b57cec5SDimitry Andric      switch (__ft) {
25610b57cec5SDimitry Andric      case file_type::none:
25620b57cec5SDimitry Andric        return _Empty;
25630b57cec5SDimitry Andric      case file_type::symlink:
25640b57cec5SDimitry Andric        return _IterSymlink;
25650b57cec5SDimitry Andric      default:
25660b57cec5SDimitry Andric        return _IterNonSymlink;
25670b57cec5SDimitry Andric      }
25680b57cec5SDimitry Andric    }();
25690b57cec5SDimitry Andric    return __data;
25700b57cec5SDimitry Andric  }
25710b57cec5SDimitry Andric
25720b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25730b57cec5SDimitry Andric  void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2574e8d8bef9SDimitry Andric    __p_ = _VSTD::move(__p);
25750b57cec5SDimitry Andric    __data_ = __dt;
25760b57cec5SDimitry Andric  }
25770b57cec5SDimitry Andric
25780b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
25790b57cec5SDimitry Andric  error_code __do_refresh() noexcept;
25800b57cec5SDimitry Andric
25810b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25820b57cec5SDimitry Andric  static bool __is_dne_error(error_code const& __ec) {
25830b57cec5SDimitry Andric    if (!__ec)
25840b57cec5SDimitry Andric      return true;
25850b57cec5SDimitry Andric    switch (static_cast<errc>(__ec.value())) {
25860b57cec5SDimitry Andric    case errc::no_such_file_or_directory:
25870b57cec5SDimitry Andric    case errc::not_a_directory:
25880b57cec5SDimitry Andric      return true;
25890b57cec5SDimitry Andric    default:
25900b57cec5SDimitry Andric      return false;
25910b57cec5SDimitry Andric    }
25920b57cec5SDimitry Andric  }
25930b57cec5SDimitry Andric
25940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25950b57cec5SDimitry Andric  void __handle_error(const char* __msg, error_code* __dest_ec,
25960b57cec5SDimitry Andric                      error_code const& __ec, bool __allow_dne = false) const {
25970b57cec5SDimitry Andric    if (__dest_ec) {
25980b57cec5SDimitry Andric      *__dest_ec = __ec;
25990b57cec5SDimitry Andric      return;
26000b57cec5SDimitry Andric    }
26010b57cec5SDimitry Andric    if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
26020b57cec5SDimitry Andric      __throw_filesystem_error(__msg, __p_, __ec);
26030b57cec5SDimitry Andric  }
26040b57cec5SDimitry Andric
26050b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26060b57cec5SDimitry Andric  void __refresh(error_code* __ec = nullptr) {
26070b57cec5SDimitry Andric    __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
26080b57cec5SDimitry Andric                   /*allow_dne*/ true);
26090b57cec5SDimitry Andric  }
26100b57cec5SDimitry Andric
26110b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26120b57cec5SDimitry Andric  file_type __get_sym_ft(error_code* __ec = nullptr) const {
26130b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
26140b57cec5SDimitry Andric    case _Empty:
26150b57cec5SDimitry Andric      return __symlink_status(__p_, __ec).type();
26160b57cec5SDimitry Andric    case _IterSymlink:
26170b57cec5SDimitry Andric    case _RefreshSymlink:
26180b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
26190b57cec5SDimitry Andric      if (__ec)
26200b57cec5SDimitry Andric        __ec->clear();
26210b57cec5SDimitry Andric      return file_type::symlink;
26220b57cec5SDimitry Andric    case _IterNonSymlink:
26230b57cec5SDimitry Andric    case _RefreshNonSymlink:
26240b57cec5SDimitry Andric      file_status __st(__data_.__type_);
26250b57cec5SDimitry Andric      if (__ec && !_VSTD_FS::exists(__st))
26260b57cec5SDimitry Andric        *__ec = make_error_code(errc::no_such_file_or_directory);
26270b57cec5SDimitry Andric      else if (__ec)
26280b57cec5SDimitry Andric        __ec->clear();
26290b57cec5SDimitry Andric      return __data_.__type_;
26300b57cec5SDimitry Andric    }
26310b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
26320b57cec5SDimitry Andric  }
26330b57cec5SDimitry Andric
26340b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26350b57cec5SDimitry Andric  file_type __get_ft(error_code* __ec = nullptr) const {
26360b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
26370b57cec5SDimitry Andric    case _Empty:
26380b57cec5SDimitry Andric    case _IterSymlink:
26390b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
26400b57cec5SDimitry Andric      return __status(__p_, __ec).type();
26410b57cec5SDimitry Andric    case _IterNonSymlink:
26420b57cec5SDimitry Andric    case _RefreshNonSymlink:
26430b57cec5SDimitry Andric    case _RefreshSymlink: {
26440b57cec5SDimitry Andric      file_status __st(__data_.__type_);
26450b57cec5SDimitry Andric      if (__ec && !_VSTD_FS::exists(__st))
26460b57cec5SDimitry Andric        *__ec = make_error_code(errc::no_such_file_or_directory);
26470b57cec5SDimitry Andric      else if (__ec)
26480b57cec5SDimitry Andric        __ec->clear();
26490b57cec5SDimitry Andric      return __data_.__type_;
26500b57cec5SDimitry Andric    }
26510b57cec5SDimitry Andric    }
26520b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
26530b57cec5SDimitry Andric  }
26540b57cec5SDimitry Andric
26550b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26560b57cec5SDimitry Andric  file_status __get_status(error_code* __ec = nullptr) const {
26570b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
26580b57cec5SDimitry Andric    case _Empty:
26590b57cec5SDimitry Andric    case _IterNonSymlink:
26600b57cec5SDimitry Andric    case _IterSymlink:
26610b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
26620b57cec5SDimitry Andric      return __status(__p_, __ec);
26630b57cec5SDimitry Andric    case _RefreshNonSymlink:
26640b57cec5SDimitry Andric    case _RefreshSymlink:
26650b57cec5SDimitry Andric      return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
26660b57cec5SDimitry Andric    }
26670b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
26680b57cec5SDimitry Andric  }
26690b57cec5SDimitry Andric
26700b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26710b57cec5SDimitry Andric  file_status __get_symlink_status(error_code* __ec = nullptr) const {
26720b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
26730b57cec5SDimitry Andric    case _Empty:
26740b57cec5SDimitry Andric    case _IterNonSymlink:
26750b57cec5SDimitry Andric    case _IterSymlink:
26760b57cec5SDimitry Andric      return __symlink_status(__p_, __ec);
26770b57cec5SDimitry Andric    case _RefreshNonSymlink:
26780b57cec5SDimitry Andric      return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
26790b57cec5SDimitry Andric    case _RefreshSymlink:
26800b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
26810b57cec5SDimitry Andric      return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
26820b57cec5SDimitry Andric    }
26830b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
26840b57cec5SDimitry Andric  }
26850b57cec5SDimitry Andric
26860b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26870b57cec5SDimitry Andric  uintmax_t __get_size(error_code* __ec = nullptr) const {
26880b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
26890b57cec5SDimitry Andric    case _Empty:
26900b57cec5SDimitry Andric    case _IterNonSymlink:
26910b57cec5SDimitry Andric    case _IterSymlink:
26920b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
26930b57cec5SDimitry Andric      return _VSTD_FS::__file_size(__p_, __ec);
26940b57cec5SDimitry Andric    case _RefreshSymlink:
26950b57cec5SDimitry Andric    case _RefreshNonSymlink: {
26960b57cec5SDimitry Andric      error_code __m_ec;
26970b57cec5SDimitry Andric      file_status __st(__get_ft(&__m_ec));
26980b57cec5SDimitry Andric      __handle_error("in directory_entry::file_size", __ec, __m_ec);
26990b57cec5SDimitry Andric      if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
27000b57cec5SDimitry Andric        errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
27010b57cec5SDimitry Andric                                                       : errc::not_supported;
27020b57cec5SDimitry Andric        __handle_error("in directory_entry::file_size", __ec,
27030b57cec5SDimitry Andric                       make_error_code(__err_kind));
27040b57cec5SDimitry Andric      }
27050b57cec5SDimitry Andric      return __data_.__size_;
27060b57cec5SDimitry Andric    }
27070b57cec5SDimitry Andric    }
27080b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
27090b57cec5SDimitry Andric  }
27100b57cec5SDimitry Andric
27110b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27120b57cec5SDimitry Andric  uintmax_t __get_nlink(error_code* __ec = nullptr) const {
27130b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
27140b57cec5SDimitry Andric    case _Empty:
27150b57cec5SDimitry Andric    case _IterNonSymlink:
27160b57cec5SDimitry Andric    case _IterSymlink:
27170b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
27180b57cec5SDimitry Andric      return _VSTD_FS::__hard_link_count(__p_, __ec);
27190b57cec5SDimitry Andric    case _RefreshSymlink:
27200b57cec5SDimitry Andric    case _RefreshNonSymlink: {
27210b57cec5SDimitry Andric      error_code __m_ec;
27220b57cec5SDimitry Andric      (void)__get_ft(&__m_ec);
27230b57cec5SDimitry Andric      __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
27240b57cec5SDimitry Andric      return __data_.__nlink_;
27250b57cec5SDimitry Andric    }
27260b57cec5SDimitry Andric    }
27270b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
27280b57cec5SDimitry Andric  }
27290b57cec5SDimitry Andric
27300b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27310b57cec5SDimitry Andric  file_time_type __get_write_time(error_code* __ec = nullptr) const {
27320b57cec5SDimitry Andric    switch (__data_.__cache_type_) {
27330b57cec5SDimitry Andric    case _Empty:
27340b57cec5SDimitry Andric    case _IterNonSymlink:
27350b57cec5SDimitry Andric    case _IterSymlink:
27360b57cec5SDimitry Andric    case _RefreshSymlinkUnresolved:
27370b57cec5SDimitry Andric      return _VSTD_FS::__last_write_time(__p_, __ec);
27380b57cec5SDimitry Andric    case _RefreshSymlink:
27390b57cec5SDimitry Andric    case _RefreshNonSymlink: {
27400b57cec5SDimitry Andric      error_code __m_ec;
27410b57cec5SDimitry Andric      file_status __st(__get_ft(&__m_ec));
27420b57cec5SDimitry Andric      __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
27430b57cec5SDimitry Andric      if (_VSTD_FS::exists(__st) &&
27440b57cec5SDimitry Andric          __data_.__write_time_ == file_time_type::min())
27450b57cec5SDimitry Andric        __handle_error("in directory_entry::last_write_time", __ec,
27460b57cec5SDimitry Andric                       make_error_code(errc::value_too_large));
27470b57cec5SDimitry Andric      return __data_.__write_time_;
27480b57cec5SDimitry Andric    }
27490b57cec5SDimitry Andric    }
27500b57cec5SDimitry Andric    _LIBCPP_UNREACHABLE();
27510b57cec5SDimitry Andric  }
27520b57cec5SDimitry Andric
27530b57cec5SDimitry Andricprivate:
27540b57cec5SDimitry Andric  _Path __p_;
27550b57cec5SDimitry Andric  __cached_data __data_;
27560b57cec5SDimitry Andric};
27570b57cec5SDimitry Andric
27580b57cec5SDimitry Andricclass __dir_element_proxy {
27590b57cec5SDimitry Andricpublic:
27600b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
27610b57cec5SDimitry Andric    return _VSTD::move(__elem_);
27620b57cec5SDimitry Andric  }
27630b57cec5SDimitry Andric
27640b57cec5SDimitry Andricprivate:
27650b57cec5SDimitry Andric  friend class directory_iterator;
27660b57cec5SDimitry Andric  friend class recursive_directory_iterator;
27670b57cec5SDimitry Andric  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
27680b57cec5SDimitry Andric  __dir_element_proxy(__dir_element_proxy&& __o)
27690b57cec5SDimitry Andric      : __elem_(_VSTD::move(__o.__elem_)) {}
27700b57cec5SDimitry Andric  directory_entry __elem_;
27710b57cec5SDimitry Andric};
27720b57cec5SDimitry Andric
27730b57cec5SDimitry Andricclass directory_iterator {
27740b57cec5SDimitry Andricpublic:
27750b57cec5SDimitry Andric  typedef directory_entry value_type;
27760b57cec5SDimitry Andric  typedef ptrdiff_t difference_type;
27770b57cec5SDimitry Andric  typedef value_type const* pointer;
27780b57cec5SDimitry Andric  typedef value_type const& reference;
27790b57cec5SDimitry Andric  typedef input_iterator_tag iterator_category;
27800b57cec5SDimitry Andric
27810b57cec5SDimitry Andricpublic:
27820b57cec5SDimitry Andric  //ctor & dtor
27830b57cec5SDimitry Andric  directory_iterator() noexcept {}
27840b57cec5SDimitry Andric
27850b57cec5SDimitry Andric  explicit directory_iterator(const path& __p)
27860b57cec5SDimitry Andric      : directory_iterator(__p, nullptr) {}
27870b57cec5SDimitry Andric
27880b57cec5SDimitry Andric  directory_iterator(const path& __p, directory_options __opts)
27890b57cec5SDimitry Andric      : directory_iterator(__p, nullptr, __opts) {}
27900b57cec5SDimitry Andric
27910b57cec5SDimitry Andric  directory_iterator(const path& __p, error_code& __ec)
27920b57cec5SDimitry Andric      : directory_iterator(__p, &__ec) {}
27930b57cec5SDimitry Andric
27940b57cec5SDimitry Andric  directory_iterator(const path& __p, directory_options __opts,
27950b57cec5SDimitry Andric                     error_code& __ec)
27960b57cec5SDimitry Andric      : directory_iterator(__p, &__ec, __opts) {}
27970b57cec5SDimitry Andric
27980b57cec5SDimitry Andric  directory_iterator(const directory_iterator&) = default;
27990b57cec5SDimitry Andric  directory_iterator(directory_iterator&&) = default;
28000b57cec5SDimitry Andric  directory_iterator& operator=(const directory_iterator&) = default;
28010b57cec5SDimitry Andric
28020b57cec5SDimitry Andric  directory_iterator& operator=(directory_iterator&& __o) noexcept {
28030b57cec5SDimitry Andric    // non-default implementation provided to support self-move assign.
28040b57cec5SDimitry Andric    if (this != &__o) {
28050b57cec5SDimitry Andric      __imp_ = _VSTD::move(__o.__imp_);
28060b57cec5SDimitry Andric    }
28070b57cec5SDimitry Andric    return *this;
28080b57cec5SDimitry Andric  }
28090b57cec5SDimitry Andric
28100b57cec5SDimitry Andric  ~directory_iterator() = default;
28110b57cec5SDimitry Andric
28120b57cec5SDimitry Andric  const directory_entry& operator*() const {
28130b57cec5SDimitry Andric    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
28140b57cec5SDimitry Andric    return __dereference();
28150b57cec5SDimitry Andric  }
28160b57cec5SDimitry Andric
28170b57cec5SDimitry Andric  const directory_entry* operator->() const { return &**this; }
28180b57cec5SDimitry Andric
28190b57cec5SDimitry Andric  directory_iterator& operator++() { return __increment(); }
28200b57cec5SDimitry Andric
28210b57cec5SDimitry Andric  __dir_element_proxy operator++(int) {
28220b57cec5SDimitry Andric    __dir_element_proxy __p(**this);
28230b57cec5SDimitry Andric    __increment();
28240b57cec5SDimitry Andric    return __p;
28250b57cec5SDimitry Andric  }
28260b57cec5SDimitry Andric
28270b57cec5SDimitry Andric  directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
28280b57cec5SDimitry Andric
28290b57cec5SDimitry Andricprivate:
28300b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool
28310b57cec5SDimitry Andric  operator==(const directory_iterator& __lhs,
28320b57cec5SDimitry Andric             const directory_iterator& __rhs) noexcept;
28330b57cec5SDimitry Andric
28340b57cec5SDimitry Andric  // construct the dir_stream
28350b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
28360b57cec5SDimitry Andric  directory_iterator(const path&, error_code*,
28370b57cec5SDimitry Andric                     directory_options = directory_options::none);
28380b57cec5SDimitry Andric
28390b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
28400b57cec5SDimitry Andric  directory_iterator& __increment(error_code* __ec = nullptr);
28410b57cec5SDimitry Andric
28420b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
28430b57cec5SDimitry Andric  const directory_entry& __dereference() const;
28440b57cec5SDimitry Andric
28450b57cec5SDimitry Andricprivate:
28460b57cec5SDimitry Andric  shared_ptr<__dir_stream> __imp_;
28470b57cec5SDimitry Andric};
28480b57cec5SDimitry Andric
28490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
28500b57cec5SDimitry Andricoperator==(const directory_iterator& __lhs,
28510b57cec5SDimitry Andric           const directory_iterator& __rhs) noexcept {
28520b57cec5SDimitry Andric  return __lhs.__imp_ == __rhs.__imp_;
28530b57cec5SDimitry Andric}
28540b57cec5SDimitry Andric
28550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
28560b57cec5SDimitry Andricoperator!=(const directory_iterator& __lhs,
28570b57cec5SDimitry Andric           const directory_iterator& __rhs) noexcept {
28580b57cec5SDimitry Andric  return !(__lhs == __rhs);
28590b57cec5SDimitry Andric}
28600b57cec5SDimitry Andric
28610b57cec5SDimitry Andric// enable directory_iterator range-based for statements
28620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY directory_iterator
28630b57cec5SDimitry Andricbegin(directory_iterator __iter) noexcept {
28640b57cec5SDimitry Andric  return __iter;
28650b57cec5SDimitry Andric}
28660b57cec5SDimitry Andric
28670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY directory_iterator
28680b57cec5SDimitry Andricend(const directory_iterator&) noexcept {
28690b57cec5SDimitry Andric  return directory_iterator();
28700b57cec5SDimitry Andric}
28710b57cec5SDimitry Andric
28720b57cec5SDimitry Andricclass recursive_directory_iterator {
28730b57cec5SDimitry Andricpublic:
28740b57cec5SDimitry Andric  using value_type = directory_entry;
2875e8d8bef9SDimitry Andric  using difference_type = ptrdiff_t;
28760b57cec5SDimitry Andric  using pointer = directory_entry const*;
28770b57cec5SDimitry Andric  using reference = directory_entry const&;
2878e8d8bef9SDimitry Andric  using iterator_category = input_iterator_tag;
28790b57cec5SDimitry Andric
28800b57cec5SDimitry Andricpublic:
28810b57cec5SDimitry Andric  // constructors and destructor
28820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28830b57cec5SDimitry Andric  recursive_directory_iterator() noexcept : __rec_(false) {}
28840b57cec5SDimitry Andric
28850b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28860b57cec5SDimitry Andric  explicit recursive_directory_iterator(
28870b57cec5SDimitry Andric      const path& __p, directory_options __xoptions = directory_options::none)
28880b57cec5SDimitry Andric      : recursive_directory_iterator(__p, __xoptions, nullptr) {}
28890b57cec5SDimitry Andric
28900b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28910b57cec5SDimitry Andric  recursive_directory_iterator(const path& __p, directory_options __xoptions,
28920b57cec5SDimitry Andric                               error_code& __ec)
28930b57cec5SDimitry Andric      : recursive_directory_iterator(__p, __xoptions, &__ec) {}
28940b57cec5SDimitry Andric
28950b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28960b57cec5SDimitry Andric  recursive_directory_iterator(const path& __p, error_code& __ec)
28970b57cec5SDimitry Andric      : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
28980b57cec5SDimitry Andric
28990b57cec5SDimitry Andric  recursive_directory_iterator(const recursive_directory_iterator&) = default;
29000b57cec5SDimitry Andric  recursive_directory_iterator(recursive_directory_iterator&&) = default;
29010b57cec5SDimitry Andric
29020b57cec5SDimitry Andric  recursive_directory_iterator&
29030b57cec5SDimitry Andric  operator=(const recursive_directory_iterator&) = default;
29040b57cec5SDimitry Andric
29050b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29060b57cec5SDimitry Andric  recursive_directory_iterator&
29070b57cec5SDimitry Andric  operator=(recursive_directory_iterator&& __o) noexcept {
29080b57cec5SDimitry Andric    // non-default implementation provided to support self-move assign.
29090b57cec5SDimitry Andric    if (this != &__o) {
29100b57cec5SDimitry Andric      __imp_ = _VSTD::move(__o.__imp_);
29110b57cec5SDimitry Andric      __rec_ = __o.__rec_;
29120b57cec5SDimitry Andric    }
29130b57cec5SDimitry Andric    return *this;
29140b57cec5SDimitry Andric  }
29150b57cec5SDimitry Andric
29160b57cec5SDimitry Andric  ~recursive_directory_iterator() = default;
29170b57cec5SDimitry Andric
29180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29190b57cec5SDimitry Andric  const directory_entry& operator*() const { return __dereference(); }
29200b57cec5SDimitry Andric
29210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29220b57cec5SDimitry Andric  const directory_entry* operator->() const { return &__dereference(); }
29230b57cec5SDimitry Andric
29240b57cec5SDimitry Andric  recursive_directory_iterator& operator++() { return __increment(); }
29250b57cec5SDimitry Andric
29260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29270b57cec5SDimitry Andric  __dir_element_proxy operator++(int) {
29280b57cec5SDimitry Andric    __dir_element_proxy __p(**this);
29290b57cec5SDimitry Andric    __increment();
29300b57cec5SDimitry Andric    return __p;
29310b57cec5SDimitry Andric  }
29320b57cec5SDimitry Andric
29330b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29340b57cec5SDimitry Andric  recursive_directory_iterator& increment(error_code& __ec) {
29350b57cec5SDimitry Andric    return __increment(&__ec);
29360b57cec5SDimitry Andric  }
29370b57cec5SDimitry Andric
29380b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS directory_options options() const;
29390b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS int depth() const;
29400b57cec5SDimitry Andric
29410b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29420b57cec5SDimitry Andric  void pop() { __pop(); }
29430b57cec5SDimitry Andric
29440b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29450b57cec5SDimitry Andric  void pop(error_code& __ec) { __pop(&__ec); }
29460b57cec5SDimitry Andric
29470b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29480b57cec5SDimitry Andric  bool recursion_pending() const { return __rec_; }
29490b57cec5SDimitry Andric
29500b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
29510b57cec5SDimitry Andric  void disable_recursion_pending() { __rec_ = false; }
29520b57cec5SDimitry Andric
29530b57cec5SDimitry Andricprivate:
2954e40139ffSDimitry Andric  _LIBCPP_FUNC_VIS
29550b57cec5SDimitry Andric  recursive_directory_iterator(const path& __p, directory_options __opt,
29560b57cec5SDimitry Andric                               error_code* __ec);
29570b57cec5SDimitry Andric
29580b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
29590b57cec5SDimitry Andric  const directory_entry& __dereference() const;
29600b57cec5SDimitry Andric
29610b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
29620b57cec5SDimitry Andric  bool __try_recursion(error_code* __ec);
29630b57cec5SDimitry Andric
29640b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
29650b57cec5SDimitry Andric  void __advance(error_code* __ec = nullptr);
29660b57cec5SDimitry Andric
29670b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
29680b57cec5SDimitry Andric  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
29690b57cec5SDimitry Andric
29700b57cec5SDimitry Andric  _LIBCPP_FUNC_VIS
29710b57cec5SDimitry Andric  void __pop(error_code* __ec = nullptr);
29720b57cec5SDimitry Andric
29730b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool
29740b57cec5SDimitry Andric  operator==(const recursive_directory_iterator&,
29750b57cec5SDimitry Andric             const recursive_directory_iterator&) noexcept;
29760b57cec5SDimitry Andric
29770b57cec5SDimitry Andric  struct _LIBCPP_HIDDEN __shared_imp;
29780b57cec5SDimitry Andric  shared_ptr<__shared_imp> __imp_;
29790b57cec5SDimitry Andric  bool __rec_;
29800b57cec5SDimitry Andric}; // class recursive_directory_iterator
29810b57cec5SDimitry Andric
29820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
29830b57cec5SDimitry Andricoperator==(const recursive_directory_iterator& __lhs,
29840b57cec5SDimitry Andric           const recursive_directory_iterator& __rhs) noexcept {
29850b57cec5SDimitry Andric  return __lhs.__imp_ == __rhs.__imp_;
29860b57cec5SDimitry Andric}
29870b57cec5SDimitry Andric
29880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
29890b57cec5SDimitry Andricinline bool operator!=(const recursive_directory_iterator& __lhs,
29900b57cec5SDimitry Andric                       const recursive_directory_iterator& __rhs) noexcept {
29910b57cec5SDimitry Andric  return !(__lhs == __rhs);
29920b57cec5SDimitry Andric}
29930b57cec5SDimitry Andric// enable recursive_directory_iterator range-based for statements
29940b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
29950b57cec5SDimitry Andricbegin(recursive_directory_iterator __iter) noexcept {
29960b57cec5SDimitry Andric  return __iter;
29970b57cec5SDimitry Andric}
29980b57cec5SDimitry Andric
29990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
30000b57cec5SDimitry Andricend(const recursive_directory_iterator&) noexcept {
30010b57cec5SDimitry Andric  return recursive_directory_iterator();
30020b57cec5SDimitry Andric}
30030b57cec5SDimitry Andric
30040b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FILESYSTEM_POP
30050b57cec5SDimitry Andric
30060b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_FILESYSTEM
30070b57cec5SDimitry Andric
30080b57cec5SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
30090b57cec5SDimitry Andric
30100b57cec5SDimitry Andric_LIBCPP_POP_MACROS
30110b57cec5SDimitry Andric
30120b57cec5SDimitry Andric#endif // _LIBCPP_FILESYSTEM
3013