16#ifndef dealii_thread_local_storage_h
17# define dealii_thread_local_storage_h
27# include <shared_mutex>
54 struct unpack_container
59 template <
typename T,
typename A>
60 struct unpack_container<
std::vector<T, A>>
65 template <
typename T,
typename A>
66 struct unpack_container<
std::list<T, A>>
100 template <
typename T>
104 std::is_copy_constructible<
105 typename internal::unpack_container<T>::type>::value ||
106 std::is_default_constructible<T>::value,
107 "The stored type must be either copyable, or default constructible");
241 std::map<std::thread::id, T>
data;
251# ifdef DEAL_II_HAVE_CXX17
262 friend class ::LogStream;
275 template <
typename T>
277 : exemplar(t.exemplar)
281 std::shared_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
287 template <
typename T>
289 : exemplar(std::move(t.exemplar))
309 std::unique_lock<
decltype(insertion_mutex)> lock(t.insertion_mutex);
310 data = std::move(t.data);
315 template <
typename T>
317 : exemplar(
std::make_shared<const
T>(t))
322 template <
typename T>
324 : exemplar(
std::make_shared<
T>(
std::forward<
T>(t)))
329 template <
typename T>
330 inline ThreadLocalStorage<T> &
335 std::shared_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
336 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
339 exemplar = t.exemplar;
346 template <
typename T>
347 inline ThreadLocalStorage<T> &
356 std::unique_lock<
decltype(insertion_mutex)> reader_lock(t.insertion_mutex);
357 std::unique_lock<
decltype(insertion_mutex)> writer_lock(insertion_mutex);
359 data = std::move(t.data);
360 exemplar = std::move(t.exemplar);
375 template <
typename T>
376 typename std::enable_if_t<
377 std::is_copy_constructible<typename unpack_container<T>::type>::value,
379 construct_element(std::map<std::thread::id, T> & data,
380 const std::thread::id &
id,
381 const std::shared_ptr<const T> &exemplar)
385 const auto it = data.emplace(
id, *exemplar).first;
391 template <
typename T>
392 typename std::enable_if_t<
393 !std::is_copy_constructible<typename unpack_container<T>::type>::value,
395 construct_element(std::map<std::thread::id, T> &data,
396 const std::thread::id &
id,
397 const std::shared_ptr<const T> &)
405 template <
typename T>
409 const std::thread::id my_id = std::this_thread::get_id();
421 std::shared_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
423 const auto it = data.find(my_id);
424 if (it != data.end())
438 std::unique_lock<
decltype(insertion_mutex)> lock(insertion_mutex);
440 return internal::construct_element(data, my_id, exemplar);
445 template <
typename T>
454 template <
typename T>
455 inline ThreadLocalStorage<T>::operator
T &()
461 template <
typename T>
462 inline ThreadLocalStorage<T> &
470 template <
typename T>
471 inline ThreadLocalStorage<T> &
474 get() = std::forward<T>(t);
479 template <
typename T>
483 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