#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