#include <__assert>
#include <__config>
#include <errno.h>
#include <filesystem>
#include <stack>
#include <utility>
#include "error.h"
#include "file_descriptor.h"
#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
# include <windows.h>
#else
# include <dirent.h>
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
ErrorHandler;
#if defined(_LIBCPP_WIN32API)
class __dir_stream {
public:
__dir_stream() = delete;
__dir_stream& operator=(const __dir_stream&) = delete;
__dir_stream(__dir_stream&& __ds) noexcept
: __stream_(__ds.__stream_), __root_(std::move(__ds.__root_)), __entry_(std::move(__ds.__entry_)) {
__ds.__stream_ = INVALID_HANDLE_VALUE;
}
__dir_stream(const path& root, directory_options opts, error_code& ec)
: __stream_(INVALID_HANDLE_VALUE), __root_(root) {
if (root.native().empty()) {
ec = make_error_code(errc::no_such_file_or_directory);
return;
}
__stream_ = ::FindFirstFileW((root / "*").c_str(), &__data_);
if (__stream_ == INVALID_HANDLE_VALUE) {
ec = detail::make_windows_error(GetLastError());
const bool ignore_permission_denied = bool(opts & directory_options::skip_permission_denied);
if (ignore_permission_denied && ec.value() == static_cast<int>(errc::permission_denied))
ec.clear();
return;
}
if (!assign())
advance(ec);
}
~__dir_stream() noexcept {
if (__stream_ == INVALID_HANDLE_VALUE)
return;
close();
}
bool good() const noexcept { return __stream_ != INVALID_HANDLE_VALUE; }
bool advance(error_code& ec) {
while (::FindNextFileW(__stream_, &__data_)) {
if (assign())
return true;
}
close();
return false;
}
bool assign() {
if (!wcscmp(__data_.cFileName, L".") || !wcscmp(__data_.cFileName, L".."))
return false;
__entry_.__assign_iter_entry(
__root_ / __data_.cFileName, directory_entry::__create_iter_result(detail::get_file_type(__data_)));
return true;
}
private:
error_code close() noexcept {
error_code ec;
if (!::FindClose(__stream_))
ec = detail::make_windows_error(GetLastError());
__stream_ = INVALID_HANDLE_VALUE;
return ec;
}
HANDLE __stream_{INVALID_HANDLE_VALUE};
WIN32_FIND_DATAW __data_;
public:
path __root_;
directory_entry __entry_;
};
#else
class __dir_stream { … };
#endif
directory_iterator::directory_iterator(const path& p, error_code* ec, directory_options opts) { … }
directory_iterator& directory_iterator::__increment(error_code* ec) { … }
directory_entry const& directory_iterator::__dereference() const { … }
struct recursive_directory_iterator::__shared_imp { … };
recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options opt, error_code* ec)
: … { … }
void recursive_directory_iterator::__pop(error_code* ec) { … }
directory_options recursive_directory_iterator::options() const { … }
int recursive_directory_iterator::depth() const { … }
const directory_entry& recursive_directory_iterator::__dereference() const { … }
recursive_directory_iterator& recursive_directory_iterator::__increment(error_code* ec) { … }
void recursive_directory_iterator::__advance(error_code* ec) { … }
bool recursive_directory_iterator::__try_recursion(error_code* ec) { … }
_LIBCPP_END_NAMESPACE_FILESYSTEM