[Bf-blender-cvs] [af8fb707dab] master: BLI: avoid calling deleted copy constructor in some compilers

Jacques Lucke noreply at git.blender.org
Thu Jul 8 19:55:53 CEST 2021


Commit: af8fb707dab1fab5cf444632fb25823b628e62f5
Author: Jacques Lucke
Date:   Thu Jul 8 19:53:58 2021 +0200
Branches: master
https://developer.blender.org/rBaf8fb707dab1fab5cf444632fb25823b628e62f5

BLI: avoid calling deleted copy constructor in some compilers

Previously, this did not compile in VS 2017, because
`new T(initializer_())` would try to call the copy constructor of `T`.

Now, `initializer_` will construct the `T` inplace.

===================================================================

M	source/blender/blenlib/BLI_enumerable_thread_specific.hh

===================================================================

diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
index 25fd02b41fb..3051d980d45 100644
--- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh
+++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
@@ -77,17 +77,18 @@ template<typename T> class EnumerableThreadSpecific : NonCopyable, NonMovable {
    * their addresses do not change when the map grows. */
   Map<int, std::reference_wrapper<T>> values_;
   Vector<std::unique_ptr<T>> owned_values_;
-  std::function<T()> initializer_;
+  std::function<void(void *)> initializer_;
 
  public:
   using iterator = typename Map<int, std::reference_wrapper<T>>::MutableValueIterator;
 
-  EnumerableThreadSpecific() : initializer_([]() { return T(); })
+  EnumerableThreadSpecific() : initializer_([](void *buffer) { new (buffer) T(); })
   {
   }
 
   template<typename F>
-  EnumerableThreadSpecific(F initializer) : initializer_(std::move(initializer))
+  EnumerableThreadSpecific(F initializer)
+      : initializer_([=](void *buffer) { new (buffer) T(initializer()); })
   {
   }
 
@@ -96,11 +97,10 @@ template<typename T> class EnumerableThreadSpecific : NonCopyable, NonMovable {
     const int thread_id = enumerable_thread_specific_utils::thread_id;
     std::lock_guard lock{mutex_};
     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<T> value{new T(initializer_())};
-      std::reference_wrapper<T> ref = *value;
-      owned_values_.append(std::move(value));
-      return ref;
+      T *value = (T *)::operator new(sizeof(T));
+      initializer_(value);
+      owned_values_.append(std::unique_ptr<T>{value});
+      return std::reference_wrapper<T>{*value};
     });
   }



More information about the Bf-blender-cvs mailing list