# include <deal.II/base/config.h>
+# include <deal.II/base/exceptions.h>
+
+# include <map>
# include <shared_mutex>
# include <thread>
class ThreadLocalStorage
{
static_assert(
- std::is_trivially_copyable<T>::value ||
- std::is_copy_constructible<T>::value,
+ std::is_copy_constructible<T>::value ||
+ std::is_default_constructible<T>::value,
"The stored type must be either copyable, or default constructible");
public:
*/
explicit ThreadLocalStorage(const T &t);
+ /**
+ * FIXME
+ */
+ explicit ThreadLocalStorage(T &&t);
+
/**
* Copy constructor. Initialize each thread local object with the
* corresponding object of the given object.
*/
ThreadLocalStorage(const ThreadLocalStorage<T> &t) = default;
+ /**
+ * Move constructor. FIXME
+ */
+ ThreadLocalStorage(ThreadLocalStorage<T> &&t) = default;
+
/**
* Return a reference to the data stored by this object for the current
* thread this function is called on.
ThreadLocalStorage<T> &
operator=(const T &t);
+
+ /**
+ * FIXME
+ */
+ ThreadLocalStorage<T> &
+ operator=(T &&t);
+
/**
* Remove the thread-local objects stored for all threads that have
* created one with this object (i.e., that have called get() at least
}
+ template <typename T>
+ inline ThreadLocalStorage<T>::ThreadLocalStorage(T &&t)
+ {
+ exemplar = std::make_shared<T>(std::forward<T>(t));
+ }
+
+
template <typename T>
inline T &
ThreadLocalStorage<T>::get(bool &exists)
// Take a shared ("reader") lock for lookup and record the fact
// whether we could find an entry in the boolean exists.
std::shared_lock<decltype(insertion_mutex)> lock(insertion_mutex);
- const auto it = data.find(my_id);
+
+ const auto it = data.find(my_id);
if (it != data.end())
{
exists = true;
//
std::unique_lock<decltype(insertion_mutex)> lock(insertion_mutex);
- if constexpr (std::is_trivially_copyable<T>::value)
+ if constexpr (std::is_copy_constructible<T>::value)
if (exemplar)
{
- const auto it =
- data.emplace(std::make_pair(my_id, *exemplar)).first;
+ const auto it = data.emplace(my_id, *exemplar).first;
return it->second;
}
if constexpr (std::is_default_constructible<T>::value)
{
- const auto it = data.emplace(std::make_pair(my_id, T())).first;
- return it->second;
+ return data[my_id]; // default construct
}
+
+ Assert(false, ExcInternalError());
}
}
}
+ template <typename T>
+ inline ThreadLocalStorage<T> &
+ ThreadLocalStorage<T>::operator=(T &&t)
+ {
+ get() = std::forward<T>(t);
+ return *this;
+ }
+
+
template <typename T>
inline void
ThreadLocalStorage<T>::clear()