1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#include <chrono>
#include <cstdlib>
#include <functional>
#include <future>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
class when {
public:
template <class Predicate, class Callable, typename... Args>
when(Predicate p, Callable c, Args... args)
{
std::thread thread(when_thread_entry<Predicate, Callable, Args...>(p, c, args...));
thread.detach();
}
private:
template <class Predicate, class Callable, typename... Args>
struct when_thread_entry {
when_thread_entry(Predicate p, Callable c, Args... args) : predicate(p), function(c), tuple(args...)
{
// Do nothing.
}
void operator()()
{
while (!(predicate()))
std::this_thread::yield();
call_function();
}
private:
template <int... Indices>
struct index {};
template <int N, int... Indices>
struct gen_seq : gen_seq<N - 1, N - 1, Indices...> {};
template <int... Indices>
struct gen_seq<0, Indices...> : index<Indices...> {};
Predicate predicate;
Callable function;
std::tuple<Args...> tuple;
template <int... Indices>
void call_function(index<Indices...>)
{
function(std::get<Indices>(tuple)...);
}
void call_function()
{
call_function(gen_seq<sizeof...(Args)>{});
}
};
};
struct timeout_predicate {
timeout_predicate(std::time_t duration) : end(curtime() + duration)
{
// Do nothing.
}
bool operator()()
{
return (curtime() >= end);
}
private:
std::time_t end;
std::time_t curtime()
{
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
}
};
class after : public when {
public:
template <class Callable, typename... Args>
after(std::time_t timeout, Callable c, Args... args) : when(timeout_predicate(timeout), c, args...)
{
// Do nothing.
}
};
struct string_printer {
string_printer(std::ostream& stream) : m_stream(stream)
{
// Do nothing.
}
void operator()(const std::string& string)
{
m_stream << string;
}
private:
std::ostream& m_stream;
};
struct stream_flusher {
stream_flusher(std::ostream& stream) : m_stream(stream)
{
// Do nothing.
}
void operator()()
{
m_stream << std::flush;
}
private:
std::ostream& m_stream;
};
struct program_exiter {
void operator()(int exit_code = EXIT_SUCCESS)
{
std::exit(exit_code);
}
};
int main()
{
string_printer printer(std::cout);
stream_flusher flusher(std::cout);
program_exiter exiter;
after( 9, flusher);
after( 7, printer, "hello, world\n");
after( 3, printer, "Message: ");
after( 5, flusher);
after(10, exiter, EXIT_SUCCESS);
while (true)
;
}
|