fork download
  1. #include <boost/range/algorithm_ext.hpp>
  2. #include <boost/range/algorithm.hpp>
  3.  
  4. #include <boost/iostreams/categories.hpp>
  5. #include <boost/iostreams/stream.hpp>
  6.  
  7. #include <boost/coroutine/all.hpp>
  8.  
  9. #include <functional>
  10. #include <algorithm>
  11. #include <iostream>
  12. #include <cstddef>
  13. #include <utility>
  14. #include <string>
  15. #include <vector>
  16. #include <deque>
  17.  
  18. using namespace boost;
  19. using namespace std;
  20. using namespace placeholders;
  21.  
  22. typedef coroutines::coroutine<void()> Coro;
  23. typedef deque<char> Buffer;
  24.  
  25. struct DataSource
  26. {
  27. typedef char char_type;
  28. typedef iostreams::source_tag category;
  29.  
  30. Coro::caller_type &ca;
  31. Buffer &buffer;
  32.  
  33. std::streamsize read(char* out, streamsize n)
  34. {
  35. if(buffer.empty())
  36. {
  37. ca();
  38. if(buffer.empty()) return -1;
  39. }
  40. auto actual_n = min(n, streamsize(buffer.size()));
  41. auto first = buffer.begin();
  42. auto last = first + actual_n;
  43. copy(first, last, out);
  44. buffer.erase(first, last);
  45. return actual_n;
  46. }
  47. };
  48. typedef iostreams::stream<DataSource> TcpStream;
  49.  
  50. void foo(TcpStream &client_stream)
  51. {
  52. string msg;
  53. do
  54. {
  55. getline(client_stream, msg);
  56. cout << "stream address: " << &client_stream << "|\t";
  57. cout << msg << endl;
  58. } while(msg != "exit");
  59. }
  60.  
  61. void coroutine_start(Buffer *buffer,Coro::caller_type &ca)
  62. {
  63. DataSource source{ca, *buffer};
  64. TcpStream client_stream(source);
  65. foo(client_stream);
  66. }
  67.  
  68. int main()
  69. {
  70. vector<Coro> fibers;
  71. vector<Buffer> buffers(4);
  72. for(auto &buffer : buffers)
  73. fibers.emplace_back(bind(coroutine_start, &buffer, _1));
  74.  
  75. struct StreamData
  76. {
  77. size_t receiver;
  78. string msg;
  79. } const stream_datas[] =
  80. {
  81. {0, "Hello"},
  82. {1, "World"},
  83. {2, "Stackfull"},
  84. {3, "Coroutines"},
  85. {2, "Rulez!"},
  86. {1, "Hasta la vista"},
  87. {0, "Baby"}
  88. };
  89.  
  90. for(auto &sd : stream_datas)
  91. {
  92. auto &buffer = buffers[sd.receiver];
  93. push_back(buffer, sd.msg);
  94. buffer.push_back('\n');
  95. fibers[sd.receiver]();
  96. }
  97.  
  98. for(auto &buffer : buffers)
  99. push_back(buffer, "exit\n");
  100. for(auto &c : fibers)
  101. c();
  102. }
  103.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty