// File: wichtounet[P]articles/plf_colony_alpha/plf_colony.h
// Function: void plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::sort<plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::less>(plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::less)
void sort(comparison_function compare)
	{
		if (total_number_of_elements < 2)
		{
			return;
		}

		element_pointer_type * const element_pointers = PLF_COLONY_ALLOCATE(element_pointer_allocator_type, erased_locations, total_number_of_elements, NULL);
		element_pointer_type *element_pointer = element_pointers;

		try
		{
			for (iterator current_element = begin_iterator; current_element != end_iterator; ++current_element)
			{
				PLF_COLONY_CONSTRUCT(element_pointer_allocator_type, erased_locations, element_pointer++, &*current_element);
			}
		}
		catch (...)
		{
			#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
				if (!std::is_trivially_destructible<element_pointer_type>::value)
			#endif
			{
				for(element_pointer_type *current_element_pointer = element_pointers; current_element_pointer != element_pointer; ++current_element_pointer)
				{
					PLF_COLONY_DESTROY(element_pointer_allocator_type, erased_locations, current_element_pointer);
				}
			}

			PLF_COLONY_DEALLOCATE(element_pointer_allocator_type, erased_locations, element_pointers, total_number_of_elements);
			throw;
		}

        std::sort(element_pointers, element_pointers + total_number_of_elements, sort_dereferencer<comparison_function>(compare));


		colony new_location;
		new_location.change_group_sizes(min_elements_per_group, group_allocator_pair.max_elements_per_group);
		new_location.reserve(static_cast<skipfield_type>((total_number_of_elements > std::numeric_limits<skipfield_type>::max()) ? std::numeric_limits<skipfield_type>::max() : total_number_of_elements));

		#if defined(PLF_COLONY_TYPE_TRAITS_SUPPORT) && defined(PLF_COLONY_MOVE_SEMANTICS_SUPPORT)
			if (std::is_move_assignable<element_type>::value)
			{
				for(element_pointer_type *current_element_pointer = element_pointers; current_element_pointer != element_pointer; ++current_element_pointer)
				{
					new_location.insert(std::move(*(*current_element_pointer)));
				}
			}
			else
		#endif
		{
			for(element_pointer_type *current_element_pointer = element_pointers; current_element_pointer != element_pointer; ++current_element_pointer)
			{
				new_location.insert(*(*current_element_pointer));
			}
		}


		#ifdef PLF_COLONY_MOVE_SEMANTICS_SUPPORT
			*this = std::move(new_location); // avoid generating temporary
		#else
			swap(new_location);
		#endif


		#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
			if (!std::is_trivially_destructible<element_pointer_type>::value)
		#endif
		{
			for(element_pointer_type *current_element_pointer = element_pointers; current_element_pointer != element_pointer; ++current_element_pointer)
			{
				PLF_COLONY_DESTROY(element_pointer_allocator_type, erased_locations, current_element_pointer);
			}
		}

		PLF_COLONY_DEALLOCATE(element_pointer_allocator_type, erased_locations, element_pointers, total_number_of_elements);
	}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x128(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq $0x2, 0x38(%rax)
jae 0xe3a88
jmp 0xe3ca0
movq 0x38(%rsp), %rax
movq %rax, %rdi
addq $0x48, %rdi
movq 0x38(%rax), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xadd90
movq 0x38(%rsp), %rsi
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x118(%rsp)
addq $0x18, %rsi
leaq 0x100(%rsp), %rdi
callq 0x16f40
movq 0x38(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x18320
testb $0x1, %al
jne 0xe3ae7
jmp 0xe3b49
movq 0x38(%rsp), %rax
addq $0x48, %rax
movq %rax, 0x28(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x30(%rsp)
addq $0x8, %rax
movq %rax, 0x118(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x18250
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq %rax, 0xf8(%rsp)
leaq 0xf8(%rsp), %rdx
callq 0xe3cc0
leaq 0x100(%rsp), %rdi
callq 0x18260
jmp 0xe3acf
movq 0x38(%rsp), %rcx
movq 0x120(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rcx), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0x18(%rsp)
leaq 0xf7(%rsp), %rdi
leaq 0x137(%rsp), %rsi
callq 0xe3d40
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0xe3cf0
leaq 0x70(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x16610
movq 0x38(%rsp), %rax
movq 0x20(%rsp), %rdi
movzwl 0x40(%rax), %esi
movzwl 0x42(%rax), %edx
callq 0xe3d50
jmp 0xe3bb4
movq 0x38(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x8(%rsp)
callq 0x16790
movw %ax, %cx
movq 0x8(%rsp), %rax
movzwl %cx, %ecx
cmpq %rcx, %rax
jbe 0xe3be5
callq 0x16790
movzwl %ax, %eax
movq %rax, (%rsp)
jmp 0xe3bf2
movq 0x38(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, (%rsp)
movq (%rsp), %rax
movzwl %ax, %esi
leaq 0x70(%rsp), %rdi
callq 0x17c10
jmp 0xe3c05
movq 0x120(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
cmpq 0x118(%rsp), %rax
je 0xe3c66
movq 0x58(%rsp), %rax
movq (%rax), %rdx
leaq 0x40(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0xe3e00
jmp 0xe3c3a
jmp 0xe3c3c
movq 0x58(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x58(%rsp)
jmp 0xe3c12
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x68(%rsp)
movl %eax, 0x64(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x165b0
jmp 0xe3ca8
movq 0x38(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x18090
jmp 0xe3c77
movq 0x38(%rsp), %rax
movq %rax, %rdi
addq $0x48, %rdi
movq 0x120(%rsp), %rsi
movq 0x38(%rax), %rdx
callq 0x15a70
jmp 0xe3c96
leaq 0x70(%rsp), %rdi
callq 0x165b0
addq $0x138, %rsp            # imm = 0x138
retq
movq 0x68(%rsp), %rdi
callq 0x5360
nopw %cs:(%rax,%rax)
nopl (%rax)