41 std::weak_ptr<const void> owner;
42 std::unique_ptr<T> value;
45 static std::vector<Slot>& thread_slots()
47 static thread_local std::vector<Slot> slots;
51 std::uint64_t m_id = detail::ets_id_counter().fetch_add(1, std::memory_order_relaxed);
52 std::function<T()> m_factory;
54 std::shared_ptr<const void>
m_alive = std::make_shared<char>(0);
58 : m_factory([]() {
return T(); })
63 typename = std::enable_if_t<!std::is_same_v<std::decay_t<U>, enumerable_thread_specific>>>
64 explicit enumerable_thread_specific(U&& init)
65 : m_factory([captured = T(std::forward<U>(init))]() {
return captured; })
68 enumerable_thread_specific(
const enumerable_thread_specific&) =
delete;
69 enumerable_thread_specific& operator=(
const enumerable_thread_specific&) =
delete;
70 enumerable_thread_specific(enumerable_thread_specific&&) =
delete;
71 enumerable_thread_specific& operator=(enumerable_thread_specific&&) =
delete;
73 ~enumerable_thread_specific()
77 auto& slots = thread_slots();
82 [
this](
const Slot& s) { return s.id == m_id; }),
88 auto& slots = thread_slots();
89 for (
auto& s : slots) {
100 [](
const Slot& s) { return s.owner.expired(); }),
102 slots.push_back(Slot{m_id,
m_alive, std::make_unique<T>(m_factory())});
103 return *slots.back().value;
std::shared_ptr< const void > m_alive
Expires when this instance is destroyed, which is how other threads learn of it.
Definition enumerable_thread_specific.hpp:54