// File: /workspace/github_cpp_makefile_star2_O1/HQarroum[P]thread-pool/examples/one-producer-many-consumers/./../../includes/concurrent_queue.hpp
// Function: moodycamel::ConcurrentQueue<std::function<void ()>, moodycamel::ConcurrentQueueDefaultTraits>::ExplicitProducer::~ExplicitProducer()
~ExplicitProducer()
		{
			// Destruct any elements not yet dequeued.
			// Since we're in the destructor, we can assume all elements
			// are either completely dequeued or completely not (no halfways).
			if (this->tailBlock != nullptr) {		// Note this means there must be a block index too
				// First find the block that's partially dequeued, if any
				Block* halfDequeuedBlock = nullptr;
				if ((this->headIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1)) != 0) {
					// The head's not on a block boundary, meaning a block somewhere is partially dequeued
					// (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary)
					size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1);
					while (details::circular_less_than<index_t>(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) {
						i = (i + 1) & (pr_blockIndexSize - 1);
					}
					assert(details::circular_less_than<index_t>(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed)));
					halfDequeuedBlock = pr_blockIndexEntries[i].block;
				}
				
				// Start at the head block (note the first line in the loop gives us the head from the tail on the first iteration)
				auto block = this->tailBlock;
				do {
					block = block->next;
					if (block->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
						continue;
					}
					
					size_t i = 0;	// Offset into block
					if (block == halfDequeuedBlock) {
						i = static_cast<size_t>(this->headIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1));
					}
					
					// Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index
					auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast<size_t>(this->tailIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1));
					while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) {
						(*block)[i++]->~T();
					}
				} while (block != this->tailBlock);
			}
			
			// Destroy all blocks that we own
			if (this->tailBlock != nullptr) {
				auto block = this->tailBlock;
				do {
					auto nextBlock = block->next;
					if (block->dynamicallyAllocated) {
						destroy(block);
					}
					else {
						this->parent->add_block_to_free_list(block);
					}
					block = nextBlock;
				} while (block != this->tailBlock);
			}
			
			// Destroy the block indices
			auto header = static_cast<BlockIndexHeader*>(pr_blockIndexRaw);
			while (header != nullptr) {
				auto prev = static_cast<BlockIndexHeader*>(header->prev);
				header->~BlockIndexHeader();
				(Traits::free)(header);
				header = prev;
			}
		}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdi, %rbx
leaq 0x59f1(%rip), %rax      # 0xbc98
movq %rax, (%rdi)
movq 0x40(%rdi), %r14
testq %r14, %r14
je 0x63c7
movq 0x28(%rbx), %rax
testb $0x1f, %al
je 0x6317
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
movq 0x68(%rbx), %rdx
movq 0x70(%rbx), %rsi
subq 0x60(%rbx), %rsi
decq %rdx
movq 0x78(%rbx), %rcx
andq %rdx, %rsi
movq %rsi, %rdi
shlq $0x4, %rdi
movq (%rcx,%rdi), %r8
movq 0x28(%rbx), %r9
movq %r8, %r10
subq %r9, %r10
addq $0x20, %r10
incq %rsi
cmpq %rax, %r10
ja 0x62dc
movq 0x28(%rbx), %rdx
subq %rdx, %r8
cmpq %rax, %r8
jbe 0x645b
movq 0x8(%rcx,%rdi), %r15
jmp 0x631a
xorl %r15d, %r15d
movq 0x400(%r14), %r14
movb 0x410(%r14), %al
testb $0x1, %al
je 0x6350
xorl %eax, %eax
cmpq $0x1f, %rax
je 0x6358
movb 0x411(%r14,%rax), %cl
incq %rax
testb $0x1, %cl
jne 0x632e
decq %rax
cmpq $0x1f, %rax
setae %al
jmp 0x6352
xorl %eax, %eax
testb %al, %al
jne 0x635b
jmp 0x635b
setae %al
testb %al, %al
jne 0x63bd
cmpq %r15, %r14
je 0x6369
xorl %r12d, %r12d
jmp 0x6371
movq 0x28(%rbx), %r12
andl $0x1f, %r12d
movq 0x20(%rbx), %rax
testb $0x1f, %al
je 0x6383
movq 0x20(%rbx), %r13
andl $0x1f, %r13d
jmp 0x6389
movl $0x20, %r13d
cmpq %r12, %r13
jne 0x6394
cmpq 0x40(%rbx), %r14
je 0x63bd
movl %r12d, %edi
andl $0x1f, %edi
shll $0x5, %edi
movq 0x10(%r14,%rdi), %rax
testq %rax, %rax
je 0x63b4
addq %r14, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
incq %r12
cmpq $0x20, %r12
jne 0x6389
cmpq 0x40(%rbx), %r14
jne 0x631a
movq 0x40(%rbx), %r14
testq %r14, %r14
je 0x6434
movq %r14, %rdi
movq 0x400(%r14), %r14
cmpb $0x1, 0x441(%rdi)
jne 0x63ea
callq 0x32a0
jmp 0x642e
movq 0x50(%rbx), %rcx
movl $0x80000000, %eax       # imm = 0x80000000
lock
xaddl %eax, 0x430(%rdi)
testl %eax, %eax
jne 0x642e
movq 0x28(%rcx), %rax
movq %rax, 0x438(%rdi)
movl $0x1, 0x430(%rdi)
lock
cmpxchgq %rdi, 0x28(%rcx)
je 0x642e
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
lock
xaddl %edx, 0x430(%rdi)
cmpl $0x1, %edx
je 0x6403
cmpq 0x40(%rbx), %r14
jne 0x63d0
movq 0x80(%rbx), %rdi
testq %rdi, %rdi
je 0x6451
movq 0x18(%rdi), %rbx
callq 0x32a0
movq %rbx, %rdi
testq %rbx, %rbx
jne 0x6440
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x13c0(%rip), %rdi      # 0x7822
leaq 0xbd5(%rip), %rsi       # 0x703e
leaq 0x1426(%rip), %rcx      # 0x7896
movl $0x6f7, %edx            # imm = 0x6F7
callq 0x3150
movq %rax, %rdi
callq 0x3b0b