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