File indexing completed on 2026-05-03 08:13:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
0011 #define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H
0012
0013 #include <__chrono/time_point.h>
0014 #include <__compare/ordering.h>
0015 #include <__config>
0016 #include <__filesystem/file_status.h>
0017 #include <__filesystem/file_time_type.h>
0018 #include <__filesystem/file_type.h>
0019 #include <__filesystem/filesystem_error.h>
0020 #include <__filesystem/operations.h>
0021 #include <__filesystem/path.h>
0022 #include <__filesystem/perms.h>
0023 #include <__fwd/ostream.h>
0024 #include <__system_error/errc.h>
0025 #include <__system_error/error_category.h>
0026 #include <__system_error/error_code.h>
0027 #include <__system_error/error_condition.h>
0028 #include <__utility/move.h>
0029 #include <__utility/unreachable.h>
0030 #include <cstdint>
0031
0032 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0033 # pragma GCC system_header
0034 #endif
0035
0036 _LIBCPP_PUSH_MACROS
0037 #include <__undef_macros>
0038
0039 #if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
0040
0041 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
0042
0043 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
0044
0045 class directory_entry {
0046 typedef filesystem::path _Path;
0047
0048 public:
0049
0050 _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default;
0051 _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default;
0052 _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default;
0053
0054 _LIBCPP_HIDE_FROM_ABI explicit directory_entry(_Path const& __p) : __p_(__p) {
0055 error_code __ec;
0056 __refresh(&__ec);
0057 }
0058
0059 _LIBCPP_HIDE_FROM_ABI directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { __refresh(&__ec); }
0060
0061 _LIBCPP_HIDE_FROM_ABI ~directory_entry() {}
0062
0063 _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default;
0064 _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default;
0065
0066 _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p) {
0067 __p_ = __p;
0068 error_code __ec;
0069 __refresh(&__ec);
0070 }
0071
0072 _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p, error_code& __ec) {
0073 __p_ = __p;
0074 __refresh(&__ec);
0075 }
0076
0077 _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p) {
0078 __p_.replace_filename(__p);
0079 error_code __ec;
0080 __refresh(&__ec);
0081 }
0082
0083 _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p, error_code& __ec) {
0084 __p_ = __p_.parent_path() / __p;
0085 __refresh(&__ec);
0086 }
0087
0088 _LIBCPP_HIDE_FROM_ABI void refresh() { __refresh(); }
0089
0090 _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
0091
0092 _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
0093
0094 _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; }
0095
0096 _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
0097
0098 _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
0099 return filesystem::exists(file_status{__get_ft(&__ec)});
0100 }
0101
0102 _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
0103
0104 _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
0105 return __get_ft(&__ec) == file_type::block;
0106 }
0107
0108 _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
0109
0110 _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
0111 return __get_ft(&__ec) == file_type::character;
0112 }
0113
0114 _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
0115
0116 _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
0117 return __get_ft(&__ec) == file_type::directory;
0118 }
0119
0120 _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
0121
0122 _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; }
0123
0124 _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
0125
0126 _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
0127 return filesystem::is_other(file_status{__get_ft(&__ec)});
0128 }
0129
0130 _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
0131
0132 _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
0133 return __get_ft(&__ec) == file_type::regular;
0134 }
0135
0136 _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
0137
0138 _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; }
0139
0140 _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
0141
0142 _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
0143 return __get_sym_ft(&__ec) == file_type::symlink;
0144 }
0145 _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
0146
0147 _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
0148
0149 _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
0150
0151 _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); }
0152
0153 _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
0154
0155 _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
0156 return __get_write_time(&__ec);
0157 }
0158
0159 _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
0160
0161 _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); }
0162
0163 _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
0164
0165 _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
0166 return __get_symlink_status(&__ec);
0167 }
0168
0169 _LIBCPP_HIDE_FROM_ABI bool operator==(directory_entry const& __rhs) const noexcept { return __p_ == __rhs.__p_; }
0170
0171 # if _LIBCPP_STD_VER <= 17
0172 _LIBCPP_HIDE_FROM_ABI bool operator!=(directory_entry const& __rhs) const noexcept { return __p_ != __rhs.__p_; }
0173
0174 _LIBCPP_HIDE_FROM_ABI bool operator<(directory_entry const& __rhs) const noexcept { return __p_ < __rhs.__p_; }
0175
0176 _LIBCPP_HIDE_FROM_ABI bool operator<=(directory_entry const& __rhs) const noexcept { return __p_ <= __rhs.__p_; }
0177
0178 _LIBCPP_HIDE_FROM_ABI bool operator>(directory_entry const& __rhs) const noexcept { return __p_ > __rhs.__p_; }
0179
0180 _LIBCPP_HIDE_FROM_ABI bool operator>=(directory_entry const& __rhs) const noexcept { return __p_ >= __rhs.__p_; }
0181
0182 # else
0183
0184 _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept {
0185 return __p_ <=> __rhs.__p_;
0186 }
0187
0188 # endif
0189
0190 template <class _CharT, class _Traits>
0191 _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>&
0192 operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) {
0193 return __os << __d.path();
0194 }
0195
0196 private:
0197 friend class directory_iterator;
0198 friend class recursive_directory_iterator;
0199 friend class _LIBCPP_HIDDEN __dir_stream;
0200
0201 enum _CacheType : unsigned char {
0202 _Empty,
0203 _IterSymlink,
0204 _IterNonSymlink,
0205 _RefreshSymlink,
0206 _RefreshSymlinkUnresolved,
0207 _RefreshNonSymlink,
0208 _IterCachedSymlink,
0209 _IterCachedNonSymlink
0210 };
0211
0212 struct __cached_data {
0213 uintmax_t __size_;
0214 uintmax_t __nlink_;
0215 file_time_type __write_time_;
0216 perms __sym_perms_;
0217 perms __non_sym_perms_;
0218 file_type __type_;
0219 _CacheType __cache_type_;
0220
0221 _LIBCPP_HIDE_FROM_ABI __cached_data() noexcept { __reset(); }
0222
0223 _LIBCPP_HIDE_FROM_ABI void __reset() {
0224 __cache_type_ = _Empty;
0225 __type_ = file_type::none;
0226 __sym_perms_ = __non_sym_perms_ = perms::unknown;
0227 __size_ = __nlink_ = uintmax_t(-1);
0228 __write_time_ = file_time_type::min();
0229 }
0230 };
0231
0232 _LIBCPP_HIDE_FROM_ABI static __cached_data __create_iter_result(file_type __ft) {
0233 __cached_data __data;
0234 __data.__type_ = __ft;
0235 __data.__cache_type_ = [&]() {
0236 switch (__ft) {
0237 case file_type::none:
0238 return _Empty;
0239 case file_type::symlink:
0240 return _IterSymlink;
0241 default:
0242 return _IterNonSymlink;
0243 }
0244 }();
0245 return __data;
0246 }
0247
0248 _LIBCPP_HIDE_FROM_ABI static __cached_data
0249 __create_iter_cached_result(file_type __ft, uintmax_t __size, perms __perm, file_time_type __write_time) {
0250 __cached_data __data;
0251 __data.__type_ = __ft;
0252 __data.__size_ = __size;
0253 __data.__write_time_ = __write_time;
0254 if (__ft == file_type::symlink)
0255 __data.__sym_perms_ = __perm;
0256 else
0257 __data.__non_sym_perms_ = __perm;
0258 __data.__cache_type_ = [&]() {
0259 switch (__ft) {
0260 case file_type::none:
0261 return _Empty;
0262 case file_type::symlink:
0263 return _IterCachedSymlink;
0264 default:
0265 return _IterCachedNonSymlink;
0266 }
0267 }();
0268 return __data;
0269 }
0270
0271 _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
0272 __p_ = std::move(__p);
0273 __data_ = __dt;
0274 }
0275
0276 _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept;
0277
0278 _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) {
0279 return !__ec || __ec == errc::no_such_file_or_directory || __ec == errc::not_a_directory;
0280 }
0281
0282 _LIBCPP_HIDE_FROM_ABI void
0283 __handle_error(const char* __msg, error_code* __dest_ec, error_code const& __ec, bool __allow_dne = false) const {
0284 if (__dest_ec) {
0285 *__dest_ec = __ec;
0286 return;
0287 }
0288 if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
0289 __throw_filesystem_error(__msg, __p_, __ec);
0290 }
0291
0292 _LIBCPP_HIDE_FROM_ABI void __refresh(error_code* __ec = nullptr) {
0293 __handle_error("in directory_entry::refresh",
0294 __ec,
0295 __do_refresh(),
0296 true);
0297 }
0298
0299 _LIBCPP_HIDE_FROM_ABI file_type __get_sym_ft(error_code* __ec = nullptr) const {
0300 switch (__data_.__cache_type_) {
0301 case _Empty:
0302 return __symlink_status(__p_, __ec).type();
0303 case _IterSymlink:
0304 case _IterCachedSymlink:
0305 case _RefreshSymlink:
0306 case _RefreshSymlinkUnresolved:
0307 if (__ec)
0308 __ec->clear();
0309 return file_type::symlink;
0310 case _IterCachedNonSymlink:
0311 case _IterNonSymlink:
0312 case _RefreshNonSymlink: {
0313 file_status __st(__data_.__type_);
0314 if (__ec && !filesystem::exists(__st))
0315 *__ec = make_error_code(errc::no_such_file_or_directory);
0316 else if (__ec)
0317 __ec->clear();
0318 return __data_.__type_;
0319 }
0320 }
0321 __libcpp_unreachable();
0322 }
0323
0324 _LIBCPP_HIDE_FROM_ABI file_type __get_ft(error_code* __ec = nullptr) const {
0325 switch (__data_.__cache_type_) {
0326 case _Empty:
0327 case _IterSymlink:
0328 case _IterCachedSymlink:
0329 case _RefreshSymlinkUnresolved:
0330 return __status(__p_, __ec).type();
0331 case _IterCachedNonSymlink:
0332 case _IterNonSymlink:
0333 case _RefreshNonSymlink:
0334 case _RefreshSymlink: {
0335 file_status __st(__data_.__type_);
0336 if (__ec && !filesystem::exists(__st))
0337 *__ec = make_error_code(errc::no_such_file_or_directory);
0338 else if (__ec)
0339 __ec->clear();
0340 return __data_.__type_;
0341 }
0342 }
0343 __libcpp_unreachable();
0344 }
0345
0346 _LIBCPP_HIDE_FROM_ABI file_status __get_status(error_code* __ec = nullptr) const {
0347 switch (__data_.__cache_type_) {
0348 case _Empty:
0349 case _IterNonSymlink:
0350 case _IterSymlink:
0351 case _IterCachedSymlink:
0352 case _RefreshSymlinkUnresolved:
0353 return __status(__p_, __ec);
0354 case _IterCachedNonSymlink:
0355 case _RefreshNonSymlink:
0356 case _RefreshSymlink:
0357 return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
0358 }
0359 __libcpp_unreachable();
0360 }
0361
0362 _LIBCPP_HIDE_FROM_ABI file_status __get_symlink_status(error_code* __ec = nullptr) const {
0363 switch (__data_.__cache_type_) {
0364 case _Empty:
0365 case _IterNonSymlink:
0366 case _IterSymlink:
0367 return __symlink_status(__p_, __ec);
0368 case _IterCachedNonSymlink:
0369 case _RefreshNonSymlink:
0370 return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
0371 case _IterCachedSymlink:
0372 case _RefreshSymlink:
0373 case _RefreshSymlinkUnresolved:
0374 return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
0375 }
0376 __libcpp_unreachable();
0377 }
0378
0379 _LIBCPP_HIDE_FROM_ABI uintmax_t __get_size(error_code* __ec = nullptr) const {
0380 switch (__data_.__cache_type_) {
0381 case _Empty:
0382 case _IterNonSymlink:
0383 case _IterSymlink:
0384 case _IterCachedSymlink:
0385 case _RefreshSymlinkUnresolved:
0386 return filesystem::__file_size(__p_, __ec);
0387 case _IterCachedNonSymlink:
0388 case _RefreshSymlink:
0389 case _RefreshNonSymlink: {
0390 error_code __m_ec;
0391 file_status __st(__get_ft(&__m_ec));
0392 __handle_error("in directory_entry::file_size", __ec, __m_ec);
0393 if (filesystem::exists(__st) && !filesystem::is_regular_file(__st)) {
0394 errc __err_kind = filesystem::is_directory(__st) ? errc::is_a_directory : errc::not_supported;
0395 __handle_error("in directory_entry::file_size", __ec, make_error_code(__err_kind));
0396 }
0397 return __data_.__size_;
0398 }
0399 }
0400 __libcpp_unreachable();
0401 }
0402
0403 _LIBCPP_HIDE_FROM_ABI uintmax_t __get_nlink(error_code* __ec = nullptr) const {
0404 switch (__data_.__cache_type_) {
0405 case _Empty:
0406 case _IterNonSymlink:
0407 case _IterSymlink:
0408 case _IterCachedNonSymlink:
0409 case _IterCachedSymlink:
0410 case _RefreshSymlinkUnresolved:
0411 return filesystem::__hard_link_count(__p_, __ec);
0412 case _RefreshSymlink:
0413 case _RefreshNonSymlink: {
0414 error_code __m_ec;
0415 (void)__get_ft(&__m_ec);
0416 __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
0417 return __data_.__nlink_;
0418 }
0419 }
0420 __libcpp_unreachable();
0421 }
0422
0423 _LIBCPP_HIDE_FROM_ABI file_time_type __get_write_time(error_code* __ec = nullptr) const {
0424 switch (__data_.__cache_type_) {
0425 case _Empty:
0426 case _IterNonSymlink:
0427 case _IterSymlink:
0428 case _IterCachedSymlink:
0429 case _RefreshSymlinkUnresolved:
0430 return filesystem::__last_write_time(__p_, __ec);
0431 case _IterCachedNonSymlink:
0432 case _RefreshSymlink:
0433 case _RefreshNonSymlink: {
0434 error_code __m_ec;
0435 file_status __st(__get_ft(&__m_ec));
0436 __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
0437 if (filesystem::exists(__st) && __data_.__write_time_ == file_time_type::min())
0438 __handle_error("in directory_entry::last_write_time", __ec, make_error_code(errc::value_too_large));
0439 return __data_.__write_time_;
0440 }
0441 }
0442 __libcpp_unreachable();
0443 }
0444
0445 private:
0446 _Path __p_;
0447 __cached_data __data_;
0448 };
0449
0450 class __dir_element_proxy {
0451 public:
0452 inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { return std::move(__elem_); }
0453
0454 private:
0455 friend class directory_iterator;
0456 friend class recursive_directory_iterator;
0457 _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
0458 _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(std::move(__o.__elem_)) {}
0459 directory_entry __elem_;
0460 };
0461
0462 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
0463
0464 _LIBCPP_END_NAMESPACE_FILESYSTEM
0465
0466 #endif
0467
0468 _LIBCPP_POP_MACROS
0469
0470 #endif