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