#pragma once #include #include #include "directory.h" namespace asyncpp { namespace fs { namespace __directory { struct read_all_stream : public base_stream< cppfs::directory::entry, read_all_stream> { public: using value_type = cppfs::directory::entry; using this_type = read_all_stream; using base_future_type = base_stream; using result_type = typename base_future_type::result_type; private: struct entry { cppfs::directory::iterator it; cppfs::directory::iterator end; }; using entry_stack = std::vector; entry_stack _stack; public: inline read_all_stream( const fs::directory& p_directory) { auto& d = p_directory.handle; if (d.exists()) { _stack.emplace_back(entry { d.begin(), d.end() }); } } public: inline result_type poll() { while (true) { if (_stack.empty()) return result_type::done(); auto& e = _stack.back(); if (e.it == e.end) { _stack.pop_back(); continue; } auto ret = result_type::ready(std::move(*e.it)); cppfs::directory d(e.it->path); ++e.it; if (d.exists()) { _stack.emplace_back(entry { d.begin(), d.end(), }); } return ret; } } }; template< chaining_mode X_mode, typename X_self> inline auto read_all_impl(X_self&& p_self) { return read_all_stream(std::forward(p_self)); } } } } namespace asyncpp { namespace fs { template auto directory ::read_all() & { return __directory::read_all_impl(*this); } template auto directory ::read_all() && { static_assert( X_mode != ref, "Can not store rvalue reference as lvalue reference!"); return __directory::read_all_impl(std::move(*this)); } } }