@@ -1008,6 +1008,18 @@ class ConcurrentQueue
1008
1008
MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 ) return false ;
1009
1009
else return inner_enqueue<CanAlloc>(std::move (item));
1010
1010
}
1011
+
1012
+ // Enqueues a single item (by constructing it in-place from arguments).
1013
+ // Allocates memory if required. Only fails if memory allocation fails (or implicit
1014
+ // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
1015
+ // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
1016
+ // Thread-safe.
1017
+ template <typename ... Args>
1018
+ inline bool enqueue_emplace (Args&&... args)
1019
+ {
1020
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 ) return false ;
1021
+ else return inner_enqueue<CanAlloc>(std::forward<Args>(args)...);
1022
+ }
1011
1023
1012
1024
// Enqueues a single item (by copying it) using an explicit producer token.
1013
1025
// Allocates memory if required. Only fails if memory allocation fails (or
@@ -1369,11 +1381,11 @@ class ConcurrentQueue
1369
1381
return static_cast <ExplicitProducer*>(token.producer )->ConcurrentQueue ::ExplicitProducer::template enqueue<canAlloc>(std::forward<U>(element));
1370
1382
}
1371
1383
1372
- template <AllocationMode canAlloc, typename U >
1373
- inline bool inner_enqueue (U && element )
1384
+ template <AllocationMode canAlloc, typename ... Args >
1385
+ inline bool inner_enqueue (Args && ... args )
1374
1386
{
1375
1387
auto producer = get_or_add_implicit_producer ();
1376
- return producer == nullptr ? false : producer->ConcurrentQueue ::ImplicitProducer::template enqueue<canAlloc>(std::forward<U>(element) );
1388
+ return producer == nullptr ? false : producer->ConcurrentQueue ::ImplicitProducer::template enqueue<canAlloc>(std::forward<Args>(args)... );
1377
1389
}
1378
1390
1379
1391
template <AllocationMode canAlloc, typename It>
@@ -1845,8 +1857,8 @@ class ConcurrentQueue
1845
1857
}
1846
1858
}
1847
1859
1848
- template <AllocationMode allocMode, typename U >
1849
- inline bool enqueue (U&& element )
1860
+ template <AllocationMode allocMode, typename ... Args >
1861
+ inline bool enqueue (Args&&... args )
1850
1862
{
1851
1863
index_t currentTailIndex = this ->tailIndex .load (std::memory_order_relaxed);
1852
1864
index_t newTailIndex = 1 + currentTailIndex;
@@ -1912,11 +1924,11 @@ class ConcurrentQueue
1912
1924
++pr_blockIndexSlotsUsed;
1913
1925
}
1914
1926
1915
- MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<U>(element) ))) {
1927
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<Args>(args)... ))) {
1916
1928
// The constructor may throw. We want the element not to appear in the queue in
1917
1929
// that case (without corrupting the queue):
1918
1930
MOODYCAMEL_TRY {
1919
- new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<U>(element) );
1931
+ new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<Args>(args)... );
1920
1932
}
1921
1933
MOODYCAMEL_CATCH (...) {
1922
1934
// Revert change to the current block, but leave the new block available
@@ -1938,14 +1950,14 @@ class ConcurrentQueue
1938
1950
blockIndex.load (std::memory_order_relaxed)->front .store (pr_blockIndexFront, std::memory_order_release);
1939
1951
pr_blockIndexFront = (pr_blockIndexFront + 1 ) & (pr_blockIndexSize - 1 );
1940
1952
1941
- MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<U>(element) ))) {
1953
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<Args>(args)... ))) {
1942
1954
this ->tailIndex .store (newTailIndex, std::memory_order_release);
1943
1955
return true ;
1944
1956
}
1945
1957
}
1946
1958
1947
1959
// Enqueue
1948
- new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<U>(element) );
1960
+ new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<Args>(args)... );
1949
1961
1950
1962
this ->tailIndex .store (newTailIndex, std::memory_order_release);
1951
1963
return true ;
@@ -2483,8 +2495,8 @@ class ConcurrentQueue
2483
2495
}
2484
2496
}
2485
2497
2486
- template <AllocationMode allocMode, typename U >
2487
- inline bool enqueue (U&& element )
2498
+ template <AllocationMode allocMode, typename ... Args >
2499
+ inline bool enqueue (Args&&... args )
2488
2500
{
2489
2501
index_t currentTailIndex = this ->tailIndex .load (std::memory_order_relaxed);
2490
2502
index_t newTailIndex = 1 + currentTailIndex;
@@ -2516,10 +2528,10 @@ class ConcurrentQueue
2516
2528
#endif
2517
2529
newBlock->ConcurrentQueue ::Block::template reset_empty<implicit_context>();
2518
2530
2519
- MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<U>(element) ))) {
2531
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<Args>(args)... ))) {
2520
2532
// May throw, try to insert now before we publish the fact that we have this new block
2521
2533
MOODYCAMEL_TRY {
2522
- new ((*newBlock)[currentTailIndex]) T (std::forward<U>(element) );
2534
+ new ((*newBlock)[currentTailIndex]) T (std::forward<Args>(args)... );
2523
2535
}
2524
2536
MOODYCAMEL_CATCH (...) {
2525
2537
rewind_block_index_tail ();
@@ -2534,14 +2546,14 @@ class ConcurrentQueue
2534
2546
2535
2547
this ->tailBlock = newBlock;
2536
2548
2537
- MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<U>(element) ))) {
2549
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new (static_cast <T*>(nullptr )) T (std::forward<Args>(args)... ))) {
2538
2550
this ->tailIndex .store (newTailIndex, std::memory_order_release);
2539
2551
return true ;
2540
2552
}
2541
2553
}
2542
2554
2543
2555
// Enqueue
2544
- new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<U>(element) );
2556
+ new ((*this ->tailBlock )[currentTailIndex]) T (std::forward<Args>(args)... );
2545
2557
2546
2558
this ->tailIndex .store (newTailIndex, std::memory_order_release);
2547
2559
return true ;
0 commit comments