4343#endif
4444#endif
4545
46+ #if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
47+ // VS2019 with /W4 warns about constant conditional expressions but unless /std=c++17 or higher
48+ // does not support `if constexpr`, so we have no choice but to simply disable the warning
49+ #pragma warning(push)
50+ #pragma warning(disable: 4127) // conditional expression is constant
51+ #endif
52+
4653#if defined(__APPLE__)
4754#include " TargetConditionals.h"
4855#endif
@@ -1890,7 +1897,7 @@ class ConcurrentQueue
18901897 ++pr_blockIndexSlotsUsed;
18911898 }
18921899
1893- if (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
1900+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
18941901 // The constructor may throw. We want the element not to appear in the queue in
18951902 // that case (without corrupting the queue):
18961903 MOODYCAMEL_TRY {
@@ -1916,7 +1923,7 @@ class ConcurrentQueue
19161923 blockIndex.load (std::memory_order_relaxed)->front .store (pr_blockIndexFront, std::memory_order_release);
19171924 pr_blockIndexFront = (pr_blockIndexFront + 1 ) & (pr_blockIndexSize - 1 );
19181925
1919- if (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
1926+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
19201927 this ->tailIndex .store (newTailIndex, std::memory_order_release);
19211928 return true ;
19221929 }
@@ -2132,7 +2139,7 @@ class ConcurrentQueue
21322139 block = block->next ;
21332140 }
21342141
2135- if (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
2142+ MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
21362143 blockIndex.load (std::memory_order_relaxed)->front .store ((pr_blockIndexFront - 1 ) & (pr_blockIndexSize - 1 ), std::memory_order_release);
21372144 }
21382145 }
@@ -2147,11 +2154,11 @@ class ConcurrentQueue
21472154 this ->tailBlock = firstAllocatedBlock;
21482155 }
21492156 while (true ) {
2150- auto stopIndex = (currentTailIndex & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
2157+ index_t stopIndex = (currentTailIndex & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
21512158 if (details::circular_less_than<index_t >(newTailIndex, stopIndex)) {
21522159 stopIndex = newTailIndex;
21532160 }
2154- if (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
2161+ MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
21552162 while (currentTailIndex != stopIndex) {
21562163 new ((*this ->tailBlock )[currentTailIndex++]) T (*itemFirst++);
21572164 }
@@ -2213,8 +2220,9 @@ class ConcurrentQueue
22132220 this ->tailBlock = this ->tailBlock ->next ;
22142221 }
22152222
2216- if (!MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst))) && firstAllocatedBlock != nullptr ) {
2217- blockIndex.load (std::memory_order_relaxed)->front .store ((pr_blockIndexFront - 1 ) & (pr_blockIndexSize - 1 ), std::memory_order_release);
2223+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
2224+ if (firstAllocatedBlock != nullptr )
2225+ blockIndex.load (std::memory_order_relaxed)->front .store ((pr_blockIndexFront - 1 ) & (pr_blockIndexSize - 1 ), std::memory_order_release);
22182226 }
22192227
22202228 this ->tailIndex .store (newTailIndex, std::memory_order_release);
@@ -2258,7 +2266,7 @@ class ConcurrentQueue
22582266 auto index = firstIndex;
22592267 do {
22602268 auto firstIndexInBlock = index;
2261- auto endIndex = (index & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
2269+ index_t endIndex = (index & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
22622270 endIndex = details::circular_less_than<index_t >(firstIndex + static_cast <index_t >(actualCount), endIndex) ? firstIndex + static_cast <index_t >(actualCount) : endIndex;
22632271 auto block = localBlockIndex->entries [indexIndex].block ;
22642272 if (MOODYCAMEL_NOEXCEPT_ASSIGN (T, T&&, details::deref_noexcept (itemFirst) = std::move ((*(*block)[index])))) {
@@ -2492,8 +2500,8 @@ class ConcurrentQueue
24922500 newBlock->owner = this ;
24932501#endif
24942502 newBlock->ConcurrentQueue ::Block::template reset_empty<implicit_context>();
2495-
2496- if (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
2503+
2504+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
24972505 // May throw, try to insert now before we publish the fact that we have this new block
24982506 MOODYCAMEL_TRY {
24992507 new ((*newBlock)[currentTailIndex]) T (std::forward<U>(element));
@@ -2511,7 +2519,7 @@ class ConcurrentQueue
25112519
25122520 this ->tailBlock = newBlock;
25132521
2514- if (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
2522+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR (T, U, new ((T*)nullptr ) T (std::forward<U>(element)))) {
25152523 this ->tailIndex .store (newTailIndex, std::memory_order_release);
25162524 return true ;
25172525 }
@@ -2595,6 +2603,10 @@ class ConcurrentQueue
25952603 return false ;
25962604 }
25972605
2606+ #ifdef _MSC_VER
2607+ #pragma warning(push)
2608+ #pragma warning(disable: 4706) // assignment within conditional expression
2609+ #endif
25982610 template <AllocationMode allocMode, typename It>
25992611 bool enqueue_bulk (It itemFirst, size_t count)
26002612 {
@@ -2630,6 +2642,7 @@ class ConcurrentQueue
26302642 auto head = this ->headIndex .load (std::memory_order_relaxed);
26312643 assert (!details::circular_less_than<index_t >(currentTailIndex, head));
26322644 bool full = !details::circular_less_than<index_t >(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t >::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head));
2645+
26332646 if (full || !(indexInserted = insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) || (newBlock = this ->parent ->ConcurrentQueue ::template requisition_block<allocMode>()) == nullptr ) {
26342647 // Index allocation or block allocation failed; revert any other allocations
26352648 // and index insertions done so far for this operation
@@ -2680,11 +2693,11 @@ class ConcurrentQueue
26802693 this ->tailBlock = firstAllocatedBlock;
26812694 }
26822695 while (true ) {
2683- auto stopIndex = (currentTailIndex & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
2696+ index_t stopIndex = (currentTailIndex & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
26842697 if (details::circular_less_than<index_t >(newTailIndex, stopIndex)) {
26852698 stopIndex = newTailIndex;
26862699 }
2687- if (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
2700+ MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR (T, decltype (*itemFirst), new ((T*)nullptr ) T (details::deref_noexcept (itemFirst)))) {
26882701 while (currentTailIndex != stopIndex) {
26892702 new ((*this ->tailBlock )[currentTailIndex++]) T (*itemFirst++);
26902703 }
@@ -2744,6 +2757,9 @@ class ConcurrentQueue
27442757 this ->tailIndex .store (newTailIndex, std::memory_order_release);
27452758 return true ;
27462759 }
2760+ #ifdef _MSC_VER
2761+ #pragma warning(pop)
2762+ #endif
27472763
27482764 template <typename It>
27492765 size_t dequeue_bulk (It& itemFirst, size_t max)
@@ -2775,7 +2791,7 @@ class ConcurrentQueue
27752791 auto indexIndex = get_block_index_index_for_index (index, localBlockIndex);
27762792 do {
27772793 auto blockStartIndex = index;
2778- auto endIndex = (index & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
2794+ index_t endIndex = (index & ~static_cast <index_t >(BLOCK_SIZE - 1 )) + static_cast <index_t >(BLOCK_SIZE);
27792795 endIndex = details::circular_less_than<index_t >(firstIndex + static_cast <index_t >(actualCount), endIndex) ? firstIndex + static_cast <index_t >(actualCount) : endIndex;
27802796
27812797 auto entry = localBlockIndex->index [indexIndex];
@@ -2873,7 +2889,7 @@ class ConcurrentQueue
28732889 if (localBlockIndex == nullptr ) {
28742890 return false ; // this can happen if new_block_index failed in the constructor
28752891 }
2876- auto newTail = (localBlockIndex->tail .load (std::memory_order_relaxed) + 1 ) & (localBlockIndex->capacity - 1 );
2892+ size_t newTail = (localBlockIndex->tail .load (std::memory_order_relaxed) + 1 ) & (localBlockIndex->capacity - 1 );
28772893 idxEntry = localBlockIndex->index [newTail];
28782894 if (idxEntry->key .load (std::memory_order_relaxed) == INVALID_BLOCK_BASE ||
28792895 idxEntry->value .load (std::memory_order_relaxed) == nullptr ) {
@@ -3443,7 +3459,7 @@ class ConcurrentQueue
34433459 }
34443460
34453461 auto newHash = new (raw) ImplicitProducerHash;
3446- newHash->capacity = newCapacity;
3462+ newHash->capacity = ( size_t ) newCapacity;
34473463 newHash->entries = reinterpret_cast <ImplicitProducerKVP*>(details::align_for<ImplicitProducerKVP>(raw + sizeof (ImplicitProducerHash)));
34483464 for (size_t i = 0 ; i != newCapacity; ++i) {
34493465 new (newHash->entries + i) ImplicitProducerKVP;
@@ -3557,23 +3573,26 @@ class ConcurrentQueue
35573573 template <typename TAlign>
35583574 static inline void * aligned_malloc (size_t size)
35593575 {
3560- if (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t >::value)
3576+ MOODYCAMEL_CONSTEXPR_IF (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t >::value)
35613577 return (Traits::malloc)(size);
3562- size_t alignment = std::alignment_of<TAlign>::value;
3563- void * raw = (Traits::malloc)(size + alignment - 1 + sizeof (void *));
3564- if (!raw)
3565- return nullptr ;
3566- char * ptr = details::align_for<TAlign>(reinterpret_cast <char *>(raw) + sizeof (void *));
3567- *(reinterpret_cast <void **>(ptr) - 1 ) = raw;
3568- return ptr;
3578+ else {
3579+ size_t alignment = std::alignment_of<TAlign>::value;
3580+ void * raw = (Traits::malloc)(size + alignment - 1 + sizeof (void *));
3581+ if (!raw)
3582+ return nullptr ;
3583+ char * ptr = details::align_for<TAlign>(reinterpret_cast <char *>(raw) + sizeof (void *));
3584+ *(reinterpret_cast <void **>(ptr) - 1 ) = raw;
3585+ return ptr;
3586+ }
35693587 }
35703588
35713589 template <typename TAlign>
35723590 static inline void aligned_free (void * ptr)
35733591 {
3574- if (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t >::value)
3592+ MOODYCAMEL_CONSTEXPR_IF (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t >::value)
35753593 return (Traits::free)(ptr);
3576- (Traits::free)(ptr ? *(reinterpret_cast <void **>(ptr) - 1 ) : nullptr );
3594+ else
3595+ (Traits::free)(ptr ? *(reinterpret_cast <void **>(ptr) - 1 ) : nullptr );
35773596 }
35783597
35793598 template <typename U>
@@ -3679,15 +3698,15 @@ ConsumerToken::ConsumerToken(ConcurrentQueue<T, Traits>& queue)
36793698 : itemsConsumedFromCurrent (0 ), currentProducer (nullptr ), desiredProducer (nullptr )
36803699{
36813700 initialOffset = queue.nextExplicitConsumerId .fetch_add (1 , std::memory_order_release);
3682- lastKnownGlobalOffset = -1 ;
3701+ lastKnownGlobalOffset = (std:: uint32_t ) -1 ;
36833702}
36843703
36853704template <typename T, typename Traits>
36863705ConsumerToken::ConsumerToken (BlockingConcurrentQueue<T, Traits>& queue)
36873706 : itemsConsumedFromCurrent (0 ), currentProducer (nullptr ), desiredProducer (nullptr )
36883707{
36893708 initialOffset = reinterpret_cast <ConcurrentQueue<T, Traits>*>(&queue)->nextExplicitConsumerId .fetch_add (1 , std::memory_order_release);
3690- lastKnownGlobalOffset = -1 ;
3709+ lastKnownGlobalOffset = (std:: uint32_t ) -1 ;
36913710}
36923711
36933712template <typename T, typename Traits>
@@ -3714,6 +3733,10 @@ inline void swap(typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& a, ty
37143733
37153734}
37163735
3736+ #if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
3737+ #pragma warning(pop)
3738+ #endif
3739+
37173740#if defined(__GNUC__)
37183741#pragma GCC diagnostic pop
37193742#endif
0 commit comments