// File: iZhangHui[P]CppPrimer/CH17_SpecializedLibraryFacilities/examples/tuple.cc
// Function: main
int main()
{
	// tuple that represents a bookstore transaction: 
	// ISBN, count, price per book
	auto item = make_tuple("0-999-78345-X", 3, 20.00);
	auto book = get<0>(item);      // returns the first member of item
	auto cnt = get<1>(item);       // returns the second member of item
	auto price = get<2>(item)/cnt; // returns the last member of item
	get<2>(item) *= 0.8;           // apply 20% discount
	
	cout << book << " " << cnt << " " << price << endl;

	typedef decltype(item) trans; // trans is the type of item 
	
	// returns the number of members in object's of type trans
	size_t sz = tuple_size<trans>::value;  // returns 3

	// cnt has the same type as the second member in item
	tuple_element<1, trans>::type cnt2 = get<1>(item); // cnt is an int
	tuple_element<0, trans>::type book2 = get<0>(item);
	tuple_element<2, trans>::type price2 = get<2>(item);
	cout << tuple_size<trans>::value << endl;
	
	cout << book2 << " " << cnt2 << " " << price2 << endl;
	
	tuple<size_t, size_t, size_t> threeD;  // all three members set to 0
	tuple<string, vector<double>, int, list<int>>
	    someVal("constants", {3.14, 2.718}, 42, {0,1,2,3,4,5});
	
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1d0, %rsp            # imm = 0x1D0
movl $0x0, -0x4(%rbp)
movl $0x3, -0x24(%rbp)
movabsq $0x4034000000000000, %rax # imm = 0x4034000000000000
movq %rax, -0x30(%rbp)
leaq 0x2d12(%rip), %rsi      # 0x4010
leaq -0x20(%rbp), %rdi
movq %rdi, -0x1c0(%rbp)
leaq -0x24(%rbp), %rdx
leaq -0x30(%rbp), %rcx
callq 0x16f0
movq -0x1c0(%rbp), %rdi
callq 0x1730
movq -0x1c0(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x38(%rbp)
callq 0x1750
movq -0x1c0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
callq 0x1770
movq -0x1c0(%rbp), %rdi
movsd (%rax), %xmm0
cvtsi2sdl -0x3c(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
callq 0x1770
movsd (%rax), %xmm0
movsd 0x2c98(%rip), %xmm1     # 0x4008
mulsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq -0x38(%rbp), %rsi
movq 0x6c55(%rip), %rdi      # 0x7fd8
movq %rdi, -0x1b8(%rbp)
callq 0x10d0
movq %rax, %rdi
leaq 0x2c85(%rip), %rsi      # 0x401e
movq %rsi, -0x1b0(%rbp)
callq 0x10d0
movq %rax, %rdi
movl -0x3c(%rbp), %esi
callq 0x1150
movq -0x1b0(%rbp), %rsi
movq %rax, %rdi
callq 0x10d0
movq %rax, %rdi
movsd -0x48(%rbp), %xmm0
callq 0x1180
movq %rax, %rdi
movq 0x6bf2(%rip), %rsi      # 0x7fc8
movq %rsi, -0x1a8(%rbp)
callq 0x1100
movq -0x1c0(%rbp), %rdi
movq $0x3, -0x50(%rbp)
callq 0x1750
movq -0x1c0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x54(%rbp)
callq 0x1730
movq -0x1c0(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x60(%rbp)
callq 0x1770
movq -0x1b8(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x68(%rbp)
movl $0x3, %esi
callq 0x1040
movq -0x1a8(%rbp), %rsi
movq %rax, %rdi
callq 0x1100
movq -0x1b8(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x10d0
movq -0x1b0(%rbp), %rsi
movq %rax, %rdi
callq 0x10d0
movq %rax, %rdi
movl -0x54(%rbp), %esi
callq 0x1150
movq -0x1b0(%rbp), %rsi
movq %rax, %rdi
callq 0x10d0
movq %rax, %rdi
movsd -0x68(%rbp), %xmm0
callq 0x1180
movq -0x1a8(%rbp), %rsi
movq %rax, %rdi
callq 0x1100
leaq -0x80(%rbp), %rdi
callq 0x1790
leaq -0xf9(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x1170
movq -0x1a0(%rbp), %rdx
leaq 0x2b5e(%rip), %rsi      # 0x4020
leaq -0xf8(%rbp), %rdi
callq 0x1120
jmp 0x14d0
movabsq $0x40091eb851eb851f, %rax # imm = 0x40091EB851EB851F
movq %rax, -0x148(%rbp)
movabsq $0x4005be76c8b43958, %rax # imm = 0x4005BE76C8B43958
movq %rax, -0x140(%rbp)
leaq -0x148(%rbp), %rax
movq %rax, -0x138(%rbp)
movq $0x2, -0x130(%rbp)
leaq -0x149(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x17c0
movq -0x1c8(%rbp), %rcx
movq -0x138(%rbp), %rsi
movq -0x130(%rbp), %rdx
leaq -0x128(%rbp), %rdi
callq 0x17e0
jmp 0x1541
movl $0x2a, -0x150(%rbp)
movabsq $0x500000004, %rax      # imm = 0x500000004
movq %rax, -0x180(%rbp)
movups 0x2af9(%rip), %xmm0     # 0x405c
movaps %xmm0, -0x190(%rbp)
leaq -0x190(%rbp), %rax
movq %rax, -0x178(%rbp)
movq $0x6, -0x170(%rbp)
leaq -0x191(%rbp), %rdi
movq %rdi, -0x1d0(%rbp)
callq 0x1860
movq -0x1d0(%rbp), %rcx
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x168(%rbp), %rdi
callq 0x1880
jmp 0x15b9
leaq -0xd8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x128(%rbp), %rdx
leaq -0x150(%rbp), %rcx
leaq -0x168(%rbp), %r8
callq 0x1920
jmp 0x15e3
leaq -0x168(%rbp), %rdi
callq 0x1960
leaq -0x191(%rbp), %rdi
callq 0x1980
leaq -0x128(%rbp), %rdi
callq 0x19a0
leaq -0x149(%rbp), %rdi
callq 0x1a00
leaq -0xf8(%rbp), %rdi
callq 0x10a0
leaq -0xf9(%rbp), %rdi
callq 0x1110
movl $0x0, -0x4(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x1a20
movl -0x4(%rbp), %eax
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x16d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x16bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x16a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x1960
leaq -0x191(%rbp), %rdi
callq 0x1980
leaq -0x128(%rbp), %rdi
callq 0x19a0
leaq -0x149(%rbp), %rdi
callq 0x1a00
leaq -0xf8(%rbp), %rdi
callq 0x10a0
leaq -0xf9(%rbp), %rdi
callq 0x1110
movq -0x108(%rbp), %rdi
callq 0x1160
nopl (%rax)