Всем привет пример демонстрирует применение сопрограмм (англ. coroutine) для "выправления" рекурсивного алгоритма... в качестве алгоритма используется рекурсивный поиск файлов... ну и покажу сразу примеры того что в итоге получилось... а вернее как этим пользоваться... например чтоб найти все файлы в c:\ и вложенных директориях надо задать маску *.* Code: int main() { FileGenerator obj("c:\\*.*"); while (obj.hasNext()) { printf("%s\n", obj.get()); } } если надо найти файлы только с расширением txt то тогда так Code: int main() { FileGenerator obj("c:\\*.txt"); while (obj.hasNext()) { printf("%s\n", obj.get()); } } второй параметр у FileGenerator определяет надо ли искать во вложенных директорих по умолчанию он ищет во всех вложенных директориях собственно реализация Code: #include <stdio.h> #include <tchar.h> #include <windows.h> #include <shlwapi.h> #include <boost/coroutine/all.hpp> #include <boost/bind.hpp> #include <boost/scope_exit.hpp> struct FileGenerator { bool skip; typedef boost::coroutines::coroutine<PCTSTR()> coro_t; coro_t coro; FileGenerator(PCTSTR path, BOOL bInnerFolders = TRUE) { skip = true; start_coroutine(path, bInnerFolders); } void coroutine(coro_t::caller_type& yield, PCTSTR _path, BOOL bInnerFolders) { TCHAR path[MAX_PATH * 2]; TCHAR filename[_MAX_EXT]; if (PathSearchAndQualify(_path, path, _countof(path))) { LPCTSTR q = PathFindFileName(path); if (q != path) { lstrcpyn(filename, q, _countof(filename)); PathRemoveFileSpec(path); DoSearch(path, filename, bInnerFolders, yield); } } } void start_coroutine(PCTSTR path, BOOL bInnerFolders) { coro = coro_t(boost::bind(&FileGenerator::coroutine, this, _1, path, bInnerFolders)); } bool hasNext() { skip ? skip = false : coro(); return coro; } PCTSTR get() { return coro.get(); } VOID DoSearch(LPTSTR path, LPCTSTR filename, BOOL bInnerFolders, coro_t::caller_type& yield) { HANDLE hSearch; WIN32_FIND_DATA wfd; PathAddBackslash(path); PathCombine(path, path, _T("*.*")); LPTSTR q = PathFindFileName(path); if(bInnerFolders) { hSearch = FindFirstFile(path, &wfd); if (INVALID_HANDLE_VALUE != hSearch) { BOOST_SCOPE_EXIT_ALL(&) { FindClose(hSearch); }; do { if (*wfd.cFileName == _T('.')) continue; if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) { lstrcpy(q, wfd.cFileName); DoSearch(path, filename, bInnerFolders, yield); } } while (FindNextFile(hSearch, &wfd)); } } lstrcpy(q, filename); hSearch = FindFirstFile(path, &wfd); if (INVALID_HANDLE_VALUE != hSearch) { BOOST_SCOPE_EXIT_ALL(&) { FindClose(hSearch); }; do { if (!(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) { lstrcpy(q, wfd.cFileName); yield(path); } } while (FindNextFile(hSearch, &wfd)); } } };