Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:27

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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   // constructors and destructors
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 // _LIBCPP_STD_VER <= 17
0180 
0181   _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept {
0182     return __p_ <=> __rhs.__p_;
0183   }
0184 
0185 #  endif // _LIBCPP_STD_VER <= 17
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                    /*allow_dne*/ 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 // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
0432 
0433 _LIBCPP_POP_MACROS
0434 
0435 #endif // _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ENTRY_H