#pragma once #ifdef _WIN32 #include #include #elif __linux__ #include #else #error "이 플랫폼은 지원되지 않습니다." #endif #include #include namespace Chattr { class Thread { public: #ifdef _WIN32 static unsigned __stdcall thread_func(LPVOID param) { auto task = static_cast*>(param); (*task)(); delete task; return 0; } #elif __linux__ static void* thread_func(void *param) { auto task = static_cast*>(param); (*task)(); delete task; return 0; } #endif Thread(Thread&&) noexcept; Thread& operator=(Thread&&) noexcept; Thread(const Thread&) = delete; Thread& operator=(Thread&) = delete; template requires (!std::is_same_v, Thread>) && (!std::is_void_v>) Thread(_Callable&& __f, _Args&&... __args) { auto boundFunc = [this, __f = std::move(__f), ... __args = std::move(__args)]() mutable { returnValuePtr = new std::invoke_result_t<_Callable, _Args...>(__f(std::move(__args)...)); }; std::packaged_task* funcPtr = new std::packaged_task(std::move(boundFunc)); #ifdef _WIN32 handle_ = (HANDLE)_beginthreadex(nullptr, 0, thread_func, funcPtr, 0, nullptr); #elif __linux__ pthread_create(&handle_, NULL, thread_func, funcPtr); #endif } template requires (!std::is_same_v, Thread>) && std::is_void_v> Thread(_Callable&& __f, _Args&&... __args) { auto boundFunc = [this, __f = std::move(__f), ... __args = std::move(__args)]() mutable { __f(std::move(__args)...); }; std::packaged_task* funcPtr = new std::packaged_task(std::move(boundFunc)); #ifdef _WIN32 handle_ = (HANDLE)_beginthreadex(nullptr, 0, thread_func, funcPtr, 0, nullptr); #elif __linux__ pthread_create(&handle_, NULL, thread_func, funcPtr); #endif } ~Thread(); void join() { #ifdef _WIN32 WaitForSingleObject(handle_, INFINITE); #elif __linux__ pthread_join(handle_, returnValue); #endif } template requires (!std::is_void_v<_RetType>) _RetType join() { #ifdef _WIN32 WaitForSingleObject(handle_, INFINITE); #elif __linux__ pthread_join(handle_, returnValue); #endif return *static_cast<_RetType *>(returnValuePtr); } void detach(); private: #ifdef _WIN32 HANDLE handle_; #elif __linux__ pthread_t handle_; #endif void* returnValuePtr = nullptr; bool detached = false; }; } // namespace Chattr