From fb46c047bd52faa735a772180af3786f4228f36c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 5 Jul 2021 12:58:43 +0200 Subject: BLI: wrap more features off tbb::enumerable_thread_specific * Make the wrapper enumerable. * Support an initializer function. --- .../blenlib/BLI_enumerable_thread_specific.hh | 51 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh index a05f7724dd2..25fd02b41fb 100644 --- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh +++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh @@ -46,25 +46,72 @@ template class EnumerableThreadSpecific : NonCopyable, NonMovable { tbb::enumerable_thread_specific values_; public: + using iterator = typename tbb::enumerable_thread_specific::iterator; + + EnumerableThreadSpecific() = default; + + template EnumerableThreadSpecific(F initializer) : values_(std::move(initializer)) + { + } + T &local() { return values_.local(); } + iterator begin() + { + return values_.begin(); + } + + iterator end() + { + return values_.end(); + } + #else /* WITH_TBB */ private: std::mutex mutex_; /* Maps thread ids to their corresponding values. The values are not embedded in the map, so that * their addresses do not change when the map grows. */ - Map> values_; + Map> values_; + Vector> owned_values_; + std::function initializer_; public: + using iterator = typename Map>::MutableValueIterator; + + EnumerableThreadSpecific() : initializer_([]() { return T(); }) + { + } + + template + EnumerableThreadSpecific(F initializer) : initializer_(std::move(initializer)) + { + } + T &local() { const int thread_id = enumerable_thread_specific_utils::thread_id; std::lock_guard lock{mutex_}; - return *values_.lookup_or_add_cb(thread_id, []() { return std::make_unique(); }); + return values_.lookup_or_add_cb(thread_id, [&]() { + /* `std::make_unique` does not work here if T is non-copyable and non-movable. */ + std::unique_ptr value{new T(initializer_())}; + std::reference_wrapper ref = *value; + owned_values_.append(std::move(value)); + return ref; + }); + } + + iterator begin() + { + return values_.values().begin(); + } + + iterator end() + { + return values_.values().end(); } #endif /* WITH_TBB */ -- cgit v1.2.3