Last active
August 29, 2015 14:16
-
-
Save ubnt-intrepid/42139e24852590e8895a to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <iostream> | |
#include <type_traits> | |
#include <utility> | |
#include <boost/optional.hpp> | |
template <typename T> | |
std::ostream& operator<<(std::ostream& os, boost::optional<T> const& val) | |
{ | |
if (val) | |
return os << val.get(); | |
else | |
return os << "none"; | |
} | |
template <typename F> | |
struct scope_exit_t { | |
F f; | |
scope_exit_t(F&& f) | |
:f(f) {} | |
~scope_exit_t() { | |
f(); | |
} | |
}; | |
template <typename F> | |
scope_exit_t<F> scope_exit(F f){ return scope_exit_t<F>(std::move(f)); } | |
/// 有効値が帰ってくるか指定回数に達するまで関数を繰り返し実行する | |
/// 関数の戻り値は以下の要件を満たす必要がある | |
/// (要件を満たす例 : std::fstream, std::unique_ptr, boost::optional) | |
/// * bool への型変換で有効か無効かを判定できる | |
/// * default/move constructorを持つ | |
/// * デフォルト構築時は無効状態 | |
template <typename Func, typename... Args> | |
typename std::result_of<Func(Args...)>::type | |
repeat(int max_repeat, Func f, Args... args) | |
{ | |
for (int i = 0; i < max_repeat; ++i) { | |
if (auto ret = f(std::forward<Args>(args)...)) | |
return ret; | |
} | |
return typename std::result_of<Func(Args...)>::type(); | |
} | |
int main() | |
{ | |
auto eval = [](int max_count, int& count) { | |
auto e = scope_exit([&]{ | |
std::cout << "eval: count=" << count << std::endl; | |
count++; | |
}); | |
return boost::optional<int>(count >= max_count, count); | |
}; | |
int count = 0; | |
std::cout << repeat(40, eval, 20, std::ref(count)) << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment