| 1 | // -*- C++ -*- |
| 2 | //===----------------------------------------------------------------------===// |
| 3 | // |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 5 | // See https://llvm.org/LICENSE.txt for license information. |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H |
| 11 | #define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H |
| 12 | |
| 13 | #include <__chrono/time_point.h> |
| 14 | #include <__compare/ordering.h> |
| 15 | #include <__config> |
| 16 | #include <__filesystem/file_status.h> |
| 17 | #include <__filesystem/file_time_type.h> |
| 18 | #include <__filesystem/file_type.h> |
| 19 | #include <__filesystem/filesystem_error.h> |
| 20 | #include <__filesystem/operations.h> |
| 21 | #include <__filesystem/path.h> |
| 22 | #include <__filesystem/perms.h> |
| 23 | #include <__fwd/ostream.h> |
| 24 | #include <__system_error/errc.h> |
| 25 | #include <__system_error/error_category.h> |
| 26 | #include <__system_error/error_code.h> |
| 27 | #include <__system_error/error_condition.h> |
| 28 | #include <__utility/move.h> |
| 29 | #include <__utility/unreachable.h> |
| 30 | #include <cstdint> |
| 31 | |
| 32 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 33 | # pragma GCC system_header |
| 34 | #endif |
| 35 | |
| 36 | _LIBCPP_PUSH_MACROS |
| 37 | #include <__undef_macros> |
| 38 | |
| 39 | #if _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM |
| 40 | |
| 41 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 42 | |
| 43 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH |
| 44 | |
| 45 | class directory_entry { |
| 46 | typedef filesystem::path _Path; |
| 47 | |
| 48 | public: |
| 49 | // constructors and destructors |
| 50 | _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; |
| 51 | _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; |
| 52 | _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default; |
| 53 | |
| 54 | _LIBCPP_HIDE_FROM_ABI explicit directory_entry(_Path const& __p) : __p_(__p) { |
| 55 | error_code __ec; |
| 56 | __refresh(ec: &__ec); |
| 57 | } |
| 58 | |
| 59 | _LIBCPP_HIDE_FROM_ABI directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { __refresh(ec: &__ec); } |
| 60 | |
| 61 | _LIBCPP_HIDE_FROM_ABI ~directory_entry() {} |
| 62 | |
| 63 | _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; |
| 64 | _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default; |
| 65 | |
| 66 | _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p) { |
| 67 | __p_ = __p; |
| 68 | error_code __ec; |
| 69 | __refresh(ec: &__ec); |
| 70 | } |
| 71 | |
| 72 | _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p, error_code& __ec) { |
| 73 | __p_ = __p; |
| 74 | __refresh(ec: &__ec); |
| 75 | } |
| 76 | |
| 77 | _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p) { |
| 78 | __p_.replace_filename(replacement: __p); |
| 79 | error_code __ec; |
| 80 | __refresh(ec: &__ec); |
| 81 | } |
| 82 | |
| 83 | _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p, error_code& __ec) { |
| 84 | __p_ = __p_.parent_path() / __p; |
| 85 | __refresh(ec: &__ec); |
| 86 | } |
| 87 | |
| 88 | _LIBCPP_HIDE_FROM_ABI void refresh() { __refresh(); } |
| 89 | |
| 90 | _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(ec: &__ec); } |
| 91 | |
| 92 | _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; } |
| 93 | |
| 94 | _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; } |
| 95 | |
| 96 | _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(s: file_status{__get_ft()}); } |
| 97 | |
| 98 | _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept { |
| 99 | return filesystem::exists(s: file_status{__get_ft(ec: &__ec)}); |
| 100 | } |
| 101 | |
| 102 | _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; } |
| 103 | |
| 104 | _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept { |
| 105 | return __get_ft(ec: &__ec) == file_type::block; |
| 106 | } |
| 107 | |
| 108 | _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; } |
| 109 | |
| 110 | _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept { |
| 111 | return __get_ft(ec: &__ec) == file_type::character; |
| 112 | } |
| 113 | |
| 114 | _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; } |
| 115 | |
| 116 | _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept { |
| 117 | return __get_ft(ec: &__ec) == file_type::directory; |
| 118 | } |
| 119 | |
| 120 | _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; } |
| 121 | |
| 122 | _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(ec: &__ec) == file_type::fifo; } |
| 123 | |
| 124 | _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(s: file_status{__get_ft()}); } |
| 125 | |
| 126 | _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept { |
| 127 | return filesystem::is_other(s: file_status{__get_ft(ec: &__ec)}); |
| 128 | } |
| 129 | |
| 130 | _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; } |
| 131 | |
| 132 | _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept { |
| 133 | return __get_ft(ec: &__ec) == file_type::regular; |
| 134 | } |
| 135 | |
| 136 | _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; } |
| 137 | |
| 138 | _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(ec: &__ec) == file_type::socket; } |
| 139 | |
| 140 | _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } |
| 141 | |
| 142 | _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept { |
| 143 | return __get_sym_ft(ec: &__ec) == file_type::symlink; |
| 144 | } |
| 145 | _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); } |
| 146 | |
| 147 | _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(ec: &__ec); } |
| 148 | |
| 149 | _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); } |
| 150 | |
| 151 | _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(ec: &__ec); } |
| 152 | |
| 153 | _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); } |
| 154 | |
| 155 | _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept { |
| 156 | return __get_write_time(ec: &__ec); |
| 157 | } |
| 158 | |
| 159 | _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); } |
| 160 | |
| 161 | _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(ec: &__ec); } |
| 162 | |
| 163 | _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); } |
| 164 | |
| 165 | _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept { |
| 166 | return __get_symlink_status(ec: &__ec); |
| 167 | } |
| 168 | |
| 169 | _LIBCPP_HIDE_FROM_ABI bool operator==(directory_entry const& __rhs) const noexcept { return __p_ == __rhs.__p_; } |
| 170 | |
| 171 | # if _LIBCPP_STD_VER <= 17 |
| 172 | _LIBCPP_HIDE_FROM_ABI bool operator!=(directory_entry const& __rhs) const noexcept { return __p_ != __rhs.__p_; } |
| 173 | |
| 174 | _LIBCPP_HIDE_FROM_ABI bool operator<(directory_entry const& __rhs) const noexcept { return __p_ < __rhs.__p_; } |
| 175 | |
| 176 | _LIBCPP_HIDE_FROM_ABI bool operator<=(directory_entry const& __rhs) const noexcept { return __p_ <= __rhs.__p_; } |
| 177 | |
| 178 | _LIBCPP_HIDE_FROM_ABI bool operator>(directory_entry const& __rhs) const noexcept { return __p_ > __rhs.__p_; } |
| 179 | |
| 180 | _LIBCPP_HIDE_FROM_ABI bool operator>=(directory_entry const& __rhs) const noexcept { return __p_ >= __rhs.__p_; } |
| 181 | |
| 182 | # else // _LIBCPP_STD_VER <= 17 |
| 183 | |
| 184 | _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { |
| 185 | return __p_ <=> __rhs.__p_; |
| 186 | } |
| 187 | |
| 188 | # endif // _LIBCPP_STD_VER <= 17 |
| 189 | |
| 190 | template <class _CharT, class _Traits> |
| 191 | _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& |
| 192 | operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { |
| 193 | return __os << __d.path(); |
| 194 | } |
| 195 | |
| 196 | private: |
| 197 | friend class directory_iterator; |
| 198 | friend class recursive_directory_iterator; |
| 199 | friend class _LIBCPP_HIDDEN __dir_stream; |
| 200 | |
| 201 | enum _CacheType : unsigned char { |
| 202 | _Empty, |
| 203 | _IterSymlink, |
| 204 | _IterNonSymlink, |
| 205 | _RefreshSymlink, |
| 206 | _RefreshSymlinkUnresolved, |
| 207 | _RefreshNonSymlink, |
| 208 | _IterCachedSymlink, |
| 209 | _IterCachedNonSymlink |
| 210 | }; |
| 211 | |
| 212 | struct __cached_data { |
| 213 | uintmax_t __size_; |
| 214 | uintmax_t __nlink_; |
| 215 | file_time_type __write_time_; |
| 216 | perms __sym_perms_; |
| 217 | perms __non_sym_perms_; |
| 218 | file_type __type_; |
| 219 | _CacheType __cache_type_; |
| 220 | |
| 221 | _LIBCPP_HIDE_FROM_ABI __cached_data() noexcept { __reset(); } |
| 222 | |
| 223 | _LIBCPP_HIDE_FROM_ABI void __reset() { |
| 224 | __cache_type_ = _Empty; |
| 225 | __type_ = file_type::none; |
| 226 | __sym_perms_ = __non_sym_perms_ = perms::unknown; |
| 227 | __size_ = __nlink_ = uintmax_t(-1); |
| 228 | __write_time_ = file_time_type::min(); |
| 229 | } |
| 230 | }; |
| 231 | |
| 232 | _LIBCPP_HIDE_FROM_ABI static __cached_data __create_iter_result(file_type __ft) { |
| 233 | __cached_data __data; |
| 234 | __data.__type_ = __ft; |
| 235 | __data.__cache_type_ = [&]() { |
| 236 | switch (__ft) { |
| 237 | case file_type::none: |
| 238 | return _Empty; |
| 239 | case file_type::symlink: |
| 240 | return _IterSymlink; |
| 241 | default: |
| 242 | return _IterNonSymlink; |
| 243 | } |
| 244 | }(); |
| 245 | return __data; |
| 246 | } |
| 247 | |
| 248 | _LIBCPP_HIDE_FROM_ABI static __cached_data |
| 249 | __create_iter_cached_result(file_type __ft, uintmax_t __size, perms __perm, file_time_type __write_time) { |
| 250 | __cached_data __data; |
| 251 | __data.__type_ = __ft; |
| 252 | __data.__size_ = __size; |
| 253 | __data.__write_time_ = __write_time; |
| 254 | if (__ft == file_type::symlink) |
| 255 | __data.__sym_perms_ = __perm; |
| 256 | else |
| 257 | __data.__non_sym_perms_ = __perm; |
| 258 | __data.__cache_type_ = [&]() { |
| 259 | switch (__ft) { |
| 260 | case file_type::none: |
| 261 | return _Empty; |
| 262 | case file_type::symlink: |
| 263 | return _IterCachedSymlink; |
| 264 | default: |
| 265 | return _IterCachedNonSymlink; |
| 266 | } |
| 267 | }(); |
| 268 | return __data; |
| 269 | } |
| 270 | |
| 271 | _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) { |
| 272 | __p_ = std::move(__p); |
| 273 | __data_ = __dt; |
| 274 | } |
| 275 | |
| 276 | _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept; |
| 277 | |
| 278 | _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) { |
| 279 | return !__ec || __ec == errc::no_such_file_or_directory || __ec == errc::not_a_directory; |
| 280 | } |
| 281 | |
| 282 | _LIBCPP_HIDE_FROM_ABI void |
| 283 | __handle_error(const char* __msg, error_code* __dest_ec, error_code const& __ec, bool __allow_dne = false) const { |
| 284 | if (__dest_ec) { |
| 285 | *__dest_ec = __ec; |
| 286 | return; |
| 287 | } |
| 288 | if (__ec && (!__allow_dne || !__is_dne_error(__ec))) |
| 289 | filesystem::__throw_filesystem_error(args&: __msg, args: __p_, args: __ec); |
| 290 | } |
| 291 | |
| 292 | _LIBCPP_HIDE_FROM_ABI void __refresh(error_code* __ec = nullptr) { |
| 293 | __handle_error(msg: "in directory_entry::refresh" , |
| 294 | dest_ec: __ec, |
| 295 | ec: __do_refresh(), |
| 296 | /*allow_dne*/ allow_dne: true); |
| 297 | } |
| 298 | |
| 299 | _LIBCPP_HIDE_FROM_ABI file_type __get_sym_ft(error_code* __ec = nullptr) const { |
| 300 | switch (__data_.__cache_type_) { |
| 301 | case _Empty: |
| 302 | return __symlink_status(__p_, __ec).type(); |
| 303 | case _IterSymlink: |
| 304 | case _IterCachedSymlink: |
| 305 | case _RefreshSymlink: |
| 306 | case _RefreshSymlinkUnresolved: |
| 307 | if (__ec) |
| 308 | __ec->clear(); |
| 309 | return file_type::symlink; |
| 310 | case _IterCachedNonSymlink: |
| 311 | case _IterNonSymlink: |
| 312 | case _RefreshNonSymlink: { |
| 313 | file_status __st(__data_.__type_); |
| 314 | if (__ec && !filesystem::exists(s: __st)) |
| 315 | *__ec = make_error_code(e: errc::no_such_file_or_directory); |
| 316 | else if (__ec) |
| 317 | __ec->clear(); |
| 318 | return __data_.__type_; |
| 319 | } |
| 320 | } |
| 321 | __libcpp_unreachable(); |
| 322 | } |
| 323 | |
| 324 | _LIBCPP_HIDE_FROM_ABI file_type __get_ft(error_code* __ec = nullptr) const { |
| 325 | switch (__data_.__cache_type_) { |
| 326 | case _Empty: |
| 327 | case _IterSymlink: |
| 328 | case _IterCachedSymlink: |
| 329 | case _RefreshSymlinkUnresolved: |
| 330 | return __status(__p_, __ec).type(); |
| 331 | case _IterCachedNonSymlink: |
| 332 | case _IterNonSymlink: |
| 333 | case _RefreshNonSymlink: |
| 334 | case _RefreshSymlink: { |
| 335 | file_status __st(__data_.__type_); |
| 336 | if (__ec && !filesystem::exists(s: __st)) |
| 337 | *__ec = make_error_code(e: errc::no_such_file_or_directory); |
| 338 | else if (__ec) |
| 339 | __ec->clear(); |
| 340 | return __data_.__type_; |
| 341 | } |
| 342 | } |
| 343 | __libcpp_unreachable(); |
| 344 | } |
| 345 | |
| 346 | _LIBCPP_HIDE_FROM_ABI file_status __get_status(error_code* __ec = nullptr) const { |
| 347 | switch (__data_.__cache_type_) { |
| 348 | case _Empty: |
| 349 | case _IterNonSymlink: |
| 350 | case _IterSymlink: |
| 351 | case _IterCachedSymlink: |
| 352 | case _RefreshSymlinkUnresolved: |
| 353 | return __status(__p_, __ec); |
| 354 | case _IterCachedNonSymlink: |
| 355 | case _RefreshNonSymlink: |
| 356 | case _RefreshSymlink: |
| 357 | return file_status(__get_ft(__ec), __data_.__non_sym_perms_); |
| 358 | } |
| 359 | __libcpp_unreachable(); |
| 360 | } |
| 361 | |
| 362 | _LIBCPP_HIDE_FROM_ABI file_status __get_symlink_status(error_code* __ec = nullptr) const { |
| 363 | switch (__data_.__cache_type_) { |
| 364 | case _Empty: |
| 365 | case _IterNonSymlink: |
| 366 | case _IterSymlink: |
| 367 | return __symlink_status(__p_, __ec); |
| 368 | case _IterCachedNonSymlink: |
| 369 | case _RefreshNonSymlink: |
| 370 | return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); |
| 371 | case _IterCachedSymlink: |
| 372 | case _RefreshSymlink: |
| 373 | case _RefreshSymlinkUnresolved: |
| 374 | return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); |
| 375 | } |
| 376 | __libcpp_unreachable(); |
| 377 | } |
| 378 | |
| 379 | _LIBCPP_HIDE_FROM_ABI uintmax_t __get_size(error_code* __ec = nullptr) const { |
| 380 | switch (__data_.__cache_type_) { |
| 381 | case _Empty: |
| 382 | case _IterNonSymlink: |
| 383 | case _IterSymlink: |
| 384 | case _IterCachedSymlink: |
| 385 | case _RefreshSymlinkUnresolved: |
| 386 | return filesystem::__file_size(__p_, __ec); |
| 387 | case _IterCachedNonSymlink: |
| 388 | case _RefreshSymlink: |
| 389 | case _RefreshNonSymlink: { |
| 390 | error_code __m_ec; |
| 391 | file_status __st(__get_ft(ec: &__m_ec)); |
| 392 | __handle_error(msg: "in directory_entry::file_size" , dest_ec: __ec, ec: __m_ec); |
| 393 | if (filesystem::exists(s: __st) && !filesystem::is_regular_file(s: __st)) { |
| 394 | errc __err_kind = filesystem::is_directory(s: __st) ? errc::is_a_directory : errc::not_supported; |
| 395 | __handle_error(msg: "in directory_entry::file_size" , dest_ec: __ec, ec: make_error_code(e: __err_kind)); |
| 396 | } |
| 397 | return __data_.__size_; |
| 398 | } |
| 399 | } |
| 400 | __libcpp_unreachable(); |
| 401 | } |
| 402 | |
| 403 | _LIBCPP_HIDE_FROM_ABI uintmax_t __get_nlink(error_code* __ec = nullptr) const { |
| 404 | switch (__data_.__cache_type_) { |
| 405 | case _Empty: |
| 406 | case _IterNonSymlink: |
| 407 | case _IterSymlink: |
| 408 | case _IterCachedNonSymlink: |
| 409 | case _IterCachedSymlink: |
| 410 | case _RefreshSymlinkUnresolved: |
| 411 | return filesystem::__hard_link_count(__p_, __ec); |
| 412 | case _RefreshSymlink: |
| 413 | case _RefreshNonSymlink: { |
| 414 | error_code __m_ec; |
| 415 | (void)__get_ft(ec: &__m_ec); |
| 416 | __handle_error(msg: "in directory_entry::hard_link_count" , dest_ec: __ec, ec: __m_ec); |
| 417 | return __data_.__nlink_; |
| 418 | } |
| 419 | } |
| 420 | __libcpp_unreachable(); |
| 421 | } |
| 422 | |
| 423 | _LIBCPP_HIDE_FROM_ABI file_time_type __get_write_time(error_code* __ec = nullptr) const { |
| 424 | switch (__data_.__cache_type_) { |
| 425 | case _Empty: |
| 426 | case _IterNonSymlink: |
| 427 | case _IterSymlink: |
| 428 | case _IterCachedSymlink: |
| 429 | case _RefreshSymlinkUnresolved: |
| 430 | return filesystem::__last_write_time(__p_, __ec); |
| 431 | case _IterCachedNonSymlink: |
| 432 | case _RefreshSymlink: |
| 433 | case _RefreshNonSymlink: { |
| 434 | error_code __m_ec; |
| 435 | file_status __st(__get_ft(ec: &__m_ec)); |
| 436 | __handle_error(msg: "in directory_entry::last_write_time" , dest_ec: __ec, ec: __m_ec); |
| 437 | if (filesystem::exists(s: __st) && __data_.__write_time_ == file_time_type::min()) |
| 438 | __handle_error(msg: "in directory_entry::last_write_time" , dest_ec: __ec, ec: make_error_code(e: errc::value_too_large)); |
| 439 | return __data_.__write_time_; |
| 440 | } |
| 441 | } |
| 442 | __libcpp_unreachable(); |
| 443 | } |
| 444 | |
| 445 | private: |
| 446 | _Path __p_; |
| 447 | __cached_data __data_; |
| 448 | }; |
| 449 | |
| 450 | class __dir_element_proxy { |
| 451 | public: |
| 452 | inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { return std::move(__elem_); } |
| 453 | |
| 454 | private: |
| 455 | friend class directory_iterator; |
| 456 | friend class recursive_directory_iterator; |
| 457 | _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} |
| 458 | _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(std::move(__o.__elem_)) {} |
| 459 | directory_entry __elem_; |
| 460 | }; |
| 461 | |
| 462 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP |
| 463 | |
| 464 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 465 | |
| 466 | #endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM |
| 467 | |
| 468 | _LIBCPP_POP_MACROS |
| 469 | |
| 470 | #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H |
| 471 | |