// File: jliesch[P]ofxget/pugixml/pugixml.cpp
// Function: pugi::xml_document::_move(pugi::xml_document&)
PUGI__FN void xml_document::_move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
	{
		impl::xml_document_struct* doc = static_cast<impl::xml_document_struct*>(_root);
		impl::xml_document_struct* other = static_cast<impl::xml_document_struct*>(rhs._root);

		// save first child pointer for later; this needs hash access
		xml_node_struct* other_first_child = other->first_child;

	#ifdef PUGIXML_COMPACT
		// reserve space for the hash table up front; this is the only operation that can fail
		// if it does, we have no choice but to throw (if we have exceptions)
		if (other_first_child)
		{
			size_t other_children = 0;
			for (xml_node_struct* node = other_first_child; node; node = node->next_sibling)
				other_children++;

			// in compact mode, each pointer assignment could result in a hash table request
			// during move, we have to relocate document first_child and parents of all children
			// normally there's just one child and its parent has a pointerless encoding but
			// we assume the worst here
			if (!other->_hash->reserve(other_children + 1))
			{
			#ifdef PUGIXML_NO_EXCEPTIONS
				return;
			#else
				throw std::bad_alloc();
			#endif
			}
		}
	#endif

		// move allocation state
		doc->_root = other->_root;
		doc->_busy_size = other->_busy_size;

		// move buffer state
		doc->buffer = other->buffer;
		doc->extra_buffers = other->extra_buffers;
		_buffer = rhs._buffer;

	#ifdef PUGIXML_COMPACT
		// move compact hash; note that the hash table can have pointers to other but they will be "inactive", similarly to nodes removed with remove_child
		doc->hash = other->hash;
		doc->_hash = &doc->hash;

		// make sure we don't access other hash up until the end when we reinitialize other document
		other->_hash = 0;
	#endif

		// move page structure
		impl::xml_memory_page* doc_page = PUGI__GETPAGE(doc);
		assert(doc_page && !doc_page->prev && !doc_page->next);

		impl::xml_memory_page* other_page = PUGI__GETPAGE(other);
		assert(other_page && !other_page->prev);

		// relink pages since root page is embedded into xml_document
		if (impl::xml_memory_page* page = other_page->next)
		{
			assert(page->prev == other_page);

			page->prev = doc_page;

			doc_page->next = page;
			other_page->next = 0;
		}

		// make sure pages point to the correct document state
		for (impl::xml_memory_page* page = doc_page->next; page; page = page->next)
		{
			assert(page->allocator == other);

			page->allocator = doc;

		#ifdef PUGIXML_COMPACT
			// this automatically migrates most children between documents and prevents ->parent assignment from allocating
			if (page->compact_shared_parent == other)
				page->compact_shared_parent = doc;
		#endif
		}

		// move tree structure
		assert(!doc->first_child);

		doc->first_child = other_first_child;

		for (xml_node_struct* node = other_first_child; node; node = node->next_sibling)
		{
		#ifdef PUGIXML_COMPACT
			// most children will have migrated when we reassigned compact_shared_parent
			assert(node->parent == other || node->parent == doc);

			node->parent = doc;
		#else
			assert(node->parent == other);
			node->parent = doc;
		#endif
		}

		// reset other document
		new (other) impl::xml_document_struct(PUGI__GETPAGE(other));
		rhs._buffer = 0;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rcx
movq 0x20(%rcx), %rcx
movq %rcx, -0x28(%rbp)
movq -0x20(%rbp), %rcx
movq 0x40(%rcx), %rdx
movq -0x18(%rbp), %rcx
movq %rdx, 0x40(%rcx)
movq -0x20(%rbp), %rcx
movq 0x48(%rcx), %rdx
movq -0x18(%rbp), %rcx
movq %rdx, 0x48(%rcx)
movq -0x20(%rbp), %rcx
movq 0x50(%rcx), %rdx
movq -0x18(%rbp), %rcx
movq %rdx, 0x50(%rcx)
movq -0x20(%rbp), %rcx
movq 0x58(%rcx), %rdx
movq -0x18(%rbp), %rcx
movq %rdx, 0x58(%rcx)
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movq (%rcx), %rdx
shrq $0x8, %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0x51(%rbp)
je 0x47b09
movq -0x30(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x8(%rcx)
movb %al, -0x51(%rbp)
jne 0x47b09
movq -0x30(%rbp), %rax
cmpq $0x0, 0x10(%rax)
setne %al
xorb $-0x1, %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x47b12
jmp 0x47b14
jmp 0x47b33
leaq 0x23f9b(%rip), %rdi     # 0x6bab6
leaq 0x23833(%rip), %rsi     # 0x6b355
movl $0x1b66, %edx           # imm = 0x1B66
leaq 0x23fb7(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x20(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rdx
shrq $0x8, %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x38(%rbp)
movb %al, -0x52(%rbp)
je 0x47b6b
movq -0x38(%rbp), %rax
cmpq $0x0, 0x8(%rax)
setne %al
xorb $-0x1, %al
movb %al, -0x52(%rbp)
movb -0x52(%rbp), %al
testb $0x1, %al
jne 0x47b74
jmp 0x47b76
jmp 0x47b95
leaq 0x23f97(%rip), %rdi     # 0x6bb14
leaq 0x237d1(%rip), %rsi     # 0x6b355
movl $0x1b69, %edx           # imm = 0x1B69
leaq 0x23f55(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x47bfb
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
cmpq -0x38(%rbp), %rax
jne 0x47bb8
jmp 0x47bd7
leaq 0x23f75(%rip), %rdi     # 0x6bb34
leaq 0x2378f(%rip), %rsi     # 0x6b355
movl $0x1b6e, %edx           # imm = 0x1B6E
leaq 0x23f13(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x30(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x47ca7
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rcx
movq %rcx, -0x68(%rbp)
xorl %eax, %eax
cmpq $0x0, %rcx
movq %rax, -0x60(%rbp)
je 0x47c3d
movq -0x68(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x60(%rbp)
movq -0x70(%rbp), %rax
movq -0x60(%rbp), %rcx
cmpq %rcx, %rax
jne 0x47c4c
jmp 0x47c6b
leaq 0x23efa(%rip), %rdi     # 0x6bb4d
leaq 0x236fb(%rip), %rsi     # 0x6b355
movl $0x1b79, %edx           # imm = 0x1B79
leaq 0x23e7f(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x18(%rbp), %rcx
movq %rcx, -0x80(%rbp)
xorl %eax, %eax
cmpq $0x0, %rcx
movq %rax, -0x78(%rbp)
je 0x47c8b
movq -0x80(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, (%rax)
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x47c07
movq -0x18(%rbp), %rax
cmpq $0x0, 0x20(%rax)
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x47cbb
jmp 0x47cbd
jmp 0x47cdc
leaq 0x23ea2(%rip), %rdi     # 0x6bb66
leaq 0x2368a(%rip), %rsi     # 0x6b355
movl $0x1b85, %edx           # imm = 0x1B85
leaq 0x23e0e(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x28(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x47d40
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
cmpq -0x20(%rbp), %rax
jne 0x47d07
jmp 0x47d26
leaq 0x23e6a(%rip), %rdi     # 0x6bb78
leaq 0x23640(%rip), %rsi     # 0x6b355
movl $0x1b91, %edx           # imm = 0x1B91
leaq 0x23dc4(%rip), %rcx     # 0x6bae5
callq 0x7180
movq -0x18(%rbp), %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x50(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x47cf0
movq -0x20(%rbp), %rdi
movq (%rdi), %rax
shrq $0x8, %rax
movq %rdi, %rsi
subq %rax, %rsi
callq 0x47ef0
jmp 0x47d58
movq -0x10(%rbp), %rax
movq $0x0, 0x8(%rax)
addq $0x80, %rsp
popq %rbp
retq
movq %rax, %rdi
callq 0xb810
nopw %cs:(%rax,%rax)