#include <boost/range/algorithm_ext.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/coroutine/all.hpp>
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstddef>
#include <utility>
#include <string>
#include <vector>
#include <deque>
using namespace boost;
using namespace std;
using namespace placeholders;
typedef coroutines::coroutine<void()> Coro;
typedef deque<char> Buffer;
struct DataSource
{
typedef char char_type;
typedef iostreams::source_tag category;
Coro::caller_type &ca;
Buffer &buffer;
std::streamsize read(char* out, streamsize n)
{
if(buffer.empty())
{
ca();
if(buffer.empty()) return -1;
}
auto actual_n = min(n, streamsize(buffer.size()));
auto first = buffer.begin();
auto last = first + actual_n;
copy(first, last, out);
buffer.erase(first, last);
return actual_n;
}
};
typedef iostreams::stream<DataSource> TcpStream;
void foo(TcpStream &client_stream)
{
string msg;
do
{
getline(client_stream, msg);
cout << "stream address: " << &client_stream << "|\t";
cout << msg << endl;
} while(msg != "exit");
}
void coroutine_start(Buffer *buffer,Coro::caller_type &ca)
{
DataSource source{ca, *buffer};
TcpStream client_stream(source);
foo(client_stream);
}
int main()
{
vector<Coro> fibers;
vector<Buffer> buffers(4);
for(auto &buffer : buffers)
fibers.emplace_back(bind(coroutine_start, &buffer, _1));
struct StreamData
{
size_t receiver;
string msg;
} const stream_datas[] =
{
{0, "Hello"},
{1, "World"},
{2, "Stackfull"},
{3, "Coroutines"},
{2, "Rulez!"},
{1, "Hasta la vista"},
{0, "Baby"}
};
for(auto &sd : stream_datas)
{
auto &buffer = buffers[sd.receiver];
push_back(buffer, sd.msg);
buffer.push_back('\n');
fibers[sd.receiver]();
}
for(auto &buffer : buffers)
push_back(buffer, "exit\n");
for(auto &c : fibers)
c();
}
I2luY2x1ZGUgPGJvb3N0L3JhbmdlL2FsZ29yaXRobV9leHQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvcmFuZ2UvYWxnb3JpdGhtLmhwcD4KCiNpbmNsdWRlIDxib29zdC9pb3N0cmVhbXMvY2F0ZWdvcmllcy5ocHA+CiNpbmNsdWRlIDxib29zdC9pb3N0cmVhbXMvc3RyZWFtLmhwcD4KCiNpbmNsdWRlIDxib29zdC9jb3JvdXRpbmUvYWxsLmhwcD4KCiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxjc3RkZGVmPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGRlcXVlPgoKdXNpbmcgbmFtZXNwYWNlIGJvb3N0Owp1c2luZyBuYW1lc3BhY2Ugc3RkOwp1c2luZyBuYW1lc3BhY2UgcGxhY2Vob2xkZXJzOwoKdHlwZWRlZiBjb3JvdXRpbmVzOjpjb3JvdXRpbmU8dm9pZCgpPiBDb3JvOwp0eXBlZGVmIGRlcXVlPGNoYXI+IEJ1ZmZlcjsKCnN0cnVjdCBEYXRhU291cmNlCnsKICAgIHR5cGVkZWYgY2hhciAgICAgICAgY2hhcl90eXBlOwogICAgdHlwZWRlZiBpb3N0cmVhbXM6OnNvdXJjZV90YWcgY2F0ZWdvcnk7CgogICAgQ29ybzo6Y2FsbGVyX3R5cGUgJmNhOwogICAgQnVmZmVyICZidWZmZXI7CgogICAgc3RkOjpzdHJlYW1zaXplIHJlYWQoY2hhciogb3V0LCBzdHJlYW1zaXplIG4pCiAgICB7CiAgICAgICAgaWYoYnVmZmVyLmVtcHR5KCkpCiAgICAgICAgewogICAgICAgICAgICBjYSgpOwogICAgICAgICAgICBpZihidWZmZXIuZW1wdHkoKSkgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBhdXRvIGFjdHVhbF9uID0gbWluKG4sIHN0cmVhbXNpemUoYnVmZmVyLnNpemUoKSkpOwogICAgICAgIGF1dG8gZmlyc3QgPSBidWZmZXIuYmVnaW4oKTsKICAgICAgICBhdXRvIGxhc3QgPSBmaXJzdCArIGFjdHVhbF9uOwogICAgICAgIGNvcHkoZmlyc3QsIGxhc3QsIG91dCk7CiAgICAgICAgYnVmZmVyLmVyYXNlKGZpcnN0LCBsYXN0KTsKICAgICAgICByZXR1cm4gYWN0dWFsX247CiAgICB9Cn07CnR5cGVkZWYgaW9zdHJlYW1zOjpzdHJlYW08RGF0YVNvdXJjZT4gVGNwU3RyZWFtOwoKdm9pZCBmb28oVGNwU3RyZWFtICZjbGllbnRfc3RyZWFtKQp7CiAgICBzdHJpbmcgbXNnOwogICAgZG8KICAgIHsKICAgICAgICBnZXRsaW5lKGNsaWVudF9zdHJlYW0sIG1zZyk7CiAgICAgICAgY291dCA8PCAic3RyZWFtIGFkZHJlc3M6ICIgPDwgJmNsaWVudF9zdHJlYW0gPDwgInxcdCI7CiAgICAgICAgY291dCA8PCBtc2cgPDwgZW5kbDsKICAgIH0gd2hpbGUobXNnICE9ICJleGl0Iik7Cn0KCnZvaWQgY29yb3V0aW5lX3N0YXJ0KEJ1ZmZlciAqYnVmZmVyLENvcm86OmNhbGxlcl90eXBlICZjYSkKewogICAgRGF0YVNvdXJjZSBzb3VyY2V7Y2EsICpidWZmZXJ9OwogICAgVGNwU3RyZWFtIGNsaWVudF9zdHJlYW0oc291cmNlKTsKICAgIGZvbyhjbGllbnRfc3RyZWFtKTsKfQoKaW50IG1haW4oKQp7CiAgICB2ZWN0b3I8Q29ybz4gZmliZXJzOwogICAgdmVjdG9yPEJ1ZmZlcj4gYnVmZmVycyg0KTsKICAgIGZvcihhdXRvICZidWZmZXIgOiBidWZmZXJzKQogICAgICAgIGZpYmVycy5lbXBsYWNlX2JhY2soYmluZChjb3JvdXRpbmVfc3RhcnQsICZidWZmZXIsIF8xKSk7CgogICAgc3RydWN0IFN0cmVhbURhdGEKICAgIHsKICAgICAgICBzaXplX3QgcmVjZWl2ZXI7CiAgICAgICAgc3RyaW5nIG1zZzsKICAgIH0gY29uc3Qgc3RyZWFtX2RhdGFzW10gPQogICAgewogICAgICAgIHswLCAiSGVsbG8ifSwKICAgICAgICB7MSwgIldvcmxkIn0sCiAgICAgICAgezIsICJTdGFja2Z1bGwifSwKICAgICAgICB7MywgIkNvcm91dGluZXMifSwKICAgICAgICB7MiwgIlJ1bGV6ISJ9LAogICAgICAgIHsxLCAiSGFzdGEgbGEgdmlzdGEifSwKICAgICAgICB7MCwgIkJhYnkifQogICAgfTsKCiAgICBmb3IoYXV0byAmc2QgOiBzdHJlYW1fZGF0YXMpCiAgICB7CiAgICAgICAgYXV0byAmYnVmZmVyID0gYnVmZmVyc1tzZC5yZWNlaXZlcl07CiAgICAgICAgcHVzaF9iYWNrKGJ1ZmZlciwgc2QubXNnKTsKICAgICAgICBidWZmZXIucHVzaF9iYWNrKCdcbicpOwogICAgICAgIGZpYmVyc1tzZC5yZWNlaXZlcl0oKTsKICAgIH0KCiAgICBmb3IoYXV0byAmYnVmZmVyIDogYnVmZmVycykKICAgICAgICBwdXNoX2JhY2soYnVmZmVyLCAiZXhpdFxuIik7CiAgICBmb3IoYXV0byAmYyA6IGZpYmVycykKICAgICAgIGMoKTsKfQo=