1 // LAF Base Library
2 // Copyright (c) 2001-2016 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifndef BASE_THREAD_H_INCLUDED
8 #define BASE_THREAD_H_INCLUDED
9 #pragma once
10 
11 namespace base {                // Based on C++0x threads lib
12 
13   class thread {
14   public:
15     typedef void* native_handle_type;
16 
17     // Create an instance to represent the current thread
18     thread();
19 
20     // Create a new thread without arguments
21     template<class Callable>
thread(const Callable & f)22     thread(const Callable& f) {
23       launch_thread(new func_wrapper0<Callable>(f));
24     }
25 
26     // Create a new thread with one argument
27     template<class Callable, class A>
thread(const Callable & f,A a)28     thread(const Callable& f, A a) {
29       launch_thread(new func_wrapper1<Callable, A>(f, a));
30     }
31 
32     // Create a new thread with two arguments
33     template<class Callable, class A, class B>
thread(const Callable & f,A a,B b)34     thread(const Callable& f, A a, B b) {
35       launch_thread(new func_wrapper2<Callable, A, B>(f, a, b));
36     }
37 
38     ~thread();
39 
40     bool joinable() const;
41     void join();
42     void detach();
43 
44     native_handle_type native_handle();
45 
46     class details {
47     public:
48       static void thread_proxy(void* data);
49     };
50 
51   private:
52     native_handle_type m_native_handle;
53 
54     class func_wrapper {
55     public:
~func_wrapper()56       virtual ~func_wrapper() { }
57       virtual void operator()() = 0;
58     };
59 
60     void launch_thread(func_wrapper* f);
61 
62     template<class Callable>
63     class func_wrapper0 : public func_wrapper {
64     public:
65       Callable f;
func_wrapper0(const Callable & f)66       func_wrapper0(const Callable& f) : f(f) { }
operator()67       void operator()() { f(); }
68     };
69 
70     template<class Callable, class A>
71     class func_wrapper1 : public func_wrapper {
72     public:
73       Callable f;
74       A a;
func_wrapper1(const Callable & f,A a)75       func_wrapper1(const Callable& f, A a) : f(f), a(a) { }
operator()76       void operator()() { f(a); }
77     };
78 
79     template<class Callable, class A, class B>
80     class func_wrapper2 : public func_wrapper {
81     public:
82       Callable f;
83       A a;
84       B b;
func_wrapper2(const Callable & f,A a,B b)85       func_wrapper2(const Callable& f, A a, B b) : f(f), a(a), b(b) { }
operator()86       void operator()() { f(a, b); }
87     };
88 
89   };
90 
91   namespace this_thread
92   {
93     void yield();
94     void sleep_for(double seconds);
95     thread::native_handle_type native_handle();
96   }
97 
98   // This class joins the thread in its destructor.
99   class thread_guard {
100     thread& m_thread;
101   public:
thread_guard(thread & t)102     explicit thread_guard(thread& t) : m_thread(t) { }
~thread_guard()103     ~thread_guard()
104     {
105       if (m_thread.joinable())
106         m_thread.join();
107     }
108   };
109 
110 }
111 
112 #endif
113