1+ #include < fstream>
2+ #include < iostream>
3+ #include < filesystem>
4+
5+ #include " concurrencpp/concurrencpp.h"
6+
7+ concurrencpp::generator<std::string_view> read_lines (std::string_view text) {
8+ std::string_view::size_type pos = 0 ;
9+ std::string_view::size_type prev = 0 ;
10+
11+ while ((pos = text.find (' \n ' , prev)) != std::string::npos) {
12+ co_yield text.substr (prev, pos - prev);
13+ prev = pos + 1 ;
14+ }
15+
16+ co_yield text.substr (prev);
17+ }
18+
19+ concurrencpp::result<void > read_file_lines (const std::filesystem::path& path,
20+ std::shared_ptr<concurrencpp::thread_pool_executor> background_executor,
21+ std::shared_ptr<concurrencpp::thread_pool_executor> thread_pool_executor) {
22+ // make sure we don't block in a thread that is used for cpu-processing
23+ co_await concurrencpp::resume_on (background_executor);
24+
25+ std::ifstream stream (path.c_str (), std::ios::binary | std::ios::in);
26+ std::string file_content (std::istreambuf_iterator<char >(stream), {});
27+
28+ // make sure we don't process cpu-bound tasks on the background executor
29+ co_await concurrencpp::resume_on (thread_pool_executor);
30+
31+ for (const auto & line : read_lines (file_content)) {
32+ std::cout << " read a new line. size: " << line.size () << std::endl;
33+ std::cout << " line: " << std::endl;
34+ std::cout << line;
35+ std::cout << " \n ==============" << std::endl;
36+ }
37+ }
38+
39+ int main (const int argc, const char * argv[]) {
40+ if (argc < 2 ) {
41+ const auto help_msg = " please pass all necessary arguments\n argv[1] - the file to be read\n " ;
42+ std::cerr << help_msg << std::endl;
43+ return -1 ;
44+ }
45+
46+ const auto file_path = std::string (argv[1 ]);
47+
48+ concurrencpp::runtime runtime;
49+ const auto thread_pool_executor = runtime.thread_pool_executor ();
50+ const auto background_executor = runtime.background_executor ();
51+
52+ read_file_lines (file_path, thread_pool_executor, background_executor).get ();
53+ return 0 ;
54+ }
0 commit comments