// File: wichtounet[P]articles/plf_colony_alpha/plf_colony.h
// Function: plf::colony<NonTrivialStringMovable, std::allocator<NonTrivialStringMovable>, unsigned short>::insert(NonTrivialStringMovable&&)
iterator insert(element_type &&element)
		{
			if (end_iterator.element_pointer != NULL)
			{
				switch(((erased_locations.total_number_of_elements != 0) << 1) | (end_iterator.element_pointer == reinterpret_cast<element_pointer_type>(end_iterator.group_pointer->skipfield)))
				{
					case 0:
					{
						const iterator return_iterator = end_iterator; /* Make copy for return before adjusting components */
						PLF_COLONY_CONSTRUCT(element_allocator_type, (*this), end_iterator.element_pointer, std::move(element));

						++end_iterator.element_pointer;
						++end_iterator.skipfield_pointer;
						++end_iterator.group_pointer->last_endpoint;
						++end_iterator.group_pointer->number_of_elements;
						++total_number_of_elements;
						return return_iterator;
					}
					case 1:
					{
						end_iterator.group_pointer->next_group = PLF_COLONY_ALLOCATE(group_allocator_type, group_allocator_pair, 1, end_iterator.group_pointer);
						group &next_group = *(end_iterator.group_pointer->next_group);

						try
						{
							#ifdef PLF_COLONY_VARIADICS_SUPPORT
								PLF_COLONY_CONSTRUCT(group_allocator_type, group_allocator_pair, &next_group, (total_number_of_elements < static_cast<size_type>(group_allocator_pair.max_elements_per_group)) ? static_cast<const skipfield_type>(total_number_of_elements) : group_allocator_pair.max_elements_per_group, end_iterator.group_pointer);
							#else
								PLF_COLONY_CONSTRUCT(group_allocator_type, group_allocator_pair, &next_group, group((total_number_of_elements < static_cast<size_type>(group_allocator_pair.max_elements_per_group)) ? static_cast<const skipfield_type>(total_number_of_elements) : group_allocator_pair.max_elements_per_group, end_iterator.group_pointer));
							#endif
						}
						catch (...)
						{
							PLF_COLONY_DEALLOCATE(group_allocator_type, group_allocator_pair, &next_group, 1);
							end_iterator.group_pointer->next_group = NULL;
							throw;
						}

						try
						{
							PLF_COLONY_CONSTRUCT(element_allocator_type, (*this), next_group.elements, std::move(element));
						}
						catch (...)
						{
							PLF_COLONY_DESTROY(group_allocator_type, group_allocator_pair, &next_group);
							PLF_COLONY_DEALLOCATE(group_allocator_type, group_allocator_pair, &next_group, 1);
							end_iterator.group_pointer->next_group = NULL;
							throw;
						}

						end_iterator.group_pointer = &next_group;
						end_iterator.element_pointer = next_group.last_endpoint;
						end_iterator.skipfield_pointer = next_group.skipfield + 1;
						++total_number_of_elements;

						return iterator(end_iterator.group_pointer, next_group.elements, next_group.skipfield); /* returns value before incrementation */
					}
					default:
					{
						iterator new_location;
						new_location.element_pointer = *erased_locations.top_element;
						PLF_COLONY_CONSTRUCT(element_allocator_type, (*this), new_location.element_pointer, std::move(element));
						erased_locations.pop();

						new_location.group_pointer = end_iterator.group_pointer; // Start with last group first, as will be the largest group

						while (new_location.element_pointer < new_location.group_pointer->elements || new_location.element_pointer >= reinterpret_cast<element_pointer_type>(new_location.group_pointer->skipfield))
						{
							new_location.group_pointer = new_location.group_pointer->previous_group;
						}

						new_location.skipfield_pointer = new_location.group_pointer->skipfield + (new_location.element_pointer - new_location.group_pointer->elements);

						++(new_location.group_pointer->number_of_elements);

						if (new_location.group_pointer == first_group && new_location.element_pointer < begin_iterator.element_pointer)
						{
							begin_iterator = new_location;
						}

						++total_number_of_elements;

						const skipfield_type value = *(new_location.skipfield_pointer);
						const bool test = (new_location.skipfield_pointer == new_location.group_pointer->skipfield);
						const unsigned char prev_skipfield = *(new_location.skipfield_pointer - !test) != value * test;
						const unsigned char after_skipfield = *(new_location.skipfield_pointer + 1) != 0;

						switch (prev_skipfield | (after_skipfield << 1))
						{
							case 1:
							{
								*(new_location.skipfield_pointer - (value - 1)) = value - 1;
								break;
							}
							case 2:
							{
								std::memmove(&*(new_location.skipfield_pointer + 2), &*(new_location.skipfield_pointer + 1), sizeof(skipfield_type) * (value - 2));
								*(new_location.skipfield_pointer + 1) = value - 1;
								break;
							}
							case 3:
							{
								const skipfield_pointer_type start_node = new_location.skipfield_pointer - (value - 1);
								const skipfield_type update_count = *start_node - value;
								*start_node = value - 1;

								std::memmove(&*(new_location.skipfield_pointer + 2), &*(start_node + 1), sizeof(skipfield_type) * (update_count - 1));
								*(new_location.skipfield_pointer + 1) = update_count;
							}
						}

						*new_location.skipfield_pointer = 0;
						return new_location;
					}
				}
			}
			else
			{
				initialize(min_elements_per_group);

				try
				{
					PLF_COLONY_CONSTRUCT(element_allocator_type, (*this), end_iterator.element_pointer++, std::move(element));
				}
				catch (...)
				{
					clear();
					throw;
				}

				++end_iterator.skipfield_pointer;
				total_number_of_elements = 1;

				return begin_iterator;
			}
		}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0x40(%rsp)
movq %rdi, %rax
movq %rax, 0x48(%rsp)
movq %rdi, 0xa0(%rsp)
movq %rsi, 0x98(%rsp)
movq %rdx, 0x90(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x8(%rax)
je 0x11b3a5
movq 0x50(%rsp), %rcx
movq 0x70(%rcx), %rax
testq %rax, %rax
setne %al
movzbl %al, %eax
addl %eax, %eax
movq (%rcx), %rdx
movq 0x8(%rcx), %rcx
movq 0x18(%rdx), %rdx
subq %rdx, %rcx
sete %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, 0x3c(%rsp)
je 0x11ae54
jmp 0x11ae46
movl 0x3c(%rsp), %eax
subl $0x1, %eax
je 0x11aec3
jmp 0x11b0e2
movq 0x50(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x3c4a0
movq 0x50(%rsp), %rdi
movq 0x8(%rdi), %rsi
movq 0x90(%rsp), %rdx
callq 0x7e1f0
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rcx
addq $0x28, %rcx
movq %rcx, 0x8(%rax)
movq 0x10(%rax), %rcx
addq $0x2, %rcx
movq %rcx, 0x10(%rax)
movq (%rax), %rcx
movq (%rcx), %rdx
addq $0x28, %rdx
movq %rdx, (%rcx)
movq (%rax), %rcx
movw 0x30(%rcx), %dx
addw $0x1, %dx
movw %dx, 0x30(%rcx)
movq 0x38(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x38(%rax)
jmp 0x11b441
movq 0x50(%rsp), %rax
movq %rax, %rdi
addq $0x42, %rdi
movq (%rax), %rdx
movl $0x1, %esi
callq 0x3c4e0
movq 0x50(%rsp), %rcx
movq %rax, %rdx
movq (%rcx), %rax
movq %rdx, 0x8(%rax)
movq (%rcx), %rax
movq 0x8(%rax), %rax
movq %rax, 0x88(%rsp)
movq %rcx, %rax
addq $0x42, %rax
movq %rax, 0x28(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rcx), %rax
movzwl 0x42(%rcx), %ecx
cmpq %rcx, %rax
jae 0x11af30
movq 0x50(%rsp), %rax
movq 0x38(%rax), %rax
movw %ax, 0x26(%rsp)
jmp 0x11af3e
movq 0x50(%rsp), %rax
movw 0x42(%rax), %ax
movw %ax, 0x26(%rsp)
movq 0x50(%rsp), %rcx
movq 0x30(%rsp), %rsi
movq 0x28(%rsp), %rdi
movw 0x26(%rsp), %ax
movw %ax, 0x86(%rsp)
leaq 0x86(%rsp), %rdx
callq 0x3c510
jmp 0x11af69
jmp 0x11afd4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
movq 0x78(%rsp), %rdi
callq 0x50b0
movq 0x50(%rsp), %rdi
addq $0x42, %rdi
movq 0x88(%rsp), %rsi
movl $0x1, %edx
callq 0x3c550
jmp 0x11afa0
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq $0x0, 0x8(%rax)
callq 0x52d0
jmp 0x11b460
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
callq 0x5350
jmp 0x11afcf
jmp 0x11b44e
movq 0x50(%rsp), %rdi
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rsi
movq 0x90(%rsp), %rdx
callq 0x7e1f0
jmp 0x11aff4
jmp 0x11b079
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
movq 0x78(%rsp), %rdi
callq 0x50b0
movq 0x50(%rsp), %rdi
addq $0x42, %rdi
movq %rdi, 0x18(%rsp)
movq 0x88(%rsp), %rsi
callq 0x3c580
movq 0x18(%rsp), %rdi
movq 0x88(%rsp), %rsi
movl $0x1, %edx
callq 0x3c550
jmp 0x11b045
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq $0x0, 0x8(%rax)
callq 0x52d0
jmp 0x11b460
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
callq 0x5350
jmp 0x11b074
jmp 0x11b44e
movq 0x40(%rsp), %rdi
movq 0x50(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rcx, (%rax)
movq 0x88(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x8(%rax)
movq 0x88(%rsp), %rcx
movq 0x18(%rcx), %rcx
addq $0x2, %rcx
movq %rcx, 0x10(%rax)
movq 0x38(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x38(%rax)
movq (%rax), %rsi
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rdx
movq 0x88(%rsp), %rax
movq 0x18(%rax), %rcx
callq 0x3c5b0
jmp 0x11b441
movq 0x40(%rsp), %rdi
callq 0x3bbc0
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rax
movq 0x58(%rdi), %rcx
movq (%rcx), %rcx
movq %rcx, 0x8(%rax)
movq 0x8(%rax), %rsi
movq 0x90(%rsp), %rdx
callq 0x7e1f0
movq 0x50(%rsp), %rdi
addq $0x48, %rdi
callq 0x3c5f0
movq 0x50(%rsp), %rcx
movq 0x40(%rsp), %rax
movq (%rcx), %rcx
movq %rcx, (%rax)
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rcx
movq (%rax), %rdx
movb $0x1, %al
cmpq 0x10(%rdx), %rcx
movb %al, 0x17(%rsp)
jb 0x11b15f
movq 0x40(%rsp), %rcx
movq 0x8(%rcx), %rax
movq (%rcx), %rcx
cmpq 0x18(%rcx), %rax
setae %al
movb %al, 0x17(%rsp)
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x11b169
jmp 0x11b17a
movq 0x40(%rsp), %rax
movq (%rax), %rcx
movq 0x20(%rcx), %rcx
movq %rcx, (%rax)
jmp 0x11b130
movq 0x50(%rsp), %rcx
movq 0x40(%rsp), %rdx
movq (%rdx), %rax
movq 0x18(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rdx), %rax
movq (%rdx), %rdx
movq 0x10(%rdx), %rdx
subq %rdx, %rax
movl $0x28, %esi
cqto
idivq %rsi
movq 0x8(%rsp), %rdx
movq %rax, %rsi
movq 0x40(%rsp), %rax
shlq %rsi
addq %rsi, %rdx
movq %rdx, 0x10(%rax)
movq (%rax), %rdx
movw 0x30(%rdx), %si
addw $0x1, %si
movw %si, 0x30(%rdx)
movq (%rax), %rax
cmpq 0x30(%rcx), %rax
jne 0x11b1fe
movq 0x50(%rsp), %rcx
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x20(%rcx), %rax
jae 0x11b1fe
movq 0x40(%rsp), %rsi
movq 0x50(%rsp), %rdi
addq $0x18, %rdi
callq 0x3c660
movq 0x40(%rsp), %rax
movq 0x50(%rsp), %rcx
movq 0x38(%rcx), %rdx
incq %rdx
movq %rdx, 0x38(%rcx)
movq 0x10(%rax), %rcx
movw (%rcx), %cx
movw %cx, 0x72(%rsp)
movq (%rax), %rdx
movq 0x10(%rax), %rcx
movq 0x18(%rdx), %rdx
subq %rdx, %rcx
sete 0x71(%rsp)
movq 0x10(%rax), %rcx
movzbl 0x71(%rsp), %esi
movb %sil, %dl
notb %dl
movzbl %dl, %edx
andl $0x1, %edx
addl %edx, %edx
subq %rdx, %rcx
movzwl (%rcx), %ecx
movzwl 0x72(%rsp), %edx
andl $0x1, %esi
imull %esi, %edx
subl %edx, %ecx
setne 0x70(%rsp)
movq 0x10(%rax), %rax
movw 0x2(%rax), %ax
testw %ax, %ax
setne 0x6f(%rsp)
movzbl 0x70(%rsp), %eax
movzbl 0x6f(%rsp), %ecx
addl %ecx, %ecx
orl %ecx, %eax
movl %eax, 0x4(%rsp)
subl $0x1, %eax
je 0x11b2a2
jmp 0x11b289
movl 0x4(%rsp), %eax
subl $0x2, %eax
je 0x11b2cf
jmp 0x11b294
movl 0x4(%rsp), %eax
subl $0x3, %eax
je 0x11b311
jmp 0x11b392
movq 0x40(%rsp), %rax
movzwl 0x72(%rsp), %ecx
subl $0x1, %ecx
movw %cx, %dx
movq 0x10(%rax), %rax
movzwl 0x72(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rsi
xorl %ecx, %ecx
subq %rsi, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x11b392
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rdi
addq $0x4, %rdi
movq 0x10(%rax), %rsi
addq $0x2, %rsi
movzwl 0x72(%rsp), %eax
subl $0x2, %eax
movslq %eax, %rdx
shlq %rdx
callq 0x5330
movq 0x40(%rsp), %rax
movzwl 0x72(%rsp), %ecx
subl $0x1, %ecx
movq 0x10(%rax), %rax
movw %cx, 0x2(%rax)
jmp 0x11b392
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rcx
movzwl 0x72(%rsp), %edx
subl $0x1, %edx
movslq %edx, %rsi
xorl %edx, %edx
subq %rsi, %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x60(%rsp)
movq 0x60(%rsp), %rcx
movzwl (%rcx), %ecx
movzwl 0x72(%rsp), %edx
subl %edx, %ecx
movw %cx, 0x5e(%rsp)
movzwl 0x72(%rsp), %ecx
subl $0x1, %ecx
movw %cx, %dx
movq 0x60(%rsp), %rcx
movw %dx, (%rcx)
movq 0x10(%rax), %rdi
addq $0x4, %rdi
movq 0x60(%rsp), %rsi
addq $0x2, %rsi
movzwl 0x5e(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rdx
shlq %rdx
callq 0x5330
movq 0x40(%rsp), %rax
movw 0x5e(%rsp), %cx
movq 0x10(%rax), %rax
movw %cx, 0x2(%rax)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rax
movw $0x0, (%rax)
jmp 0x11b441
movq 0x50(%rsp), %rdi
movzwl 0x40(%rdi), %esi
callq 0x3c6a0
movq 0x50(%rsp), %rdi
movq 0x8(%rdi), %rsi
movq %rsi, %rax
addq $0x28, %rax
movq %rax, 0x8(%rdi)
movq 0x90(%rsp), %rdx
callq 0x7e1f0
jmp 0x11b3d6
jmp 0x11b41a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
movq 0x78(%rsp), %rdi
callq 0x50b0
movq 0x50(%rsp), %rdi
callq 0x3c7a0
jmp 0x11b3fc
callq 0x52d0
jmp 0x11b460
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
callq 0x5350
jmp 0x11b418
jmp 0x11b44e
movq 0x40(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x10(%rsi), %rax
addq $0x2, %rax
movq %rax, 0x10(%rsi)
movq $0x1, 0x38(%rsi)
addq $0x18, %rsi
callq 0x3c4a0
movq 0x48(%rsp), %rax
addq $0xa8, %rsp
retq
movq 0x78(%rsp), %rdi
callq 0x5360
movq %rax, %rdi
callq 0x14670