15#ifndef dealii_thread_local_storage_h
16# define dealii_thread_local_storage_h
27# include <shared_mutex>
56 struct unpack_container
61 template <
typename T,
typename A>
62 struct unpack_container<
std::vector<T, A>>
67 template <
typename T,
typename A>
68 struct unpack_container<
std::list<T, A>>
102 template <
typename T>
106 std::is_copy_constructible<
107 typename internal::unpack_container<T>::type>::value ||
108 std::is_default_constructible_v<T>,
109 "The stored type must be either copyable, or default constructible");
243 std::map<std::thread::id, T>
data;
260 friend class ::LogStream;
273 template <
typename T>
275 : exemplar(t.exemplar)
279 std::shared_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
285 template <
typename T>
287 : exemplar(std::move(t.exemplar))
307 std::unique_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
308 data = std::move(t.data);
313 template <
typename T>
315 : exemplar(
std::make_shared<const T>(t))
320 template <
typename T>
322 : exemplar(
std::make_shared<T>(
std::forward<T>(t)))
327 template <
typename T>
328 inline ThreadLocalStorage<T> &
333 std::shared_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
334 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
337 exemplar = t.exemplar;
344 template <
typename T>
345 inline ThreadLocalStorage<T> &
354 std::unique_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
355 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
357 data = std::move(t.data);
358 exemplar = std::move(t.exemplar);
373 template <
typename T>
375 std::is_copy_constructible_v<typename unpack_container<T>::type>,
377 construct_element(std::map<std::thread::id, T> &data,
378 const std::thread::id &
id,
379 const std::shared_ptr<const T> &exemplar)
383 const auto it = data.emplace(
id, *exemplar).first;
389 template <
typename T>
391 !std::is_copy_constructible_v<typename unpack_container<T>::type>,
393 construct_element(std::map<std::thread::id, T> &data,
394 const std::thread::id &
id,
395 const std::shared_ptr<const T> &)
403 template <
typename T>
407 const std::thread::id my_id = std::this_thread::get_id();
419 std::shared_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
421 const auto it = data.find(my_id);
422 if (it != data.end())
436 std::unique_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
438 return internal::construct_element(data, my_id, exemplar);
443 template <
typename T>
452 template <
typename T>
453 inline ThreadLocalStorage<T>::operator T &()
459 template <
typename T>
460 inline ThreadLocalStorage<T> &
468 template <
typename T>
469 inline ThreadLocalStorage<T> &
472 get() = std::forward<T>(t);
477 template <
typename T>
481 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 & operator=(const ThreadLocalStorage &t)
ThreadLocalStorage(const ThreadLocalStorage &)
ThreadLocalStorage(const T &t)
ThreadLocalStorage()=default
std::map< std::thread::id, T > data
ThreadLocalStorage< T > & operator=(const T &t)
std::shared_ptr< const T > exemplar
ThreadLocalStorage(T &&t)
ThreadLocalStorage & operator=(ThreadLocalStorage &&t) noexcept
ThreadLocalStorage< T > & operator=(T &&t)
ThreadLocalStorage(ThreadLocalStorage &&t) noexcept
std::shared_mutex insertion_mutex
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE