@@ -188,6 +188,82 @@ struct MultiConsumerTypeTraits
188188 };
189189};
190190
191+ struct MultiProducerForSingleConsumerTypeTraits
192+ {
193+ template <typename BaseType>
194+ struct Behavior : BaseType
195+ {
196+ private:
197+ CacheAlignedAndPaddedObject<std::atomic_size_t > end{std::size_t (0 )};
198+
199+ public:
200+ using ElementType = typename BaseType::ElementType;
201+
202+ template <typename ... Args>
203+ bool push (Args &&... args)
204+ {
205+ if (BaseType::push_task_count.fetch_sub (1 , std::memory_order_acquire) <= std::int64_t (0 ))
206+ {
207+ BaseType::push_task_count.fetch_add (1 , std::memory_order_relaxed);
208+ return false ;
209+ }
210+
211+ const std::size_t element_index = end.fetch_add (1 , std::memory_order_acquire) & BaseType::COUNT_MASK;
212+ auto &element = BaseType::elements[element_index];
213+
214+ element.value_ptr = new (&element.storage ) ElementType (std::forward<Args>(args)...);
215+ element.state .store (ElementState::READY_FOR_POP, std::memory_order_release);
216+ BaseType::pop_task_count.fetch_add (1 , std::memory_order_release);
217+ return true ;
218+ }
219+ };
220+
221+ template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
222+ struct SharedState : BaseType
223+ {
224+ protected:
225+ CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> push_task_count{static_cast <std::int64_t >(BaseType::COUNT)};
226+ };
227+ };
228+
229+ struct MultiConsumerForSingleProducerTypeTraits
230+ {
231+ template <typename BaseType>
232+ struct Behavior : BaseType
233+ {
234+ private:
235+ CacheAlignedAndPaddedObject<std::atomic_size_t > begin{std::size_t (0 )};
236+
237+ public:
238+ using ElementType = typename BaseType::ElementType;
239+
240+ OptionalType<ElementType> pop ()
241+ {
242+ if (BaseType::pop_task_count.fetch_sub (1 , std::memory_order_acquire) <= std::int64_t (0 ))
243+ {
244+ BaseType::pop_task_count.fetch_add (1 , std::memory_order_relaxed);
245+ return OptionalType<ElementType>{};
246+ }
247+
248+ const std::size_t element_index = begin.fetch_add (1 , std::memory_order_acquire) & BaseType::COUNT_MASK;
249+ auto &element = BaseType::elements[element_index];
250+
251+ OptionalType<ElementType> result{std::move (*element.value_ptr )};
252+ element.value_ptr ->~ElementType ();
253+
254+ element.state .store (ElementState::READY_FOR_PUSH, std::memory_order_release);
255+ return result;
256+ }
257+ };
258+
259+ template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
260+ struct SharedState : BaseType
261+ {
262+ protected:
263+ CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> pop_task_count{std::int64_t {0 }};
264+ };
265+ };
266+
191267struct SingleProducerTypeTraits
192268{
193269 template <typename BaseType>
0 commit comments