Skip to content

Instantly share code, notes, and snippets.

@LYP951018
Last active May 31, 2017 04:43
Show Gist options
  • Save LYP951018/53ac5ccdcd2b38734a94b3242984324b to your computer and use it in GitHub Desktop.
Save LYP951018/53ac5ccdcd2b38734a94b3242984324b to your computer and use it in GitHub Desktop.
#define UNICODE
#include <string>
#include <experimental/generator>
#include <iostream>
#include <functional>
#include <string_view>
#include <Windows.h>
using namespace std::experimental;
[[noreturn]] void ThrowSystem()
{
throw std::system_error{static_cast<int>(::GetLastError()), std::system_category()};
}
template<typename F>
class ScopeExit
{
private:
F f_;
public:
ScopeExit(F f)
: f_{std::move(f)}
{}
ScopeExit(const ScopeExit&) = delete;
ScopeExit& operator= (const ScopeExit&) = delete;
ScopeExit(ScopeExit&&) = default;
ScopeExit& operator= (ScopeExit&&) = default;
~ScopeExit()
{
std::invoke(f_);
}
};
template<typename F>
ScopeExit<F> Finally(F f) noexcept
{
return {std::move(f)};
}
generator<std::wstring> Files(const std::wstring &path)
{
::WIN32_FIND_DATAW ffd = {};
auto newPath = path + L"\\*";
auto file = ::FindFirstFileW(newPath.c_str(), &ffd);
auto clean = Finally([file]() noexcept {::FindClose(file);});
if (file == INVALID_HANDLE_VALUE)
{
ThrowSystem();
}
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
auto name = std::wstring_view{ffd.cFileName};
if (name == L"." || name == L"..")
{
continue;
}
auto nextPath = path + L"\\" + name.data();
for (auto p : Files(nextPath))
{
co_yield p;
}
}
else
{
co_yield ffd.cFileName;
}
} while (::FindNextFileW(file, &ffd));
}
int main()
{
std::wstring dir = L"C:\\Users\\LYP\\Documents\\GitHub\\IntrusivePtr";
for (auto path : Files(dir))
{
std::wcout << path << "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment