Skip to content

Instantly share code, notes, and snippets.

@wilburding
Created April 1, 2013 15:58
Show Gist options
  • Save wilburding/5285775 to your computer and use it in GitHub Desktop.
Save wilburding/5285775 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
#include <string>
#include <mutex>
#include <future>
#include <chrono>
#include <utility>
#include <assert.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
//printf is thread-safe
void asyncApi(const function<void(string)>& handler, const string& s)
{
thread th([handler, s]{
printf("Started async\n");
this_thread::sleep_for(chrono::seconds(3));
handler(s);
});
th.detach();
}
template<class R, class A>
struct Continuator
{
typedef function<R(const function<R(A)>&)> ActionFunc;
Continuator(ActionFunc f)
:_action(f)
{}
R andThen(const function<R(A)>& k) const
{
return _action(k);
}
ActionFunc _action;
};
template<class R, class A>
R andThen(const Continuator<R, A>& ktor, const function<R(A)>& f)
{
return ktor.andThen(f);
}
template<class R, class A>
Continuator<R, A> Return(A a)
{
return { [a](const function<R(A)>& f) { return f(a); }};
}
template<class R, class A>
Continuator<R, A> Bind(const Continuator<R, A>& ktor, const function<Continuator<R, A>(A)>& rest)
{
return { [ktor, rest](const function<R(A)>& k)
{
auto lambda = [k, rest](A a) {
return rest(a).andThen(k);
};
return ktor.andThen(lambda);
}
};
}
Continuator<void, string> Async(const string& s)
{
return {
[s](const function<void(string)>& f) {
asyncApi(f, s);
}
};
}
Continuator<void, string> loop(string s)
{
return {
[s](const function<void(string)>& f) {
printf("In loop %s\n", s.c_str());
Bind<void, string>(Async(s), loop).andThen(f);
}
};
}
Continuator<void, string> loop_n(string s, int n)
{
if(n == 0)
{
return Return<void, string>(s);
}
else
{
return {
[n, s](const function<void(string)>& f){
printf("in loop %d: %s\n", n, s.c_str());
Bind<void, string>(Async(s.substr(0, s.size() - 1)), bind(loop_n, placeholders::_1, n - 1)).andThen(f);
}
};
}
}
int main(int argc, char* argv[])
{
/*andThen<void, string>(ktor, [](string s) { cout << "worker: " << s << endl;});*/
/*loop("blah").andThen([](string s) { cout << "never" << endl; });*/
loop_n("blahblahblah", 5).andThen([](string s) { printf("done: %s\n", s.c_str()); });
for(int i = 0; i < 20; ++i)
{
cout << i << endl;
this_thread::sleep_for(chrono::seconds(1));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment