/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: TLSVariable.hpp Date: 2021-6-11 Author: Reece ***/ #pragma once namespace Aurora::Threading::Threads { template class TLSVariable { private: int _; public: TLSVariable() {} ~TLSVariable() { if constexpr (!isStatic) { GetThread()->GetTlsView()->Remove(GetHandle()); } } T& operator ->() { return Get(); } operator T&() { return Get(); } T operator *() { return Get(); } TLSVariable& operator =(const T & val) { Get() = val; return *this; } private: AuUInt64 GetHandle() { if constexpr (isStatic) { return (AuUInt64(reinterpret_cast(&_)) & (~kTlsKeyMask)) | kTlsKeyFollowsConvention | kTlsKeyStaticPointerHandle; } else { return (AuUInt64(reinterpret_cast(&_)) & (~kTlsKeyMask)) | kTlsKeyFollowsConvention | kTlsKeyResettablePointerHandle; } } T &Get() { auto view = GetThread()->GetTlsView(); auto ptr = view->GetOrSetup(GetHandle(), sizeof(T), [](void *buffer) -> void { if constexpr (AuIsClass_v) { new (buffer) T(); } else { //std::memset(buffer, 0, sizeof(T)); } }, [](void *buffer) -> void { if constexpr (AuIsClass_v) { reinterpret_cast(buffer)->~T(); } }); return *reinterpret_cast(ptr); } }; }