fork download
  1. namespace thread {
  2.  
  3. /**
  4.   \brief Thread class for running member functions in a separate thread.
  5.  
  6.   Example:
  7.   \code{.cpp}
  8.   struct trooper {
  9.   void figth(int num) {
  10.   std::cerr << "fighting: " << num << '\n';
  11.   }
  12.   };
  13.  
  14.   trooper tr1;
  15.   trooper tr2;
  16.   thread para_trooper1(&trooper::fight, &tr1, 1);
  17.   thread para_trooper2(&trooper::fight, &tr2, 2);
  18.   \endcode
  19.  
  20. */
  21. struct thread
  22. {
  23. /**
  24.   \brief Creates a thread for a member function with no parameters.
  25.  
  26.   \param f Member function with signature T::*()
  27.   \param t Object of type T where f can be called
  28.   */
  29. template<typename F, typename T>
  30. thread(F f, T t) : joinable_(false), id_(0)
  31. {
  32. thread_helper_a0<F, T>* ph = new thread_helper_a0<F, T>(f, t);
  33. int const res = pthread_create(&id_, 0, &thread_helper_a0<F, T>::call, ph);
  34. if (res)
  35. {
  36. delete ph;
  37. throw std::runtime_error("thread creation failed");
  38. }
  39. joinable_ = true;
  40. }
  41.  
  42. /**
  43.   \brief Creates a thread for a member function with one parameters.
  44.  
  45.   \param f Member function with signature T::*(A)
  46.   \param t Object of type T where f can be called
  47.   \param a Parameter for thread function f
  48.   */
  49. template<typename F, typename T, typename A>
  50. thread(F f, T t, A a) : joinable_(false), id_(0)
  51. {
  52. thread_helper_a1<F, T, A>* ph = new thread_helper_a1<F, T, A>(f, t, a);
  53. int const res = pthread_create(&id_, 0, &thread_helper_a1<F, T, A>::call, ph);
  54. if (res)
  55. {
  56. delete ph;
  57. throw std::runtime_error("thread creation failed");
  58. }
  59. joinable_ = true;
  60. }
  61.  
  62. /**
  63.   \brief Creates a thread for a member function with two parameters.
  64.  
  65.   \param f Member function with signature T::*(A)
  66.   \param t Object of type T where f can be called
  67.   \param a first parameter for thread function f
  68.   \param b second parameter for thread function f
  69.   */
  70. template<typename F, typename T, typename A, typename B>
  71. thread(F f, T t, A a, B b) : joinable_(false), id_(0)
  72. {
  73. thread_helper_a2<F, T, A, B>* ph = new thread_helper_a2<F, T, A, B>(f, t, a, b);
  74. int const res = pthread_create(&id_, 0, &thread_helper_a2<F, T, A, B>::call, ph);
  75. if (res)
  76. {
  77. delete ph;
  78. throw std::runtime_error("thread creation failed");
  79. }
  80. joinable_ = true;
  81. }
  82.  
  83. /**
  84.   \brief Join with thread if thread is joinable otherwise throws an
  85.   exception of type std::runtime_error.
  86.   */
  87. void join()
  88. {
  89. if (!joinable_)
  90. throw std::logic_error("thread not joinable");
  91. int const res = pthread_join(id_, 0);
  92. if (res)
  93. throw std::runtime_error("thread joining failed");
  94. }
  95.  
  96. /**
  97.   \brief Detaches thread if thread is joinable otherwise throws an
  98.   exception of type std::runtime_exception.
  99.   */
  100. void detach()
  101. {
  102. if (!joinable_)
  103. throw std::logic_error("thread not detachable");
  104. int const res = pthread_detach(id_);
  105. if (res)
  106. throw std::runtime_error("thread detaching failed");
  107. }
  108.  
  109. ~thread()
  110. {
  111. }
  112.  
  113. private:
  114. template<typename F, typename T>
  115. struct thread_helper_a0
  116. {
  117. thread_helper_a0(F f, T t) : f(f), t(t) {}
  118.  
  119. static void* call(void* data)
  120. {
  121. thread_helper_a0* th = (thread_helper_a0*)data;
  122. F f = th->f;
  123. T t = th->t;
  124. delete th;
  125. (t->*f)();
  126. return 0;
  127. }
  128.  
  129. F f;
  130. T t;
  131. };
  132.  
  133. template<typename F, typename T, typename A>
  134. struct thread_helper_a1
  135. {
  136. thread_helper_a1(F f, T t, A a) : f(f), t(t), a(a) {}
  137.  
  138. static void* call(void* data)
  139. {
  140. thread_helper_a1* th = (thread_helper_a1*)data;
  141. F f = th->f;
  142. T t = th->t;
  143. A a = th->a;
  144. delete th;
  145. (t->*f)(a);
  146. return 0;
  147. }
  148.  
  149. F f;
  150. T t;
  151. A a;
  152. };
  153.  
  154. template<typename F, typename T, typename A, typename B>
  155. struct thread_helper_a2
  156. {
  157. thread_helper_a2(F f, T t, A a, B b) : f(f), t(t), a(a), b(b) {}
  158.  
  159. static void* call(void* data)
  160. {
  161. thread_helper_a2* th = (thread_helper_a2*)data;
  162. F f = th->f;
  163. T t = th->t;
  164. A a = th->a;
  165. B b = th->b;
  166. delete th;
  167. (t->*f)(a,b);
  168. return 0;
  169. }
  170.  
  171. F f;
  172. T t;
  173. A a;
  174. B b;
  175. };
  176.  
  177. thread();
  178. thread(thread const&);
  179. thread const& operator=(thread const&);
  180.  
  181. bool joinable_;
  182. pthread_t id_;
  183. };
  184.  
  185.  
  186.  
  187. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty