blob: 4ad1ef4f473cd1a5cda53435db8af131e68289db (
plain)
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
|
#ifndef HEADER_THREAD_H
#define HEADER_THREAD_H
#include "Base.h"
#ifdef CRU_WINDOWS
#include <Windows.h>
#else
#include <pthread.h>
#endif
#ifdef __cplusplus
#include <cassert>
#include <functional>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
namespace cru {
class CRU_API Thread {
public:
Thread() = default;
template <typename Fn, typename... Args> Thread(Fn &&process, Args &&...args);
Thread(const Thread &other) = delete;
Thread(Thread &&other) noexcept;
Thread &operator=(const Thread &other) = delete;
Thread &operator=(Thread &&other) noexcept;
~Thread();
public:
void Join();
void Detach();
#ifdef CRU_WINDOWS
DWORD
#else
pthread_t
#endif
GetNativeID();
#ifdef CRU_WINDOWS
HANDLE
#else
pthread_t
#endif
GetNativeHandle();
void swap(Thread &other) noexcept;
private:
void Destroy() noexcept;
void CreateThread(std::function<void()> *proc);
private:
bool detached_ = false;
bool joined_ = false;
#ifdef CRU_WINDOWS
DWORD thread_id_ = 0;
HANDLE thread_handle_ = nullptr;
#else
std::unique_ptr<pthread_t> thread_;
#endif
};
template <typename Fn, typename... Args>
Thread::Thread(Fn &&process, Args &&...args) {
std::tuple<std::decay_t<Args>...> a{std::forward<Args>(args)...};
auto p = new std::function<void()>(
[process = std::forward<Fn>(process), args = std::move(a)]() {
std::apply(process, std::move(args));
});
CreateThread(p);
};
} // namespace cru
#endif
#endif
|