Skip to content

Instantly share code, notes, and snippets.

@ubnt-intrepid
Last active August 29, 2015 14:16
Show Gist options
  • Save ubnt-intrepid/42139e24852590e8895a to your computer and use it in GitHub Desktop.
Save ubnt-intrepid/42139e24852590e8895a to your computer and use it in GitHub Desktop.
#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