1*4bdff4beSrobert // -*- C++ -*- 2*4bdff4beSrobert //===----------------------------------------------------------------------===// 3*4bdff4beSrobert // 4*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information. 6*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4bdff4beSrobert // 8*4bdff4beSrobert //===----------------------------------------------------------------------===// 9*4bdff4beSrobert 10*4bdff4beSrobert #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H 11*4bdff4beSrobert #define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H 12*4bdff4beSrobert 13*4bdff4beSrobert #include <__availability> 14*4bdff4beSrobert #include <__chrono/time_point.h> 15*4bdff4beSrobert #include <__config> 16*4bdff4beSrobert #include <__errc> 17*4bdff4beSrobert #include <__filesystem/file_status.h> 18*4bdff4beSrobert #include <__filesystem/file_time_type.h> 19*4bdff4beSrobert #include <__filesystem/file_type.h> 20*4bdff4beSrobert #include <__filesystem/filesystem_error.h> 21*4bdff4beSrobert #include <__filesystem/operations.h> 22*4bdff4beSrobert #include <__filesystem/path.h> 23*4bdff4beSrobert #include <__filesystem/perms.h> 24*4bdff4beSrobert #include <__utility/unreachable.h> 25*4bdff4beSrobert #include <cstdint> 26*4bdff4beSrobert #include <cstdlib> 27*4bdff4beSrobert #include <iosfwd> 28*4bdff4beSrobert #include <system_error> 29*4bdff4beSrobert 30*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 31*4bdff4beSrobert # pragma GCC system_header 32*4bdff4beSrobert #endif 33*4bdff4beSrobert 34*4bdff4beSrobert _LIBCPP_PUSH_MACROS 35*4bdff4beSrobert #include <__undef_macros> 36*4bdff4beSrobert 37*4bdff4beSrobert #ifndef _LIBCPP_CXX03_LANG 38*4bdff4beSrobert 39*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM 40*4bdff4beSrobert 41*4bdff4beSrobert _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH 42*4bdff4beSrobert 43*4bdff4beSrobert 44*4bdff4beSrobert class directory_entry { 45*4bdff4beSrobert typedef _VSTD_FS::path _Path; 46*4bdff4beSrobert 47*4bdff4beSrobert public: 48*4bdff4beSrobert // constructors and destructors 49*4bdff4beSrobert directory_entry() noexcept = default; 50*4bdff4beSrobert directory_entry(directory_entry const&) = default; 51*4bdff4beSrobert directory_entry(directory_entry&&) noexcept = default; 52*4bdff4beSrobert 53*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY directory_entry(_Path const & __p)54*4bdff4beSrobert explicit directory_entry(_Path const& __p) : __p_(__p) { 55*4bdff4beSrobert error_code __ec; 56*4bdff4beSrobert __refresh(&__ec); 57*4bdff4beSrobert } 58*4bdff4beSrobert 59*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY directory_entry(_Path const & __p,error_code & __ec)60*4bdff4beSrobert directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { 61*4bdff4beSrobert __refresh(&__ec); 62*4bdff4beSrobert } 63*4bdff4beSrobert ~directory_entry()64*4bdff4beSrobert ~directory_entry() {} 65*4bdff4beSrobert 66*4bdff4beSrobert directory_entry& operator=(directory_entry const&) = default; 67*4bdff4beSrobert directory_entry& operator=(directory_entry&&) noexcept = default; 68*4bdff4beSrobert 69*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY assign(_Path const & __p)70*4bdff4beSrobert void assign(_Path const& __p) { 71*4bdff4beSrobert __p_ = __p; 72*4bdff4beSrobert error_code __ec; 73*4bdff4beSrobert __refresh(&__ec); 74*4bdff4beSrobert } 75*4bdff4beSrobert 76*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY assign(_Path const & __p,error_code & __ec)77*4bdff4beSrobert void assign(_Path const& __p, error_code& __ec) { 78*4bdff4beSrobert __p_ = __p; 79*4bdff4beSrobert __refresh(&__ec); 80*4bdff4beSrobert } 81*4bdff4beSrobert 82*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY replace_filename(_Path const & __p)83*4bdff4beSrobert void replace_filename(_Path const& __p) { 84*4bdff4beSrobert __p_.replace_filename(__p); 85*4bdff4beSrobert error_code __ec; 86*4bdff4beSrobert __refresh(&__ec); 87*4bdff4beSrobert } 88*4bdff4beSrobert 89*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY replace_filename(_Path const & __p,error_code & __ec)90*4bdff4beSrobert void replace_filename(_Path const& __p, error_code& __ec) { 91*4bdff4beSrobert __p_ = __p_.parent_path() / __p; 92*4bdff4beSrobert __refresh(&__ec); 93*4bdff4beSrobert } 94*4bdff4beSrobert 95*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY refresh()96*4bdff4beSrobert void refresh() { __refresh(); } 97*4bdff4beSrobert 98*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY refresh(error_code & __ec)99*4bdff4beSrobert void refresh(error_code& __ec) noexcept { __refresh(&__ec); } 100*4bdff4beSrobert 101*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY path()102*4bdff4beSrobert _Path const& path() const noexcept { return __p_; } 103*4bdff4beSrobert 104*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 105*4bdff4beSrobert operator const _Path&() const noexcept { return __p_; } 106*4bdff4beSrobert 107*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY exists()108*4bdff4beSrobert bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } 109*4bdff4beSrobert 110*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY exists(error_code & __ec)111*4bdff4beSrobert bool exists(error_code& __ec) const noexcept { 112*4bdff4beSrobert return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); 113*4bdff4beSrobert } 114*4bdff4beSrobert 115*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_block_file()116*4bdff4beSrobert bool is_block_file() const { return __get_ft() == file_type::block; } 117*4bdff4beSrobert 118*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_block_file(error_code & __ec)119*4bdff4beSrobert bool is_block_file(error_code& __ec) const noexcept { 120*4bdff4beSrobert return __get_ft(&__ec) == file_type::block; 121*4bdff4beSrobert } 122*4bdff4beSrobert 123*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_character_file()124*4bdff4beSrobert bool is_character_file() const { return __get_ft() == file_type::character; } 125*4bdff4beSrobert 126*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_character_file(error_code & __ec)127*4bdff4beSrobert bool is_character_file(error_code& __ec) const noexcept { 128*4bdff4beSrobert return __get_ft(&__ec) == file_type::character; 129*4bdff4beSrobert } 130*4bdff4beSrobert 131*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_directory()132*4bdff4beSrobert bool is_directory() const { return __get_ft() == file_type::directory; } 133*4bdff4beSrobert 134*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_directory(error_code & __ec)135*4bdff4beSrobert bool is_directory(error_code& __ec) const noexcept { 136*4bdff4beSrobert return __get_ft(&__ec) == file_type::directory; 137*4bdff4beSrobert } 138*4bdff4beSrobert 139*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_fifo()140*4bdff4beSrobert bool is_fifo() const { return __get_ft() == file_type::fifo; } 141*4bdff4beSrobert 142*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_fifo(error_code & __ec)143*4bdff4beSrobert bool is_fifo(error_code& __ec) const noexcept { 144*4bdff4beSrobert return __get_ft(&__ec) == file_type::fifo; 145*4bdff4beSrobert } 146*4bdff4beSrobert 147*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_other()148*4bdff4beSrobert bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } 149*4bdff4beSrobert 150*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_other(error_code & __ec)151*4bdff4beSrobert bool is_other(error_code& __ec) const noexcept { 152*4bdff4beSrobert return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); 153*4bdff4beSrobert } 154*4bdff4beSrobert 155*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_regular_file()156*4bdff4beSrobert bool is_regular_file() const { return __get_ft() == file_type::regular; } 157*4bdff4beSrobert 158*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_regular_file(error_code & __ec)159*4bdff4beSrobert bool is_regular_file(error_code& __ec) const noexcept { 160*4bdff4beSrobert return __get_ft(&__ec) == file_type::regular; 161*4bdff4beSrobert } 162*4bdff4beSrobert 163*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_socket()164*4bdff4beSrobert bool is_socket() const { return __get_ft() == file_type::socket; } 165*4bdff4beSrobert 166*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_socket(error_code & __ec)167*4bdff4beSrobert bool is_socket(error_code& __ec) const noexcept { 168*4bdff4beSrobert return __get_ft(&__ec) == file_type::socket; 169*4bdff4beSrobert } 170*4bdff4beSrobert 171*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_symlink()172*4bdff4beSrobert bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } 173*4bdff4beSrobert 174*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY is_symlink(error_code & __ec)175*4bdff4beSrobert bool is_symlink(error_code& __ec) const noexcept { 176*4bdff4beSrobert return __get_sym_ft(&__ec) == file_type::symlink; 177*4bdff4beSrobert } 178*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY file_size()179*4bdff4beSrobert uintmax_t file_size() const { return __get_size(); } 180*4bdff4beSrobert 181*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY file_size(error_code & __ec)182*4bdff4beSrobert uintmax_t file_size(error_code& __ec) const noexcept { 183*4bdff4beSrobert return __get_size(&__ec); 184*4bdff4beSrobert } 185*4bdff4beSrobert 186*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY hard_link_count()187*4bdff4beSrobert uintmax_t hard_link_count() const { return __get_nlink(); } 188*4bdff4beSrobert 189*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY hard_link_count(error_code & __ec)190*4bdff4beSrobert uintmax_t hard_link_count(error_code& __ec) const noexcept { 191*4bdff4beSrobert return __get_nlink(&__ec); 192*4bdff4beSrobert } 193*4bdff4beSrobert 194*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY last_write_time()195*4bdff4beSrobert file_time_type last_write_time() const { return __get_write_time(); } 196*4bdff4beSrobert 197*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY last_write_time(error_code & __ec)198*4bdff4beSrobert file_time_type last_write_time(error_code& __ec) const noexcept { 199*4bdff4beSrobert return __get_write_time(&__ec); 200*4bdff4beSrobert } 201*4bdff4beSrobert 202*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY status()203*4bdff4beSrobert file_status status() const { return __get_status(); } 204*4bdff4beSrobert 205*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY status(error_code & __ec)206*4bdff4beSrobert file_status status(error_code& __ec) const noexcept { 207*4bdff4beSrobert return __get_status(&__ec); 208*4bdff4beSrobert } 209*4bdff4beSrobert 210*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY symlink_status()211*4bdff4beSrobert file_status symlink_status() const { return __get_symlink_status(); } 212*4bdff4beSrobert 213*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY symlink_status(error_code & __ec)214*4bdff4beSrobert file_status symlink_status(error_code& __ec) const noexcept { 215*4bdff4beSrobert return __get_symlink_status(&__ec); 216*4bdff4beSrobert } 217*4bdff4beSrobert 218*4bdff4beSrobert 219*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 220*4bdff4beSrobert bool operator==(directory_entry const& __rhs) const noexcept { 221*4bdff4beSrobert return __p_ == __rhs.__p_; 222*4bdff4beSrobert } 223*4bdff4beSrobert 224*4bdff4beSrobert #if _LIBCPP_STD_VER <= 17 225*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 226*4bdff4beSrobert bool operator!=(directory_entry const& __rhs) const noexcept { 227*4bdff4beSrobert return __p_ != __rhs.__p_; 228*4bdff4beSrobert } 229*4bdff4beSrobert 230*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 231*4bdff4beSrobert bool operator<(directory_entry const& __rhs) const noexcept { 232*4bdff4beSrobert return __p_ < __rhs.__p_; 233*4bdff4beSrobert } 234*4bdff4beSrobert 235*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 236*4bdff4beSrobert bool operator<=(directory_entry const& __rhs) const noexcept { 237*4bdff4beSrobert return __p_ <= __rhs.__p_; 238*4bdff4beSrobert } 239*4bdff4beSrobert 240*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 241*4bdff4beSrobert bool operator>(directory_entry const& __rhs) const noexcept { 242*4bdff4beSrobert return __p_ > __rhs.__p_; 243*4bdff4beSrobert } 244*4bdff4beSrobert 245*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 246*4bdff4beSrobert bool operator>=(directory_entry const& __rhs) const noexcept { 247*4bdff4beSrobert return __p_ >= __rhs.__p_; 248*4bdff4beSrobert } 249*4bdff4beSrobert 250*4bdff4beSrobert #else // _LIBCPP_STD_VER <= 17 251*4bdff4beSrobert 252*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 253*4bdff4beSrobert strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { 254*4bdff4beSrobert return __p_ <=> __rhs.__p_; 255*4bdff4beSrobert } 256*4bdff4beSrobert 257*4bdff4beSrobert #endif // _LIBCPP_STD_VER <= 17 258*4bdff4beSrobert 259*4bdff4beSrobert template <class _CharT, class _Traits> 260*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 261*4bdff4beSrobert friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { 262*4bdff4beSrobert return __os << __d.path(); 263*4bdff4beSrobert } 264*4bdff4beSrobert 265*4bdff4beSrobert private: 266*4bdff4beSrobert friend class directory_iterator; 267*4bdff4beSrobert friend class recursive_directory_iterator; 268*4bdff4beSrobert friend class _LIBCPP_HIDDEN __dir_stream; 269*4bdff4beSrobert 270*4bdff4beSrobert enum _CacheType : unsigned char { 271*4bdff4beSrobert _Empty, 272*4bdff4beSrobert _IterSymlink, 273*4bdff4beSrobert _IterNonSymlink, 274*4bdff4beSrobert _RefreshSymlink, 275*4bdff4beSrobert _RefreshSymlinkUnresolved, 276*4bdff4beSrobert _RefreshNonSymlink 277*4bdff4beSrobert }; 278*4bdff4beSrobert 279*4bdff4beSrobert struct __cached_data { 280*4bdff4beSrobert uintmax_t __size_; 281*4bdff4beSrobert uintmax_t __nlink_; 282*4bdff4beSrobert file_time_type __write_time_; 283*4bdff4beSrobert perms __sym_perms_; 284*4bdff4beSrobert perms __non_sym_perms_; 285*4bdff4beSrobert file_type __type_; 286*4bdff4beSrobert _CacheType __cache_type_; 287*4bdff4beSrobert 288*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __cached_data__cached_data289*4bdff4beSrobert __cached_data() noexcept { __reset(); } 290*4bdff4beSrobert 291*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __reset__cached_data292*4bdff4beSrobert void __reset() { 293*4bdff4beSrobert __cache_type_ = _Empty; 294*4bdff4beSrobert __type_ = file_type::none; 295*4bdff4beSrobert __sym_perms_ = __non_sym_perms_ = perms::unknown; 296*4bdff4beSrobert __size_ = __nlink_ = uintmax_t(-1); 297*4bdff4beSrobert __write_time_ = file_time_type::min(); 298*4bdff4beSrobert } 299*4bdff4beSrobert }; 300*4bdff4beSrobert 301*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __create_iter_result(file_type __ft)302*4bdff4beSrobert static __cached_data __create_iter_result(file_type __ft) { 303*4bdff4beSrobert __cached_data __data; 304*4bdff4beSrobert __data.__type_ = __ft; 305*4bdff4beSrobert __data.__cache_type_ = [&]() { 306*4bdff4beSrobert switch (__ft) { 307*4bdff4beSrobert case file_type::none: 308*4bdff4beSrobert return _Empty; 309*4bdff4beSrobert case file_type::symlink: 310*4bdff4beSrobert return _IterSymlink; 311*4bdff4beSrobert default: 312*4bdff4beSrobert return _IterNonSymlink; 313*4bdff4beSrobert } 314*4bdff4beSrobert }(); 315*4bdff4beSrobert return __data; 316*4bdff4beSrobert } 317*4bdff4beSrobert 318*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __assign_iter_entry(_Path && __p,__cached_data __dt)319*4bdff4beSrobert void __assign_iter_entry(_Path&& __p, __cached_data __dt) { 320*4bdff4beSrobert __p_ = _VSTD::move(__p); 321*4bdff4beSrobert __data_ = __dt; 322*4bdff4beSrobert } 323*4bdff4beSrobert 324*4bdff4beSrobert _LIBCPP_FUNC_VIS 325*4bdff4beSrobert error_code __do_refresh() noexcept; 326*4bdff4beSrobert 327*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __is_dne_error(error_code const & __ec)328*4bdff4beSrobert static bool __is_dne_error(error_code const& __ec) { 329*4bdff4beSrobert if (!__ec) 330*4bdff4beSrobert return true; 331*4bdff4beSrobert switch (static_cast<errc>(__ec.value())) { 332*4bdff4beSrobert case errc::no_such_file_or_directory: 333*4bdff4beSrobert case errc::not_a_directory: 334*4bdff4beSrobert return true; 335*4bdff4beSrobert default: 336*4bdff4beSrobert return false; 337*4bdff4beSrobert } 338*4bdff4beSrobert } 339*4bdff4beSrobert 340*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 341*4bdff4beSrobert void __handle_error(const char* __msg, error_code* __dest_ec, 342*4bdff4beSrobert error_code const& __ec, bool __allow_dne = false) const { 343*4bdff4beSrobert if (__dest_ec) { 344*4bdff4beSrobert *__dest_ec = __ec; 345*4bdff4beSrobert return; 346*4bdff4beSrobert } 347*4bdff4beSrobert if (__ec && (!__allow_dne || !__is_dne_error(__ec))) 348*4bdff4beSrobert __throw_filesystem_error(__msg, __p_, __ec); 349*4bdff4beSrobert } 350*4bdff4beSrobert 351*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 352*4bdff4beSrobert void __refresh(error_code* __ec = nullptr) { 353*4bdff4beSrobert __handle_error("in directory_entry::refresh", __ec, __do_refresh(), 354*4bdff4beSrobert /*allow_dne*/ true); 355*4bdff4beSrobert } 356*4bdff4beSrobert 357*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 358*4bdff4beSrobert file_type __get_sym_ft(error_code* __ec = nullptr) const { 359*4bdff4beSrobert switch (__data_.__cache_type_) { 360*4bdff4beSrobert case _Empty: 361*4bdff4beSrobert return __symlink_status(__p_, __ec).type(); 362*4bdff4beSrobert case _IterSymlink: 363*4bdff4beSrobert case _RefreshSymlink: 364*4bdff4beSrobert case _RefreshSymlinkUnresolved: 365*4bdff4beSrobert if (__ec) 366*4bdff4beSrobert __ec->clear(); 367*4bdff4beSrobert return file_type::symlink; 368*4bdff4beSrobert case _IterNonSymlink: 369*4bdff4beSrobert case _RefreshNonSymlink: 370*4bdff4beSrobert file_status __st(__data_.__type_); 371*4bdff4beSrobert if (__ec && !_VSTD_FS::exists(__st)) 372*4bdff4beSrobert *__ec = make_error_code(errc::no_such_file_or_directory); 373*4bdff4beSrobert else if (__ec) 374*4bdff4beSrobert __ec->clear(); 375*4bdff4beSrobert return __data_.__type_; 376*4bdff4beSrobert } 377*4bdff4beSrobert __libcpp_unreachable(); 378*4bdff4beSrobert } 379*4bdff4beSrobert 380*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 381*4bdff4beSrobert file_type __get_ft(error_code* __ec = nullptr) const { 382*4bdff4beSrobert switch (__data_.__cache_type_) { 383*4bdff4beSrobert case _Empty: 384*4bdff4beSrobert case _IterSymlink: 385*4bdff4beSrobert case _RefreshSymlinkUnresolved: 386*4bdff4beSrobert return __status(__p_, __ec).type(); 387*4bdff4beSrobert case _IterNonSymlink: 388*4bdff4beSrobert case _RefreshNonSymlink: 389*4bdff4beSrobert case _RefreshSymlink: { 390*4bdff4beSrobert file_status __st(__data_.__type_); 391*4bdff4beSrobert if (__ec && !_VSTD_FS::exists(__st)) 392*4bdff4beSrobert *__ec = make_error_code(errc::no_such_file_or_directory); 393*4bdff4beSrobert else if (__ec) 394*4bdff4beSrobert __ec->clear(); 395*4bdff4beSrobert return __data_.__type_; 396*4bdff4beSrobert } 397*4bdff4beSrobert } 398*4bdff4beSrobert __libcpp_unreachable(); 399*4bdff4beSrobert } 400*4bdff4beSrobert 401*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 402*4bdff4beSrobert file_status __get_status(error_code* __ec = nullptr) const { 403*4bdff4beSrobert switch (__data_.__cache_type_) { 404*4bdff4beSrobert case _Empty: 405*4bdff4beSrobert case _IterNonSymlink: 406*4bdff4beSrobert case _IterSymlink: 407*4bdff4beSrobert case _RefreshSymlinkUnresolved: 408*4bdff4beSrobert return __status(__p_, __ec); 409*4bdff4beSrobert case _RefreshNonSymlink: 410*4bdff4beSrobert case _RefreshSymlink: 411*4bdff4beSrobert return file_status(__get_ft(__ec), __data_.__non_sym_perms_); 412*4bdff4beSrobert } 413*4bdff4beSrobert __libcpp_unreachable(); 414*4bdff4beSrobert } 415*4bdff4beSrobert 416*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 417*4bdff4beSrobert file_status __get_symlink_status(error_code* __ec = nullptr) const { 418*4bdff4beSrobert switch (__data_.__cache_type_) { 419*4bdff4beSrobert case _Empty: 420*4bdff4beSrobert case _IterNonSymlink: 421*4bdff4beSrobert case _IterSymlink: 422*4bdff4beSrobert return __symlink_status(__p_, __ec); 423*4bdff4beSrobert case _RefreshNonSymlink: 424*4bdff4beSrobert return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); 425*4bdff4beSrobert case _RefreshSymlink: 426*4bdff4beSrobert case _RefreshSymlinkUnresolved: 427*4bdff4beSrobert return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); 428*4bdff4beSrobert } 429*4bdff4beSrobert __libcpp_unreachable(); 430*4bdff4beSrobert } 431*4bdff4beSrobert 432*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 433*4bdff4beSrobert uintmax_t __get_size(error_code* __ec = nullptr) const { 434*4bdff4beSrobert switch (__data_.__cache_type_) { 435*4bdff4beSrobert case _Empty: 436*4bdff4beSrobert case _IterNonSymlink: 437*4bdff4beSrobert case _IterSymlink: 438*4bdff4beSrobert case _RefreshSymlinkUnresolved: 439*4bdff4beSrobert return _VSTD_FS::__file_size(__p_, __ec); 440*4bdff4beSrobert case _RefreshSymlink: 441*4bdff4beSrobert case _RefreshNonSymlink: { 442*4bdff4beSrobert error_code __m_ec; 443*4bdff4beSrobert file_status __st(__get_ft(&__m_ec)); 444*4bdff4beSrobert __handle_error("in directory_entry::file_size", __ec, __m_ec); 445*4bdff4beSrobert if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { 446*4bdff4beSrobert errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory 447*4bdff4beSrobert : errc::not_supported; 448*4bdff4beSrobert __handle_error("in directory_entry::file_size", __ec, 449*4bdff4beSrobert make_error_code(__err_kind)); 450*4bdff4beSrobert } 451*4bdff4beSrobert return __data_.__size_; 452*4bdff4beSrobert } 453*4bdff4beSrobert } 454*4bdff4beSrobert __libcpp_unreachable(); 455*4bdff4beSrobert } 456*4bdff4beSrobert 457*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 458*4bdff4beSrobert uintmax_t __get_nlink(error_code* __ec = nullptr) const { 459*4bdff4beSrobert switch (__data_.__cache_type_) { 460*4bdff4beSrobert case _Empty: 461*4bdff4beSrobert case _IterNonSymlink: 462*4bdff4beSrobert case _IterSymlink: 463*4bdff4beSrobert case _RefreshSymlinkUnresolved: 464*4bdff4beSrobert return _VSTD_FS::__hard_link_count(__p_, __ec); 465*4bdff4beSrobert case _RefreshSymlink: 466*4bdff4beSrobert case _RefreshNonSymlink: { 467*4bdff4beSrobert error_code __m_ec; 468*4bdff4beSrobert (void)__get_ft(&__m_ec); 469*4bdff4beSrobert __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); 470*4bdff4beSrobert return __data_.__nlink_; 471*4bdff4beSrobert } 472*4bdff4beSrobert } 473*4bdff4beSrobert __libcpp_unreachable(); 474*4bdff4beSrobert } 475*4bdff4beSrobert 476*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 477*4bdff4beSrobert file_time_type __get_write_time(error_code* __ec = nullptr) const { 478*4bdff4beSrobert switch (__data_.__cache_type_) { 479*4bdff4beSrobert case _Empty: 480*4bdff4beSrobert case _IterNonSymlink: 481*4bdff4beSrobert case _IterSymlink: 482*4bdff4beSrobert case _RefreshSymlinkUnresolved: 483*4bdff4beSrobert return _VSTD_FS::__last_write_time(__p_, __ec); 484*4bdff4beSrobert case _RefreshSymlink: 485*4bdff4beSrobert case _RefreshNonSymlink: { 486*4bdff4beSrobert error_code __m_ec; 487*4bdff4beSrobert file_status __st(__get_ft(&__m_ec)); 488*4bdff4beSrobert __handle_error("in directory_entry::last_write_time", __ec, __m_ec); 489*4bdff4beSrobert if (_VSTD_FS::exists(__st) && 490*4bdff4beSrobert __data_.__write_time_ == file_time_type::min()) 491*4bdff4beSrobert __handle_error("in directory_entry::last_write_time", __ec, 492*4bdff4beSrobert make_error_code(errc::value_too_large)); 493*4bdff4beSrobert return __data_.__write_time_; 494*4bdff4beSrobert } 495*4bdff4beSrobert } 496*4bdff4beSrobert __libcpp_unreachable(); 497*4bdff4beSrobert } 498*4bdff4beSrobert 499*4bdff4beSrobert private: 500*4bdff4beSrobert _Path __p_; 501*4bdff4beSrobert __cached_data __data_; 502*4bdff4beSrobert }; 503*4bdff4beSrobert 504*4bdff4beSrobert class __dir_element_proxy { 505*4bdff4beSrobert public: 506*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { 507*4bdff4beSrobert return _VSTD::move(__elem_); 508*4bdff4beSrobert } 509*4bdff4beSrobert 510*4bdff4beSrobert private: 511*4bdff4beSrobert friend class directory_iterator; 512*4bdff4beSrobert friend class recursive_directory_iterator; __dir_element_proxy(directory_entry const & __e)513*4bdff4beSrobert explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} __dir_element_proxy(__dir_element_proxy && __o)514*4bdff4beSrobert __dir_element_proxy(__dir_element_proxy&& __o) 515*4bdff4beSrobert : __elem_(_VSTD::move(__o.__elem_)) {} 516*4bdff4beSrobert directory_entry __elem_; 517*4bdff4beSrobert }; 518*4bdff4beSrobert 519*4bdff4beSrobert _LIBCPP_AVAILABILITY_FILESYSTEM_POP 520*4bdff4beSrobert 521*4bdff4beSrobert _LIBCPP_END_NAMESPACE_FILESYSTEM 522*4bdff4beSrobert 523*4bdff4beSrobert #endif // _LIBCPP_CXX03_LANG 524*4bdff4beSrobert 525*4bdff4beSrobert _LIBCPP_POP_MACROS 526*4bdff4beSrobert 527*4bdff4beSrobert #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H 528