Last active
August 29, 2015 14:15
-
-
Save ubnt-intrepid/6968fb2c13da559402fc to your computer and use it in GitHub Desktop.
遅延評価サンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cl /EHsc coroutine.cpp && coroutine.exe | |
#include <iostream> | |
#include <functional> | |
#include <thread> // std::this_thread::sleep_for | |
#include <future> | |
#include <queue> | |
using namespace std; | |
inline void sleep() { | |
this_thread::sleep_for(chrono::seconds(1)); | |
} | |
template <class F> | |
inline future<void> make_task(F&& f) { | |
// 遅延評価(future<void>.get()の初回呼び出し時に実行する) | |
return async(launch::deferred, f); | |
} | |
queue<future<void>> make_taskset() | |
{ | |
queue<future<void>> taskset; | |
taskset.push( make_task([]{ cout << "method1"; }) ); | |
taskset.push( make_task([]{ cout << "method2"; }) ); | |
taskset.push( make_task([]{ cout << "method3"; }) ); | |
taskset.push( make_task([]{ cout << "method4"; }) ); | |
taskset.push( make_task([]{ cout << "method5"; }) ); | |
return taskset; | |
} | |
void run_all(queue<future<void>>&& taskset) | |
{ | |
for (int i = 0; !taskset.empty(); ++i) | |
{ | |
// タスクの呼び出し前にメッセージを追加 | |
cout << "[" << (i + 1) << "回目の呼び出し]: "; | |
// タスクの実行 | |
auto f = move(taskset.front()); // タスクを取り出し | |
f.get(); // 実行(遅延評価) | |
taskset.pop(); // 先頭要素を削除し,次の要素に移動 | |
// 次のタスクを実行する前に実行 | |
cout << " [" << (i+1) << "回目の呼び出し完了]\n" << flush; | |
sleep(); | |
} | |
} | |
int main() | |
{ | |
queue<future<void>> taskset = make_taskset(); | |
cout << "start method" << endl; | |
run_all(move(taskset)); | |
cout << "finished" << endl; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <queue> | |
#include <functional> | |
class task_chain | |
{ | |
using task_t = std::function<void()>; | |
private: | |
std::queue<task_t> tasks_; | |
public: | |
template <class Task> | |
void push(Task task) | |
{ | |
// queueの末尾にタスクを追加する | |
tasks_.push(task_t(std::move(task))); | |
} | |
void apply() | |
{ | |
// queueの先頭要素を取り出し実行する | |
auto task = std::move(tasks_.front()); | |
task(); | |
tasks_.pop(); | |
} | |
void apply_all() | |
{ | |
// queueが空になるまで実行する | |
while (!tasks_.empty()) { | |
tasks.apply(); | |
} | |
} | |
}; | |
int main() | |
{ | |
task_chain tasks; | |
tasks.push([]{ | |
do_something(); | |
}); | |
tasks.push([]{ | |
for (int i = 0; i < 10; ++i) { | |
do_something(); | |
} | |
}); | |
tasks.apply(); | |
tasks.apply_all(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment