xref: /freebsd-src/contrib/llvm-project/libcxx/include/__filesystem/directory_entry.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10eae32dcSDimitry Andric // -*- C++ -*-
20eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
30eae32dcSDimitry Andric //
40eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70eae32dcSDimitry Andric //
80eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
90eae32dcSDimitry Andric 
100eae32dcSDimitry Andric #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
110eae32dcSDimitry Andric #define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
120eae32dcSDimitry Andric 
1381ad6265SDimitry Andric #include <__chrono/time_point.h>
1406c3fb27SDimitry Andric #include <__compare/ordering.h>
150eae32dcSDimitry Andric #include <__config>
1604eeddc0SDimitry Andric #include <__filesystem/file_status.h>
1704eeddc0SDimitry Andric #include <__filesystem/file_time_type.h>
1804eeddc0SDimitry Andric #include <__filesystem/file_type.h>
1904eeddc0SDimitry Andric #include <__filesystem/filesystem_error.h>
2004eeddc0SDimitry Andric #include <__filesystem/operations.h>
2104eeddc0SDimitry Andric #include <__filesystem/path.h>
2204eeddc0SDimitry Andric #include <__filesystem/perms.h>
2306c3fb27SDimitry Andric #include <__system_error/errc.h>
2406c3fb27SDimitry Andric #include <__system_error/error_code.h>
2506c3fb27SDimitry Andric #include <__utility/move.h>
2681ad6265SDimitry Andric #include <__utility/unreachable.h>
270eae32dcSDimitry Andric #include <cstdint>
280eae32dcSDimitry Andric 
2981ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3081ad6265SDimitry Andric #  pragma GCC system_header
3181ad6265SDimitry Andric #endif
3281ad6265SDimitry Andric 
330eae32dcSDimitry Andric _LIBCPP_PUSH_MACROS
340eae32dcSDimitry Andric #include <__undef_macros>
350eae32dcSDimitry Andric 
365f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
370eae32dcSDimitry Andric 
380eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
390eae32dcSDimitry Andric 
4006c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
410eae32dcSDimitry Andric 
420eae32dcSDimitry Andric class directory_entry {
435f757f3fSDimitry Andric   typedef filesystem::path _Path;
440eae32dcSDimitry Andric 
450eae32dcSDimitry Andric public:
460eae32dcSDimitry Andric   // constructors and destructors
4706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept                  = default;
4806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&)     = default;
4906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default;
500eae32dcSDimitry Andric 
51*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit directory_entry(_Path const& __p) : __p_(__p) {
520eae32dcSDimitry Andric     error_code __ec;
530eae32dcSDimitry Andric     __refresh(&__ec);
540eae32dcSDimitry Andric   }
550eae32dcSDimitry Andric 
56*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { __refresh(&__ec); }
570eae32dcSDimitry Andric 
5806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~directory_entry() {}
590eae32dcSDimitry Andric 
6006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&)     = default;
6106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default;
620eae32dcSDimitry Andric 
63*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p) {
640eae32dcSDimitry Andric     __p_ = __p;
650eae32dcSDimitry Andric     error_code __ec;
660eae32dcSDimitry Andric     __refresh(&__ec);
670eae32dcSDimitry Andric   }
680eae32dcSDimitry Andric 
69*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p, error_code& __ec) {
700eae32dcSDimitry Andric     __p_ = __p;
710eae32dcSDimitry Andric     __refresh(&__ec);
720eae32dcSDimitry Andric   }
730eae32dcSDimitry Andric 
74*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p) {
750eae32dcSDimitry Andric     __p_.replace_filename(__p);
760eae32dcSDimitry Andric     error_code __ec;
770eae32dcSDimitry Andric     __refresh(&__ec);
780eae32dcSDimitry Andric   }
790eae32dcSDimitry Andric 
80*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p, error_code& __ec) {
810eae32dcSDimitry Andric     __p_ = __p_.parent_path() / __p;
820eae32dcSDimitry Andric     __refresh(&__ec);
830eae32dcSDimitry Andric   }
840eae32dcSDimitry Andric 
85*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void refresh() { __refresh(); }
860eae32dcSDimitry Andric 
87*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
880eae32dcSDimitry Andric 
89*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
900eae32dcSDimitry Andric 
91*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; }
920eae32dcSDimitry Andric 
93*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
940eae32dcSDimitry Andric 
95*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
965f757f3fSDimitry Andric     return filesystem::exists(file_status{__get_ft(&__ec)});
970eae32dcSDimitry Andric   }
980eae32dcSDimitry Andric 
99*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
1000eae32dcSDimitry Andric 
101*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
1020eae32dcSDimitry Andric     return __get_ft(&__ec) == file_type::block;
1030eae32dcSDimitry Andric   }
1040eae32dcSDimitry Andric 
105*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
1060eae32dcSDimitry Andric 
107*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
1080eae32dcSDimitry Andric     return __get_ft(&__ec) == file_type::character;
1090eae32dcSDimitry Andric   }
1100eae32dcSDimitry Andric 
111*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
1120eae32dcSDimitry Andric 
113*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
1140eae32dcSDimitry Andric     return __get_ft(&__ec) == file_type::directory;
1150eae32dcSDimitry Andric   }
1160eae32dcSDimitry Andric 
117*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
1180eae32dcSDimitry Andric 
119*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; }
1200eae32dcSDimitry Andric 
121*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
1220eae32dcSDimitry Andric 
123*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
1245f757f3fSDimitry Andric     return filesystem::is_other(file_status{__get_ft(&__ec)});
1250eae32dcSDimitry Andric   }
1260eae32dcSDimitry Andric 
127*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
1280eae32dcSDimitry Andric 
129*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
1300eae32dcSDimitry Andric     return __get_ft(&__ec) == file_type::regular;
1310eae32dcSDimitry Andric   }
1320eae32dcSDimitry Andric 
133*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
1340eae32dcSDimitry Andric 
135*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; }
1360eae32dcSDimitry Andric 
137*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
1380eae32dcSDimitry Andric 
139*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
1400eae32dcSDimitry Andric     return __get_sym_ft(&__ec) == file_type::symlink;
1410eae32dcSDimitry Andric   }
142*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
1430eae32dcSDimitry Andric 
144*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
1450eae32dcSDimitry Andric 
146*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
1470eae32dcSDimitry Andric 
148*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); }
1490eae32dcSDimitry Andric 
150*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
1510eae32dcSDimitry Andric 
152*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
1530eae32dcSDimitry Andric     return __get_write_time(&__ec);
1540eae32dcSDimitry Andric   }
1550eae32dcSDimitry Andric 
156*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
1570eae32dcSDimitry Andric 
158*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); }
1590eae32dcSDimitry Andric 
160*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
1610eae32dcSDimitry Andric 
162*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
1630eae32dcSDimitry Andric     return __get_symlink_status(&__ec);
1640eae32dcSDimitry Andric   }
1650eae32dcSDimitry Andric 
166*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator==(directory_entry const& __rhs) const noexcept { return __p_ == __rhs.__p_; }
1670eae32dcSDimitry Andric 
168bdd1243dSDimitry Andric #  if _LIBCPP_STD_VER <= 17
169*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator!=(directory_entry const& __rhs) const noexcept { return __p_ != __rhs.__p_; }
1700eae32dcSDimitry Andric 
171*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator<(directory_entry const& __rhs) const noexcept { return __p_ < __rhs.__p_; }
172bdd1243dSDimitry Andric 
173*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator<=(directory_entry const& __rhs) const noexcept { return __p_ <= __rhs.__p_; }
1740eae32dcSDimitry Andric 
175*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator>(directory_entry const& __rhs) const noexcept { return __p_ > __rhs.__p_; }
1760eae32dcSDimitry Andric 
177*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool operator>=(directory_entry const& __rhs) const noexcept { return __p_ >= __rhs.__p_; }
1780eae32dcSDimitry Andric 
179bdd1243dSDimitry Andric #  else // _LIBCPP_STD_VER <= 17
180bdd1243dSDimitry Andric 
181*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept {
182bdd1243dSDimitry Andric     return __p_ <=> __rhs.__p_;
183bdd1243dSDimitry Andric   }
184bdd1243dSDimitry Andric 
185bdd1243dSDimitry Andric #  endif // _LIBCPP_STD_VER <= 17
186bdd1243dSDimitry Andric 
18704eeddc0SDimitry Andric   template <class _CharT, class _Traits>
188*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>&
189*cb14a3feSDimitry Andric   operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) {
19004eeddc0SDimitry Andric     return __os << __d.path();
19104eeddc0SDimitry Andric   }
19204eeddc0SDimitry Andric 
1930eae32dcSDimitry Andric private:
1940eae32dcSDimitry Andric   friend class directory_iterator;
1950eae32dcSDimitry Andric   friend class recursive_directory_iterator;
196a1f13cbcSDimitry Andric   friend class _LIBCPP_HIDDEN __dir_stream;
1970eae32dcSDimitry Andric 
1980eae32dcSDimitry Andric   enum _CacheType : unsigned char {
1990eae32dcSDimitry Andric     _Empty,
2000eae32dcSDimitry Andric     _IterSymlink,
2010eae32dcSDimitry Andric     _IterNonSymlink,
2020eae32dcSDimitry Andric     _RefreshSymlink,
2030eae32dcSDimitry Andric     _RefreshSymlinkUnresolved,
2040eae32dcSDimitry Andric     _RefreshNonSymlink
2050eae32dcSDimitry Andric   };
2060eae32dcSDimitry Andric 
2070eae32dcSDimitry Andric   struct __cached_data {
2080eae32dcSDimitry Andric     uintmax_t __size_;
2090eae32dcSDimitry Andric     uintmax_t __nlink_;
2100eae32dcSDimitry Andric     file_time_type __write_time_;
2110eae32dcSDimitry Andric     perms __sym_perms_;
2120eae32dcSDimitry Andric     perms __non_sym_perms_;
2130eae32dcSDimitry Andric     file_type __type_;
2140eae32dcSDimitry Andric     _CacheType __cache_type_;
2150eae32dcSDimitry Andric 
216*cb14a3feSDimitry Andric     _LIBCPP_HIDE_FROM_ABI __cached_data() noexcept { __reset(); }
2170eae32dcSDimitry Andric 
218*cb14a3feSDimitry Andric     _LIBCPP_HIDE_FROM_ABI void __reset() {
2190eae32dcSDimitry Andric       __cache_type_ = _Empty;
2200eae32dcSDimitry Andric       __type_       = file_type::none;
2210eae32dcSDimitry Andric       __sym_perms_ = __non_sym_perms_ = perms::unknown;
2220eae32dcSDimitry Andric       __size_ = __nlink_ = uintmax_t(-1);
2230eae32dcSDimitry Andric       __write_time_      = file_time_type::min();
2240eae32dcSDimitry Andric     }
2250eae32dcSDimitry Andric   };
2260eae32dcSDimitry Andric 
227*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static __cached_data __create_iter_result(file_type __ft) {
2280eae32dcSDimitry Andric     __cached_data __data;
2290eae32dcSDimitry Andric     __data.__type_       = __ft;
2300eae32dcSDimitry Andric     __data.__cache_type_ = [&]() {
2310eae32dcSDimitry Andric       switch (__ft) {
2320eae32dcSDimitry Andric       case file_type::none:
2330eae32dcSDimitry Andric         return _Empty;
2340eae32dcSDimitry Andric       case file_type::symlink:
2350eae32dcSDimitry Andric         return _IterSymlink;
2360eae32dcSDimitry Andric       default:
2370eae32dcSDimitry Andric         return _IterNonSymlink;
2380eae32dcSDimitry Andric       }
2390eae32dcSDimitry Andric     }();
2400eae32dcSDimitry Andric     return __data;
2410eae32dcSDimitry Andric   }
2420eae32dcSDimitry Andric 
243*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
2445f757f3fSDimitry Andric     __p_    = std::move(__p);
2450eae32dcSDimitry Andric     __data_ = __dt;
2460eae32dcSDimitry Andric   }
2470eae32dcSDimitry Andric 
24806c3fb27SDimitry Andric   _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept;
2490eae32dcSDimitry Andric 
250*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) {
2510eae32dcSDimitry Andric     if (!__ec)
2520eae32dcSDimitry Andric       return true;
2530eae32dcSDimitry Andric     switch (static_cast<errc>(__ec.value())) {
2540eae32dcSDimitry Andric     case errc::no_such_file_or_directory:
2550eae32dcSDimitry Andric     case errc::not_a_directory:
2560eae32dcSDimitry Andric       return true;
2570eae32dcSDimitry Andric     default:
2580eae32dcSDimitry Andric       return false;
2590eae32dcSDimitry Andric     }
2600eae32dcSDimitry Andric   }
2610eae32dcSDimitry Andric 
262*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void
263*cb14a3feSDimitry Andric   __handle_error(const char* __msg, error_code* __dest_ec, error_code const& __ec, bool __allow_dne = false) const {
2640eae32dcSDimitry Andric     if (__dest_ec) {
2650eae32dcSDimitry Andric       *__dest_ec = __ec;
2660eae32dcSDimitry Andric       return;
2670eae32dcSDimitry Andric     }
2680eae32dcSDimitry Andric     if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
2690eae32dcSDimitry Andric       __throw_filesystem_error(__msg, __p_, __ec);
2700eae32dcSDimitry Andric   }
2710eae32dcSDimitry Andric 
272*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void __refresh(error_code* __ec = nullptr) {
273*cb14a3feSDimitry Andric     __handle_error("in directory_entry::refresh",
274*cb14a3feSDimitry Andric                    __ec,
275*cb14a3feSDimitry Andric                    __do_refresh(),
2760eae32dcSDimitry Andric                    /*allow_dne*/ true);
2770eae32dcSDimitry Andric   }
2780eae32dcSDimitry Andric 
279*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_type __get_sym_ft(error_code* __ec = nullptr) const {
2800eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
2810eae32dcSDimitry Andric     case _Empty:
2820eae32dcSDimitry Andric       return __symlink_status(__p_, __ec).type();
2830eae32dcSDimitry Andric     case _IterSymlink:
2840eae32dcSDimitry Andric     case _RefreshSymlink:
2850eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
2860eae32dcSDimitry Andric       if (__ec)
2870eae32dcSDimitry Andric         __ec->clear();
2880eae32dcSDimitry Andric       return file_type::symlink;
2890eae32dcSDimitry Andric     case _IterNonSymlink:
2900eae32dcSDimitry Andric     case _RefreshNonSymlink:
2910eae32dcSDimitry Andric       file_status __st(__data_.__type_);
2925f757f3fSDimitry Andric       if (__ec && !filesystem::exists(__st))
2930eae32dcSDimitry Andric         *__ec = make_error_code(errc::no_such_file_or_directory);
2940eae32dcSDimitry Andric       else if (__ec)
2950eae32dcSDimitry Andric         __ec->clear();
2960eae32dcSDimitry Andric       return __data_.__type_;
2970eae32dcSDimitry Andric     }
29881ad6265SDimitry Andric     __libcpp_unreachable();
2990eae32dcSDimitry Andric   }
3000eae32dcSDimitry Andric 
301*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_type __get_ft(error_code* __ec = nullptr) const {
3020eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3030eae32dcSDimitry Andric     case _Empty:
3040eae32dcSDimitry Andric     case _IterSymlink:
3050eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3060eae32dcSDimitry Andric       return __status(__p_, __ec).type();
3070eae32dcSDimitry Andric     case _IterNonSymlink:
3080eae32dcSDimitry Andric     case _RefreshNonSymlink:
3090eae32dcSDimitry Andric     case _RefreshSymlink: {
3100eae32dcSDimitry Andric       file_status __st(__data_.__type_);
3115f757f3fSDimitry Andric       if (__ec && !filesystem::exists(__st))
3120eae32dcSDimitry Andric         *__ec = make_error_code(errc::no_such_file_or_directory);
3130eae32dcSDimitry Andric       else if (__ec)
3140eae32dcSDimitry Andric         __ec->clear();
3150eae32dcSDimitry Andric       return __data_.__type_;
3160eae32dcSDimitry Andric     }
3170eae32dcSDimitry Andric     }
31881ad6265SDimitry Andric     __libcpp_unreachable();
3190eae32dcSDimitry Andric   }
3200eae32dcSDimitry Andric 
321*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status __get_status(error_code* __ec = nullptr) const {
3220eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3230eae32dcSDimitry Andric     case _Empty:
3240eae32dcSDimitry Andric     case _IterNonSymlink:
3250eae32dcSDimitry Andric     case _IterSymlink:
3260eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3270eae32dcSDimitry Andric       return __status(__p_, __ec);
3280eae32dcSDimitry Andric     case _RefreshNonSymlink:
3290eae32dcSDimitry Andric     case _RefreshSymlink:
3300eae32dcSDimitry Andric       return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
3310eae32dcSDimitry Andric     }
33281ad6265SDimitry Andric     __libcpp_unreachable();
3330eae32dcSDimitry Andric   }
3340eae32dcSDimitry Andric 
335*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_status __get_symlink_status(error_code* __ec = nullptr) const {
3360eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3370eae32dcSDimitry Andric     case _Empty:
3380eae32dcSDimitry Andric     case _IterNonSymlink:
3390eae32dcSDimitry Andric     case _IterSymlink:
3400eae32dcSDimitry Andric       return __symlink_status(__p_, __ec);
3410eae32dcSDimitry Andric     case _RefreshNonSymlink:
3420eae32dcSDimitry Andric       return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
3430eae32dcSDimitry Andric     case _RefreshSymlink:
3440eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3450eae32dcSDimitry Andric       return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
3460eae32dcSDimitry Andric     }
34781ad6265SDimitry Andric     __libcpp_unreachable();
3480eae32dcSDimitry Andric   }
3490eae32dcSDimitry Andric 
350*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t __get_size(error_code* __ec = nullptr) const {
3510eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3520eae32dcSDimitry Andric     case _Empty:
3530eae32dcSDimitry Andric     case _IterNonSymlink:
3540eae32dcSDimitry Andric     case _IterSymlink:
3550eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3565f757f3fSDimitry Andric       return filesystem::__file_size(__p_, __ec);
3570eae32dcSDimitry Andric     case _RefreshSymlink:
3580eae32dcSDimitry Andric     case _RefreshNonSymlink: {
3590eae32dcSDimitry Andric       error_code __m_ec;
3600eae32dcSDimitry Andric       file_status __st(__get_ft(&__m_ec));
3610eae32dcSDimitry Andric       __handle_error("in directory_entry::file_size", __ec, __m_ec);
3625f757f3fSDimitry Andric       if (filesystem::exists(__st) && !filesystem::is_regular_file(__st)) {
363*cb14a3feSDimitry Andric         errc __err_kind = filesystem::is_directory(__st) ? errc::is_a_directory : errc::not_supported;
364*cb14a3feSDimitry Andric         __handle_error("in directory_entry::file_size", __ec, make_error_code(__err_kind));
3650eae32dcSDimitry Andric       }
3660eae32dcSDimitry Andric       return __data_.__size_;
3670eae32dcSDimitry Andric     }
3680eae32dcSDimitry Andric     }
36981ad6265SDimitry Andric     __libcpp_unreachable();
3700eae32dcSDimitry Andric   }
3710eae32dcSDimitry Andric 
372*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI uintmax_t __get_nlink(error_code* __ec = nullptr) const {
3730eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3740eae32dcSDimitry Andric     case _Empty:
3750eae32dcSDimitry Andric     case _IterNonSymlink:
3760eae32dcSDimitry Andric     case _IterSymlink:
3770eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3785f757f3fSDimitry Andric       return filesystem::__hard_link_count(__p_, __ec);
3790eae32dcSDimitry Andric     case _RefreshSymlink:
3800eae32dcSDimitry Andric     case _RefreshNonSymlink: {
3810eae32dcSDimitry Andric       error_code __m_ec;
3820eae32dcSDimitry Andric       (void)__get_ft(&__m_ec);
3830eae32dcSDimitry Andric       __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
3840eae32dcSDimitry Andric       return __data_.__nlink_;
3850eae32dcSDimitry Andric     }
3860eae32dcSDimitry Andric     }
38781ad6265SDimitry Andric     __libcpp_unreachable();
3880eae32dcSDimitry Andric   }
3890eae32dcSDimitry Andric 
390*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI file_time_type __get_write_time(error_code* __ec = nullptr) const {
3910eae32dcSDimitry Andric     switch (__data_.__cache_type_) {
3920eae32dcSDimitry Andric     case _Empty:
3930eae32dcSDimitry Andric     case _IterNonSymlink:
3940eae32dcSDimitry Andric     case _IterSymlink:
3950eae32dcSDimitry Andric     case _RefreshSymlinkUnresolved:
3965f757f3fSDimitry Andric       return filesystem::__last_write_time(__p_, __ec);
3970eae32dcSDimitry Andric     case _RefreshSymlink:
3980eae32dcSDimitry Andric     case _RefreshNonSymlink: {
3990eae32dcSDimitry Andric       error_code __m_ec;
4000eae32dcSDimitry Andric       file_status __st(__get_ft(&__m_ec));
4010eae32dcSDimitry Andric       __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
402*cb14a3feSDimitry Andric       if (filesystem::exists(__st) && __data_.__write_time_ == file_time_type::min())
403*cb14a3feSDimitry Andric         __handle_error("in directory_entry::last_write_time", __ec, make_error_code(errc::value_too_large));
4040eae32dcSDimitry Andric       return __data_.__write_time_;
4050eae32dcSDimitry Andric     }
4060eae32dcSDimitry Andric     }
40781ad6265SDimitry Andric     __libcpp_unreachable();
4080eae32dcSDimitry Andric   }
4090eae32dcSDimitry Andric 
4100eae32dcSDimitry Andric private:
4110eae32dcSDimitry Andric   _Path __p_;
4120eae32dcSDimitry Andric   __cached_data __data_;
4130eae32dcSDimitry Andric };
4140eae32dcSDimitry Andric 
4150eae32dcSDimitry Andric class __dir_element_proxy {
4160eae32dcSDimitry Andric public:
417*cb14a3feSDimitry Andric   inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { return std::move(__elem_); }
4180eae32dcSDimitry Andric 
4190eae32dcSDimitry Andric private:
4200eae32dcSDimitry Andric   friend class directory_iterator;
4210eae32dcSDimitry Andric   friend class recursive_directory_iterator;
42206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
423*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(std::move(__o.__elem_)) {}
4240eae32dcSDimitry Andric   directory_entry __elem_;
4250eae32dcSDimitry Andric };
4260eae32dcSDimitry Andric 
42706c3fb27SDimitry Andric _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
4280eae32dcSDimitry Andric 
4290eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
4300eae32dcSDimitry Andric 
4315f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
4320eae32dcSDimitry Andric 
4330eae32dcSDimitry Andric _LIBCPP_POP_MACROS
4340eae32dcSDimitry Andric 
4350eae32dcSDimitry Andric #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
436