20#ifndef WIN32STDTHREAD_H
21#define WIN32STDTHREAD_H
23#if !defined(__cplusplus) || (__cplusplus < 201103L)
24#error A C++11 compiler is required!
34#include <system_error>
42#define _STD_THREAD_INVALID_HANDLE 0
48#if __cplusplus < 201703L
49 template<
bool PMemFunc,
bool PMemData>
52 template<
class F,
class... Args>
53 inline static typename std::result_of<F(Args...)>::type
invoke (F&& f, Args&&... args)
55 return std::forward<F>(f)(std::forward<Args>(args)...);
65 inline static auto get (T1&& t1) ->
decltype(*std::forward<T1>(t1))
67 return *std::forward<T1>(t1);
71 inline static auto get (
const std::reference_wrapper<T1>& t1) ->
decltype(t1.get())
81 inline static auto get (T1&& t1) ->
decltype(std::forward<T1>(t1))
83 return std::forward<T1>(t1);
90 template<
class T,
class F,
class T1,
class... Args>
91 inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\
92 decltype((
InvokerHelper<std::is_base_of<T,
typename std::decay<T1>::type>::value>
::get(std::forward<T1>(t1)).*f)(std::forward<Args>(args)...))
94 return (
InvokerHelper<std::is_base_of<T,
typename std::decay<T1>::type>::value>
::get(std::forward<T1>(t1)).*f)(std::forward<Args>(args)...);
101 template<
class T,
class F,
class T1,
class... Args>
102 inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\
103 decltype(
InvokerHelper<std::is_base_of<T,
typename std::decay<T1>::type>::value>
::get(t1).*f)
109 template<
class F,
class... Args>
113 std::is_member_object_pointer<typename std::remove_reference<F>::type>::value &&
115 inline static auto invoke (F&& f, Args&&... args) ->
decltype(
invoker::invoke(std::forward<F>(f), std::forward<Args>(args)...))
117 return invoker::invoke(std::forward<F>(f), std::forward<Args>(args)...);
121 template<
class F,
class...Args>
133 template<
int N,
int... S>
140 template<
class Func,
typename... Args>
165 friend class std::hash<
id>;
167 explicit id(DWORD aId=0) noexcept :
mId(aId){}
168 friend bool operator==(
id x,
id y)
noexcept {
return x.mId == y.mId; }
169 friend bool operator!=(
id x,
id y)
noexcept {
return x.mId != y.mId; }
170 friend bool operator< (
id x,
id y)
noexcept {
return x.mId < y.mId; }
171 friend bool operator<=(
id x,
id y)
noexcept {
return x.mId <= y.mId; }
172 friend bool operator> (
id x,
id y)
noexcept {
return x.mId > y.mId; }
173 friend bool operator>=(
id x,
id y)
noexcept {
return x.mId >= y.mId; }
175 template<
class _CharT,
class _Traits>
176 friend std::basic_ostream<_CharT, _Traits>&
177 operator<<(std::basic_ostream<_CharT, _Traits>& __out,
id __id)
181 return __out <<
"(invalid std::thread::id)";
185 return __out << __id.
mId;
202 other.mThreadId.clear();
207 template<
class Func,
typename... Args>
211 auto call =
new Call(
212 std::forward<Func>(func), std::forward<Args>(args)...);
213 mHandle = (HANDLE)_beginthreadex(NULL, 0, threadfunc<Call, Args...>,
219 throw std::system_error(errnum, std::generic_category());
222 template <
class Call,
typename... Args>
225 std::unique_ptr<Call> call(
static_cast<Call*
>(arg));
232 if (
get_id() ==
id(GetCurrentThreadId()))
233 throw std::system_error(EDEADLK, std::generic_category());
235 throw std::system_error(ESRCH, std::generic_category());
237 throw std::system_error(EINVAL, std::generic_category());
238 WaitForSingleObject(
mHandle, INFINITE);
254 swap(std::forward<thread>(other));
266 ::GetSystemInfo(&sysinfo);
267 return sysinfo.dwNumberOfProcessors;
279 throw std::system_error(EINVAL, std::generic_category());
292 inline void yield() noexcept {Sleep(0);}
293 template<
class Rep,
class Period >
294 void sleep_for(
const std::chrono::duration<Rep,Period>& sleep_duration)
296 Sleep(std::chrono::duration_cast<std::chrono::milliseconds>(sleep_duration).count());
298 template <
class Clock,
class Duration>
299 void sleep_until(
const std::chrono::time_point<Clock,Duration>& sleep_time)
313#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)
321#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING)
322#define MINGW_STDTHREAD_REDUNDANCY_WARNING
323#pragma message "This version of MinGW seems to include a win32 port of\
324 pthreads, and probably already has C++11 std threading classes implemented,\
325 based on pthreads. These classes, found in namespace std, are not overridden\
326 by the mingw-std-thread library. If you would still like to use this\
327 implementation (as it is more lightweight), use the classes provided in\
328 namespace mingw_stdthread."
friend bool operator==(id x, id y) noexcept
friend bool operator<(id x, id y) noexcept
friend bool operator>=(id x, id y) noexcept
friend bool operator<=(id x, id y) noexcept
friend std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__out, id __id)
friend bool operator>(id x, id y) noexcept
friend bool operator!=(id x, id y) noexcept
static unsigned int _hardware_concurrency_helper() noexcept
thread(Func &&func, Args &&... args)
static unsigned int hardware_concurrency() noexcept
id get_id() const noexcept
void swap(thread &&other) noexcept
thread & operator=(thread &&other) noexcept
static unsigned __stdcall threadfunc(void *arg)
native_handle_type native_handle() const
thread(const thread &other)=delete
HANDLE native_handle_type
thread & operator=(const thread &)=delete
#define _STD_THREAD_INVALID_HANDLE
auto invoke(F &&f, Args &&... args) -> decltype(InvokeResult< F, Args... >::invoke(std::forward< F >(f), std::forward< Args >(args)...))
thread::id get_id() noexcept
void sleep_for(const std::chrono::duration< Rep, Period > &sleep_duration)
void sleep_until(const std::chrono::time_point< Clock, Duration > &sleep_time)
void swap(shared_lock< Mutex > &lhs, shared_lock< Mutex > &rhs) noexcept
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Provides common mathematical functions and vector operations.
static auto invoke(F &&f, Args &&... args) -> decltype(invoker::invoke(std::forward< F >(f), std::forward< Args >(args)...))
Invoker< std::is_member_function_pointer< typename std::remove_reference< F >::type >::value, std::is_member_object_pointer< typename std::remove_reference< F >::type >::value &&(sizeof...(Args)==1)> invoker
static auto invoke(F T::*f, T1 &&t1, Args &&... args) -> decltype(InvokerHelper< std::is_base_of< T, typename std::decay< T1 >::type >::value >::get(t1).*f)
static auto invoke(F T::*f, T1 &&t1, Args &&... args) -> decltype((InvokerHelper< std::is_base_of< T, typename std::decay< T1 >::type >::value >::get(std::forward< T1 >(t1)).*f)(std::forward< Args >(args)...))
static auto get(const std::reference_wrapper< T1 > &t1) -> decltype(t1.get())
static auto get(T1 &&t1) -> decltype(*std::forward< T1 >(t1))
static auto get(T1 &&t1) -> decltype(std::forward< T1 >(t1))
static std::result_of< F(Args...)>::type invoke(F &&f, Args &&... args)
std::tuple< Args... > Tuple
void callFunc(detail::IntSeq< S... >)
ThreadFuncCall(Func &&aFunc, Args &&... aArgs)
mingw_stdthread::thread::id argument_type