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