9 #define WIN32_LEAN_AND_MEAN
12 #elif defined(__APPLE__)
27 static_assert(sizeof(T
) <= sizeof(void*));
28 static_assert(std::is_trivially_destructible_v
<T
> && std::is_trivially_copy_constructible_v
<T
>);
31 static auto to_ptr(const T
&value
) noexcept
-> void*
33 if constexpr(std::is_pointer_v
<T
>)
35 if constexpr(std::is_const_v
<std::remove_pointer_t
<T
>>)
36 return const_cast<void*>(static_cast<const void*>(value
)); /* NOLINT(*-const-cast) */
38 return static_cast<void*>(value
);
40 else if constexpr(sizeof(T
) == sizeof(void*))
41 return al::bit_cast
<void*>(value
);
42 else if constexpr(std::is_integral_v
<T
>)
43 return al::bit_cast
<void*>(static_cast<std::uintptr_t>(value
));
47 static auto from_ptr(void *ptr
) noexcept
-> T
49 if constexpr(std::is_pointer_v
<T
>)
50 return static_cast<T
>(ptr
);
51 else if constexpr(sizeof(T
) == sizeof(void*))
52 return al::bit_cast
<T
>(ptr
);
53 else if constexpr(std::is_integral_v
<T
>)
54 return static_cast<T
>(al::bit_cast
<std::uintptr_t>(ptr
));
58 DWORD mTss
{TLS_OUT_OF_INDEXES
};
61 tss() : mTss
{TlsAlloc()}
63 if(mTss
== TLS_OUT_OF_INDEXES
)
64 throw std::runtime_error
{"al::tss::tss()"};
66 explicit tss(const T
&init
) : tss
{}
68 if(TlsSetValue(mTss
, to_ptr(init
)) == FALSE
)
69 throw std::runtime_error
{"al::tss::tss(T)"};
71 ~tss() { TlsFree(mTss
); }
73 void set(const T
&value
) const
75 if(TlsSetValue(mTss
, to_ptr(value
)) == FALSE
)
76 throw std::runtime_error
{"al::tss::set(T)"};
80 auto get() const noexcept
-> T
{ return from_ptr(TlsGetValue(mTss
)); }
82 #elif defined(__APPLE__)
89 if(int res
{pthread_key_create(&mTss
, nullptr)}; res
!= 0)
90 throw std::runtime_error
{"al::tss::tss()"};
92 explicit tss(const T
&init
) : tss
{}
94 if(int res
{pthread_setspecific(mTss
, to_ptr(init
))}; res
!= 0)
95 throw std::runtime_error
{"al::tss::tss(T)"};
97 ~tss() { pthread_key_delete(mTss
); }
99 void set(const T
&value
) const
101 if(int res
{pthread_setspecific(mTss
, to_ptr(value
))}; res
!= 0)
102 throw std::runtime_error
{"al::tss::set(T)"};
106 auto get() const noexcept
-> T
{ return from_ptr(pthread_getspecific(mTss
)); }
115 if(int res
{tss_create(&mTss
, nullptr)}; res
!= thrd_success
)
116 throw std::runtime_error
{"al::tss::tss()"};
118 explicit tss(const T
&init
) : tss
{}
120 if(int res
{tss_set(mTss
, to_ptr(init
))}; res
!= thrd_success
)
121 throw std::runtime_error
{"al::tss::tss(T)"};
123 ~tss() { tss_delete(mTss
); }
125 void set(const T
&value
) const
127 if(int res
{tss_set(mTss
, to_ptr(value
))}; res
!= thrd_success
)
128 throw std::runtime_error
{"al::tss::set(T)"};
132 auto get() const noexcept
-> T
{ return from_ptr(tss_get(mTss
)); }
135 tss(const tss
&) = delete;
137 void operator=(const tss
&) = delete;
138 void operator=(tss
&&) = delete;
143 #endif /* AL_THREADS_H */