38 #ifndef __UT_ThreadSpecificValue_h__
39 #define __UT_ThreadSpecificValue_h__
50 #include <type_traits>
56 static const size_t theNbStaticThreadValues = 1;
58 static const size_t theNbStaticThreadValues = 32;
61 namespace UT_ThreadSpecificValueDetail
63 template<
typename U,
size_t Align,
typename Enable =
void>
66 template<
typename U,
size_t Align>
75 memset((
void *)&myValue, 0,
sizeof(U));
78 operator const U &()
const
98 template<
typename U,
size_t Align>
107 memset((
void *)&myValue, 0,
sizeof(U));
110 operator const U &()
const
136 template <
typename T,
size_t ALIGNMENT = 64>
143 using ut_DynamicValueMap = UT_ConcurrentHashMap<int, UT_UniquePtr<T>>;
180 for (
int i = 0; i < theNbStaticThreadValues; ++i)
182 myStaticThreadValues[i] = src.myStaticThreadValues[i];
184 for (
auto &&item : src.myDynamicThreadValues)
186 myDynamicThreadValues.emplace(
187 item.first, UTmakeUnique<T>(*item.second));
215 return myStaticThreadValues[0];
218 if (thread_index == 0)
222 if (thread_index < theNbStaticThreadValues)
223 return myStaticThreadValues[thread_index];
225 return getDynamicValue(thread_index);
231 return myStaticThreadValues[0];
234 if (thread_index == 0)
238 if (thread_index < theNbStaticThreadValues)
239 return myStaticThreadValues[thread_index];
241 return getDynamicValue(thread_index);
265 : myConstVal(copy.myConstVal)
281 if (myI < theNbStaticThreadValues)
282 return myConstVal->myStaticThreadValues[myI];
283 return *myDynamicIt->second;
294 if (myI < theNbStaticThreadValues)
297 val = myDynamicIt->first;
304 if (myI == theNbStaticThreadValues)
305 myDynamicIt = myConstVal->myDynamicThreadValues.begin();
306 else if (myI > theNbStaticThreadValues)
314 && myI == right.
myI);
318 return !(*
this ==
right);
369 const_iterator::operator++();
391 {
return iterator(
this, 0); }
403 return theNbStaticThreadValues + myDynamicThreadValues.size();
414 exint mem = inclusive ?
sizeof(*this) : 0;
419 mem += myDynamicThreadValues.size() *
sizeof(
T);
425 T &getDynamicValue(
int thread_index)
const
430 typename ut_DynamicValueMap::accessor
a;
431 if (myDynamicThreadValues.insert(a, thread_index))
433 a->second = UTmakeUnique<T>();
435 ::memset((
void *)a->second.get(), 0,
sizeof(
T));
443 AlignType myStaticThreadValues[theNbStaticThreadValues];
444 mutable ut_DynamicValueMap myDynamicThreadValues;
446 friend class const_iterator;
const_iterator begin() const
begin() const iterator
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
#define SYS_STATIC_ASSERT(expr)
iterator end()
end() iterator
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
const_iterator end() const
end() const iterator
const_iterator & operator=(const const_iterator ©)
GLboolean GLboolean GLboolean GLboolean a
ut_DynamicValueMap::const_iterator myDynamicIt
const_iterator(const ThisType *value, int start)
bool operator!=(const const_iterator &right)
iterator & operator=(const iterator ©)
const T & getValueForThread(int thread_index) const
UT_ThreadSpecificValue & operator=(const ThisType &src)
Assignment is NOT thread-safe when src is being concurrently modified!
U & operator=(const U &v)
U & operator=(const U &v)
UT_ThreadSpecificValue(const ThisType &src)
void clear()
Clear values for all threads, resetting to the initial state.
const_iterator & operator++()
auto get(const UT_ARTIterator< T > &it) -> decltype(it.key())
int64 UTgetMemoryUsage(const UT_ConcurrentHashMap< K, V, H, A > &map, const bool inclusive)
friend class const_iterator
iterator begin()
begin() iterator
bool operator==(const const_iterator &right)
iterator(const iterator ©)
const T & operator*() const
LeafData & operator=(const LeafData &)=delete
const_iterator(const const_iterator ©)
exint getMemoryUsage(bool inclusive) const
const ThisType * myConstVal
T & getValueForThread(int thread_index)
int maxThreadsSeen() const