// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x6bad(%rip), %rax      # 0xccb8
movq %rax, (%rdi)
movq 0x40(%rdi), %r14
testq %r14, %r14
je 0x621b
movq 0x28(%rbx), %rax
testb $0x1f, %al
je 0x617b
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 0x6140
movq 0x28(%rbx), %rdx
subq %rdx, %r8
cmpq %rax, %r8
jbe 0x6244
movq 0x8(%rcx,%rdi), %r15
jmp 0x617e
xorl %r15d, %r15d
pushq $0x20
popq %r12
movq 0x400(%r14), %r14
movq %r14, %rdi
callq 0x6284
testb %al, %al
je 0x61a0
movq 0x40(%rbx), %rsi
cmpq %rsi, %r14
jne 0x6182
jmp 0x61eb
cmpq %r15, %r14
je 0x61a9
xorl %edi, %edi
jmp 0x61b0
movq 0x28(%rbx), %rdi
andl $0x1f, %edi
movq 0x20(%rbx), %rax
movq %r12, %r13
testb $0x1f, %al
je 0x61c3
movq 0x20(%rbx), %r13
andl $0x1f, %r13d
cmpq $0x20, %rdi
je 0x6195
cmpq %rdi, %r13
jne 0x61d4
cmpq 0x40(%rbx), %r14
je 0x6195
leaq 0x1(%rdi), %rbp
andl $0x1f, %edi
shll $0x5, %edi
addq %r14, %rdi
callq 0x5276
movq %rbp, %rdi
jmp 0x61c3
movq 0x400(%rsi), %r14
cmpb $0x1, 0x441(%rsi)
jne 0x6205
movq %rsi, %rdi
callq 0x3290
jmp 0x6212
movq 0x50(%rbx), %rdi
addq $0x28, %rdi
callq 0x4a92
movq %r14, %rsi
cmpq 0x40(%rbx), %r14
jne 0x61eb
movq 0x80(%rbx), %rdi
testq %rdi, %rdi
je 0x6235
movq 0x18(%rdi), %rbx
callq 0x3290
movq %rbx, %rdi
jmp 0x6222
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x16bb(%rip), %rdi      # 0x7906
leaq 0xdec(%rip), %rsi       # 0x703e
leaq 0x1721(%rip), %rcx      # 0x797a
movl $0x6f7, %edx            # imm = 0x6F7
callq 0x3170
movq %rax, %rdi
callq 0x3914
nop