// File: 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
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq 0xf729(%rip), %rcx      # 0x23c70
addq $0x10, %rcx
movq %rcx, (%rax)
cmpq $0x0, 0x40(%rax)
je 0x14ad2
movq -0xe8(%rbp), %rax
movq $0x0, -0xa0(%rbp)
addq $0x28, %rax
movq %rax, -0x8(%rbp)
movl $0x0, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movl -0xc(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x10(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0xec(%rbp)
decl %eax
subl $0x2, %eax
jb 0x145c4
jmp 0x145a7
movl -0xec(%rbp), %eax
subl $0x5, %eax
je 0x145d4
jmp 0x145b4
movq -0xf8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x145e2
movq -0xf8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x145e2
movq -0xf8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
andq $0x1f, %rax
cmpq $0x0, %rax
je 0x147e3
movq -0xe8(%rbp), %rcx
movq 0x70(%rcx), %rax
subq 0x60(%rcx), %rax
movq 0x68(%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq -0xe8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0xa8(%rbp), %rdx
shlq $0x4, %rdx
movq (%rcx,%rdx), %rcx
addq $0x20, %rcx
movq %rcx, -0x110(%rbp)
addq $0x28, %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x108(%rbp)
movl -0x24(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x28(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0xfc(%rbp)
decl %eax
subl $0x2, %eax
jb 0x14693
jmp 0x14676
movl -0xfc(%rbp), %eax
subl $0x5, %eax
je 0x146a3
jmp 0x14683
movq -0x108(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x146b1
movq -0x108(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x146b1
movq -0x108(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x110(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x3800
testb $0x1, %al
jne 0x146c7
jmp 0x146f0
movq -0xe8(%rbp), %rcx
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq 0x68(%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0xa8(%rbp)
jmp 0x14615
movq -0xe8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0xa8(%rbp), %rdx
shlq $0x4, %rdx
movq (%rcx,%rdx), %rcx
movq %rcx, -0x128(%rbp)
addq $0x28, %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x120(%rbp)
movl -0x3c(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, -0x114(%rbp)
decl %eax
subl $0x2, %eax
jb 0x1476a
jmp 0x1474d
movl -0x114(%rbp), %eax
subl $0x5, %eax
je 0x1477a
jmp 0x1475a
movq -0x120(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x14788
movq -0x120(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x14788
movq -0x120(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x128(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x3800
testb $0x1, %al
jne 0x1479e
jmp 0x147a0
jmp 0x147bf
leaq 0x44c7(%rip), %rdi      # 0x18c6e
leaq 0x3bf8(%rip), %rsi      # 0x183a6
movl $0x6f7, %edx            # imm = 0x6F7
leaq 0x4528(%rip), %rcx      # 0x18ce2
callq 0x3180
movq -0xe8(%rbp), %rax
movq 0x78(%rax), %rax
movq -0xa8(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0xe8(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq 0x400(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x14d40
movb %al, -0x129(%rbp)
jmp 0x1481e
movb -0x129(%rbp), %al
testb $0x1, %al
jne 0x1482a
jmp 0x1482f
jmp 0x14ab8
movq $0x0, -0xb8(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jne 0x148db
movq -0xe8(%rbp), %rax
addq $0x28, %rax
movq %rax, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x138(%rbp)
movl -0x54(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x58(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0x130(%rbp)
decl %eax
subl $0x2, %eax
jb 0x148ae
jmp 0x14891
movl -0x130(%rbp), %eax
subl $0x5, %eax
je 0x148be
jmp 0x1489e
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x60(%rbp)
jmp 0x148cc
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x60(%rbp)
jmp 0x148cc
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
andq $0x1f, %rax
movq %rax, -0xb8(%rbp)
movq -0xe8(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x148(%rbp)
movl -0x6c(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x70(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x13c(%rbp)
decl %eax
subl $0x2, %eax
jb 0x1493b
jmp 0x1491e
movl -0x13c(%rbp), %eax
subl $0x5, %eax
je 0x1494b
jmp 0x1492b
movq -0x148(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0x14959
movq -0x148(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0x14959
movq -0x148(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
andq $0x1f, %rax
cmpq $0x0, %rax
jne 0x14978
movl $0x20, %eax
movq %rax, -0x150(%rbp)
jmp 0x14a1d
movq -0xe8(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x80(%rbp)
movl $0x0, -0x84(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x160(%rbp)
movl -0x84(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x88(%rbp)
movl -0x84(%rbp), %eax
movl %eax, -0x154(%rbp)
decl %eax
subl $0x2, %eax
jb 0x149e7
jmp 0x149c7
movl -0x154(%rbp), %eax
subl $0x5, %eax
je 0x149fa
jmp 0x149d4
movq -0x160(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
jmp 0x14a0b
movq -0x160(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
jmp 0x14a0b
movq -0x160(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
andq $0x1f, %rax
movq %rax, -0x150(%rbp)
movq -0x150(%rbp), %rax
movq %rax, -0xc0(%rbp)
xorl %eax, %eax
cmpq $0x20, -0xb8(%rbp)
movb %al, -0x161(%rbp)
je 0x14a7c
movq -0xe8(%rbp), %rdx
movq -0xb0(%rbp), %rcx
movb $0x1, %al
cmpq 0x40(%rdx), %rcx
movb %al, -0x162(%rbp)
jne 0x14a70
movq -0xb8(%rbp), %rax
cmpq -0xc0(%rbp), %rax
setne %al
movb %al, -0x162(%rbp)
movb -0x162(%rbp), %al
movb %al, -0x161(%rbp)
movb -0x161(%rbp), %al
testb $0x1, %al
jne 0x14a88
jmp 0x14ab6
movq -0xb0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq %rsi, %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
callq 0xa830
movq %rax, %rdi
callq 0x6fc0
jmp 0x14a2b
jmp 0x14ab8
movq -0xe8(%rbp), %rcx
movq -0xb0(%rbp), %rax
cmpq 0x40(%rcx), %rax
jne 0x147f5
jmp 0x14ad2
movq -0xe8(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x14b6a
movq -0xe8(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq 0x400(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0xc8(%rbp), %rax
testb $0x1, 0x441(%rax)
je 0x14b2b
movq -0xc8(%rbp), %rdi
callq 0x6290
jmp 0x14b29
jmp 0x14b46
movq -0xe8(%rbp), %rax
movq 0x50(%rax), %rdi
movq -0xc8(%rbp), %rsi
callq 0xb130
jmp 0x14b44
jmp 0x14b46
movq -0xd0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xe8(%rbp), %rcx
movq -0xc8(%rbp), %rax
cmpq 0x40(%rcx), %rax
jne 0x14af6
jmp 0x14b6a
movq -0xe8(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, -0xd8(%rbp)
je 0x14bb7
movq -0xd8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rdi
callq 0x5cc0
movq -0xe0(%rbp), %rax
movq %rax, -0xd8(%rbp)
jmp 0x14b7f
movq -0xe8(%rbp), %rdi
callq 0x14c50
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq %rax, %rdi
callq 0x4410
nopw %cs:(%rax,%rax)
nop