14ba319b5SDimitry Andric// -*- C++ -*-
24ba319b5SDimitry Andric//===--------------------------- filesystem -------------------------------===//
34ba319b5SDimitry Andric//
44ba319b5SDimitry Andric//                     The LLVM Compiler Infrastructure
54ba319b5SDimitry Andric//
64ba319b5SDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open
74ba319b5SDimitry Andric// Source Licenses. See LICENSE.TXT for details.
84ba319b5SDimitry Andric//
94ba319b5SDimitry Andric//===----------------------------------------------------------------------===//
104ba319b5SDimitry Andric#ifndef _LIBCPP_FILESYSTEM
114ba319b5SDimitry Andric#define _LIBCPP_FILESYSTEM
124ba319b5SDimitry Andric/*
134ba319b5SDimitry Andric    filesystem synopsis
144ba319b5SDimitry Andric
154ba319b5SDimitry Andric    namespace std { namespace filesystem {
164ba319b5SDimitry Andric
174ba319b5SDimitry Andric    class path;
184ba319b5SDimitry Andric
194ba319b5SDimitry Andric    void swap(path& lhs, path& rhs) noexcept;
204ba319b5SDimitry Andric    size_t hash_value(const path& p) noexcept;
214ba319b5SDimitry Andric
224ba319b5SDimitry Andric    bool operator==(const path& lhs, const path& rhs) noexcept;
234ba319b5SDimitry Andric    bool operator!=(const path& lhs, const path& rhs) noexcept;
244ba319b5SDimitry Andric    bool operator< (const path& lhs, const path& rhs) noexcept;
254ba319b5SDimitry Andric    bool operator<=(const path& lhs, const path& rhs) noexcept;
264ba319b5SDimitry Andric    bool operator> (const path& lhs, const path& rhs) noexcept;
274ba319b5SDimitry Andric    bool operator>=(const path& lhs, const path& rhs) noexcept;
284ba319b5SDimitry Andric
294ba319b5SDimitry Andric    path operator/ (const path& lhs, const path& rhs);
304ba319b5SDimitry Andric
314ba319b5SDimitry Andric    // fs.path.io operators are friends of path.
324ba319b5SDimitry Andric    template <class charT, class traits>
334ba319b5SDimitry Andric    friend basic_ostream<charT, traits>&
344ba319b5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os, const path& p);
354ba319b5SDimitry Andric
364ba319b5SDimitry Andric    template <class charT, class traits>
374ba319b5SDimitry Andric    friend basic_istream<charT, traits>&
384ba319b5SDimitry Andric    operator>>(basic_istream<charT, traits>& is, path& p);
394ba319b5SDimitry Andric
404ba319b5SDimitry Andric    template <class Source>
414ba319b5SDimitry Andric      path u8path(const Source& source);
424ba319b5SDimitry Andric    template <class InputIterator>
434ba319b5SDimitry Andric      path u8path(InputIterator first, InputIterator last);
444ba319b5SDimitry Andric
454ba319b5SDimitry Andric    class filesystem_error;
464ba319b5SDimitry Andric    class directory_entry;
474ba319b5SDimitry Andric
484ba319b5SDimitry Andric    class directory_iterator;
494ba319b5SDimitry Andric
504ba319b5SDimitry Andric    // enable directory_iterator range-based for statements
514ba319b5SDimitry Andric    directory_iterator begin(directory_iterator iter) noexcept;
524ba319b5SDimitry Andric    directory_iterator end(const directory_iterator&) noexcept;
534ba319b5SDimitry Andric
544ba319b5SDimitry Andric    class recursive_directory_iterator;
554ba319b5SDimitry Andric
564ba319b5SDimitry Andric    // enable recursive_directory_iterator range-based for statements
574ba319b5SDimitry Andric    recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
584ba319b5SDimitry Andric    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
594ba319b5SDimitry Andric
604ba319b5SDimitry Andric    class file_status;
614ba319b5SDimitry Andric
624ba319b5SDimitry Andric    struct space_info
634ba319b5SDimitry Andric    {
644ba319b5SDimitry Andric      uintmax_t capacity;
654ba319b5SDimitry Andric      uintmax_t free;
664ba319b5SDimitry Andric      uintmax_t available;
674ba319b5SDimitry Andric    };
684ba319b5SDimitry Andric
694ba319b5SDimitry Andric    enum class file_type;
704ba319b5SDimitry Andric    enum class perms;
714ba319b5SDimitry Andric    enum class perm_options;
724ba319b5SDimitry Andric    enum class copy_options;
734ba319b5SDimitry Andric    enum class directory_options;
744ba319b5SDimitry Andric
754ba319b5SDimitry Andric    typedef chrono::time_point<trivial-clock>  file_time_type;
764ba319b5SDimitry Andric
774ba319b5SDimitry Andric    // operational functions
784ba319b5SDimitry Andric
794ba319b5SDimitry Andric    path absolute(const path& p);
804ba319b5SDimitry Andric    path absolute(const path& p, error_code &ec);
814ba319b5SDimitry Andric
824ba319b5SDimitry Andric    path canonical(const path& p);
834ba319b5SDimitry Andric    path canonical(const path& p, error_code& ec);
844ba319b5SDimitry Andric
854ba319b5SDimitry Andric    void copy(const path& from, const path& to);
864ba319b5SDimitry Andric    void copy(const path& from, const path& to, error_code& ec);
874ba319b5SDimitry Andric    void copy(const path& from, const path& to, copy_options options);
884ba319b5SDimitry Andric    void copy(const path& from, const path& to, copy_options options,
894ba319b5SDimitry Andric                   error_code& ec);
904ba319b5SDimitry Andric
914ba319b5SDimitry Andric    bool copy_file(const path& from, const path& to);
924ba319b5SDimitry Andric    bool copy_file(const path& from, const path& to, error_code& ec);
934ba319b5SDimitry Andric    bool copy_file(const path& from, const path& to, copy_options option);
944ba319b5SDimitry Andric    bool copy_file(const path& from, const path& to, copy_options option,
954ba319b5SDimitry Andric                           error_code& ec);
964ba319b5SDimitry Andric
974ba319b5SDimitry Andric    void copy_symlink(const path& existing_symlink, const path& new_symlink);
984ba319b5SDimitry Andric    void copy_symlink(const path& existing_symlink, const path& new_symlink,
994ba319b5SDimitry Andric                              error_code& ec) noexcept;
1004ba319b5SDimitry Andric
1014ba319b5SDimitry Andric    bool create_directories(const path& p);
1024ba319b5SDimitry Andric    bool create_directories(const path& p, error_code& ec);
1034ba319b5SDimitry Andric
1044ba319b5SDimitry Andric    bool create_directory(const path& p);
1054ba319b5SDimitry Andric    bool create_directory(const path& p, error_code& ec) noexcept;
1064ba319b5SDimitry Andric
1074ba319b5SDimitry Andric    bool create_directory(const path& p, const path& attributes);
1084ba319b5SDimitry Andric    bool create_directory(const path& p, const path& attributes,
1094ba319b5SDimitry Andric                                  error_code& ec) noexcept;
1104ba319b5SDimitry Andric
1114ba319b5SDimitry Andric    void create_directory_symlink(const path& to, const path& new_symlink);
1124ba319b5SDimitry Andric    void create_directory_symlink(const path& to, const path& new_symlink,
1134ba319b5SDimitry Andric                                          error_code& ec) noexcept;
1144ba319b5SDimitry Andric
1154ba319b5SDimitry Andric    void create_hard_link(const path& to, const path& new_hard_link);
1164ba319b5SDimitry Andric    void create_hard_link(const path& to, const path& new_hard_link,
1174ba319b5SDimitry Andric                                  error_code& ec) noexcept;
1184ba319b5SDimitry Andric
1194ba319b5SDimitry Andric    void create_symlink(const path& to, const path& new_symlink);
1204ba319b5SDimitry Andric    void create_symlink(const path& to, const path& new_symlink,
1214ba319b5SDimitry Andric                                error_code& ec) noexcept;
1224ba319b5SDimitry Andric
1234ba319b5SDimitry Andric    path current_path();
1244ba319b5SDimitry Andric    path current_path(error_code& ec);
1254ba319b5SDimitry Andric    void current_path(const path& p);
1264ba319b5SDimitry Andric    void current_path(const path& p, error_code& ec) noexcept;
1274ba319b5SDimitry Andric
1284ba319b5SDimitry Andric    bool exists(file_status s) noexcept;
1294ba319b5SDimitry Andric    bool exists(const path& p);
1304ba319b5SDimitry Andric    bool exists(const path& p, error_code& ec) noexcept;
1314ba319b5SDimitry Andric
1324ba319b5SDimitry Andric    bool equivalent(const path& p1, const path& p2);
1334ba319b5SDimitry Andric    bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
1344ba319b5SDimitry Andric
1354ba319b5SDimitry Andric    uintmax_t    file_size(const path& p);
1364ba319b5SDimitry Andric    uintmax_t    file_size(const path& p, error_code& ec) noexcept;
1374ba319b5SDimitry Andric
1384ba319b5SDimitry Andric    uintmax_t    hard_link_count(const path& p);
1394ba319b5SDimitry Andric    uintmax_t    hard_link_count(const path& p, error_code& ec) noexcept;
1404ba319b5SDimitry Andric
1414ba319b5SDimitry Andric    bool is_block_file(file_status s) noexcept;
1424ba319b5SDimitry Andric    bool is_block_file(const path& p);
1434ba319b5SDimitry Andric    bool is_block_file(const path& p, error_code& ec) noexcept;
1444ba319b5SDimitry Andric
1454ba319b5SDimitry Andric    bool is_character_file(file_status s) noexcept;
1464ba319b5SDimitry Andric    bool is_character_file(const path& p);
1474ba319b5SDimitry Andric    bool is_character_file(const path& p, error_code& ec) noexcept;
1484ba319b5SDimitry Andric
1494ba319b5SDimitry Andric    bool is_directory(file_status s) noexcept;
1504ba319b5SDimitry Andric    bool is_directory(const path& p);
1514ba319b5SDimitry Andric    bool is_directory(const path& p, error_code& ec) noexcept;
1524ba319b5SDimitry Andric
1534ba319b5SDimitry Andric    bool is_empty(const path& p);
1544ba319b5SDimitry Andric    bool is_empty(const path& p, error_code& ec) noexcept;
1554ba319b5SDimitry Andric
1564ba319b5SDimitry Andric    bool is_fifo(file_status s) noexcept;
1574ba319b5SDimitry Andric    bool is_fifo(const path& p);
1584ba319b5SDimitry Andric    bool is_fifo(const path& p, error_code& ec) noexcept;
1594ba319b5SDimitry Andric
1604ba319b5SDimitry Andric    bool is_other(file_status s) noexcept;
1614ba319b5SDimitry Andric    bool is_other(const path& p);
1624ba319b5SDimitry Andric    bool is_other(const path& p, error_code& ec) noexcept;
1634ba319b5SDimitry Andric
1644ba319b5SDimitry Andric    bool is_regular_file(file_status s) noexcept;
1654ba319b5SDimitry Andric    bool is_regular_file(const path& p);
1664ba319b5SDimitry Andric    bool is_regular_file(const path& p, error_code& ec) noexcept;
1674ba319b5SDimitry Andric
1684ba319b5SDimitry Andric    bool is_socket(file_status s) noexcept;
1694ba319b5SDimitry Andric    bool is_socket(const path& p);
1704ba319b5SDimitry Andric    bool is_socket(const path& p, error_code& ec) noexcept;
1714ba319b5SDimitry Andric
1724ba319b5SDimitry Andric    bool is_symlink(file_status s) noexcept;
1734ba319b5SDimitry Andric    bool is_symlink(const path& p);
1744ba319b5SDimitry Andric    bool is_symlink(const path& p, error_code& ec) noexcept;
1754ba319b5SDimitry Andric
1764ba319b5SDimitry Andric    file_time_type  last_write_time(const path& p);
1774ba319b5SDimitry Andric    file_time_type  last_write_time(const path& p, error_code& ec) noexcept;
1784ba319b5SDimitry Andric    void last_write_time(const path& p, file_time_type new_time);
1794ba319b5SDimitry Andric    void last_write_time(const path& p, file_time_type new_time,
1804ba319b5SDimitry Andric                                 error_code& ec) noexcept;
1814ba319b5SDimitry Andric
1824ba319b5SDimitry Andric    void permissions(const path& p, perms prms,
1834ba319b5SDimitry Andric                     perm_options opts=perm_options::replace);
1844ba319b5SDimitry Andric    void permissions(const path& p, perms prms, error_code& ec) noexcept;
1854ba319b5SDimitry Andric    void permissions(const path& p, perms prms, perm_options opts,
1864ba319b5SDimitry Andric                     error_code& ec);
1874ba319b5SDimitry Andric
1884ba319b5SDimitry Andric    path proximate(const path& p, error_code& ec);
1894ba319b5SDimitry Andric    path proximate(const path& p, const path& base = current_path());
1904ba319b5SDimitry Andric    path proximate(const path& p, const path& base, error_code &ec);
1914ba319b5SDimitry Andric
1924ba319b5SDimitry Andric    path read_symlink(const path& p);
1934ba319b5SDimitry Andric    path read_symlink(const path& p, error_code& ec);
1944ba319b5SDimitry Andric
1954ba319b5SDimitry Andric    path relative(const path& p, error_code& ec);
1964ba319b5SDimitry Andric    path relative(const path& p, const path& base=current_path());
1974ba319b5SDimitry Andric    path relative(const path& p, const path& base, error_code& ec);
1984ba319b5SDimitry Andric
1994ba319b5SDimitry Andric    bool remove(const path& p);
2004ba319b5SDimitry Andric    bool remove(const path& p, error_code& ec) noexcept;
2014ba319b5SDimitry Andric
2024ba319b5SDimitry Andric    uintmax_t    remove_all(const path& p);
2034ba319b5SDimitry Andric    uintmax_t    remove_all(const path& p, error_code& ec);
2044ba319b5SDimitry Andric
2054ba319b5SDimitry Andric    void rename(const path& from, const path& to);
2064ba319b5SDimitry Andric    void rename(const path& from, const path& to, error_code& ec) noexcept;
2074ba319b5SDimitry Andric
2084ba319b5SDimitry Andric    void resize_file(const path& p, uintmax_t size);
2094ba319b5SDimitry Andric    void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
2104ba319b5SDimitry Andric
2114ba319b5SDimitry Andric    space_info   space(const path& p);
2124ba319b5SDimitry Andric    space_info   space(const path& p, error_code& ec) noexcept;
2134ba319b5SDimitry Andric
2144ba319b5SDimitry Andric    file_status  status(const path& p);
2154ba319b5SDimitry Andric    file_status  status(const path& p, error_code& ec) noexcept;
2164ba319b5SDimitry Andric
2174ba319b5SDimitry Andric    bool status_known(file_status s) noexcept;
2184ba319b5SDimitry Andric
2194ba319b5SDimitry Andric    file_status  symlink_status(const path& p);
2204ba319b5SDimitry Andric    file_status  symlink_status(const path& p, error_code& ec) noexcept;
2214ba319b5SDimitry Andric
2224ba319b5SDimitry Andric    path temp_directory_path();
2234ba319b5SDimitry Andric    path temp_directory_path(error_code& ec);
2244ba319b5SDimitry Andric
2254ba319b5SDimitry Andric    path weakly_canonical(path const& p);
2264ba319b5SDimitry Andric    path weakly_canonical(path const& p, error_code& ec);
2274ba319b5SDimitry Andric
2284ba319b5SDimitry Andric
2294ba319b5SDimitry Andric} }  // namespaces std::filesystem
2304ba319b5SDimitry Andric
2314ba319b5SDimitry Andric*/
2324ba319b5SDimitry Andric
2334ba319b5SDimitry Andric#include <__config>
2344ba319b5SDimitry Andric#include <cstddef>
2354ba319b5SDimitry Andric#include <cstdlib>
2364ba319b5SDimitry Andric#include <chrono>
2374ba319b5SDimitry Andric#include <iterator>
2384ba319b5SDimitry Andric#include <iosfwd>
2394ba319b5SDimitry Andric#include <locale>
2404ba319b5SDimitry Andric#include <memory>
2414ba319b5SDimitry Andric#include <stack>
2424ba319b5SDimitry Andric#include <string>
2434ba319b5SDimitry Andric#include <system_error>
2444ba319b5SDimitry Andric#include <utility>
2454ba319b5SDimitry Andric#include <iomanip> // for quoted
2464ba319b5SDimitry Andric#include <string_view>
247*b5893f02SDimitry Andric#include <version>
2484ba319b5SDimitry Andric
2494ba319b5SDimitry Andric#include <__debug>
2504ba319b5SDimitry Andric
2514ba319b5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2524ba319b5SDimitry Andric#pragma GCC system_header
2534ba319b5SDimitry Andric#endif
2544ba319b5SDimitry Andric
2554ba319b5SDimitry Andric_LIBCPP_PUSH_MACROS
2564ba319b5SDimitry Andric#include <__undef_macros>
2574ba319b5SDimitry Andric
2584ba319b5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2594ba319b5SDimitry Andric
2604ba319b5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2614ba319b5SDimitry Andric
2624ba319b5SDimitry Andrictypedef chrono::time_point<_FilesystemClock> file_time_type;
2634ba319b5SDimitry Andric
2644ba319b5SDimitry Andricstruct _LIBCPP_TYPE_VIS space_info {
2654ba319b5SDimitry Andric  uintmax_t capacity;
2664ba319b5SDimitry Andric  uintmax_t free;
2674ba319b5SDimitry Andric  uintmax_t available;
2684ba319b5SDimitry Andric};
2694ba319b5SDimitry Andric
2704ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS file_type : signed char {
2714ba319b5SDimitry Andric  none = 0,
2724ba319b5SDimitry Andric  not_found = -1,
2734ba319b5SDimitry Andric  regular = 1,
2744ba319b5SDimitry Andric  directory = 2,
2754ba319b5SDimitry Andric  symlink = 3,
2764ba319b5SDimitry Andric  block = 4,
2774ba319b5SDimitry Andric  character = 5,
2784ba319b5SDimitry Andric  fifo = 6,
2794ba319b5SDimitry Andric  socket = 7,
2804ba319b5SDimitry Andric  unknown = 8
2814ba319b5SDimitry Andric};
2824ba319b5SDimitry Andric
2834ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS perms : unsigned {
2844ba319b5SDimitry Andric  none = 0,
2854ba319b5SDimitry Andric
2864ba319b5SDimitry Andric  owner_read = 0400,
2874ba319b5SDimitry Andric  owner_write = 0200,
2884ba319b5SDimitry Andric  owner_exec = 0100,
2894ba319b5SDimitry Andric  owner_all = 0700,
2904ba319b5SDimitry Andric
2914ba319b5SDimitry Andric  group_read = 040,
2924ba319b5SDimitry Andric  group_write = 020,
2934ba319b5SDimitry Andric  group_exec = 010,
2944ba319b5SDimitry Andric  group_all = 070,
2954ba319b5SDimitry Andric
2964ba319b5SDimitry Andric  others_read = 04,
2974ba319b5SDimitry Andric  others_write = 02,
2984ba319b5SDimitry Andric  others_exec = 01,
2994ba319b5SDimitry Andric  others_all = 07,
3004ba319b5SDimitry Andric
3014ba319b5SDimitry Andric  all = 0777,
3024ba319b5SDimitry Andric
3034ba319b5SDimitry Andric  set_uid = 04000,
3044ba319b5SDimitry Andric  set_gid = 02000,
3054ba319b5SDimitry Andric  sticky_bit = 01000,
3064ba319b5SDimitry Andric  mask = 07777,
3074ba319b5SDimitry Andric  unknown = 0xFFFF,
3084ba319b5SDimitry Andric};
3094ba319b5SDimitry Andric
3104ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3114ba319b5SDimitry Andricinline constexpr perms operator&(perms _LHS, perms _RHS) {
3124ba319b5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) &
3134ba319b5SDimitry Andric                            static_cast<unsigned>(_RHS));
3144ba319b5SDimitry Andric}
3154ba319b5SDimitry Andric
3164ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3174ba319b5SDimitry Andricinline constexpr perms operator|(perms _LHS, perms _RHS) {
3184ba319b5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) |
3194ba319b5SDimitry Andric                            static_cast<unsigned>(_RHS));
3204ba319b5SDimitry Andric}
3214ba319b5SDimitry Andric
3224ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3234ba319b5SDimitry Andricinline constexpr perms operator^(perms _LHS, perms _RHS) {
3244ba319b5SDimitry Andric  return static_cast<perms>(static_cast<unsigned>(_LHS) ^
3254ba319b5SDimitry Andric                            static_cast<unsigned>(_RHS));
3264ba319b5SDimitry Andric}
3274ba319b5SDimitry Andric
3284ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3294ba319b5SDimitry Andricinline constexpr perms operator~(perms _LHS) {
3304ba319b5SDimitry Andric  return static_cast<perms>(~static_cast<unsigned>(_LHS));
3314ba319b5SDimitry Andric}
3324ba319b5SDimitry Andric
3334ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3344ba319b5SDimitry Andricinline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
3354ba319b5SDimitry Andric
3364ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3374ba319b5SDimitry Andricinline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
3384ba319b5SDimitry Andric
3394ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3404ba319b5SDimitry Andricinline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
3414ba319b5SDimitry Andric
3424ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
3434ba319b5SDimitry Andric  replace = 1,
3444ba319b5SDimitry Andric  add = 2,
3454ba319b5SDimitry Andric  remove = 4,
3464ba319b5SDimitry Andric  nofollow = 8
3474ba319b5SDimitry Andric};
3484ba319b5SDimitry Andric
3494ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3504ba319b5SDimitry Andricinline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
3514ba319b5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
3524ba319b5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3534ba319b5SDimitry Andric}
3544ba319b5SDimitry Andric
3554ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3564ba319b5SDimitry Andricinline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
3574ba319b5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
3584ba319b5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3594ba319b5SDimitry Andric}
3604ba319b5SDimitry Andric
3614ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3624ba319b5SDimitry Andricinline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
3634ba319b5SDimitry Andric  return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
3644ba319b5SDimitry Andric                                   static_cast<unsigned>(_RHS));
3654ba319b5SDimitry Andric}
3664ba319b5SDimitry Andric
3674ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3684ba319b5SDimitry Andricinline constexpr perm_options operator~(perm_options _LHS) {
3694ba319b5SDimitry Andric  return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
3704ba319b5SDimitry Andric}
3714ba319b5SDimitry Andric
3724ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3734ba319b5SDimitry Andricinline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
3744ba319b5SDimitry Andric  return _LHS = _LHS & _RHS;
3754ba319b5SDimitry Andric}
3764ba319b5SDimitry Andric
3774ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3784ba319b5SDimitry Andricinline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
3794ba319b5SDimitry Andric  return _LHS = _LHS | _RHS;
3804ba319b5SDimitry Andric}
3814ba319b5SDimitry Andric
3824ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
3834ba319b5SDimitry Andricinline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
3844ba319b5SDimitry Andric  return _LHS = _LHS ^ _RHS;
3854ba319b5SDimitry Andric}
3864ba319b5SDimitry Andric
3874ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
3884ba319b5SDimitry Andric  none = 0,
3894ba319b5SDimitry Andric  skip_existing = 1,
3904ba319b5SDimitry Andric  overwrite_existing = 2,
3914ba319b5SDimitry Andric  update_existing = 4,
3924ba319b5SDimitry Andric  recursive = 8,
3934ba319b5SDimitry Andric  copy_symlinks = 16,
3944ba319b5SDimitry Andric  skip_symlinks = 32,
3954ba319b5SDimitry Andric  directories_only = 64,
3964ba319b5SDimitry Andric  create_symlinks = 128,
3974ba319b5SDimitry Andric  create_hard_links = 256,
3984ba319b5SDimitry Andric  __in_recursive_copy = 512,
3994ba319b5SDimitry Andric};
4004ba319b5SDimitry Andric
4014ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4024ba319b5SDimitry Andricinline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
4034ba319b5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
4044ba319b5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4054ba319b5SDimitry Andric}
4064ba319b5SDimitry Andric
4074ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4084ba319b5SDimitry Andricinline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
4094ba319b5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
4104ba319b5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4114ba319b5SDimitry Andric}
4124ba319b5SDimitry Andric
4134ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4144ba319b5SDimitry Andricinline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
4154ba319b5SDimitry Andric  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
4164ba319b5SDimitry Andric                                   static_cast<unsigned short>(_RHS));
4174ba319b5SDimitry Andric}
4184ba319b5SDimitry Andric
4194ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4204ba319b5SDimitry Andricinline constexpr copy_options operator~(copy_options _LHS) {
4214ba319b5SDimitry Andric  return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
4224ba319b5SDimitry Andric}
4234ba319b5SDimitry Andric
4244ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4254ba319b5SDimitry Andricinline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
4264ba319b5SDimitry Andric  return _LHS = _LHS & _RHS;
4274ba319b5SDimitry Andric}
4284ba319b5SDimitry Andric
4294ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4304ba319b5SDimitry Andricinline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
4314ba319b5SDimitry Andric  return _LHS = _LHS | _RHS;
4324ba319b5SDimitry Andric}
4334ba319b5SDimitry Andric
4344ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4354ba319b5SDimitry Andricinline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
4364ba319b5SDimitry Andric  return _LHS = _LHS ^ _RHS;
4374ba319b5SDimitry Andric}
4384ba319b5SDimitry Andric
4394ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
4404ba319b5SDimitry Andric  none = 0,
4414ba319b5SDimitry Andric  follow_directory_symlink = 1,
4424ba319b5SDimitry Andric  skip_permission_denied = 2
4434ba319b5SDimitry Andric};
4444ba319b5SDimitry Andric
4454ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4464ba319b5SDimitry Andricinline constexpr directory_options operator&(directory_options _LHS,
4474ba319b5SDimitry Andric                                             directory_options _RHS) {
4484ba319b5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
4494ba319b5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4504ba319b5SDimitry Andric}
4514ba319b5SDimitry Andric
4524ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4534ba319b5SDimitry Andricinline constexpr directory_options operator|(directory_options _LHS,
4544ba319b5SDimitry Andric                                             directory_options _RHS) {
4554ba319b5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
4564ba319b5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4574ba319b5SDimitry Andric}
4584ba319b5SDimitry Andric
4594ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4604ba319b5SDimitry Andricinline constexpr directory_options operator^(directory_options _LHS,
4614ba319b5SDimitry Andric                                             directory_options _RHS) {
4624ba319b5SDimitry Andric  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
4634ba319b5SDimitry Andric                                        static_cast<unsigned char>(_RHS));
4644ba319b5SDimitry Andric}
4654ba319b5SDimitry Andric
4664ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4674ba319b5SDimitry Andricinline constexpr directory_options operator~(directory_options _LHS) {
4684ba319b5SDimitry Andric  return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
4694ba319b5SDimitry Andric}
4704ba319b5SDimitry Andric
4714ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4724ba319b5SDimitry Andricinline directory_options& operator&=(directory_options& _LHS,
4734ba319b5SDimitry Andric                                     directory_options _RHS) {
4744ba319b5SDimitry Andric  return _LHS = _LHS & _RHS;
4754ba319b5SDimitry Andric}
4764ba319b5SDimitry Andric
4774ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4784ba319b5SDimitry Andricinline directory_options& operator|=(directory_options& _LHS,
4794ba319b5SDimitry Andric                                     directory_options _RHS) {
4804ba319b5SDimitry Andric  return _LHS = _LHS | _RHS;
4814ba319b5SDimitry Andric}
4824ba319b5SDimitry Andric
4834ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
4844ba319b5SDimitry Andricinline directory_options& operator^=(directory_options& _LHS,
4854ba319b5SDimitry Andric                                     directory_options _RHS) {
4864ba319b5SDimitry Andric  return _LHS = _LHS ^ _RHS;
4874ba319b5SDimitry Andric}
4884ba319b5SDimitry Andric
4894ba319b5SDimitry Andricclass _LIBCPP_TYPE_VIS file_status {
4904ba319b5SDimitry Andricpublic:
4914ba319b5SDimitry Andric  // constructors
4924ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
4934ba319b5SDimitry Andric  file_status() noexcept : file_status(file_type::none) {}
4944ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
4954ba319b5SDimitry Andric  explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
4964ba319b5SDimitry Andric      : __ft_(__ft),
4974ba319b5SDimitry Andric        __prms_(__prms) {}
4984ba319b5SDimitry Andric
4994ba319b5SDimitry Andric  file_status(const file_status&) noexcept = default;
5004ba319b5SDimitry Andric  file_status(file_status&&) noexcept = default;
5014ba319b5SDimitry Andric
5024ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5034ba319b5SDimitry Andric  ~file_status() {}
5044ba319b5SDimitry Andric
5054ba319b5SDimitry Andric  file_status& operator=(const file_status&) noexcept = default;
5064ba319b5SDimitry Andric  file_status& operator=(file_status&&) noexcept = default;
5074ba319b5SDimitry Andric
5084ba319b5SDimitry Andric  // observers
5094ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5104ba319b5SDimitry Andric  file_type type() const noexcept { return __ft_; }
5114ba319b5SDimitry Andric
5124ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5134ba319b5SDimitry Andric  perms permissions() const noexcept { return __prms_; }
5144ba319b5SDimitry Andric
5154ba319b5SDimitry Andric  // modifiers
5164ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5174ba319b5SDimitry Andric  void type(file_type __ft) noexcept { __ft_ = __ft; }
5184ba319b5SDimitry Andric
5194ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
5204ba319b5SDimitry Andric  void permissions(perms __p) noexcept { __prms_ = __p; }
5214ba319b5SDimitry Andric
5224ba319b5SDimitry Andricprivate:
5234ba319b5SDimitry Andric  file_type __ft_;
5244ba319b5SDimitry Andric  perms __prms_;
5254ba319b5SDimitry Andric};
5264ba319b5SDimitry Andric
5274ba319b5SDimitry Andricclass _LIBCPP_TYPE_VIS directory_entry;
5284ba319b5SDimitry Andric
5294ba319b5SDimitry Andrictemplate <class _Tp>
5304ba319b5SDimitry Andricstruct __can_convert_char {
5314ba319b5SDimitry Andric  static const bool value = false;
5324ba319b5SDimitry Andric};
5334ba319b5SDimitry Andrictemplate <class _Tp>
5344ba319b5SDimitry Andricstruct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
5354ba319b5SDimitry Andrictemplate <>
5364ba319b5SDimitry Andricstruct __can_convert_char<char> {
5374ba319b5SDimitry Andric  static const bool value = true;
5384ba319b5SDimitry Andric  using __char_type = char;
5394ba319b5SDimitry Andric};
5404ba319b5SDimitry Andrictemplate <>
5414ba319b5SDimitry Andricstruct __can_convert_char<wchar_t> {
5424ba319b5SDimitry Andric  static const bool value = true;
5434ba319b5SDimitry Andric  using __char_type = wchar_t;
5444ba319b5SDimitry Andric};
5454ba319b5SDimitry Andrictemplate <>
5464ba319b5SDimitry Andricstruct __can_convert_char<char16_t> {
5474ba319b5SDimitry Andric  static const bool value = true;
5484ba319b5SDimitry Andric  using __char_type = char16_t;
5494ba319b5SDimitry Andric};
5504ba319b5SDimitry Andrictemplate <>
5514ba319b5SDimitry Andricstruct __can_convert_char<char32_t> {
5524ba319b5SDimitry Andric  static const bool value = true;
5534ba319b5SDimitry Andric  using __char_type = char32_t;
5544ba319b5SDimitry Andric};
5554ba319b5SDimitry Andric
5564ba319b5SDimitry Andrictemplate <class _ECharT>
5574ba319b5SDimitry Andrictypename enable_if<__can_convert_char<_ECharT>::value, bool>::type
5584ba319b5SDimitry Andric__is_separator(_ECharT __e) {
5594ba319b5SDimitry Andric  return __e == _ECharT('/');
560*b5893f02SDimitry Andric}
5614ba319b5SDimitry Andric
5624ba319b5SDimitry Andricstruct _NullSentinal {};
5634ba319b5SDimitry Andric
5644ba319b5SDimitry Andrictemplate <class _Tp>
5654ba319b5SDimitry Andricusing _Void = void;
5664ba319b5SDimitry Andric
5674ba319b5SDimitry Andrictemplate <class _Tp, class = void>
5684ba319b5SDimitry Andricstruct __is_pathable_string : public false_type {};
5694ba319b5SDimitry Andric
5704ba319b5SDimitry Andrictemplate <class _ECharT, class _Traits, class _Alloc>
5714ba319b5SDimitry Andricstruct __is_pathable_string<
5724ba319b5SDimitry Andric    basic_string<_ECharT, _Traits, _Alloc>,
5734ba319b5SDimitry Andric    _Void<typename __can_convert_char<_ECharT>::__char_type> >
5744ba319b5SDimitry Andric    : public __can_convert_char<_ECharT> {
5754ba319b5SDimitry Andric  using _Str = basic_string<_ECharT, _Traits, _Alloc>;
5764ba319b5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
5774ba319b5SDimitry Andric  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
5784ba319b5SDimitry Andric  static _ECharT const* __range_end(_Str const& __s) {
5794ba319b5SDimitry Andric    return __s.data() + __s.length();
5804ba319b5SDimitry Andric  }
5814ba319b5SDimitry Andric  static _ECharT __first_or_null(_Str const& __s) {
5824ba319b5SDimitry Andric    return __s.empty() ? _ECharT{} : __s[0];
5834ba319b5SDimitry Andric  }
5844ba319b5SDimitry Andric};
5854ba319b5SDimitry Andric
5864ba319b5SDimitry Andrictemplate <class _ECharT, class _Traits>
5874ba319b5SDimitry Andricstruct __is_pathable_string<
5884ba319b5SDimitry Andric    basic_string_view<_ECharT, _Traits>,
5894ba319b5SDimitry Andric    _Void<typename __can_convert_char<_ECharT>::__char_type> >
5904ba319b5SDimitry Andric    : public __can_convert_char<_ECharT> {
5914ba319b5SDimitry Andric  using _Str = basic_string_view<_ECharT, _Traits>;
5924ba319b5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
5934ba319b5SDimitry Andric  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
5944ba319b5SDimitry Andric  static _ECharT const* __range_end(_Str const& __s) {
5954ba319b5SDimitry Andric    return __s.data() + __s.length();
5964ba319b5SDimitry Andric  }
5974ba319b5SDimitry Andric  static _ECharT __first_or_null(_Str const& __s) {
5984ba319b5SDimitry Andric    return __s.empty() ? _ECharT{} : __s[0];
5994ba319b5SDimitry Andric  }
6004ba319b5SDimitry Andric};
6014ba319b5SDimitry Andric
6024ba319b5SDimitry Andrictemplate <class _Source, class _DS = typename decay<_Source>::type,
6034ba319b5SDimitry Andric          class _UnqualPtrType =
6044ba319b5SDimitry Andric              typename remove_const<typename remove_pointer<_DS>::type>::type,
6054ba319b5SDimitry Andric          bool _IsCharPtr = is_pointer<_DS>::value&&
6064ba319b5SDimitry Andric              __can_convert_char<_UnqualPtrType>::value>
6074ba319b5SDimitry Andricstruct __is_pathable_char_array : false_type {};
6084ba319b5SDimitry Andric
6094ba319b5SDimitry Andrictemplate <class _Source, class _ECharT, class _UPtr>
6104ba319b5SDimitry Andricstruct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
6114ba319b5SDimitry Andric    : __can_convert_char<typename remove_const<_ECharT>::type> {
6124ba319b5SDimitry Andric  using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
6134ba319b5SDimitry Andric
6144ba319b5SDimitry Andric  static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
6154ba319b5SDimitry Andric  static _ECharT const* __range_end(const _ECharT* __b) {
6164ba319b5SDimitry Andric    using _Iter = const _ECharT*;
6174ba319b5SDimitry Andric    const _ECharT __sentinal = _ECharT{};
6184ba319b5SDimitry Andric    _Iter __e = __b;
6194ba319b5SDimitry Andric    for (; *__e != __sentinal; ++__e)
6204ba319b5SDimitry Andric      ;
6214ba319b5SDimitry Andric    return __e;
6224ba319b5SDimitry Andric  }
6234ba319b5SDimitry Andric
6244ba319b5SDimitry Andric  static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
6254ba319b5SDimitry Andric};
6264ba319b5SDimitry Andric
6274ba319b5SDimitry Andrictemplate <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value,
6284ba319b5SDimitry Andric          class = void>
6294ba319b5SDimitry Andricstruct __is_pathable_iter : false_type {};
6304ba319b5SDimitry Andric
6314ba319b5SDimitry Andrictemplate <class _Iter>
6324ba319b5SDimitry Andricstruct __is_pathable_iter<
6334ba319b5SDimitry Andric    _Iter, true,
6344ba319b5SDimitry Andric    _Void<typename __can_convert_char<
6354ba319b5SDimitry Andric        typename iterator_traits<_Iter>::value_type>::__char_type> >
6364ba319b5SDimitry Andric    : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
6374ba319b5SDimitry Andric  using _ECharT = typename iterator_traits<_Iter>::value_type;
6384ba319b5SDimitry Andric  using _Base = __can_convert_char<_ECharT>;
6394ba319b5SDimitry Andric
6404ba319b5SDimitry Andric  static _Iter __range_begin(_Iter __b) { return __b; }
6414ba319b5SDimitry Andric  static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
6424ba319b5SDimitry Andric
6434ba319b5SDimitry Andric  static _ECharT __first_or_null(_Iter __b) { return *__b; }
6444ba319b5SDimitry Andric};
6454ba319b5SDimitry Andric
6464ba319b5SDimitry Andrictemplate <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
6474ba319b5SDimitry Andric          bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
6484ba319b5SDimitry Andric          bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
6494ba319b5SDimitry Andricstruct __is_pathable : false_type {
6504ba319b5SDimitry Andric  static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
6514ba319b5SDimitry Andric};
6524ba319b5SDimitry Andric
6534ba319b5SDimitry Andrictemplate <class _Tp>
6544ba319b5SDimitry Andricstruct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
6554ba319b5SDimitry Andric
6564ba319b5SDimitry Andrictemplate <class _Tp>
6574ba319b5SDimitry Andricstruct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
6584ba319b5SDimitry Andric};
6594ba319b5SDimitry Andric
6604ba319b5SDimitry Andrictemplate <class _Tp>
6614ba319b5SDimitry Andricstruct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
6624ba319b5SDimitry Andric
6634ba319b5SDimitry Andrictemplate <class _ECharT>
6644ba319b5SDimitry Andricstruct _PathCVT {
6654ba319b5SDimitry Andric  static_assert(__can_convert_char<_ECharT>::value,
6664ba319b5SDimitry Andric                "Char type not convertible");
6674ba319b5SDimitry Andric
6684ba319b5SDimitry Andric  typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
6694ba319b5SDimitry Andric
6704ba319b5SDimitry Andric  static void __append_range(string& __dest, _ECharT const* __b,
6714ba319b5SDimitry Andric                             _ECharT const* __e) {
6724ba319b5SDimitry Andric    _Narrower()(back_inserter(__dest), __b, __e);
6734ba319b5SDimitry Andric  }
6744ba319b5SDimitry Andric
6754ba319b5SDimitry Andric  template <class _Iter>
6764ba319b5SDimitry Andric  static void __append_range(string& __dest, _Iter __b, _Iter __e) {
6774ba319b5SDimitry Andric    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
6784ba319b5SDimitry Andric    if (__b == __e)
6794ba319b5SDimitry Andric      return;
6804ba319b5SDimitry Andric    basic_string<_ECharT> __tmp(__b, __e);
6814ba319b5SDimitry Andric    _Narrower()(back_inserter(__dest), __tmp.data(),
6824ba319b5SDimitry Andric                __tmp.data() + __tmp.length());
6834ba319b5SDimitry Andric  }
6844ba319b5SDimitry Andric
6854ba319b5SDimitry Andric  template <class _Iter>
6864ba319b5SDimitry Andric  static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
6874ba319b5SDimitry Andric    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
6884ba319b5SDimitry Andric    const _ECharT __sentinal = _ECharT{};
6894ba319b5SDimitry Andric    if (*__b == __sentinal)
6904ba319b5SDimitry Andric      return;
6914ba319b5SDimitry Andric    basic_string<_ECharT> __tmp;
6924ba319b5SDimitry Andric    for (; *__b != __sentinal; ++__b)
6934ba319b5SDimitry Andric      __tmp.push_back(*__b);
6944ba319b5SDimitry Andric    _Narrower()(back_inserter(__dest), __tmp.data(),
6954ba319b5SDimitry Andric                __tmp.data() + __tmp.length());
6964ba319b5SDimitry Andric  }
6974ba319b5SDimitry Andric
6984ba319b5SDimitry Andric  template <class _Source>
6994ba319b5SDimitry Andric  static void __append_source(string& __dest, _Source const& __s) {
7004ba319b5SDimitry Andric    using _Traits = __is_pathable<_Source>;
7014ba319b5SDimitry Andric    __append_range(__dest, _Traits::__range_begin(__s),
7024ba319b5SDimitry Andric                   _Traits::__range_end(__s));
7034ba319b5SDimitry Andric  }
7044ba319b5SDimitry Andric};
7054ba319b5SDimitry Andric
7064ba319b5SDimitry Andrictemplate <>
7074ba319b5SDimitry Andricstruct _PathCVT<char> {
7084ba319b5SDimitry Andric
7094ba319b5SDimitry Andric  template <class _Iter>
7104ba319b5SDimitry Andric  static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type
7114ba319b5SDimitry Andric  __append_range(string& __dest, _Iter __b, _Iter __e) {
7124ba319b5SDimitry Andric    for (; __b != __e; ++__b)
7134ba319b5SDimitry Andric      __dest.push_back(*__b);
7144ba319b5SDimitry Andric  }
7154ba319b5SDimitry Andric
7164ba319b5SDimitry Andric  template <class _Iter>
7174ba319b5SDimitry Andric  static typename enable_if<__is_forward_iterator<_Iter>::value>::type
7184ba319b5SDimitry Andric  __append_range(string& __dest, _Iter __b, _Iter __e) {
7194ba319b5SDimitry Andric    __dest.__append_forward_unsafe(__b, __e);
7204ba319b5SDimitry Andric  }
7214ba319b5SDimitry Andric
7224ba319b5SDimitry Andric  template <class _Iter>
7234ba319b5SDimitry Andric  static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
7244ba319b5SDimitry Andric    const char __sentinal = char{};
7254ba319b5SDimitry Andric    for (; *__b != __sentinal; ++__b)
7264ba319b5SDimitry Andric      __dest.push_back(*__b);
7274ba319b5SDimitry Andric  }
7284ba319b5SDimitry Andric
7294ba319b5SDimitry Andric  template <class _Source>
7304ba319b5SDimitry Andric  static void __append_source(string& __dest, _Source const& __s) {
7314ba319b5SDimitry Andric    using _Traits = __is_pathable<_Source>;
7324ba319b5SDimitry Andric    __append_range(__dest, _Traits::__range_begin(__s),
7334ba319b5SDimitry Andric                   _Traits::__range_end(__s));
7344ba319b5SDimitry Andric  }
7354ba319b5SDimitry Andric};
7364ba319b5SDimitry Andric
7374ba319b5SDimitry Andricclass _LIBCPP_TYPE_VIS path {
7384ba319b5SDimitry Andric  template <class _SourceOrIter, class _Tp = path&>
7394ba319b5SDimitry Andric  using _EnableIfPathable =
7404ba319b5SDimitry Andric      typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
7414ba319b5SDimitry Andric
7424ba319b5SDimitry Andric  template <class _Tp>
7434ba319b5SDimitry Andric  using _SourceChar = typename __is_pathable<_Tp>::__char_type;
7444ba319b5SDimitry Andric
7454ba319b5SDimitry Andric  template <class _Tp>
7464ba319b5SDimitry Andric  using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
7474ba319b5SDimitry Andric
7484ba319b5SDimitry Andricpublic:
7494ba319b5SDimitry Andric  typedef char value_type;
7504ba319b5SDimitry Andric  typedef basic_string<value_type> string_type;
7514ba319b5SDimitry Andric  typedef _VSTD::string_view __string_view;
7524ba319b5SDimitry Andric  static constexpr value_type preferred_separator = '/';
7534ba319b5SDimitry Andric
7544ba319b5SDimitry Andric  enum class _LIBCPP_ENUM_VIS format : unsigned char {
7554ba319b5SDimitry Andric    auto_format,
7564ba319b5SDimitry Andric    native_format,
7574ba319b5SDimitry Andric    generic_format
7584ba319b5SDimitry Andric  };
7594ba319b5SDimitry Andric
7604ba319b5SDimitry Andric  // constructors and destructor
7614ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path() noexcept {}
7624ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
7634ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
7644ba319b5SDimitry Andric      : __pn_(_VSTD::move(__p.__pn_)) {}
7654ba319b5SDimitry Andric
7664ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
7674ba319b5SDimitry Andric  path(string_type&& __s, format = format::auto_format) noexcept
7684ba319b5SDimitry Andric      : __pn_(_VSTD::move(__s)) {}
7694ba319b5SDimitry Andric
7704ba319b5SDimitry Andric  template <class _Source, class = _EnableIfPathable<_Source, void> >
7714ba319b5SDimitry Andric  path(const _Source& __src, format = format::auto_format) {
7724ba319b5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __src);
7734ba319b5SDimitry Andric  }
7744ba319b5SDimitry Andric
7754ba319b5SDimitry Andric  template <class _InputIt>
7764ba319b5SDimitry Andric  path(_InputIt __first, _InputIt __last, format = format::auto_format) {
7774ba319b5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
7784ba319b5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
7794ba319b5SDimitry Andric  }
7804ba319b5SDimitry Andric
7814ba319b5SDimitry Andric  // TODO Implement locale conversions.
7824ba319b5SDimitry Andric  template <class _Source, class = _EnableIfPathable<_Source, void> >
7834ba319b5SDimitry Andric  path(const _Source& __src, const locale& __loc, format = format::auto_format);
7844ba319b5SDimitry Andric  template <class _InputIt>
7854ba319b5SDimitry Andric  path(_InputIt __first, _InputIt _last, const locale& __loc,
7864ba319b5SDimitry Andric       format = format::auto_format);
7874ba319b5SDimitry Andric
7884ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
7894ba319b5SDimitry Andric  ~path() = default;
7904ba319b5SDimitry Andric
7914ba319b5SDimitry Andric  // assignments
7924ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
7934ba319b5SDimitry Andric  path& operator=(const path& __p) {
7944ba319b5SDimitry Andric    __pn_ = __p.__pn_;
7954ba319b5SDimitry Andric    return *this;
7964ba319b5SDimitry Andric  }
7974ba319b5SDimitry Andric
7984ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
7994ba319b5SDimitry Andric  path& operator=(path&& __p) noexcept {
8004ba319b5SDimitry Andric    __pn_ = _VSTD::move(__p.__pn_);
8014ba319b5SDimitry Andric    return *this;
8024ba319b5SDimitry Andric  }
8034ba319b5SDimitry Andric
8044ba319b5SDimitry Andric  template <class = void>
8054ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
8064ba319b5SDimitry Andric    __pn_ = _VSTD::move(__s);
8074ba319b5SDimitry Andric    return *this;
8084ba319b5SDimitry Andric  }
8094ba319b5SDimitry Andric
8104ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
8114ba319b5SDimitry Andric  path& assign(string_type&& __s) noexcept {
8124ba319b5SDimitry Andric    __pn_ = _VSTD::move(__s);
8134ba319b5SDimitry Andric    return *this;
8144ba319b5SDimitry Andric  }
8154ba319b5SDimitry Andric
8164ba319b5SDimitry Andric  template <class _Source>
8174ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
8184ba319b5SDimitry Andric  operator=(const _Source& __src) {
8194ba319b5SDimitry Andric    return this->assign(__src);
8204ba319b5SDimitry Andric  }
8214ba319b5SDimitry Andric
8224ba319b5SDimitry Andric  template <class _Source>
8234ba319b5SDimitry Andric  _EnableIfPathable<_Source> assign(const _Source& __src) {
8244ba319b5SDimitry Andric    __pn_.clear();
8254ba319b5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __src);
8264ba319b5SDimitry Andric    return *this;
8274ba319b5SDimitry Andric  }
8284ba319b5SDimitry Andric
8294ba319b5SDimitry Andric  template <class _InputIt>
8304ba319b5SDimitry Andric  path& assign(_InputIt __first, _InputIt __last) {
8314ba319b5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
8324ba319b5SDimitry Andric    __pn_.clear();
8334ba319b5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
8344ba319b5SDimitry Andric    return *this;
8354ba319b5SDimitry Andric  }
8364ba319b5SDimitry Andric
8374ba319b5SDimitry Andricprivate:
8384ba319b5SDimitry Andric  template <class _ECharT>
8394ba319b5SDimitry Andric  static bool __source_is_absolute(_ECharT __first_or_null) {
8404ba319b5SDimitry Andric    return __is_separator(__first_or_null);
8414ba319b5SDimitry Andric  }
8424ba319b5SDimitry Andric
8434ba319b5SDimitry Andricpublic:
8444ba319b5SDimitry Andric  // appends
8454ba319b5SDimitry Andric  path& operator/=(const path& __p) {
8464ba319b5SDimitry Andric    if (__p.is_absolute()) {
8474ba319b5SDimitry Andric      __pn_ = __p.__pn_;
8484ba319b5SDimitry Andric      return *this;
8494ba319b5SDimitry Andric    }
8504ba319b5SDimitry Andric    if (has_filename())
8514ba319b5SDimitry Andric      __pn_ += preferred_separator;
8524ba319b5SDimitry Andric    __pn_ += __p.native();
8534ba319b5SDimitry Andric    return *this;
8544ba319b5SDimitry Andric  }
8554ba319b5SDimitry Andric
8564ba319b5SDimitry Andric  // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
8574ba319b5SDimitry Andric  // is known at compile time to be "/' since the user almost certainly intended
8584ba319b5SDimitry Andric  // to append a separator instead of overwriting the path with "/"
8594ba319b5SDimitry Andric  template <class _Source>
8604ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
8614ba319b5SDimitry Andric  operator/=(const _Source& __src) {
8624ba319b5SDimitry Andric    return this->append(__src);
8634ba319b5SDimitry Andric  }
8644ba319b5SDimitry Andric
8654ba319b5SDimitry Andric  template <class _Source>
8664ba319b5SDimitry Andric  _EnableIfPathable<_Source> append(const _Source& __src) {
8674ba319b5SDimitry Andric    using _Traits = __is_pathable<_Source>;
8684ba319b5SDimitry Andric    using _CVT = _PathCVT<_SourceChar<_Source> >;
8694ba319b5SDimitry Andric    if (__source_is_absolute(_Traits::__first_or_null(__src)))
8704ba319b5SDimitry Andric      __pn_.clear();
8714ba319b5SDimitry Andric    else if (has_filename())
8724ba319b5SDimitry Andric      __pn_ += preferred_separator;
8734ba319b5SDimitry Andric    _CVT::__append_source(__pn_, __src);
8744ba319b5SDimitry Andric    return *this;
8754ba319b5SDimitry Andric  }
8764ba319b5SDimitry Andric
8774ba319b5SDimitry Andric  template <class _InputIt>
8784ba319b5SDimitry Andric  path& append(_InputIt __first, _InputIt __last) {
8794ba319b5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
8804ba319b5SDimitry Andric    static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
8814ba319b5SDimitry Andric    using _CVT = _PathCVT<_ItVal>;
8824ba319b5SDimitry Andric    if (__first != __last && __source_is_absolute(*__first))
8834ba319b5SDimitry Andric      __pn_.clear();
8844ba319b5SDimitry Andric    else if (has_filename())
8854ba319b5SDimitry Andric      __pn_ += preferred_separator;
8864ba319b5SDimitry Andric    _CVT::__append_range(__pn_, __first, __last);
8874ba319b5SDimitry Andric    return *this;
8884ba319b5SDimitry Andric  }
8894ba319b5SDimitry Andric
8904ba319b5SDimitry Andric  // concatenation
8914ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
8924ba319b5SDimitry Andric  path& operator+=(const path& __x) {
8934ba319b5SDimitry Andric    __pn_ += __x.__pn_;
8944ba319b5SDimitry Andric    return *this;
8954ba319b5SDimitry Andric  }
8964ba319b5SDimitry Andric
8974ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
8984ba319b5SDimitry Andric  path& operator+=(const string_type& __x) {
8994ba319b5SDimitry Andric    __pn_ += __x;
9004ba319b5SDimitry Andric    return *this;
9014ba319b5SDimitry Andric  }
9024ba319b5SDimitry Andric
9034ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9044ba319b5SDimitry Andric  path& operator+=(__string_view __x) {
9054ba319b5SDimitry Andric    __pn_ += __x;
9064ba319b5SDimitry Andric    return *this;
9074ba319b5SDimitry Andric  }
9084ba319b5SDimitry Andric
9094ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9104ba319b5SDimitry Andric  path& operator+=(const value_type* __x) {
9114ba319b5SDimitry Andric    __pn_ += __x;
9124ba319b5SDimitry Andric    return *this;
9134ba319b5SDimitry Andric  }
9144ba319b5SDimitry Andric
9154ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9164ba319b5SDimitry Andric  path& operator+=(value_type __x) {
9174ba319b5SDimitry Andric    __pn_ += __x;
9184ba319b5SDimitry Andric    return *this;
9194ba319b5SDimitry Andric  }
9204ba319b5SDimitry Andric
9214ba319b5SDimitry Andric  template <class _ECharT>
9224ba319b5SDimitry Andric  typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
9234ba319b5SDimitry Andric  operator+=(_ECharT __x) {
9244ba319b5SDimitry Andric    basic_string<_ECharT> __tmp;
9254ba319b5SDimitry Andric    __tmp += __x;
9264ba319b5SDimitry Andric    _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
9274ba319b5SDimitry Andric    return *this;
9284ba319b5SDimitry Andric  }
9294ba319b5SDimitry Andric
9304ba319b5SDimitry Andric  template <class _Source>
9314ba319b5SDimitry Andric  _EnableIfPathable<_Source> operator+=(const _Source& __x) {
9324ba319b5SDimitry Andric    return this->concat(__x);
9334ba319b5SDimitry Andric  }
9344ba319b5SDimitry Andric
9354ba319b5SDimitry Andric  template <class _Source>
9364ba319b5SDimitry Andric  _EnableIfPathable<_Source> concat(const _Source& __x) {
9374ba319b5SDimitry Andric    _SourceCVT<_Source>::__append_source(__pn_, __x);
9384ba319b5SDimitry Andric    return *this;
9394ba319b5SDimitry Andric  }
9404ba319b5SDimitry Andric
9414ba319b5SDimitry Andric  template <class _InputIt>
9424ba319b5SDimitry Andric  path& concat(_InputIt __first, _InputIt __last) {
9434ba319b5SDimitry Andric    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
9444ba319b5SDimitry Andric    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
9454ba319b5SDimitry Andric    return *this;
9464ba319b5SDimitry Andric  }
9474ba319b5SDimitry Andric
9484ba319b5SDimitry Andric  // modifiers
9494ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9504ba319b5SDimitry Andric  void clear() noexcept { __pn_.clear(); }
9514ba319b5SDimitry Andric
9524ba319b5SDimitry Andric  path& make_preferred() { return *this; }
9534ba319b5SDimitry Andric
9544ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9554ba319b5SDimitry Andric  path& remove_filename() {
9564ba319b5SDimitry Andric    auto __fname = __filename();
9574ba319b5SDimitry Andric    if (!__fname.empty())
9584ba319b5SDimitry Andric      __pn_.erase(__fname.data() - __pn_.data());
9594ba319b5SDimitry Andric    return *this;
9604ba319b5SDimitry Andric  }
9614ba319b5SDimitry Andric
9624ba319b5SDimitry Andric  path& replace_filename(const path& __replacement) {
9634ba319b5SDimitry Andric    remove_filename();
9644ba319b5SDimitry Andric    return (*this /= __replacement);
9654ba319b5SDimitry Andric  }
9664ba319b5SDimitry Andric
9674ba319b5SDimitry Andric  path& replace_extension(const path& __replacement = path());
9684ba319b5SDimitry Andric
9694ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9704ba319b5SDimitry Andric  void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
9714ba319b5SDimitry Andric
9724ba319b5SDimitry Andric  // private helper to allow reserving memory in the path
9734ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9744ba319b5SDimitry Andric  void __reserve(size_t __s) { __pn_.reserve(__s); }
9754ba319b5SDimitry Andric
9764ba319b5SDimitry Andric  // native format observers
9774ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9784ba319b5SDimitry Andric  const string_type& native() const noexcept { return __pn_; }
9794ba319b5SDimitry Andric
9804ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9814ba319b5SDimitry Andric  const value_type* c_str() const noexcept { return __pn_.c_str(); }
9824ba319b5SDimitry Andric
9834ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
9844ba319b5SDimitry Andric
9854ba319b5SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
9864ba319b5SDimitry Andric            class _Allocator = allocator<_ECharT> >
9874ba319b5SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
9884ba319b5SDimitry Andric  string(const _Allocator& __a = _Allocator()) const {
9894ba319b5SDimitry Andric    using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
9904ba319b5SDimitry Andric    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
9914ba319b5SDimitry Andric    _Str __s(__a);
9924ba319b5SDimitry Andric    __s.reserve(__pn_.size());
9934ba319b5SDimitry Andric    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
9944ba319b5SDimitry Andric    return __s;
9954ba319b5SDimitry Andric  }
9964ba319b5SDimitry Andric
9974ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
9984ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const {
9994ba319b5SDimitry Andric    return string<wchar_t>();
10004ba319b5SDimitry Andric  }
10014ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
10024ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const {
10034ba319b5SDimitry Andric    return string<char16_t>();
10044ba319b5SDimitry Andric  }
10054ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const {
10064ba319b5SDimitry Andric    return string<char32_t>();
10074ba319b5SDimitry Andric  }
10084ba319b5SDimitry Andric
10094ba319b5SDimitry Andric  // generic format observers
10104ba319b5SDimitry Andric  template <class _ECharT, class _Traits = char_traits<_ECharT>,
10114ba319b5SDimitry Andric            class _Allocator = allocator<_ECharT> >
10124ba319b5SDimitry Andric  basic_string<_ECharT, _Traits, _Allocator>
10134ba319b5SDimitry Andric  generic_string(const _Allocator& __a = _Allocator()) const {
10144ba319b5SDimitry Andric    return string<_ECharT, _Traits, _Allocator>(__a);
10154ba319b5SDimitry Andric  }
10164ba319b5SDimitry Andric
10174ba319b5SDimitry Andric  std::string generic_string() const { return __pn_; }
10184ba319b5SDimitry Andric  std::wstring generic_wstring() const { return string<wchar_t>(); }
10194ba319b5SDimitry Andric  std::string generic_u8string() const { return __pn_; }
10204ba319b5SDimitry Andric  std::u16string generic_u16string() const { return string<char16_t>(); }
10214ba319b5SDimitry Andric  std::u32string generic_u32string() const { return string<char32_t>(); }
10224ba319b5SDimitry Andric
10234ba319b5SDimitry Andricprivate:
10244ba319b5SDimitry Andric  int __compare(__string_view) const;
10254ba319b5SDimitry Andric  __string_view __root_name() const;
10264ba319b5SDimitry Andric  __string_view __root_directory() const;
10274ba319b5SDimitry Andric  __string_view __root_path_raw() const;
10284ba319b5SDimitry Andric  __string_view __relative_path() const;
10294ba319b5SDimitry Andric  __string_view __parent_path() const;
10304ba319b5SDimitry Andric  __string_view __filename() const;
10314ba319b5SDimitry Andric  __string_view __stem() const;
10324ba319b5SDimitry Andric  __string_view __extension() const;
10334ba319b5SDimitry Andric
10344ba319b5SDimitry Andricpublic:
10354ba319b5SDimitry Andric  // compare
10364ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
10374ba319b5SDimitry Andric    return __compare(__p.__pn_);
10384ba319b5SDimitry Andric  }
10394ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
10404ba319b5SDimitry Andric    return __compare(__s);
10414ba319b5SDimitry Andric  }
10424ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
10434ba319b5SDimitry Andric    return __compare(__s);
10444ba319b5SDimitry Andric  }
10454ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
10464ba319b5SDimitry Andric    return __compare(__s);
10474ba319b5SDimitry Andric  }
10484ba319b5SDimitry Andric
10494ba319b5SDimitry Andric  // decomposition
10504ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_name() const {
10514ba319b5SDimitry Andric    return string_type(__root_name());
10524ba319b5SDimitry Andric  }
10534ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_directory() const {
10544ba319b5SDimitry Andric    return string_type(__root_directory());
10554ba319b5SDimitry Andric  }
10564ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path root_path() const {
10574ba319b5SDimitry Andric    return root_name().append(string_type(__root_directory()));
10584ba319b5SDimitry Andric  }
10594ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path relative_path() const {
10604ba319b5SDimitry Andric    return string_type(__relative_path());
10614ba319b5SDimitry Andric  }
10624ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path parent_path() const {
10634ba319b5SDimitry Andric    return string_type(__parent_path());
10644ba319b5SDimitry Andric  }
10654ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path filename() const {
10664ba319b5SDimitry Andric    return string_type(__filename());
10674ba319b5SDimitry Andric  }
10684ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
10694ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path extension() const {
10704ba319b5SDimitry Andric    return string_type(__extension());
10714ba319b5SDimitry Andric  }
10724ba319b5SDimitry Andric
10734ba319b5SDimitry Andric  // query
10744ba319b5SDimitry Andric  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
10754ba319b5SDimitry Andric  empty() const noexcept {
10764ba319b5SDimitry Andric    return __pn_.empty();
10774ba319b5SDimitry Andric  }
10784ba319b5SDimitry Andric
10794ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
10804ba319b5SDimitry Andric    return !__root_name().empty();
10814ba319b5SDimitry Andric  }
10824ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
10834ba319b5SDimitry Andric    return !__root_directory().empty();
10844ba319b5SDimitry Andric  }
10854ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
10864ba319b5SDimitry Andric    return !__root_path_raw().empty();
10874ba319b5SDimitry Andric  }
10884ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
10894ba319b5SDimitry Andric    return !__relative_path().empty();
10904ba319b5SDimitry Andric  }
10914ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
10924ba319b5SDimitry Andric    return !__parent_path().empty();
10934ba319b5SDimitry Andric  }
10944ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
10954ba319b5SDimitry Andric    return !__filename().empty();
10964ba319b5SDimitry Andric  }
10974ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
10984ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
10994ba319b5SDimitry Andric    return !__extension().empty();
11004ba319b5SDimitry Andric  }
11014ba319b5SDimitry Andric
11024ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
11034ba319b5SDimitry Andric    return has_root_directory();
11044ba319b5SDimitry Andric  }
11054ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
11064ba319b5SDimitry Andric
11074ba319b5SDimitry Andric  // relative paths
11084ba319b5SDimitry Andric  path lexically_normal() const;
11094ba319b5SDimitry Andric  path lexically_relative(const path& __base) const;
11104ba319b5SDimitry Andric
11114ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
11124ba319b5SDimitry Andric    path __result = this->lexically_relative(__base);
11134ba319b5SDimitry Andric    if (__result.native().empty())
11144ba319b5SDimitry Andric      return *this;
11154ba319b5SDimitry Andric    return __result;
11164ba319b5SDimitry Andric  }
11174ba319b5SDimitry Andric
11184ba319b5SDimitry Andric  // iterators
11194ba319b5SDimitry Andric  class _LIBCPP_TYPE_VIS iterator;
11204ba319b5SDimitry Andric  typedef iterator const_iterator;
11214ba319b5SDimitry Andric
11224ba319b5SDimitry Andric  iterator begin() const;
11234ba319b5SDimitry Andric  iterator end() const;
11244ba319b5SDimitry Andric
11254ba319b5SDimitry Andric  template <class _CharT, class _Traits>
11264ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend
11274ba319b5SDimitry Andric      typename enable_if<is_same<_CharT, char>::value &&
11284ba319b5SDimitry Andric                             is_same<_Traits, char_traits<char> >::value,
11294ba319b5SDimitry Andric                         basic_ostream<_CharT, _Traits>&>::type
11304ba319b5SDimitry Andric      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
11314ba319b5SDimitry Andric    __os << std::__quoted(__p.native());
11324ba319b5SDimitry Andric    return __os;
11334ba319b5SDimitry Andric  }
11344ba319b5SDimitry Andric
11354ba319b5SDimitry Andric  template <class _CharT, class _Traits>
11364ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend
11374ba319b5SDimitry Andric      typename enable_if<!is_same<_CharT, char>::value ||
11384ba319b5SDimitry Andric                             !is_same<_Traits, char_traits<char> >::value,
11394ba319b5SDimitry Andric                         basic_ostream<_CharT, _Traits>&>::type
11404ba319b5SDimitry Andric      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
11414ba319b5SDimitry Andric    __os << std::__quoted(__p.string<_CharT, _Traits>());
11424ba319b5SDimitry Andric    return __os;
11434ba319b5SDimitry Andric  }
11444ba319b5SDimitry Andric
11454ba319b5SDimitry Andric  template <class _CharT, class _Traits>
11464ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
11474ba319b5SDimitry Andric  operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
11484ba319b5SDimitry Andric    basic_string<_CharT, _Traits> __tmp;
11494ba319b5SDimitry Andric    __is >> __quoted(__tmp);
11504ba319b5SDimitry Andric    __p = __tmp;
11514ba319b5SDimitry Andric    return __is;
11524ba319b5SDimitry Andric  }
11534ba319b5SDimitry Andric
1154*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
1155*b5893f02SDimitry Andric    return __lhs.compare(__rhs) == 0;
1156*b5893f02SDimitry Andric  }
1157*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
1158*b5893f02SDimitry Andric    return __lhs.compare(__rhs) != 0;
1159*b5893f02SDimitry Andric  }
1160*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
1161*b5893f02SDimitry Andric    return __lhs.compare(__rhs) < 0;
1162*b5893f02SDimitry Andric  }
1163*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
1164*b5893f02SDimitry Andric    return __lhs.compare(__rhs) <= 0;
1165*b5893f02SDimitry Andric  }
1166*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
1167*b5893f02SDimitry Andric    return __lhs.compare(__rhs) > 0;
1168*b5893f02SDimitry Andric  }
1169*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
1170*b5893f02SDimitry Andric    return __lhs.compare(__rhs) >= 0;
1171*b5893f02SDimitry Andric  }
1172*b5893f02SDimitry Andric
1173*b5893f02SDimitry Andric  friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
1174*b5893f02SDimitry Andric                                                  const path& __rhs) {
1175*b5893f02SDimitry Andric    path __result(__lhs);
1176*b5893f02SDimitry Andric    __result /= __rhs;
1177*b5893f02SDimitry Andric    return __result;
1178*b5893f02SDimitry Andric  }
11794ba319b5SDimitry Andricprivate:
11804ba319b5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY path&
11814ba319b5SDimitry Andric  __assign_view(__string_view const& __s) noexcept {
11824ba319b5SDimitry Andric    __pn_ = string_type(__s);
11834ba319b5SDimitry Andric    return *this;
11844ba319b5SDimitry Andric  }
11854ba319b5SDimitry Andric  string_type __pn_;
11864ba319b5SDimitry Andric};
11874ba319b5SDimitry Andric
11884ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
11894ba319b5SDimitry Andric  __lhs.swap(__rhs);
11904ba319b5SDimitry Andric}
11914ba319b5SDimitry Andric
11924ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
11934ba319b5SDimitry Andricsize_t hash_value(const path& __p) noexcept;
11944ba319b5SDimitry Andric
11954ba319b5SDimitry Andrictemplate <class _Source>
11964ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11974ba319b5SDimitry Andric    typename enable_if<__is_pathable<_Source>::value, path>::type
11984ba319b5SDimitry Andric    u8path(const _Source& __s) {
11994ba319b5SDimitry Andric  static_assert(
12004ba319b5SDimitry Andric      is_same<typename __is_pathable<_Source>::__char_type, char>::value,
12014ba319b5SDimitry Andric      "u8path(Source const&) requires Source have a character type of type "
12024ba319b5SDimitry Andric      "'char'");
12034ba319b5SDimitry Andric  return path(__s);
12044ba319b5SDimitry Andric}
12054ba319b5SDimitry Andric
12064ba319b5SDimitry Andrictemplate <class _InputIt>
12074ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12084ba319b5SDimitry Andric    typename enable_if<__is_pathable<_InputIt>::value, path>::type
12094ba319b5SDimitry Andric    u8path(_InputIt __f, _InputIt __l) {
12104ba319b5SDimitry Andric  static_assert(
12114ba319b5SDimitry Andric      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
12124ba319b5SDimitry Andric      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
12134ba319b5SDimitry Andric  return path(__f, __l);
12144ba319b5SDimitry Andric}
12154ba319b5SDimitry Andric
12164ba319b5SDimitry Andricclass _LIBCPP_TYPE_VIS path::iterator {
12174ba319b5SDimitry Andricpublic:
12184ba319b5SDimitry Andric  enum _ParserState : unsigned char {
12194ba319b5SDimitry Andric    _Singular,
12204ba319b5SDimitry Andric    _BeforeBegin,
12214ba319b5SDimitry Andric    _InRootName,
12224ba319b5SDimitry Andric    _InRootDir,
12234ba319b5SDimitry Andric    _InFilenames,
12244ba319b5SDimitry Andric    _InTrailingSep,
12254ba319b5SDimitry Andric    _AtEnd
12264ba319b5SDimitry Andric  };
12274ba319b5SDimitry Andric
12284ba319b5SDimitry Andricpublic:
12294ba319b5SDimitry Andric  typedef bidirectional_iterator_tag iterator_category;
12304ba319b5SDimitry Andric
12314ba319b5SDimitry Andric  typedef path value_type;
12324ba319b5SDimitry Andric  typedef std::ptrdiff_t difference_type;
12334ba319b5SDimitry Andric  typedef const path* pointer;
12344ba319b5SDimitry Andric  typedef const path& reference;
12354ba319b5SDimitry Andric
12364ba319b5SDimitry Andric  typedef void
12374ba319b5SDimitry Andric      __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
12384ba319b5SDimitry Andric
12394ba319b5SDimitry Andricpublic:
12404ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12414ba319b5SDimitry Andric  iterator()
12424ba319b5SDimitry Andric      : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
12434ba319b5SDimitry Andric        __state_(_Singular) {}
12444ba319b5SDimitry Andric
12454ba319b5SDimitry Andric  iterator(const iterator&) = default;
12464ba319b5SDimitry Andric  ~iterator() = default;
12474ba319b5SDimitry Andric
12484ba319b5SDimitry Andric  iterator& operator=(const iterator&) = default;
12494ba319b5SDimitry Andric
12504ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12514ba319b5SDimitry Andric  reference operator*() const { return __stashed_elem_; }
12524ba319b5SDimitry Andric
12534ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12544ba319b5SDimitry Andric  pointer operator->() const { return &__stashed_elem_; }
12554ba319b5SDimitry Andric
12564ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12574ba319b5SDimitry Andric  iterator& operator++() {
12584ba319b5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _Singular,
12594ba319b5SDimitry Andric                   "attempting to increment a singular iterator");
12604ba319b5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _AtEnd,
12614ba319b5SDimitry Andric                   "attempting to increment the end iterator");
12624ba319b5SDimitry Andric    return __increment();
12634ba319b5SDimitry Andric  }
12644ba319b5SDimitry Andric
12654ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12664ba319b5SDimitry Andric  iterator operator++(int) {
12674ba319b5SDimitry Andric    iterator __it(*this);
12684ba319b5SDimitry Andric    this->operator++();
12694ba319b5SDimitry Andric    return __it;
12704ba319b5SDimitry Andric  }
12714ba319b5SDimitry Andric
12724ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12734ba319b5SDimitry Andric  iterator& operator--() {
12744ba319b5SDimitry Andric    _LIBCPP_ASSERT(__state_ != _Singular,
12754ba319b5SDimitry Andric                   "attempting to decrement a singular iterator");
12764ba319b5SDimitry Andric    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
12774ba319b5SDimitry Andric                   "attempting to decrement the begin iterator");
12784ba319b5SDimitry Andric    return __decrement();
12794ba319b5SDimitry Andric  }
12804ba319b5SDimitry Andric
12814ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12824ba319b5SDimitry Andric  iterator operator--(int) {
12834ba319b5SDimitry Andric    iterator __it(*this);
12844ba319b5SDimitry Andric    this->operator--();
12854ba319b5SDimitry Andric    return __it;
12864ba319b5SDimitry Andric  }
12874ba319b5SDimitry Andric
12884ba319b5SDimitry Andricprivate:
12894ba319b5SDimitry Andric  friend class path;
12904ba319b5SDimitry Andric
12914ba319b5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
12924ba319b5SDimitry Andric                                                          const iterator&);
12934ba319b5SDimitry Andric
12944ba319b5SDimitry Andric  iterator& __increment();
12954ba319b5SDimitry Andric  iterator& __decrement();
12964ba319b5SDimitry Andric
12974ba319b5SDimitry Andric  path __stashed_elem_;
12984ba319b5SDimitry Andric  const path* __path_ptr_;
12994ba319b5SDimitry Andric  path::__string_view __entry_;
13004ba319b5SDimitry Andric  _ParserState __state_;
13014ba319b5SDimitry Andric};
13024ba319b5SDimitry Andric
13034ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
13044ba319b5SDimitry Andric                                                 const path::iterator& __rhs) {
13054ba319b5SDimitry Andric  return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
13064ba319b5SDimitry Andric         __lhs.__entry_.data() == __rhs.__entry_.data();
13074ba319b5SDimitry Andric}
13084ba319b5SDimitry Andric
13094ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
13104ba319b5SDimitry Andric                                                 const path::iterator& __rhs) {
13114ba319b5SDimitry Andric  return !(__lhs == __rhs);
13124ba319b5SDimitry Andric}
13134ba319b5SDimitry Andric
13144ba319b5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
13154ba319b5SDimitry Andricpublic:
13164ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13174ba319b5SDimitry Andric  filesystem_error(const string& __what, error_code __ec)
13184ba319b5SDimitry Andric      : system_error(__ec, __what),
13194ba319b5SDimitry Andric        __storage_(make_shared<_Storage>(path(), path())) {
13204ba319b5SDimitry Andric    __create_what(0);
13214ba319b5SDimitry Andric  }
13224ba319b5SDimitry Andric
13234ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13244ba319b5SDimitry Andric  filesystem_error(const string& __what, const path& __p1, error_code __ec)
13254ba319b5SDimitry Andric      : system_error(__ec, __what),
13264ba319b5SDimitry Andric        __storage_(make_shared<_Storage>(__p1, path())) {
13274ba319b5SDimitry Andric    __create_what(1);
13284ba319b5SDimitry Andric  }
13294ba319b5SDimitry Andric
13304ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13314ba319b5SDimitry Andric  filesystem_error(const string& __what, const path& __p1, const path& __p2,
13324ba319b5SDimitry Andric                   error_code __ec)
13334ba319b5SDimitry Andric      : system_error(__ec, __what),
13344ba319b5SDimitry Andric        __storage_(make_shared<_Storage>(__p1, __p2)) {
13354ba319b5SDimitry Andric    __create_what(2);
13364ba319b5SDimitry Andric  }
13374ba319b5SDimitry Andric
13384ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13394ba319b5SDimitry Andric  const path& path1() const noexcept { return __storage_->__p1_; }
13404ba319b5SDimitry Andric
13414ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13424ba319b5SDimitry Andric  const path& path2() const noexcept { return __storage_->__p2_; }
13434ba319b5SDimitry Andric
13444ba319b5SDimitry Andric  ~filesystem_error() override; // key function
13454ba319b5SDimitry Andric
13464ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13474ba319b5SDimitry Andric  const char* what() const noexcept override {
13484ba319b5SDimitry Andric    return __storage_->__what_.c_str();
13494ba319b5SDimitry Andric  }
13504ba319b5SDimitry Andric
13514ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
13524ba319b5SDimitry Andric  void __create_what(int __num_paths);
13534ba319b5SDimitry Andric
13544ba319b5SDimitry Andricprivate:
13554ba319b5SDimitry Andric  struct _Storage {
13564ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
13574ba319b5SDimitry Andric    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
13584ba319b5SDimitry Andric
13594ba319b5SDimitry Andric    path __p1_;
13604ba319b5SDimitry Andric    path __p2_;
13614ba319b5SDimitry Andric    string __what_;
13624ba319b5SDimitry Andric  };
13634ba319b5SDimitry Andric  shared_ptr<_Storage> __storage_;
13644ba319b5SDimitry Andric};
13654ba319b5SDimitry Andric
13664ba319b5SDimitry Andrictemplate <class... _Args>
13674ba319b5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
13684ba319b5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
13694ba319b5SDimitry Andric    void
13704ba319b5SDimitry Andric    __throw_filesystem_error(_Args&&... __args) {
13714ba319b5SDimitry Andric  throw filesystem_error(std::forward<_Args>(__args)...);
13724ba319b5SDimitry Andric}
13734ba319b5SDimitry Andric#else
13744ba319b5SDimitry Andric    void
13754ba319b5SDimitry Andric    __throw_filesystem_error(_Args&&...) {
13764ba319b5SDimitry Andric  _VSTD::abort();
13774ba319b5SDimitry Andric}
13784ba319b5SDimitry Andric#endif
13794ba319b5SDimitry Andric
13804ba319b5SDimitry Andric// operational functions
13814ba319b5SDimitry Andric
13824ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13834ba319b5SDimitry Andricpath __absolute(const path&, error_code* __ec = nullptr);
13844ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13854ba319b5SDimitry Andricpath __canonical(const path&, error_code* __ec = nullptr);
13864ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13874ba319b5SDimitry Andricvoid __copy(const path& __from, const path& __to, copy_options __opt,
13884ba319b5SDimitry Andric            error_code* __ec = nullptr);
13894ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13904ba319b5SDimitry Andricbool __copy_file(const path& __from, const path& __to, copy_options __opt,
13914ba319b5SDimitry Andric                 error_code* __ec = nullptr);
13924ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13934ba319b5SDimitry Andricvoid __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
13944ba319b5SDimitry Andric                    error_code* __ec = nullptr);
13954ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13964ba319b5SDimitry Andricbool __create_directories(const path& p, error_code* ec = nullptr);
13974ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
13984ba319b5SDimitry Andricbool __create_directory(const path& p, error_code* ec = nullptr);
13994ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14004ba319b5SDimitry Andricbool __create_directory(const path& p, const path& attributes,
14014ba319b5SDimitry Andric                        error_code* ec = nullptr);
14024ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14034ba319b5SDimitry Andricvoid __create_directory_symlink(const path& __to, const path& __new_symlink,
14044ba319b5SDimitry Andric                                error_code* __ec = nullptr);
14054ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14064ba319b5SDimitry Andricvoid __create_hard_link(const path& __to, const path& __new_hard_link,
14074ba319b5SDimitry Andric                        error_code* __ec = nullptr);
14084ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14094ba319b5SDimitry Andricvoid __create_symlink(const path& __to, const path& __new_symlink,
14104ba319b5SDimitry Andric                      error_code* __ec = nullptr);
14114ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14124ba319b5SDimitry Andricpath __current_path(error_code* __ec = nullptr);
14134ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14144ba319b5SDimitry Andricvoid __current_path(const path&, error_code* __ec = nullptr);
14154ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14164ba319b5SDimitry Andricbool __equivalent(const path&, const path&, error_code* __ec = nullptr);
14174ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14184ba319b5SDimitry Andricuintmax_t __file_size(const path&, error_code* __ec = nullptr);
14194ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14204ba319b5SDimitry Andricuintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
14214ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14224ba319b5SDimitry Andricbool __fs_is_empty(const path& p, error_code* ec = nullptr);
14234ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14244ba319b5SDimitry Andricfile_time_type __last_write_time(const path& p, error_code* ec = nullptr);
14254ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14264ba319b5SDimitry Andricvoid __last_write_time(const path& p, file_time_type new_time,
14274ba319b5SDimitry Andric                       error_code* ec = nullptr);
14284ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14294ba319b5SDimitry Andricvoid __permissions(const path&, perms, perm_options, error_code* = nullptr);
14304ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14314ba319b5SDimitry Andricpath __read_symlink(const path& p, error_code* ec = nullptr);
14324ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14334ba319b5SDimitry Andricbool __remove(const path& p, error_code* ec = nullptr);
14344ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14354ba319b5SDimitry Andricuintmax_t __remove_all(const path& p, error_code* ec = nullptr);
14364ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14374ba319b5SDimitry Andricvoid __rename(const path& from, const path& to, error_code* ec = nullptr);
14384ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14394ba319b5SDimitry Andricvoid __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
14404ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14414ba319b5SDimitry Andricspace_info __space(const path&, error_code* __ec = nullptr);
14424ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14434ba319b5SDimitry Andricfile_status __status(const path&, error_code* __ec = nullptr);
14444ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14454ba319b5SDimitry Andricfile_status __symlink_status(const path&, error_code* __ec = nullptr);
14464ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14474ba319b5SDimitry Andricpath __system_complete(const path&, error_code* __ec = nullptr);
14484ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14494ba319b5SDimitry Andricpath __temp_directory_path(error_code* __ec = nullptr);
14504ba319b5SDimitry Andric_LIBCPP_FUNC_VIS
14514ba319b5SDimitry Andricpath __weakly_canonical(path const& __p, error_code* __ec = nullptr);
14524ba319b5SDimitry Andric
14534ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path current_path() {
14544ba319b5SDimitry Andric  return __current_path();
14554ba319b5SDimitry Andric}
14564ba319b5SDimitry Andric
14574ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
14584ba319b5SDimitry Andric  return __current_path(&__ec);
14594ba319b5SDimitry Andric}
14604ba319b5SDimitry Andric
14614ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
14624ba319b5SDimitry Andric  __current_path(__p);
14634ba319b5SDimitry Andric}
14644ba319b5SDimitry Andric
14654ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
14664ba319b5SDimitry Andric                                                   error_code& __ec) noexcept {
14674ba319b5SDimitry Andric  __current_path(__p, &__ec);
14684ba319b5SDimitry Andric}
14694ba319b5SDimitry Andric
14704ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
14714ba319b5SDimitry Andric  return __absolute(__p);
14724ba319b5SDimitry Andric}
14734ba319b5SDimitry Andric
14744ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
14754ba319b5SDimitry Andric                                               error_code& __ec) {
14764ba319b5SDimitry Andric  return __absolute(__p, &__ec);
14774ba319b5SDimitry Andric}
14784ba319b5SDimitry Andric
14794ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
14804ba319b5SDimitry Andric  return __canonical(__p);
14814ba319b5SDimitry Andric}
14824ba319b5SDimitry Andric
14834ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
14844ba319b5SDimitry Andric                                                error_code& __ec) {
14854ba319b5SDimitry Andric  return __canonical(__p, &__ec);
14864ba319b5SDimitry Andric}
14874ba319b5SDimitry Andric
14884ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
14894ba319b5SDimitry Andric                                           const path& __to) {
14904ba319b5SDimitry Andric  __copy(__from, __to, copy_options::none);
14914ba319b5SDimitry Andric}
14924ba319b5SDimitry Andric
14934ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
14944ba319b5SDimitry Andric                                           error_code& __ec) {
14954ba319b5SDimitry Andric  __copy(__from, __to, copy_options::none, &__ec);
14964ba319b5SDimitry Andric}
14974ba319b5SDimitry Andric
14984ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
14994ba319b5SDimitry Andric                                           copy_options __opt) {
15004ba319b5SDimitry Andric  __copy(__from, __to, __opt);
15014ba319b5SDimitry Andric}
15024ba319b5SDimitry Andric
15034ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
15044ba319b5SDimitry Andric                                           copy_options __opt,
15054ba319b5SDimitry Andric                                           error_code& __ec) {
15064ba319b5SDimitry Andric  __copy(__from, __to, __opt, &__ec);
15074ba319b5SDimitry Andric}
15084ba319b5SDimitry Andric
15094ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
15104ba319b5SDimitry Andric                                                const path& __to) {
15114ba319b5SDimitry Andric  return __copy_file(__from, __to, copy_options::none);
15124ba319b5SDimitry Andric}
15134ba319b5SDimitry Andric
15144ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
15154ba319b5SDimitry Andriccopy_file(const path& __from, const path& __to, error_code& __ec) {
15164ba319b5SDimitry Andric  return __copy_file(__from, __to, copy_options::none, &__ec);
15174ba319b5SDimitry Andric}
15184ba319b5SDimitry Andric
15194ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
15204ba319b5SDimitry Andriccopy_file(const path& __from, const path& __to, copy_options __opt) {
15214ba319b5SDimitry Andric  return __copy_file(__from, __to, __opt);
15224ba319b5SDimitry Andric}
15234ba319b5SDimitry Andric
15244ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
15254ba319b5SDimitry Andric                                                const path& __to,
15264ba319b5SDimitry Andric                                                copy_options __opt,
15274ba319b5SDimitry Andric                                                error_code& __ec) {
15284ba319b5SDimitry Andric  return __copy_file(__from, __to, __opt, &__ec);
15294ba319b5SDimitry Andric}
15304ba319b5SDimitry Andric
15314ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
15324ba319b5SDimitry Andric                                                   const path& __new) {
15334ba319b5SDimitry Andric  __copy_symlink(__existing, __new);
15344ba319b5SDimitry Andric}
15354ba319b5SDimitry Andric
15364ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
15374ba319b5SDimitry Andriccopy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
15384ba319b5SDimitry Andric  __copy_symlink(__ext, __new, &__ec);
15394ba319b5SDimitry Andric}
15404ba319b5SDimitry Andric
15414ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
15424ba319b5SDimitry Andric  return __create_directories(__p);
15434ba319b5SDimitry Andric}
15444ba319b5SDimitry Andric
15454ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
15464ba319b5SDimitry Andric                                                         error_code& __ec) {
15474ba319b5SDimitry Andric  return __create_directories(__p, &__ec);
15484ba319b5SDimitry Andric}
15494ba319b5SDimitry Andric
15504ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
15514ba319b5SDimitry Andric  return __create_directory(__p);
15524ba319b5SDimitry Andric}
15534ba319b5SDimitry Andric
15544ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
15554ba319b5SDimitry Andriccreate_directory(const path& __p, error_code& __ec) noexcept {
15564ba319b5SDimitry Andric  return __create_directory(__p, &__ec);
15574ba319b5SDimitry Andric}
15584ba319b5SDimitry Andric
15594ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
15604ba319b5SDimitry Andric                                                       const path& __attrs) {
15614ba319b5SDimitry Andric  return __create_directory(__p, __attrs);
15624ba319b5SDimitry Andric}
15634ba319b5SDimitry Andric
15644ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
15654ba319b5SDimitry Andriccreate_directory(const path& __p, const path& __attrs,
15664ba319b5SDimitry Andric                 error_code& __ec) noexcept {
15674ba319b5SDimitry Andric  return __create_directory(__p, __attrs, &__ec);
15684ba319b5SDimitry Andric}
15694ba319b5SDimitry Andric
15704ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
15714ba319b5SDimitry Andriccreate_directory_symlink(const path& __to, const path& __new) {
15724ba319b5SDimitry Andric  __create_directory_symlink(__to, __new);
15734ba319b5SDimitry Andric}
15744ba319b5SDimitry Andric
15754ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
15764ba319b5SDimitry Andriccreate_directory_symlink(const path& __to, const path& __new,
15774ba319b5SDimitry Andric                         error_code& __ec) noexcept {
15784ba319b5SDimitry Andric  __create_directory_symlink(__to, __new, &__ec);
15794ba319b5SDimitry Andric}
15804ba319b5SDimitry Andric
15814ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
15824ba319b5SDimitry Andric                                                       const path& __new) {
15834ba319b5SDimitry Andric  __create_hard_link(__to, __new);
15844ba319b5SDimitry Andric}
15854ba319b5SDimitry Andric
15864ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
15874ba319b5SDimitry Andriccreate_hard_link(const path& __to, const path& __new,
15884ba319b5SDimitry Andric                 error_code& __ec) noexcept {
15894ba319b5SDimitry Andric  __create_hard_link(__to, __new, &__ec);
15904ba319b5SDimitry Andric}
15914ba319b5SDimitry Andric
15924ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
15934ba319b5SDimitry Andric                                                     const path& __new) {
15944ba319b5SDimitry Andric  __create_symlink(__to, __new);
15954ba319b5SDimitry Andric}
15964ba319b5SDimitry Andric
15974ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
15984ba319b5SDimitry Andriccreate_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
15994ba319b5SDimitry Andric  return __create_symlink(__to, __new, &__ec);
16004ba319b5SDimitry Andric}
16014ba319b5SDimitry Andric
16024ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
16034ba319b5SDimitry Andric  return __s.type() != file_type::none;
16044ba319b5SDimitry Andric}
16054ba319b5SDimitry Andric
16064ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
16074ba319b5SDimitry Andric  return status_known(__s) && __s.type() != file_type::not_found;
16084ba319b5SDimitry Andric}
16094ba319b5SDimitry Andric
16104ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
16114ba319b5SDimitry Andric  return exists(__status(__p));
16124ba319b5SDimitry Andric}
16134ba319b5SDimitry Andric
16144ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
16154ba319b5SDimitry Andric                                             error_code& __ec) noexcept {
16164ba319b5SDimitry Andric  auto __s = __status(__p, &__ec);
16174ba319b5SDimitry Andric  if (status_known(__s))
16184ba319b5SDimitry Andric    __ec.clear();
16194ba319b5SDimitry Andric  return exists(__s);
16204ba319b5SDimitry Andric}
16214ba319b5SDimitry Andric
16224ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
16234ba319b5SDimitry Andric                                                 const path& __p2) {
16244ba319b5SDimitry Andric  return __equivalent(__p1, __p2);
16254ba319b5SDimitry Andric}
16264ba319b5SDimitry Andric
16274ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
16284ba319b5SDimitry Andricequivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
16294ba319b5SDimitry Andric  return __equivalent(__p1, __p2, &__ec);
16304ba319b5SDimitry Andric}
16314ba319b5SDimitry Andric
16324ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
16334ba319b5SDimitry Andric  return __file_size(__p);
16344ba319b5SDimitry Andric}
16354ba319b5SDimitry Andric
16364ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t
16374ba319b5SDimitry Andricfile_size(const path& __p, error_code& __ec) noexcept {
16384ba319b5SDimitry Andric  return __file_size(__p, &__ec);
16394ba319b5SDimitry Andric}
16404ba319b5SDimitry Andric
16414ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
16424ba319b5SDimitry Andric  return __hard_link_count(__p);
16434ba319b5SDimitry Andric}
16444ba319b5SDimitry Andric
16454ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t
16464ba319b5SDimitry Andrichard_link_count(const path& __p, error_code& __ec) noexcept {
16474ba319b5SDimitry Andric  return __hard_link_count(__p, &__ec);
16484ba319b5SDimitry Andric}
16494ba319b5SDimitry Andric
16504ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
16514ba319b5SDimitry Andric  return __s.type() == file_type::block;
16524ba319b5SDimitry Andric}
16534ba319b5SDimitry Andric
16544ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
16554ba319b5SDimitry Andric  return is_block_file(__status(__p));
16564ba319b5SDimitry Andric}
16574ba319b5SDimitry Andric
16584ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
16594ba319b5SDimitry Andric                                                    error_code& __ec) noexcept {
16604ba319b5SDimitry Andric  return is_block_file(__status(__p, &__ec));
16614ba319b5SDimitry Andric}
16624ba319b5SDimitry Andric
16634ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
16644ba319b5SDimitry Andricis_character_file(file_status __s) noexcept {
16654ba319b5SDimitry Andric  return __s.type() == file_type::character;
16664ba319b5SDimitry Andric}
16674ba319b5SDimitry Andric
16684ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
16694ba319b5SDimitry Andric  return is_character_file(__status(__p));
16704ba319b5SDimitry Andric}
16714ba319b5SDimitry Andric
16724ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
16734ba319b5SDimitry Andricis_character_file(const path& __p, error_code& __ec) noexcept {
16744ba319b5SDimitry Andric  return is_character_file(__status(__p, &__ec));
16754ba319b5SDimitry Andric}
16764ba319b5SDimitry Andric
16774ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
16784ba319b5SDimitry Andric  return __s.type() == file_type::directory;
16794ba319b5SDimitry Andric}
16804ba319b5SDimitry Andric
16814ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
16824ba319b5SDimitry Andric  return is_directory(__status(__p));
16834ba319b5SDimitry Andric}
16844ba319b5SDimitry Andric
16854ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
16864ba319b5SDimitry Andric                                                   error_code& __ec) noexcept {
16874ba319b5SDimitry Andric  return is_directory(__status(__p, &__ec));
16884ba319b5SDimitry Andric}
16894ba319b5SDimitry Andric
16904ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
16914ba319b5SDimitry Andric  return __fs_is_empty(__p);
16924ba319b5SDimitry Andric}
16934ba319b5SDimitry Andric
16944ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
16954ba319b5SDimitry Andric                                               error_code& __ec) {
16964ba319b5SDimitry Andric  return __fs_is_empty(__p, &__ec);
16974ba319b5SDimitry Andric}
16984ba319b5SDimitry Andric
16994ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
17004ba319b5SDimitry Andric  return __s.type() == file_type::fifo;
17014ba319b5SDimitry Andric}
17024ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
17034ba319b5SDimitry Andric  return is_fifo(__status(__p));
17044ba319b5SDimitry Andric}
17054ba319b5SDimitry Andric
17064ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
17074ba319b5SDimitry Andric                                              error_code& __ec) noexcept {
17084ba319b5SDimitry Andric  return is_fifo(__status(__p, &__ec));
17094ba319b5SDimitry Andric}
17104ba319b5SDimitry Andric
17114ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
17124ba319b5SDimitry Andricis_regular_file(file_status __s) noexcept {
17134ba319b5SDimitry Andric  return __s.type() == file_type::regular;
17144ba319b5SDimitry Andric}
17154ba319b5SDimitry Andric
17164ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
17174ba319b5SDimitry Andric  return is_regular_file(__status(__p));
17184ba319b5SDimitry Andric}
17194ba319b5SDimitry Andric
17204ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
17214ba319b5SDimitry Andricis_regular_file(const path& __p, error_code& __ec) noexcept {
17224ba319b5SDimitry Andric  return is_regular_file(__status(__p, &__ec));
17234ba319b5SDimitry Andric}
17244ba319b5SDimitry Andric
17254ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
17264ba319b5SDimitry Andric  return __s.type() == file_type::socket;
17274ba319b5SDimitry Andric}
17284ba319b5SDimitry Andric
17294ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
17304ba319b5SDimitry Andric  return is_socket(__status(__p));
17314ba319b5SDimitry Andric}
17324ba319b5SDimitry Andric
17334ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
17344ba319b5SDimitry Andric                                                error_code& __ec) noexcept {
17354ba319b5SDimitry Andric  return is_socket(__status(__p, &__ec));
17364ba319b5SDimitry Andric}
17374ba319b5SDimitry Andric
17384ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
17394ba319b5SDimitry Andric  return __s.type() == file_type::symlink;
17404ba319b5SDimitry Andric}
17414ba319b5SDimitry Andric
17424ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
17434ba319b5SDimitry Andric  return is_symlink(__symlink_status(__p));
17444ba319b5SDimitry Andric}
17454ba319b5SDimitry Andric
17464ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
17474ba319b5SDimitry Andric                                                 error_code& __ec) noexcept {
17484ba319b5SDimitry Andric  return is_symlink(__symlink_status(__p, &__ec));
17494ba319b5SDimitry Andric}
17504ba319b5SDimitry Andric
17514ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
17524ba319b5SDimitry Andric  return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
17534ba319b5SDimitry Andric         !is_symlink(__s);
17544ba319b5SDimitry Andric}
17554ba319b5SDimitry Andric
17564ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
17574ba319b5SDimitry Andric  return is_other(__status(__p));
17584ba319b5SDimitry Andric}
17594ba319b5SDimitry Andric
17604ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
17614ba319b5SDimitry Andric                                               error_code& __ec) noexcept {
17624ba319b5SDimitry Andric  return is_other(__status(__p, &__ec));
17634ba319b5SDimitry Andric}
17644ba319b5SDimitry Andric
17654ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_time_type
17664ba319b5SDimitry Andriclast_write_time(const path& __p) {
17674ba319b5SDimitry Andric  return __last_write_time(__p);
17684ba319b5SDimitry Andric}
17694ba319b5SDimitry Andric
17704ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_time_type
17714ba319b5SDimitry Andriclast_write_time(const path& __p, error_code& __ec) noexcept {
17724ba319b5SDimitry Andric  return __last_write_time(__p, &__ec);
17734ba319b5SDimitry Andric}
17744ba319b5SDimitry Andric
17754ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
17764ba319b5SDimitry Andric                                                      file_time_type __t) {
17774ba319b5SDimitry Andric  __last_write_time(__p, __t);
17784ba319b5SDimitry Andric}
17794ba319b5SDimitry Andric
17804ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
17814ba319b5SDimitry Andriclast_write_time(const path& __p, file_time_type __t,
17824ba319b5SDimitry Andric                error_code& __ec) noexcept {
17834ba319b5SDimitry Andric  __last_write_time(__p, __t, &__ec);
17844ba319b5SDimitry Andric}
17854ba319b5SDimitry Andric
17864ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
17874ba319b5SDimitry Andricpermissions(const path& __p, perms __prms,
17884ba319b5SDimitry Andric            perm_options __opts = perm_options::replace) {
17894ba319b5SDimitry Andric  __permissions(__p, __prms, __opts);
17904ba319b5SDimitry Andric}
17914ba319b5SDimitry Andric
17924ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
17934ba319b5SDimitry Andric                                                  error_code& __ec) noexcept {
17944ba319b5SDimitry Andric  __permissions(__p, __prms, perm_options::replace, &__ec);
17954ba319b5SDimitry Andric}
17964ba319b5SDimitry Andric
17974ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
17984ba319b5SDimitry Andric                                                  perm_options __opts,
17994ba319b5SDimitry Andric                                                  error_code& __ec) {
18004ba319b5SDimitry Andric  __permissions(__p, __prms, __opts, &__ec);
18014ba319b5SDimitry Andric}
18024ba319b5SDimitry Andric
18034ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
18044ba319b5SDimitry Andric                                                const path& __base,
18054ba319b5SDimitry Andric                                                error_code& __ec) {
18064ba319b5SDimitry Andric  path __tmp = __weakly_canonical(__p, &__ec);
18074ba319b5SDimitry Andric  if (__ec)
18084ba319b5SDimitry Andric    return {};
18094ba319b5SDimitry Andric  path __tmp_base = __weakly_canonical(__base, &__ec);
18104ba319b5SDimitry Andric  if (__ec)
18114ba319b5SDimitry Andric    return {};
18124ba319b5SDimitry Andric  return __tmp.lexically_proximate(__tmp_base);
18134ba319b5SDimitry Andric}
18144ba319b5SDimitry Andric
18154ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
18164ba319b5SDimitry Andric                                                error_code& __ec) {
18174ba319b5SDimitry Andric  return proximate(__p, current_path(), __ec);
18184ba319b5SDimitry Andric}
18194ba319b5SDimitry Andric
18204ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path
18214ba319b5SDimitry Andricproximate(const path& __p, const path& __base = current_path()) {
18224ba319b5SDimitry Andric  return __weakly_canonical(__p).lexically_proximate(
18234ba319b5SDimitry Andric      __weakly_canonical(__base));
18244ba319b5SDimitry Andric}
18254ba319b5SDimitry Andric
18264ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
18274ba319b5SDimitry Andric  return __read_symlink(__p);
18284ba319b5SDimitry Andric}
18294ba319b5SDimitry Andric
18304ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
18314ba319b5SDimitry Andric                                                   error_code& __ec) {
18324ba319b5SDimitry Andric  return __read_symlink(__p, &__ec);
18334ba319b5SDimitry Andric}
18344ba319b5SDimitry Andric
18354ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
18364ba319b5SDimitry Andric                                               const path& __base,
18374ba319b5SDimitry Andric                                               error_code& __ec) {
18384ba319b5SDimitry Andric  path __tmp = __weakly_canonical(__p, &__ec);
18394ba319b5SDimitry Andric  if (__ec)
18404ba319b5SDimitry Andric    return path();
18414ba319b5SDimitry Andric  path __tmpbase = __weakly_canonical(__base, &__ec);
18424ba319b5SDimitry Andric  if (__ec)
18434ba319b5SDimitry Andric    return path();
18444ba319b5SDimitry Andric  return __tmp.lexically_relative(__tmpbase);
18454ba319b5SDimitry Andric}
18464ba319b5SDimitry Andric
18474ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
18484ba319b5SDimitry Andric                                               error_code& __ec) {
18494ba319b5SDimitry Andric  return relative(__p, current_path(), __ec);
18504ba319b5SDimitry Andric}
18514ba319b5SDimitry Andric
18524ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path
18534ba319b5SDimitry Andricrelative(const path& __p, const path& __base = current_path()) {
18544ba319b5SDimitry Andric  return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
18554ba319b5SDimitry Andric}
18564ba319b5SDimitry Andric
18574ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
18584ba319b5SDimitry Andric  return __remove(__p);
18594ba319b5SDimitry Andric}
18604ba319b5SDimitry Andric
18614ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
18624ba319b5SDimitry Andric                                             error_code& __ec) noexcept {
18634ba319b5SDimitry Andric  return __remove(__p, &__ec);
18644ba319b5SDimitry Andric}
18654ba319b5SDimitry Andric
18664ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
18674ba319b5SDimitry Andric  return __remove_all(__p);
18684ba319b5SDimitry Andric}
18694ba319b5SDimitry Andric
18704ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
18714ba319b5SDimitry Andric                                                      error_code& __ec) {
18724ba319b5SDimitry Andric  return __remove_all(__p, &__ec);
18734ba319b5SDimitry Andric}
18744ba319b5SDimitry Andric
18754ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
18764ba319b5SDimitry Andric                                             const path& __to) {
18774ba319b5SDimitry Andric  return __rename(__from, __to);
18784ba319b5SDimitry Andric}
18794ba319b5SDimitry Andric
18804ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
18814ba319b5SDimitry Andricrename(const path& __from, const path& __to, error_code& __ec) noexcept {
18824ba319b5SDimitry Andric  return __rename(__from, __to, &__ec);
18834ba319b5SDimitry Andric}
18844ba319b5SDimitry Andric
18854ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
18864ba319b5SDimitry Andric                                                  uintmax_t __ns) {
18874ba319b5SDimitry Andric  return __resize_file(__p, __ns);
18884ba319b5SDimitry Andric}
18894ba319b5SDimitry Andric
18904ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void
18914ba319b5SDimitry Andricresize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
18924ba319b5SDimitry Andric  return __resize_file(__p, __ns, &__ec);
18934ba319b5SDimitry Andric}
18944ba319b5SDimitry Andric
18954ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
18964ba319b5SDimitry Andric  return __space(__p);
18974ba319b5SDimitry Andric}
18984ba319b5SDimitry Andric
18994ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
19004ba319b5SDimitry Andric                                                  error_code& __ec) noexcept {
19014ba319b5SDimitry Andric  return __space(__p, &__ec);
19024ba319b5SDimitry Andric}
19034ba319b5SDimitry Andric
19044ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
19054ba319b5SDimitry Andric  return __status(__p);
19064ba319b5SDimitry Andric}
19074ba319b5SDimitry Andric
19084ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
19094ba319b5SDimitry Andric                                                    error_code& __ec) noexcept {
19104ba319b5SDimitry Andric  return __status(__p, &__ec);
19114ba319b5SDimitry Andric}
19124ba319b5SDimitry Andric
19134ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
19144ba319b5SDimitry Andric  return __symlink_status(__p);
19154ba319b5SDimitry Andric}
19164ba319b5SDimitry Andric
19174ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY file_status
19184ba319b5SDimitry Andricsymlink_status(const path& __p, error_code& __ec) noexcept {
19194ba319b5SDimitry Andric  return __symlink_status(__p, &__ec);
19204ba319b5SDimitry Andric}
19214ba319b5SDimitry Andric
19224ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
19234ba319b5SDimitry Andric  return __temp_directory_path();
19244ba319b5SDimitry Andric}
19254ba319b5SDimitry Andric
19264ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
19274ba319b5SDimitry Andric  return __temp_directory_path(&__ec);
19284ba319b5SDimitry Andric}
19294ba319b5SDimitry Andric
19304ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
19314ba319b5SDimitry Andric  return __weakly_canonical(__p);
19324ba319b5SDimitry Andric}
19334ba319b5SDimitry Andric
19344ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
19354ba319b5SDimitry Andric                                                       error_code& __ec) {
19364ba319b5SDimitry Andric  return __weakly_canonical(__p, &__ec);
19374ba319b5SDimitry Andric}
19384ba319b5SDimitry Andric
19394ba319b5SDimitry Andricclass directory_iterator;
19404ba319b5SDimitry Andricclass recursive_directory_iterator;
19414ba319b5SDimitry Andricclass __dir_stream;
19424ba319b5SDimitry Andric
19434ba319b5SDimitry Andricclass directory_entry {
19444ba319b5SDimitry Andric  typedef _VSTD_FS::path _Path;
19454ba319b5SDimitry Andric
19464ba319b5SDimitry Andricpublic:
19474ba319b5SDimitry Andric  // constructors and destructors
19484ba319b5SDimitry Andric  directory_entry() noexcept = default;
19494ba319b5SDimitry Andric  directory_entry(directory_entry const&) = default;
19504ba319b5SDimitry Andric  directory_entry(directory_entry&&) noexcept = default;
19514ba319b5SDimitry Andric
19524ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19534ba319b5SDimitry Andric  explicit directory_entry(_Path const& __p) : __p_(__p) {
19544ba319b5SDimitry Andric    error_code __ec;
19554ba319b5SDimitry Andric    __refresh(&__ec);
19564ba319b5SDimitry Andric  }
19574ba319b5SDimitry Andric
19584ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19594ba319b5SDimitry Andric  directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
19604ba319b5SDimitry Andric    __refresh(&__ec);
19614ba319b5SDimitry Andric  }
19624ba319b5SDimitry Andric
19634ba319b5SDimitry Andric  ~directory_entry() {}
19644ba319b5SDimitry Andric
19654ba319b5SDimitry Andric  directory_entry& operator=(directory_entry const&) = default;
19664ba319b5SDimitry Andric  directory_entry& operator=(directory_entry&&) noexcept = default;
19674ba319b5SDimitry Andric
19684ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19694ba319b5SDimitry Andric  void assign(_Path const& __p) {
19704ba319b5SDimitry Andric    __p_ = __p;
19714ba319b5SDimitry Andric    error_code __ec;
19724ba319b5SDimitry Andric    __refresh(&__ec);
19734ba319b5SDimitry Andric  }
19744ba319b5SDimitry Andric
19754ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19764ba319b5SDimitry Andric  void assign(_Path const& __p, error_code& __ec) {
19774ba319b5SDimitry Andric    __p_ = __p;
19784ba319b5SDimitry Andric    __refresh(&__ec);
19794ba319b5SDimitry Andric  }
19804ba319b5SDimitry Andric
19814ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19824ba319b5SDimitry Andric  void replace_filename(_Path const& __p) {
19834ba319b5SDimitry Andric    __p_.replace_filename(__p);
19844ba319b5SDimitry Andric    error_code __ec;
19854ba319b5SDimitry Andric    __refresh(&__ec);
19864ba319b5SDimitry Andric  }
19874ba319b5SDimitry Andric
19884ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19894ba319b5SDimitry Andric  void replace_filename(_Path const& __p, error_code& __ec) {
19904ba319b5SDimitry Andric    __p_ = __p_.parent_path() / __p;
19914ba319b5SDimitry Andric    __refresh(&__ec);
19924ba319b5SDimitry Andric  }
19934ba319b5SDimitry Andric
19944ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19954ba319b5SDimitry Andric  void refresh() { __refresh(); }
19964ba319b5SDimitry Andric
19974ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
19984ba319b5SDimitry Andric  void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
19994ba319b5SDimitry Andric
20004ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20014ba319b5SDimitry Andric  _Path const& path() const noexcept { return __p_; }
20024ba319b5SDimitry Andric
20034ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20044ba319b5SDimitry Andric  operator const _Path&() const noexcept { return __p_; }
20054ba319b5SDimitry Andric
20064ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20074ba319b5SDimitry Andric  bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
20084ba319b5SDimitry Andric
20094ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20104ba319b5SDimitry Andric  bool exists(error_code& __ec) const noexcept {
20114ba319b5SDimitry Andric    return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
20124ba319b5SDimitry Andric  }
20134ba319b5SDimitry Andric
20144ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20154ba319b5SDimitry Andric  bool is_block_file() const { return __get_ft() == file_type::block; }
20164ba319b5SDimitry Andric
20174ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20184ba319b5SDimitry Andric  bool is_block_file(error_code& __ec) const noexcept {
20194ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::block;
20204ba319b5SDimitry Andric  }
20214ba319b5SDimitry Andric
20224ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20234ba319b5SDimitry Andric  bool is_character_file() const { return __get_ft() == file_type::character; }
20244ba319b5SDimitry Andric
20254ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20264ba319b5SDimitry Andric  bool is_character_file(error_code& __ec) const noexcept {
20274ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::character;
20284ba319b5SDimitry Andric  }
20294ba319b5SDimitry Andric
20304ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20314ba319b5SDimitry Andric  bool is_directory() const { return __get_ft() == file_type::directory; }
20324ba319b5SDimitry Andric
20334ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20344ba319b5SDimitry Andric  bool is_directory(error_code& __ec) const noexcept {
20354ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::directory;
20364ba319b5SDimitry Andric  }
20374ba319b5SDimitry Andric
20384ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20394ba319b5SDimitry Andric  bool is_fifo() const { return __get_ft() == file_type::fifo; }
20404ba319b5SDimitry Andric
20414ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20424ba319b5SDimitry Andric  bool is_fifo(error_code& __ec) const noexcept {
20434ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::fifo;
20444ba319b5SDimitry Andric  }
20454ba319b5SDimitry Andric
20464ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20474ba319b5SDimitry Andric  bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
20484ba319b5SDimitry Andric
20494ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20504ba319b5SDimitry Andric  bool is_other(error_code& __ec) const noexcept {
20514ba319b5SDimitry Andric    return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
20524ba319b5SDimitry Andric  }
20534ba319b5SDimitry Andric
20544ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20554ba319b5SDimitry Andric  bool is_regular_file() const { return __get_ft() == file_type::regular; }
20564ba319b5SDimitry Andric
20574ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20584ba319b5SDimitry Andric  bool is_regular_file(error_code& __ec) const noexcept {
20594ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::regular;
20604ba319b5SDimitry Andric  }
20614ba319b5SDimitry Andric
20624ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20634ba319b5SDimitry Andric  bool is_socket() const { return __get_ft() == file_type::socket; }
20644ba319b5SDimitry Andric
20654ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20664ba319b5SDimitry Andric  bool is_socket(error_code& __ec) const noexcept {
20674ba319b5SDimitry Andric    return __get_ft(&__ec) == file_type::socket;
20684ba319b5SDimitry Andric  }
20694ba319b5SDimitry Andric
20704ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20714ba319b5SDimitry Andric  bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
20724ba319b5SDimitry Andric
20734ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20744ba319b5SDimitry Andric  bool is_symlink(error_code& __ec) const noexcept {
20754ba319b5SDimitry Andric    return __get_sym_ft(&__ec) == file_type::symlink;
20764ba319b5SDimitry Andric  }
20774ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20784ba319b5SDimitry Andric  uintmax_t file_size() const { return __get_size(); }
20794ba319b5SDimitry Andric
20804ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20814ba319b5SDimitry Andric  uintmax_t file_size(error_code& __ec) const noexcept {
20824ba319b5SDimitry Andric    return __get_size(&__ec);
20834ba319b5SDimitry Andric  }
20844ba319b5SDimitry Andric
20854ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20864ba319b5SDimitry Andric  uintmax_t hard_link_count() const { return __get_nlink(); }
20874ba319b5SDimitry Andric
20884ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20894ba319b5SDimitry Andric  uintmax_t hard_link_count(error_code& __ec) const noexcept {
20904ba319b5SDimitry Andric    return __get_nlink(&__ec);
20914ba319b5SDimitry Andric  }
20924ba319b5SDimitry Andric
20934ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20944ba319b5SDimitry Andric  file_time_type last_write_time() const { return __get_write_time(); }
20954ba319b5SDimitry Andric
20964ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
20974ba319b5SDimitry Andric  file_time_type last_write_time(error_code& __ec) const noexcept {
20984ba319b5SDimitry Andric    return __get_write_time(&__ec);
20994ba319b5SDimitry Andric  }
21004ba319b5SDimitry Andric
21014ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21024ba319b5SDimitry Andric  file_status status() const { return __get_status(); }
21034ba319b5SDimitry Andric
21044ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21054ba319b5SDimitry Andric  file_status status(error_code& __ec) const noexcept {
21064ba319b5SDimitry Andric    return __get_status(&__ec);
21074ba319b5SDimitry Andric  }
21084ba319b5SDimitry Andric
21094ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21104ba319b5SDimitry Andric  file_status symlink_status() const { return __get_symlink_status(); }
21114ba319b5SDimitry Andric
21124ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21134ba319b5SDimitry Andric  file_status symlink_status(error_code& __ec) const noexcept {
21144ba319b5SDimitry Andric    return __get_symlink_status(&__ec);
21154ba319b5SDimitry Andric  }
21164ba319b5SDimitry Andric
21174ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21184ba319b5SDimitry Andric  bool operator<(directory_entry const& __rhs) const noexcept {
21194ba319b5SDimitry Andric    return __p_ < __rhs.__p_;
21204ba319b5SDimitry Andric  }
21214ba319b5SDimitry Andric
21224ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21234ba319b5SDimitry Andric  bool operator==(directory_entry const& __rhs) const noexcept {
21244ba319b5SDimitry Andric    return __p_ == __rhs.__p_;
21254ba319b5SDimitry Andric  }
21264ba319b5SDimitry Andric
21274ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21284ba319b5SDimitry Andric  bool operator!=(directory_entry const& __rhs) const noexcept {
21294ba319b5SDimitry Andric    return __p_ != __rhs.__p_;
21304ba319b5SDimitry Andric  }
21314ba319b5SDimitry Andric
21324ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21334ba319b5SDimitry Andric  bool operator<=(directory_entry const& __rhs) const noexcept {
21344ba319b5SDimitry Andric    return __p_ <= __rhs.__p_;
21354ba319b5SDimitry Andric  }
21364ba319b5SDimitry Andric
21374ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21384ba319b5SDimitry Andric  bool operator>(directory_entry const& __rhs) const noexcept {
21394ba319b5SDimitry Andric    return __p_ > __rhs.__p_;
21404ba319b5SDimitry Andric  }
21414ba319b5SDimitry Andric
21424ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21434ba319b5SDimitry Andric  bool operator>=(directory_entry const& __rhs) const noexcept {
21444ba319b5SDimitry Andric    return __p_ >= __rhs.__p_;
21454ba319b5SDimitry Andric  }
21464ba319b5SDimitry Andric
21474ba319b5SDimitry Andricprivate:
21484ba319b5SDimitry Andric  friend class directory_iterator;
21494ba319b5SDimitry Andric  friend class recursive_directory_iterator;
21504ba319b5SDimitry Andric  friend class __dir_stream;
21514ba319b5SDimitry Andric
21524ba319b5SDimitry Andric  enum _CacheType : unsigned char {
21534ba319b5SDimitry Andric    _Empty,
21544ba319b5SDimitry Andric    _IterSymlink,
21554ba319b5SDimitry Andric    _IterNonSymlink,
21564ba319b5SDimitry Andric    _RefreshSymlink,
21574ba319b5SDimitry Andric    _RefreshSymlinkUnresolved,
21584ba319b5SDimitry Andric    _RefreshNonSymlink
21594ba319b5SDimitry Andric  };
21604ba319b5SDimitry Andric
21614ba319b5SDimitry Andric  struct __cached_data {
21624ba319b5SDimitry Andric    uintmax_t __size_;
21634ba319b5SDimitry Andric    uintmax_t __nlink_;
21644ba319b5SDimitry Andric    file_time_type __write_time_;
21654ba319b5SDimitry Andric    perms __sym_perms_;
21664ba319b5SDimitry Andric    perms __non_sym_perms_;
21674ba319b5SDimitry Andric    file_type __type_;
21684ba319b5SDimitry Andric    _CacheType __cache_type_;
21694ba319b5SDimitry Andric
21704ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21714ba319b5SDimitry Andric    __cached_data() noexcept { __reset(); }
21724ba319b5SDimitry Andric
21734ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21744ba319b5SDimitry Andric    void __reset() {
21754ba319b5SDimitry Andric      __cache_type_ = _Empty;
21764ba319b5SDimitry Andric      __type_ = file_type::none;
21774ba319b5SDimitry Andric      __sym_perms_ = __non_sym_perms_ = perms::unknown;
21784ba319b5SDimitry Andric      __size_ = __nlink_ = uintmax_t(-1);
21794ba319b5SDimitry Andric      __write_time_ = file_time_type::min();
21804ba319b5SDimitry Andric    }
21814ba319b5SDimitry Andric  };
21824ba319b5SDimitry Andric
21834ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
21844ba319b5SDimitry Andric  static __cached_data __create_iter_result(file_type __ft) {
21854ba319b5SDimitry Andric    __cached_data __data;
21864ba319b5SDimitry Andric    __data.__type_ = __ft;
21874ba319b5SDimitry Andric    __data.__cache_type_ = [&]() {
21884ba319b5SDimitry Andric      switch (__ft) {
21894ba319b5SDimitry Andric      case file_type::none:
21904ba319b5SDimitry Andric        return _Empty;
21914ba319b5SDimitry Andric      case file_type::symlink:
21924ba319b5SDimitry Andric        return _IterSymlink;
21934ba319b5SDimitry Andric      default:
21944ba319b5SDimitry Andric        return _IterNonSymlink;
21954ba319b5SDimitry Andric      }
21964ba319b5SDimitry Andric    }();
21974ba319b5SDimitry Andric    return __data;
21984ba319b5SDimitry Andric  }
21994ba319b5SDimitry Andric
22004ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22014ba319b5SDimitry Andric  void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
22024ba319b5SDimitry Andric    __p_ = std::move(__p);
22034ba319b5SDimitry Andric    __data_ = __dt;
22044ba319b5SDimitry Andric  }
22054ba319b5SDimitry Andric
22064ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
22074ba319b5SDimitry Andric  error_code __do_refresh() noexcept;
22084ba319b5SDimitry Andric
22094ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22104ba319b5SDimitry Andric  static bool __is_dne_error(error_code const& __ec) {
22114ba319b5SDimitry Andric    if (!__ec)
22124ba319b5SDimitry Andric      return true;
22134ba319b5SDimitry Andric    switch (static_cast<errc>(__ec.value())) {
22144ba319b5SDimitry Andric    case errc::no_such_file_or_directory:
22154ba319b5SDimitry Andric    case errc::not_a_directory:
22164ba319b5SDimitry Andric      return true;
22174ba319b5SDimitry Andric    default:
22184ba319b5SDimitry Andric      return false;
22194ba319b5SDimitry Andric    }
22204ba319b5SDimitry Andric  }
22214ba319b5SDimitry Andric
22224ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22234ba319b5SDimitry Andric  void __handle_error(const char* __msg, error_code* __dest_ec,
22244ba319b5SDimitry Andric                      error_code const& __ec, bool __allow_dne = false) const {
22254ba319b5SDimitry Andric    if (__dest_ec) {
22264ba319b5SDimitry Andric      *__dest_ec = __ec;
22274ba319b5SDimitry Andric      return;
22284ba319b5SDimitry Andric    }
22294ba319b5SDimitry Andric    if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
22304ba319b5SDimitry Andric      __throw_filesystem_error(__msg, __p_, __ec);
22314ba319b5SDimitry Andric  }
22324ba319b5SDimitry Andric
22334ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22344ba319b5SDimitry Andric  void __refresh(error_code* __ec = nullptr) {
22354ba319b5SDimitry Andric    __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
22364ba319b5SDimitry Andric                   /*allow_dne*/ true);
22374ba319b5SDimitry Andric  }
22384ba319b5SDimitry Andric
22394ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22404ba319b5SDimitry Andric  file_type __get_sym_ft(error_code* __ec = nullptr) const {
22414ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
22424ba319b5SDimitry Andric    case _Empty:
22434ba319b5SDimitry Andric      return __symlink_status(__p_, __ec).type();
22444ba319b5SDimitry Andric    case _IterSymlink:
22454ba319b5SDimitry Andric    case _RefreshSymlink:
22464ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
22474ba319b5SDimitry Andric      if (__ec)
22484ba319b5SDimitry Andric        __ec->clear();
22494ba319b5SDimitry Andric      return file_type::symlink;
22504ba319b5SDimitry Andric    case _IterNonSymlink:
22514ba319b5SDimitry Andric    case _RefreshNonSymlink:
22524ba319b5SDimitry Andric      file_status __st(__data_.__type_);
22534ba319b5SDimitry Andric      if (__ec && !_VSTD_FS::exists(__st))
22544ba319b5SDimitry Andric        *__ec = make_error_code(errc::no_such_file_or_directory);
22554ba319b5SDimitry Andric      else if (__ec)
22564ba319b5SDimitry Andric        __ec->clear();
22574ba319b5SDimitry Andric      return __data_.__type_;
22584ba319b5SDimitry Andric    }
22594ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
22604ba319b5SDimitry Andric  }
22614ba319b5SDimitry Andric
22624ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22634ba319b5SDimitry Andric  file_type __get_ft(error_code* __ec = nullptr) const {
22644ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
22654ba319b5SDimitry Andric    case _Empty:
22664ba319b5SDimitry Andric    case _IterSymlink:
22674ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
22684ba319b5SDimitry Andric      return __status(__p_, __ec).type();
22694ba319b5SDimitry Andric    case _IterNonSymlink:
22704ba319b5SDimitry Andric    case _RefreshNonSymlink:
22714ba319b5SDimitry Andric    case _RefreshSymlink: {
22724ba319b5SDimitry Andric      file_status __st(__data_.__type_);
22734ba319b5SDimitry Andric      if (__ec && !_VSTD_FS::exists(__st))
22744ba319b5SDimitry Andric        *__ec = make_error_code(errc::no_such_file_or_directory);
22754ba319b5SDimitry Andric      else if (__ec)
22764ba319b5SDimitry Andric        __ec->clear();
22774ba319b5SDimitry Andric      return __data_.__type_;
22784ba319b5SDimitry Andric    }
22794ba319b5SDimitry Andric    }
22804ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
22814ba319b5SDimitry Andric  }
22824ba319b5SDimitry Andric
22834ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22844ba319b5SDimitry Andric  file_status __get_status(error_code* __ec = nullptr) const {
22854ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
22864ba319b5SDimitry Andric    case _Empty:
22874ba319b5SDimitry Andric    case _IterNonSymlink:
22884ba319b5SDimitry Andric    case _IterSymlink:
22894ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
22904ba319b5SDimitry Andric      return __status(__p_, __ec);
22914ba319b5SDimitry Andric    case _RefreshNonSymlink:
22924ba319b5SDimitry Andric    case _RefreshSymlink:
22934ba319b5SDimitry Andric      return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
22944ba319b5SDimitry Andric    }
22954ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
22964ba319b5SDimitry Andric  }
22974ba319b5SDimitry Andric
22984ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22994ba319b5SDimitry Andric  file_status __get_symlink_status(error_code* __ec = nullptr) const {
23004ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
23014ba319b5SDimitry Andric    case _Empty:
23024ba319b5SDimitry Andric    case _IterNonSymlink:
23034ba319b5SDimitry Andric    case _IterSymlink:
23044ba319b5SDimitry Andric      return __symlink_status(__p_, __ec);
23054ba319b5SDimitry Andric    case _RefreshNonSymlink:
23064ba319b5SDimitry Andric      return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
23074ba319b5SDimitry Andric    case _RefreshSymlink:
23084ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
23094ba319b5SDimitry Andric      return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
23104ba319b5SDimitry Andric    }
23114ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
23124ba319b5SDimitry Andric  }
23134ba319b5SDimitry Andric
23144ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23154ba319b5SDimitry Andric  uintmax_t __get_size(error_code* __ec = nullptr) const {
23164ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
23174ba319b5SDimitry Andric    case _Empty:
23184ba319b5SDimitry Andric    case _IterNonSymlink:
23194ba319b5SDimitry Andric    case _IterSymlink:
23204ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
23214ba319b5SDimitry Andric      return _VSTD_FS::__file_size(__p_, __ec);
23224ba319b5SDimitry Andric    case _RefreshSymlink:
23234ba319b5SDimitry Andric    case _RefreshNonSymlink: {
23244ba319b5SDimitry Andric      error_code __m_ec;
23254ba319b5SDimitry Andric      file_status __st(__get_ft(&__m_ec));
23264ba319b5SDimitry Andric      __handle_error("in directory_entry::file_size", __ec, __m_ec);
23274ba319b5SDimitry Andric      if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
23284ba319b5SDimitry Andric        errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
23294ba319b5SDimitry Andric                                                       : errc::not_supported;
23304ba319b5SDimitry Andric        __handle_error("in directory_entry::file_size", __ec,
23314ba319b5SDimitry Andric                       make_error_code(__err_kind));
23324ba319b5SDimitry Andric      }
23334ba319b5SDimitry Andric      return __data_.__size_;
23344ba319b5SDimitry Andric    }
23354ba319b5SDimitry Andric    }
23364ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
23374ba319b5SDimitry Andric  }
23384ba319b5SDimitry Andric
23394ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23404ba319b5SDimitry Andric  uintmax_t __get_nlink(error_code* __ec = nullptr) const {
23414ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
23424ba319b5SDimitry Andric    case _Empty:
23434ba319b5SDimitry Andric    case _IterNonSymlink:
23444ba319b5SDimitry Andric    case _IterSymlink:
23454ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
23464ba319b5SDimitry Andric      return _VSTD_FS::__hard_link_count(__p_, __ec);
23474ba319b5SDimitry Andric    case _RefreshSymlink:
23484ba319b5SDimitry Andric    case _RefreshNonSymlink: {
23494ba319b5SDimitry Andric      error_code __m_ec;
23504ba319b5SDimitry Andric      (void)__get_ft(&__m_ec);
23514ba319b5SDimitry Andric      __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
23524ba319b5SDimitry Andric      return __data_.__nlink_;
23534ba319b5SDimitry Andric    }
23544ba319b5SDimitry Andric    }
23554ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
23564ba319b5SDimitry Andric  }
23574ba319b5SDimitry Andric
23584ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23594ba319b5SDimitry Andric  file_time_type __get_write_time(error_code* __ec = nullptr) const {
23604ba319b5SDimitry Andric    switch (__data_.__cache_type_) {
23614ba319b5SDimitry Andric    case _Empty:
23624ba319b5SDimitry Andric    case _IterNonSymlink:
23634ba319b5SDimitry Andric    case _IterSymlink:
23644ba319b5SDimitry Andric    case _RefreshSymlinkUnresolved:
23654ba319b5SDimitry Andric      return _VSTD_FS::__last_write_time(__p_, __ec);
23664ba319b5SDimitry Andric    case _RefreshSymlink:
23674ba319b5SDimitry Andric    case _RefreshNonSymlink: {
23684ba319b5SDimitry Andric      error_code __m_ec;
23694ba319b5SDimitry Andric      file_status __st(__get_ft(&__m_ec));
23704ba319b5SDimitry Andric      __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
23714ba319b5SDimitry Andric      if (_VSTD_FS::exists(__st) &&
23724ba319b5SDimitry Andric          __data_.__write_time_ == file_time_type::min())
23734ba319b5SDimitry Andric        __handle_error("in directory_entry::last_write_time", __ec,
23744ba319b5SDimitry Andric                       make_error_code(errc::value_too_large));
23754ba319b5SDimitry Andric      return __data_.__write_time_;
23764ba319b5SDimitry Andric    }
23774ba319b5SDimitry Andric    }
23784ba319b5SDimitry Andric    _LIBCPP_UNREACHABLE();
23794ba319b5SDimitry Andric  }
23804ba319b5SDimitry Andric
23814ba319b5SDimitry Andricprivate:
23824ba319b5SDimitry Andric  _Path __p_;
23834ba319b5SDimitry Andric  __cached_data __data_;
23844ba319b5SDimitry Andric};
23854ba319b5SDimitry Andric
23864ba319b5SDimitry Andricclass __dir_element_proxy {
23874ba319b5SDimitry Andricpublic:
23884ba319b5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
23894ba319b5SDimitry Andric    return _VSTD::move(__elem_);
23904ba319b5SDimitry Andric  }
23914ba319b5SDimitry Andric
23924ba319b5SDimitry Andricprivate:
23934ba319b5SDimitry Andric  friend class directory_iterator;
23944ba319b5SDimitry Andric  friend class recursive_directory_iterator;
23954ba319b5SDimitry Andric  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
23964ba319b5SDimitry Andric  __dir_element_proxy(__dir_element_proxy&& __o)
23974ba319b5SDimitry Andric      : __elem_(_VSTD::move(__o.__elem_)) {}
23984ba319b5SDimitry Andric  directory_entry __elem_;
23994ba319b5SDimitry Andric};
24004ba319b5SDimitry Andric
24014ba319b5SDimitry Andricclass directory_iterator {
24024ba319b5SDimitry Andricpublic:
24034ba319b5SDimitry Andric  typedef directory_entry value_type;
24044ba319b5SDimitry Andric  typedef ptrdiff_t difference_type;
24054ba319b5SDimitry Andric  typedef value_type const* pointer;
24064ba319b5SDimitry Andric  typedef value_type const& reference;
24074ba319b5SDimitry Andric  typedef input_iterator_tag iterator_category;
24084ba319b5SDimitry Andric
24094ba319b5SDimitry Andricpublic:
24104ba319b5SDimitry Andric  //ctor & dtor
24114ba319b5SDimitry Andric  directory_iterator() noexcept {}
24124ba319b5SDimitry Andric
24134ba319b5SDimitry Andric  explicit directory_iterator(const path& __p)
24144ba319b5SDimitry Andric      : directory_iterator(__p, nullptr) {}
24154ba319b5SDimitry Andric
24164ba319b5SDimitry Andric  directory_iterator(const path& __p, directory_options __opts)
24174ba319b5SDimitry Andric      : directory_iterator(__p, nullptr, __opts) {}
24184ba319b5SDimitry Andric
24194ba319b5SDimitry Andric  directory_iterator(const path& __p, error_code& __ec)
24204ba319b5SDimitry Andric      : directory_iterator(__p, &__ec) {}
24214ba319b5SDimitry Andric
24224ba319b5SDimitry Andric  directory_iterator(const path& __p, directory_options __opts,
24234ba319b5SDimitry Andric                     error_code& __ec)
24244ba319b5SDimitry Andric      : directory_iterator(__p, &__ec, __opts) {}
24254ba319b5SDimitry Andric
24264ba319b5SDimitry Andric  directory_iterator(const directory_iterator&) = default;
24274ba319b5SDimitry Andric  directory_iterator(directory_iterator&&) = default;
24284ba319b5SDimitry Andric  directory_iterator& operator=(const directory_iterator&) = default;
24294ba319b5SDimitry Andric
24304ba319b5SDimitry Andric  directory_iterator& operator=(directory_iterator&& __o) noexcept {
24314ba319b5SDimitry Andric    // non-default implementation provided to support self-move assign.
24324ba319b5SDimitry Andric    if (this != &__o) {
24334ba319b5SDimitry Andric      __imp_ = _VSTD::move(__o.__imp_);
24344ba319b5SDimitry Andric    }
24354ba319b5SDimitry Andric    return *this;
24364ba319b5SDimitry Andric  }
24374ba319b5SDimitry Andric
24384ba319b5SDimitry Andric  ~directory_iterator() = default;
24394ba319b5SDimitry Andric
24404ba319b5SDimitry Andric  const directory_entry& operator*() const {
24414ba319b5SDimitry Andric    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
24424ba319b5SDimitry Andric    return __dereference();
24434ba319b5SDimitry Andric  }
24444ba319b5SDimitry Andric
24454ba319b5SDimitry Andric  const directory_entry* operator->() const { return &**this; }
24464ba319b5SDimitry Andric
24474ba319b5SDimitry Andric  directory_iterator& operator++() { return __increment(); }
24484ba319b5SDimitry Andric
24494ba319b5SDimitry Andric  __dir_element_proxy operator++(int) {
24504ba319b5SDimitry Andric    __dir_element_proxy __p(**this);
24514ba319b5SDimitry Andric    __increment();
24524ba319b5SDimitry Andric    return __p;
24534ba319b5SDimitry Andric  }
24544ba319b5SDimitry Andric
24554ba319b5SDimitry Andric  directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
24564ba319b5SDimitry Andric
24574ba319b5SDimitry Andricprivate:
24584ba319b5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool
24594ba319b5SDimitry Andric  operator==(const directory_iterator& __lhs,
24604ba319b5SDimitry Andric             const directory_iterator& __rhs) noexcept;
24614ba319b5SDimitry Andric
24624ba319b5SDimitry Andric  // construct the dir_stream
24634ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
24644ba319b5SDimitry Andric  directory_iterator(const path&, error_code*,
24654ba319b5SDimitry Andric                     directory_options = directory_options::none);
24664ba319b5SDimitry Andric
24674ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
24684ba319b5SDimitry Andric  directory_iterator& __increment(error_code* __ec = nullptr);
24694ba319b5SDimitry Andric
24704ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
24714ba319b5SDimitry Andric  const directory_entry& __dereference() const;
24724ba319b5SDimitry Andric
24734ba319b5SDimitry Andricprivate:
24744ba319b5SDimitry Andric  shared_ptr<__dir_stream> __imp_;
24754ba319b5SDimitry Andric};
24764ba319b5SDimitry Andric
24774ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
24784ba319b5SDimitry Andricoperator==(const directory_iterator& __lhs,
24794ba319b5SDimitry Andric           const directory_iterator& __rhs) noexcept {
24804ba319b5SDimitry Andric  return __lhs.__imp_ == __rhs.__imp_;
24814ba319b5SDimitry Andric}
24824ba319b5SDimitry Andric
24834ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
24844ba319b5SDimitry Andricoperator!=(const directory_iterator& __lhs,
24854ba319b5SDimitry Andric           const directory_iterator& __rhs) noexcept {
24864ba319b5SDimitry Andric  return !(__lhs == __rhs);
24874ba319b5SDimitry Andric}
24884ba319b5SDimitry Andric
24894ba319b5SDimitry Andric// enable directory_iterator range-based for statements
24904ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY directory_iterator
24914ba319b5SDimitry Andricbegin(directory_iterator __iter) noexcept {
24924ba319b5SDimitry Andric  return __iter;
24934ba319b5SDimitry Andric}
24944ba319b5SDimitry Andric
24954ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY directory_iterator
24964ba319b5SDimitry Andricend(const directory_iterator&) noexcept {
24974ba319b5SDimitry Andric  return directory_iterator();
24984ba319b5SDimitry Andric}
24994ba319b5SDimitry Andric
25004ba319b5SDimitry Andricclass recursive_directory_iterator {
25014ba319b5SDimitry Andricpublic:
25024ba319b5SDimitry Andric  using value_type = directory_entry;
25034ba319b5SDimitry Andric  using difference_type = std::ptrdiff_t;
25044ba319b5SDimitry Andric  using pointer = directory_entry const*;
25054ba319b5SDimitry Andric  using reference = directory_entry const&;
25064ba319b5SDimitry Andric  using iterator_category = std::input_iterator_tag;
25074ba319b5SDimitry Andric
25084ba319b5SDimitry Andricpublic:
25094ba319b5SDimitry Andric  // constructors and destructor
25104ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25114ba319b5SDimitry Andric  recursive_directory_iterator() noexcept : __rec_(false) {}
25124ba319b5SDimitry Andric
25134ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25144ba319b5SDimitry Andric  explicit recursive_directory_iterator(
25154ba319b5SDimitry Andric      const path& __p, directory_options __xoptions = directory_options::none)
25164ba319b5SDimitry Andric      : recursive_directory_iterator(__p, __xoptions, nullptr) {}
25174ba319b5SDimitry Andric
25184ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25194ba319b5SDimitry Andric  recursive_directory_iterator(const path& __p, directory_options __xoptions,
25204ba319b5SDimitry Andric                               error_code& __ec)
25214ba319b5SDimitry Andric      : recursive_directory_iterator(__p, __xoptions, &__ec) {}
25224ba319b5SDimitry Andric
25234ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25244ba319b5SDimitry Andric  recursive_directory_iterator(const path& __p, error_code& __ec)
25254ba319b5SDimitry Andric      : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
25264ba319b5SDimitry Andric
25274ba319b5SDimitry Andric  recursive_directory_iterator(const recursive_directory_iterator&) = default;
25284ba319b5SDimitry Andric  recursive_directory_iterator(recursive_directory_iterator&&) = default;
25294ba319b5SDimitry Andric
25304ba319b5SDimitry Andric  recursive_directory_iterator&
25314ba319b5SDimitry Andric  operator=(const recursive_directory_iterator&) = default;
25324ba319b5SDimitry Andric
25334ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25344ba319b5SDimitry Andric  recursive_directory_iterator&
25354ba319b5SDimitry Andric  operator=(recursive_directory_iterator&& __o) noexcept {
25364ba319b5SDimitry Andric    // non-default implementation provided to support self-move assign.
25374ba319b5SDimitry Andric    if (this != &__o) {
25384ba319b5SDimitry Andric      __imp_ = _VSTD::move(__o.__imp_);
25394ba319b5SDimitry Andric      __rec_ = __o.__rec_;
25404ba319b5SDimitry Andric    }
25414ba319b5SDimitry Andric    return *this;
25424ba319b5SDimitry Andric  }
25434ba319b5SDimitry Andric
25444ba319b5SDimitry Andric  ~recursive_directory_iterator() = default;
25454ba319b5SDimitry Andric
25464ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25474ba319b5SDimitry Andric  const directory_entry& operator*() const { return __dereference(); }
25484ba319b5SDimitry Andric
25494ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25504ba319b5SDimitry Andric  const directory_entry* operator->() const { return &__dereference(); }
25514ba319b5SDimitry Andric
25524ba319b5SDimitry Andric  recursive_directory_iterator& operator++() { return __increment(); }
25534ba319b5SDimitry Andric
25544ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25554ba319b5SDimitry Andric  __dir_element_proxy operator++(int) {
25564ba319b5SDimitry Andric    __dir_element_proxy __p(**this);
25574ba319b5SDimitry Andric    __increment();
25584ba319b5SDimitry Andric    return __p;
25594ba319b5SDimitry Andric  }
25604ba319b5SDimitry Andric
25614ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25624ba319b5SDimitry Andric  recursive_directory_iterator& increment(error_code& __ec) {
25634ba319b5SDimitry Andric    return __increment(&__ec);
25644ba319b5SDimitry Andric  }
25654ba319b5SDimitry Andric
25664ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS directory_options options() const;
25674ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS int depth() const;
25684ba319b5SDimitry Andric
25694ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25704ba319b5SDimitry Andric  void pop() { __pop(); }
25714ba319b5SDimitry Andric
25724ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25734ba319b5SDimitry Andric  void pop(error_code& __ec) { __pop(&__ec); }
25744ba319b5SDimitry Andric
25754ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25764ba319b5SDimitry Andric  bool recursion_pending() const { return __rec_; }
25774ba319b5SDimitry Andric
25784ba319b5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25794ba319b5SDimitry Andric  void disable_recursion_pending() { __rec_ = false; }
25804ba319b5SDimitry Andric
25814ba319b5SDimitry Andricprivate:
25824ba319b5SDimitry Andric  recursive_directory_iterator(const path& __p, directory_options __opt,
25834ba319b5SDimitry Andric                               error_code* __ec);
25844ba319b5SDimitry Andric
25854ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
25864ba319b5SDimitry Andric  const directory_entry& __dereference() const;
25874ba319b5SDimitry Andric
25884ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
25894ba319b5SDimitry Andric  bool __try_recursion(error_code* __ec);
25904ba319b5SDimitry Andric
25914ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
25924ba319b5SDimitry Andric  void __advance(error_code* __ec = nullptr);
25934ba319b5SDimitry Andric
25944ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
25954ba319b5SDimitry Andric  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
25964ba319b5SDimitry Andric
25974ba319b5SDimitry Andric  _LIBCPP_FUNC_VIS
25984ba319b5SDimitry Andric  void __pop(error_code* __ec = nullptr);
25994ba319b5SDimitry Andric
26004ba319b5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY friend bool
26014ba319b5SDimitry Andric  operator==(const recursive_directory_iterator&,
26024ba319b5SDimitry Andric             const recursive_directory_iterator&) noexcept;
26034ba319b5SDimitry Andric
26044ba319b5SDimitry Andric  struct __shared_imp;
26054ba319b5SDimitry Andric  shared_ptr<__shared_imp> __imp_;
26064ba319b5SDimitry Andric  bool __rec_;
26074ba319b5SDimitry Andric}; // class recursive_directory_iterator
26084ba319b5SDimitry Andric
26094ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool
26104ba319b5SDimitry Andricoperator==(const recursive_directory_iterator& __lhs,
26114ba319b5SDimitry Andric           const recursive_directory_iterator& __rhs) noexcept {
26124ba319b5SDimitry Andric  return __lhs.__imp_ == __rhs.__imp_;
26134ba319b5SDimitry Andric}
26144ba319b5SDimitry Andric
26154ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
26164ba319b5SDimitry Andricinline bool operator!=(const recursive_directory_iterator& __lhs,
26174ba319b5SDimitry Andric                       const recursive_directory_iterator& __rhs) noexcept {
26184ba319b5SDimitry Andric  return !(__lhs == __rhs);
26194ba319b5SDimitry Andric}
26204ba319b5SDimitry Andric// enable recursive_directory_iterator range-based for statements
26214ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
26224ba319b5SDimitry Andricbegin(recursive_directory_iterator __iter) noexcept {
26234ba319b5SDimitry Andric  return __iter;
26244ba319b5SDimitry Andric}
26254ba319b5SDimitry Andric
26264ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
26274ba319b5SDimitry Andricend(const recursive_directory_iterator&) noexcept {
26284ba319b5SDimitry Andric  return recursive_directory_iterator();
26294ba319b5SDimitry Andric}
26304ba319b5SDimitry Andric
26314ba319b5SDimitry Andric_LIBCPP_END_NAMESPACE_FILESYSTEM
26324ba319b5SDimitry Andric
26334ba319b5SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
26344ba319b5SDimitry Andric
26354ba319b5SDimitry Andric_LIBCPP_POP_MACROS
26364ba319b5SDimitry Andric
26374ba319b5SDimitry Andric#endif // _LIBCPP_FILESYSTEM
2638