16#ifndef dealii_thread_local_storage_h
17# define dealii_thread_local_storage_h
28# include <shared_mutex>
55 struct unpack_container
60 template <
typename T,
typename A>
61 struct unpack_container<
std::vector<T, A>>
66 template <
typename T,
typename A>
67 struct unpack_container<
std::list<T, A>>
101 template <
typename T>
105 std::is_copy_constructible<
106 typename internal::unpack_container<T>::type>::value ||
107 std::is_default_constructible<T>::value,
108 "The stored type must be either copyable, or default constructible");
242 std::map<std::thread::id, T>
data;
252# ifdef DEAL_II_HAVE_CXX17
263 friend class ::LogStream;
276 template <
typename T>
278 : exemplar(t.exemplar)
282 std::shared_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
288 template <
typename T>
290 : exemplar(std::move(t.exemplar))
310 std::unique_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
311 data = std::move(t.data);
316 template <
typename T>
318 : exemplar(
std::make_shared<const T>(t))
323 template <
typename T>
325 : exemplar(
std::make_shared<T>(
std::forward<T>(t)))
330 template <
typename T>
331 inline ThreadLocalStorage<T> &
336 std::shared_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
337 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
340 exemplar = t.exemplar;
347 template <
typename T>
348 inline ThreadLocalStorage<T> &
357 std::unique_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
358 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
360 data = std::move(t.data);
361 exemplar = std::move(t.exemplar);
376 template <
typename T>
377 typename std::enable_if_t<
378 std::is_copy_constructible<typename unpack_container<T>::type>::value,
380 construct_element(std::map<std::thread::id, T> & data,
381 const std::thread::id &
id,
382 const std::shared_ptr<const T> &exemplar)
386 const auto it = data.emplace(
id, *exemplar).first;
392 template <
typename T>
393 typename std::enable_if_t<
394 !std::is_copy_constructible<typename unpack_container<T>::type>::value,
396 construct_element(std::map<std::thread::id, T> &data,
397 const std::thread::id &
id,
398 const std::shared_ptr<const T> &)
406 template <
typename T>
410 const std::thread::id my_id = std::this_thread::get_id();
422 std::shared_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
424 const auto it = data.find(my_id);
425 if (it != data.end())
439 std::unique_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
441 return internal::construct_element(data, my_id, exemplar);
446 template <
typename T>
455 template <
typename T>
456 inline ThreadLocalStorage<T>::operator T &()
462 template <
typename T>
463 inline ThreadLocalStorage<T> &
471 template <
typename T>
472 inline ThreadLocalStorage<T> &
475 get() = std::forward<T>(t);
480 template <
typename T>
484 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