// File: /workspace/github_cpp_makefile_star2_O1/iZhangHui[P]CppPrimer/CH16_TemplatesAndGenericProgramming/exercises/ex16_47.cc
// Function: main
int main(int argc, char const *argv[])
{
	int i = 0, j = 0, k = 0, l = 0;
	cout << i << " " << j << " " << k << " " << l << endl;

	f(42, i);        // f changes its argument i
	flip1(f, j, 42); // f called through flip1 leaves j unchanged
	flip2(f, k, 42); // ok: k is changed
	cout << "=========================================" << endl;
	g(1, i);
	flip(g, i, 42);  // ok: rvalue-ness of the third argument is preserved
	cout << i << " " << j << " " << k << " " << l << endl;
	cout << "=========================================" << endl;

	// test for lvalue reference
	string s1;
	string s2;
	flip(func_lvalue, s1, s2);
	cout << s1 << " " << s2 << endl;

	// test for rvalue reference
	flip(func_rvalue, 99, 88);

	// void flip1(F, T1, T2) [with F = void (*)(int&&, int&&); T1 = int; T2 = int]’:
	// ex16_47.cc:88:27:   required from here
	// ex16_47.cc:28:3: error: cannot bind ‘int’ lvalue to ‘int&&’
	// f(t2, t1);
	// ^
	// flip1(func_rvalue, 99, 88);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
xorl %r15d, %r15d
leaq -0x7c(%rbp), %r12
movl %r15d, (%r12)
leaq -0x2c(%rbp), %rax
movl %r15d, (%rax)
movq 0x2c02(%rip), %rbx      # 0x3fd8
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r13
leaq 0xc1a(%rip), %r14       # 0x2004
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r13, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r13, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r13, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r13
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x1060
movsbl %al, %esi
movq %r13, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1040
movl $0x2a, %edi
movq %r12, %rsi
callq 0x121c
leaq -0x50(%rbp), %r13
movl %r15d, (%r13)
movl $0x2a, %edi
movq %r13, %rsi
callq 0x121c
movl $0x2a, %edi
leaq -0x2c(%rbp), %rsi
callq 0x121c
leaq 0xb74(%rip), %rsi       # 0x2013
movl $0x29, %edx
movq %rbx, %rdi
callq 0x1090
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1060
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1040
movl $0x1, (%r13)
movq %r13, %rdi
movq %r12, %rsi
callq 0x1287
movl $0x2a, (%r13)
leaq -0x50(%rbp), %rdi
movq %r12, %rsi
callq 0x1287
movl (%r12), %esi
movq %rbx, %rdi
callq 0x10c0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r12, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
leaq -0x2c(%rbp), %rax
movl (%rax), %esi
movq %r12, %rdi
callq 0x10c0
movq %rax, %r15
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r15, %rdi
xorl %esi, %esi
callq 0x10c0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x1060
movsbl %al, %esi
movq %r14, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1040
movl $0x29, %edx
movq %rbx, %rdi
leaq 0xa79(%rip), %rsi       # 0x2013
callq 0x1090
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1060
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1040
leaq -0x40(%rbp), %r14
movq %r14, -0x10(%r14)
xorl %eax, %eax
movq %rax, -0x8(%r14)
movb %al, (%r14)
leaq -0x60(%rbp), %r15
movq %r15, -0x10(%r15)
movq %rax, -0x8(%r15)
movb %al, (%r15)
leaq -0x70(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x12ee
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq 0x29d6(%rip), %rdi      # 0x3fd8
callq 0x1090
movq %rax, %rbx
leaq 0x9f3(%rip), %rsi       # 0x2004
movl $0x1, %edx
movq %rax, %rdi
callq 0x1090
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %rbx, %rdi
callq 0x1090
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1060
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1040
leaq -0x78(%rbp), %rsi
movl $0x63, (%rsi)
leaq -0x74(%rbp), %rdi
movl $0x58, (%rdi)
callq 0x1330
movq -0x70(%rbp), %rdi
cmpq %r15, %rdi
je 0x1686
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x1080
movq -0x50(%rbp), %rdi
cmpq %r14, %rdi
je 0x169b
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x1080
xorl %eax, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x16ae
movq %rax, %rbx
movq -0x70(%rbp), %rdi
cmpq %r15, %rdi
je 0x16c6
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x1080
movq -0x50(%rbp), %rdi
cmpq %r14, %rdi
je 0x16db
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x1080
movq %rbx, %rdi
callq 0x10d0