// File: wichtounet[P]articles/plf_colony_alpha/plf_colony.h
// Function: plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::insert(unsigned long, Trivial<8> const&)
iterator insert(const size_type number_of_elements, const element_type &element)
	{
		if (number_of_elements == 0)
		{
			return end_iterator;
		}

		if (first_group == NULL) // Empty colony, no groups created yet
		{
			if (number_of_elements > group_allocator_pair.max_elements_per_group)
			{
				// Create and fill first group:
				initialize(group_allocator_pair.max_elements_per_group); // Construct first group
				group_fill(element, group_allocator_pair.max_elements_per_group);

				// Create and fill all remaining groups:
				size_type multiples = (number_of_elements / static_cast<size_type>(group_allocator_pair.max_elements_per_group));
				const skipfield_type element_remainder = static_cast<const skipfield_type>(number_of_elements - (multiples * static_cast<size_type>(group_allocator_pair.max_elements_per_group)));

				while (--multiples != 0)
				{
					group_create(group_allocator_pair.max_elements_per_group);
					group_fill(element, group_allocator_pair.max_elements_per_group);
				}

				if (element_remainder != 0)
				{
					group_create(group_allocator_pair.max_elements_per_group);
					group_fill(element, element_remainder);
				}
			}
			else
			{
				initialize((number_of_elements < min_elements_per_group) ? min_elements_per_group : static_cast<skipfield_type>(number_of_elements)); // Construct first group
				group_fill(element, static_cast<skipfield_type>(number_of_elements));
			}

			end_iterator.skipfield_pointer = end_iterator.group_pointer->skipfield + end_iterator.group_pointer->number_of_elements;
			total_number_of_elements += number_of_elements;
			return begin_iterator;
		}
		else
		{
			const iterator return_iterator = insert(element);
			size_type num_elements = number_of_elements - 1;
			size_type capacity_available = (reinterpret_cast<element_pointer_type>(end_iterator.group_pointer->skipfield) - end_iterator.element_pointer) + erased_locations.total_number_of_elements;

			// Use up erased locations and remainder of current group first:
			while (capacity_available-- != 0 && num_elements-- != 0)
			{
				insert(element);
			}

			// If still some left over, create new groups and fill:
			if (num_elements > group_allocator_pair.max_elements_per_group)
			{
				size_type multiples = (num_elements / static_cast<size_type>(group_allocator_pair.max_elements_per_group));
				const skipfield_type element_remainder = static_cast<const skipfield_type>(num_elements - (multiples * static_cast<size_type>(group_allocator_pair.max_elements_per_group)));

				while (multiples-- != 0)
				{
					group_create(group_allocator_pair.max_elements_per_group);
					group_fill(element, group_allocator_pair.max_elements_per_group);
				}

				if (element_remainder != 0)
				{
					group_create(group_allocator_pair.max_elements_per_group);
					group_fill(element, element_remainder);
				}
			}
			else if (num_elements > total_number_of_elements)
			{
				group_create(static_cast<skipfield_type>(num_elements));
				group_fill(element, static_cast<skipfield_type>(num_elements));
			}

			end_iterator.skipfield_pointer = end_iterator.group_pointer->skipfield + end_iterator.group_pointer->number_of_elements;
			total_number_of_elements += num_elements; // Adds the remainder - the insert functions above will already have incremented total_number_of_elements

			return return_iterator;
		}
	}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x8(%rsp)
movq %rdi, %rax
movq %rax, 0x10(%rsp)
movq %rdi, 0x80(%rsp)
movq %rsi, 0x78(%rsp)
movq %rdx, 0x70(%rsp)
movq %rcx, 0x68(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x70(%rsp)
jne 0x139951
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x16f40
jmp 0x139c9c
movq 0x18(%rsp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x139ada
movq 0x18(%rsp), %rcx
movq 0x70(%rsp), %rax
movzwl 0x42(%rcx), %ecx
cmpq %rcx, %rax
jbe 0x139a44
movq 0x18(%rsp), %rax
movq %rax, %rdi
movzwl 0x42(%rax), %esi
callq 0x17110
movq 0x18(%rsp), %rax
movq 0x68(%rsp), %rsi
movq %rax, %rdi
movzwl 0x42(%rax), %edx
callq 0x139cb0
movq 0x18(%rsp), %rcx
movq 0x70(%rsp), %rax
movzwl 0x42(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq 0x18(%rsp), %rdx
movq %rax, 0x60(%rsp)
movq 0x70(%rsp), %rax
movq 0x60(%rsp), %rcx
movzwl 0x42(%rdx), %edx
imulq %rdx, %rcx
subq %rcx, %rax
movw %ax, 0x5e(%rsp)
movq 0x60(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, %rax
je 0x139a13
movq 0x18(%rsp), %rax
movq %rax, %rdi
movzwl 0x42(%rax), %esi
callq 0x139d40
movq 0x18(%rsp), %rax
movq 0x68(%rsp), %rsi
movq %rax, %rdi
movzwl 0x42(%rax), %edx
callq 0x139cb0
jmp 0x1399d6
movzwl 0x5e(%rsp), %eax
cmpl $0x0, %eax
je 0x139a42
movq 0x18(%rsp), %rax
movq %rax, %rdi
movzwl 0x42(%rax), %esi
callq 0x139d40
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rsi
movzwl 0x5e(%rsp), %edx
callq 0x139cb0
jmp 0x139a9a
movq 0x18(%rsp), %rcx
movq 0x70(%rsp), %rax
movzwl 0x40(%rcx), %ecx
cmpq %rcx, %rax
jae 0x139a67
movq 0x18(%rsp), %rax
movw 0x40(%rax), %ax
movw %ax, 0x6(%rsp)
jmp 0x139a71
movq 0x70(%rsp), %rax
movw %ax, 0x6(%rsp)
movq 0x18(%rsp), %rdi
movw 0x6(%rsp), %ax
movzwl %ax, %esi
callq 0x17110
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rax
movzwl %ax, %edx
callq 0x139cb0
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq (%rsi), %rax
movq 0x18(%rax), %rax
movq (%rsi), %rcx
movzwl 0x30(%rcx), %ecx
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x10(%rsi)
movq 0x70(%rsp), %rax
addq 0x38(%rsi), %rax
movq %rax, 0x38(%rsi)
addq $0x18, %rsi
callq 0x16f40
jmp 0x139c9c
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %rdi
movq 0x68(%rsp), %rdx
callq 0x169c0
movq 0x18(%rsp), %rcx
movq 0x70(%rsp), %rax
subq $0x1, %rax
movq %rax, 0x50(%rsp)
movq (%rcx), %rax
movq 0x18(%rax), %rax
movq 0x8(%rcx), %rdx
subq %rdx, %rax
sarq $0x3, %rax
addq 0x70(%rcx), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rcx
movq %rcx, %rax
addq $-0x1, %rax
movq %rax, 0x48(%rsp)
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, 0x5(%rsp)
je 0x139b55
movq 0x50(%rsp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, 0x50(%rsp)
cmpq $0x0, %rax
setne %al
movb %al, 0x5(%rsp)
movb 0x5(%rsp), %al
testb $0x1, %al
jne 0x139b5f
jmp 0x139b75
movq 0x18(%rsp), %rsi
movq 0x68(%rsp), %rdx
leaq 0x30(%rsp), %rdi
callq 0x169c0
jmp 0x139b1c
movq 0x18(%rsp), %rcx
movq 0x50(%rsp), %rax
movzwl 0x42(%rcx), %ecx
cmpq %rcx, %rax
jbe 0x139c34
movq 0x18(%rsp), %rcx
movq 0x50(%rsp), %rax
movzwl 0x42(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq 0x18(%rsp), %rdx
movq %rax, 0x28(%rsp)
movq 0x50(%rsp), %rax
movq 0x28(%rsp), %rcx
movzwl 0x42(%rdx), %edx
imulq %rdx, %rcx
subq %rcx, %rax
movw %ax, 0x26(%rsp)
movq 0x28(%rsp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, 0x28(%rsp)
cmpq $0x0, %rax
je 0x139c03
movq 0x18(%rsp), %rax
movq %rax, %rdi
movzwl 0x42(%rax), %esi
callq 0x139d40
movq 0x18(%rsp), %rax
movq 0x68(%rsp), %rsi
movq %rax, %rdi
movzwl 0x42(%rax), %edx
callq 0x139cb0
jmp 0x139bc3
movzwl 0x26(%rsp), %eax
cmpl $0x0, %eax
je 0x139c32
movq 0x18(%rsp), %rax
movq %rax, %rdi
movzwl 0x42(%rax), %esi
callq 0x139d40
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rsi
movzwl 0x26(%rsp), %edx
callq 0x139cb0
jmp 0x139c6f
movq 0x18(%rsp), %rcx
movq 0x50(%rsp), %rax
cmpq 0x38(%rcx), %rax
jbe 0x139c6d
movq 0x18(%rsp), %rdi
movq 0x50(%rsp), %rax
movzwl %ax, %esi
callq 0x139d40
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x50(%rsp), %rax
movzwl %ax, %edx
callq 0x139cb0
jmp 0x139c6f
movq 0x18(%rsp), %rax
movq (%rax), %rcx
movq 0x18(%rcx), %rcx
movq (%rax), %rdx
movzwl 0x30(%rdx), %edx
movslq %edx, %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x50(%rsp), %rcx
addq 0x38(%rax), %rcx
movq %rcx, 0x38(%rax)
movq 0x10(%rsp), %rax
addq $0x88, %rsp
retq
nopl (%rax)