diff --git a/include/daking/MPSC_queue.hpp b/include/daking/MPSC_queue.hpp index b7eab58..4591429 100644 --- a/include/daking/MPSC_queue.hpp +++ b/include/daking/MPSC_queue.hpp @@ -486,6 +486,9 @@ namespace daking { DAKING_ALWAYS_INLINE void enqueue_bulk(const_reference value, size_type n) { // N times thread_local operation, One time CAS operation. // So it is more efficient than N times enqueue. + if (n == 0) { + return; + } node_t* first_new_node = _allocate(); node_t* prev_node = first_new_node; @@ -511,6 +514,9 @@ namespace daking { "Iterator must be at least input iterator."); static_assert(std::is_same_v::value_type, value_type>, "The value type of iterator must be same as MPSC_queue::value_type."); + if (n == 0) { + return; + } node_t* first_new_node = _allocate(); node_t* prev_node = first_new_node; @@ -743,4 +749,4 @@ namespace daking { }; } -#endif // !DAKING_MPSC_QUEUE_HPP \ No newline at end of file +#endif // !DAKING_MPSC_QUEUE_HPP diff --git a/tests/test_MPSC.cpp b/tests/test_MPSC.cpp index 6811700..58988ff 100644 --- a/tests/test_MPSC.cpp +++ b/tests/test_MPSC.cpp @@ -133,6 +133,21 @@ TEST(MPSCQueueBulkTest, EnqueueBulk_InputIterator) { EXPECT_TRUE(queue.empty()); } +TEST(MPSCQueueBulkTest, EnqueueBulk_EmptyRangeIsNoOp) { + TestQueue queue; + const int value = 99; + std::vector data; + + queue.enqueue_bulk(value, 0); + EXPECT_TRUE(queue.empty()); + + queue.enqueue_bulk(data.begin(), data.size()); + EXPECT_TRUE(queue.empty()); + + queue.enqueue_bulk(data.begin(), data.end()); + EXPECT_TRUE(queue.empty()); +} + TEST(MPSCQueueBulkTest, TryDequeueBulk_Partial) { TestQueue queue; queue.enqueue(1); @@ -306,4 +321,4 @@ TEST(MPSCQueueBlockTest, DequeueBulk_BlockAndWait) { EXPECT_EQ(results[2], 3); EXPECT_TRUE(queue.empty()); } -#endif \ No newline at end of file +#endif