diff --git a/dbms/include/DB/Common/ConcurrentBoundedQueue.h b/dbms/include/DB/Common/ConcurrentBoundedQueue.h index 876f641951f..714dbfd929f 100644 --- a/dbms/include/DB/Common/ConcurrentBoundedQueue.h +++ b/dbms/include/DB/Common/ConcurrentBoundedQueue.h @@ -8,6 +8,35 @@ #include +namespace detail +{ + template ::value> + struct MoveOrCopyIfThrow; + + template + struct MoveOrCopyIfThrow + { + void operator()(T && src, T & dst) const + { + dst = std::forward(src); + } + }; + + template + struct MoveOrCopyIfThrow + { + void operator()(T && src, T & dst) const + { + dst = src; + } + }; + + template + void moveOrCopyIfThrow(T && src, T & dst) + { + MoveOrCopyIfThrow()(std::forward(src), dst); + } +}; /** Очень простая thread-safe очередь ограниченной длины. * Если пытаться вынуть элемент из пустой очереди, то поток блокируется, пока очередь не станет непустой. @@ -53,10 +82,7 @@ public: fill_count.wait(); { Poco::ScopedLock lock(mutex); - if (std::is_nothrow_move_assignable::value) - x = std::move(queue.front()); - else - x = queue.front(); + detail::moveOrCopyIfThrow(std::move(queue.front()), x); queue.pop(); } empty_count.set(); @@ -97,10 +123,7 @@ public: { { Poco::ScopedLock lock(mutex); - if (std::is_nothrow_move_assignable::value) - x = std::move(queue.front()); - else - x = queue.front(); + detail::moveOrCopyIfThrow(std::move(queue.front()), x); queue.pop(); } empty_count.set();