16 #ifndef dealii_thread_local_storage_h
17 # define dealii_thread_local_storage_h
28 # include <shared_mutex>
57 struct unpack_container
62 template <
typename T,
typename A>
63 struct unpack_container<std::vector<T, A>>
68 template <
typename T,
typename A>
69 struct unpack_container<std::list<T, A>>
103 template <
typename T>
107 std::is_copy_constructible<
108 typename internal::unpack_container<T>::type>::value ||
109 std::is_default_constructible_v<T>,
110 "The stored type must be either copyable, or default constructible");
244 std::map<std::thread::id, T>
data;
261 friend class ::LogStream;
274 template <
typename T>
276 : exemplar(t.exemplar)
280 std::shared_lock<decltype(insertion_mutex)> lock(t.insertion_mutex);
286 template <
typename T>
288 : exemplar(std::move(t.exemplar))
308 std::unique_lock<decltype(insertion_mutex)> lock(t.insertion_mutex);
309 data = std::move(t.data);
314 template <
typename T>
316 : exemplar(std::make_shared<const
T>(t))
321 template <
typename T>
323 : exemplar(std::make_shared<
T>(std::forward<
T>(t)))
328 template <
typename T>
329 inline ThreadLocalStorage<T> &
334 std::shared_lock<decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
335 std::unique_lock<decltype(insertion_mutex)> writer_lock(insertion_mutex);
338 exemplar = t.exemplar;
345 template <
typename T>
346 inline ThreadLocalStorage<T> &
355 std::unique_lock<decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
356 std::unique_lock<decltype(insertion_mutex)> writer_lock(insertion_mutex);
358 data = std::move(t.data);
359 exemplar = std::move(t.exemplar);
374 template <
typename T>
376 std::is_copy_constructible_v<typename unpack_container<T>::type>,
378 construct_element(std::map<std::thread::id, T> &data,
379 const std::thread::id &
id,
380 const std::shared_ptr<const T> &exemplar)
384 const auto it = data.emplace(
id, *exemplar).first;
390 template <
typename T>
392 !std::is_copy_constructible_v<typename unpack_container<T>::type>,
394 construct_element(std::map<std::thread::id, T> &data,
395 const std::thread::id &
id,
396 const std::shared_ptr<const T> &)
404 template <
typename T>
408 const std::thread::id my_id = std::this_thread::get_id();
420 std::shared_lock<decltype(insertion_mutex)> lock(insertion_mutex);
422 const auto it = data.find(my_id);
423 if (it != data.end())
437 std::unique_lock<decltype(insertion_mutex)> lock(insertion_mutex);
439 return internal::construct_element(data, my_id, exemplar);
444 template <
typename T>
453 template <
typename T>
454 inline ThreadLocalStorage<T>::operator
T &()
460 template <
typename T>
461 inline ThreadLocalStorage<T> &
469 template <
typename T>
470 inline ThreadLocalStorage<T> &
473 get() = std::forward<T>(t);
478 template <
typename T>
482 std::unique_lock<decltype(insertion_mutex)> lock(insertion_mutex);
A class that provides a separate storage location on each thread that accesses the object.
ThreadLocalStorage(const ThreadLocalStorage &)
ThreadLocalStorage(const T &t)
ThreadLocalStorage & operator=(ThreadLocalStorage &&t) noexcept
ThreadLocalStorage()=default
std::map< std::thread::id, T > data
ThreadLocalStorage< T > & operator=(const T &t)
ThreadLocalStorage & operator=(const ThreadLocalStorage &t)
ThreadLocalStorage< T > & operator=(T &&t)
std::shared_ptr< const T > exemplar
ThreadLocalStorage(T &&t)
ThreadLocalStorage(ThreadLocalStorage &&t) noexcept
std::shared_mutex insertion_mutex
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE