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