111template<
typename Obj_t,
typename Tag_t>
122 static_assert(!std::is_trivially_destructible_v<Obj_t>,
123 "There is no point in using Thread_local_obj_deinit_safe with a trivially-destructible Obj: "
124 "a plain `thread_local Obj` is already accessible at all times from its thread, deinit "
125 "included (cf. this_thread_unique_token() internals which use that technique).");
174template<
typename Obj_t,
typename Tag_t>
176 m_dead_flag(dead_flag)
181template<
typename Obj_t,
typename Tag_t>
187template<
typename Obj_t,
typename Tag_t>
193 "All or most of this should work in other OS, with which we have not tested, but upon "
194 "porting to such an OS be sure you've handled any corner cases mentioned throughout "
195 "the comments in this impl, starting with class doc header. At least one corner case "
196 "concerns behavior if this_thread_obj_or_null() is called for the first time near thread exit.");
202 thread_local bool s_this_thread_obj_dead =
false;
203 if (s_this_thread_obj_dead)
214 thread_local Guarded_obj s_this_thread_obj{&s_this_thread_obj_dead};
215 return &s_this_thread_obj.m_obj;
A thread_local object of type Obj, in effect, but with death-aware access: this_thread_obj_or_null() ...
Tag_t Tag
Short-hand for template parameter type: the disambiguating tag type.
Thread_local_obj_deinit_safe()=delete
No instances: *this class is a static-access facility.
static Obj * this_thread_obj_or_null()
Returns pointer to the calling thread's Obj, lazily default-constructing it if this is the first call...
Obj_t Obj
Short-hand for template parameter type: the per-thread object type.
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
Holds the actual per-thread Obj; its destruction records itself in the adjacent dead-flag.
Guarded_obj(bool *dead_flag)
Constructs m_obj via its default ctor.
~Guarded_obj()
Flips the dead-flag; then m_obj dies (in that order: members are destroyed after the dtor body).
bool *const m_dead_flag
See ctor.