blob: c71c11ff0cbcabf39340d8af8f2ffa26148ae956 (
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
|
#ifndef HEADER_THREAD_H
#define HEADER_THREAD_H
#include "Base.h"
#ifdef __cplusplus
#include <functional>
#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();
void swap(Thread &other) noexcept;
private:
void Destroy() noexcept;
private:
bool detached_ = false;
bool joined_ = false;
#ifdef CRU_WINDOWS
DWORD thread_id_ = 0;
HANDLE thread_handle_ = nullptr;
#endif
};
namespace details {
#ifdef CRU_WINDOWS
CRU_API DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter);
#else
#endif
} // namespace details
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));
});
#ifdef CRU_WINDOWS
thread_handle_ = ::CreateThread(nullptr, 0, &::cru::details::ThreadProc,
static_cast<void *>(p), 0, &thread_id_);
#endif
};
} // namespace cru
#endif
#endif
|