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