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