// File: iZhangHui[P]CppPrimer/CH03_StringsVectorsAndArrays/examples/char_repl.cc
// Function: main
int main()
{
	string str("some string"), orig = str;
	if (!str.empty())          // make sure there's a character to print
		cout << str[0] << endl;// print the first character in str

	if (!str.empty())       // make sure there's a character in str[0]
		// assign a new value to the first character in str
		str[0] = toupper(str[0]);
	cout << str << endl;

	str = orig; // restore str to its original value

	// equivalent code using iterators instead of subscripts
	if (str.begin() != str.end()) { // make sure str is not empty
		auto it = str.begin();  // it denotes the first character in str
		*it = toupper(*it);     // make that character uppercase
	}
	cout << str << endl;

	str = orig; // restore str to its original value

	// four wasy to capitalize first word in str:
	// 1. for loop with subscripts
	for (decltype(str.size()) index = 0; 
		 index != str.size() && !isspace(str[index]); ++index) 
    		str[index] = toupper(str[index]); // capitalize the current character
	cout << str << endl;

	str = orig; // restore str to its original value

	// 2. for loop with iterators instead of subscripts
	for (auto it = str.begin(); it != str.end() && !isspace(*it); ++it)
		*it = toupper(*it); // capitalize the current character
	cout << str << endl;

	str = orig; // restore str to its original value

	// 3. while instead of a for with subscripts
	decltype(str.size()) index = 0; // subscript to look at characters in str
	while (index != str.size() && !isspace(str[index])) {
		str[index] = toupper(str[index]);  // capitalize the current character
		++index;        // advance the index to get the next character
	}
	cout << str << endl;

	// 4. while loop with iterators
	auto beg = str.begin();
	while (beg != str.end() && !isspace(*beg)) {
		*beg = toupper(*beg);
		++beg;
	}
	cout << str << endl;

	str = orig; // restore str to its original value

	// range for loop to process every character
	// first a loop to print the characters in str one character to a line
	for (auto c : str)      // for every char in str
		cout << c << endl;  // print the current character followed by a newline

	// next change every character in str
	for (auto &c : str)  // note: c is a reference 
		c = '*';         // assign a new value to the underlying char in str
	cout << str << endl;
	
	str = orig;  // restore str to its original value

	// equivalent code using traditional for loops
	// first print the characters in str
	for (decltype(str.size()) ix = 0; ix != str.size(); ++ix)
		cout << str[ix] << endl;  // print current character followd by a newline

	// next change every character in str
	for (decltype(str.size()) ix = 0; ix != str.size(); ++ix)
		str[ix] = '*';  // assigns a new value to the character in str
	cout << str << endl;

	str = orig;  // restore str to its original value

	// equivalent code using traditional for loops and iterators
	// first print the characters in str
	for (auto beg = str.begin(); beg != str.end(); ++beg)
		cout << *beg << endl;  // print current character followd by a newline

	// next change every character in str
	for (auto beg = str.begin(); beg != str.end(); ++beg)
		*beg = '*';  // assigns a new value to the character in str
	cout << str << endl;
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x240, %rsp            # imm = 0x240
movl $0x0, -0x4(%rbp)
leaq -0x29(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x1130
movq -0x120(%rbp), %rdx
leaq 0xd34(%rip), %rsi       # 0x2004
leaq -0x28(%rbp), %rdi
callq 0x10f0
jmp 0x12db
leaq -0x29(%rbp), %rdi
callq 0x10d0
leaq -0x60(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x1050
jmp 0x12f3
leaq -0x28(%rbp), %rdi
callq 0x1110
testb $0x1, %al
jne 0x1395
xorl %eax, %eax
movl %eax, %esi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x128(%rbp)
jmp 0x131a
movq -0x128(%rbp), %rax
movsbl (%rax), %esi
movq 0x2cad(%rip), %rdi      # 0x3fd8
callq 0x10e0
movq %rax, -0x130(%rbp)
jmp 0x1339
movq -0x130(%rbp), %rdi
movq 0x2c81(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x134e
jmp 0x1395
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x29(%rbp), %rdi
callq 0x10d0
jmp 0x1c91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x1c88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x1070
jmp 0x1c88
leaq -0x28(%rbp), %rdi
callq 0x1110
testb $0x1, %al
jne 0x13f2
xorl %eax, %eax
movl %eax, %esi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x138(%rbp)
jmp 0x13b8
movq -0x138(%rbp), %rax
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x141(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x140(%rbp)
jmp 0x13e3
movq -0x140(%rbp), %rax
movb -0x141(%rbp), %cl
movb %cl, (%rax)
movq 0x2bdf(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x150(%rbp)
jmp 0x140b
movq -0x150(%rbp), %rdi
movq 0x2baf(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1420
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x142f
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0x68(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1060
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x1ca0
testb $0x1, %al
jne 0x145c
jmp 0x1491
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0x78(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x151(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x1ce0
movb -0x151(%rbp), %cl
movb %cl, (%rax)
movq 0x2b40(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x160(%rbp)
jmp 0x14aa
movq -0x160(%rbp), %rdi
movq 0x2b10(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x14bf
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x14ce
movq $0x0, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x170(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1080
movq -0x170(%rbp), %rcx
movq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x161(%rbp)
je 0x1534
movq -0x80(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x178(%rbp)
jmp 0x1517
movq -0x178(%rbp), %rax
movsbl (%rax), %edi
callq 0x1040
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x161(%rbp)
movb -0x161(%rbp), %al
testb $0x1, %al
jne 0x1540
jmp 0x15a1
movq -0x80(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x180(%rbp)
jmp 0x1556
movq -0x180(%rbp), %rax
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x189(%rbp)
movq -0x80(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x188(%rbp)
jmp 0x1581
movq -0x188(%rbp), %rax
movb -0x189(%rbp), %cl
movb %cl, (%rax)
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
jmp 0x14d6
movq 0x2a30(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x198(%rbp)
jmp 0x15ba
movq -0x198(%rbp), %rdi
movq 0x2a00(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x15cf
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x15de
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0x88(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1060
movq %rax, -0x90(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x1ca0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x199(%rbp)
jne 0x1622
jmp 0x1644
leaq -0x88(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %edi
callq 0x1040
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x199(%rbp)
movb -0x199(%rbp), %al
testb $0x1, %al
jne 0x1650
jmp 0x168f
leaq -0x88(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x19a(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x1ce0
movb -0x19a(%rbp), %cl
movb %cl, (%rax)
leaq -0x88(%rbp), %rdi
callq 0x1d00
jmp 0x15ee
movq 0x2942(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x1a8(%rbp)
jmp 0x16a8
movq -0x1a8(%rbp), %rdi
movq 0x2912(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x16bd
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x16cc
movq $0x0, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x1b8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1080
movq -0x1b8(%rbp), %rcx
movq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x1a9(%rbp)
je 0x173b
movq -0x98(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x1c0(%rbp)
jmp 0x171e
movq -0x1c0(%rbp), %rax
movsbl (%rax), %edi
callq 0x1040
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x1a9(%rbp)
movb -0x1a9(%rbp), %al
testb $0x1, %al
jne 0x1747
jmp 0x17b4
movq -0x98(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x1c8(%rbp)
jmp 0x1760
movq -0x1c8(%rbp), %rax
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x1d1(%rbp)
movq -0x98(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x1d0(%rbp)
jmp 0x178e
movq -0x1d0(%rbp), %rax
movb -0x1d1(%rbp), %cl
movb %cl, (%rax)
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x16d7
movq 0x281d(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x1e0(%rbp)
jmp 0x17cd
movq -0x1e0(%rbp), %rdi
movq 0x27ed(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x17e2
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0xa0(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1060
movq %rax, -0xa8(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x1ca0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1e1(%rbp)
jne 0x1826
jmp 0x1848
leaq -0xa0(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %edi
callq 0x1040
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x1e1(%rbp)
movb -0x1e1(%rbp), %al
testb $0x1, %al
jne 0x1854
jmp 0x1893
leaq -0xa0(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %edi
callq 0x1140
movb %al, -0x1e2(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x1ce0
movb -0x1e2(%rbp), %cl
movb %cl, (%rax)
leaq -0xa0(%rbp), %rdi
callq 0x1d00
jmp 0x17f2
movq 0x273e(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x1f0(%rbp)
jmp 0x18ac
movq -0x1f0(%rbp), %rdi
movq 0x270e(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x18c1
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x18d0
leaq -0x28(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x1090
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x1060
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x1ca0
testb $0x1, %al
jne 0x191a
jmp 0x196f
leaq -0xb8(%rbp), %rdi
callq 0x1ce0
movb (%rax), %al
movb %al, -0xc1(%rbp)
movsbl -0xc1(%rbp), %esi
movq 0x269c(%rip), %rdi      # 0x3fd8
callq 0x10e0
movq %rax, -0x1f8(%rbp)
jmp 0x194a
movq -0x1f8(%rbp), %rdi
movq 0x2670(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x195f
jmp 0x1961
leaq -0xb8(%rbp), %rdi
callq 0x1d00
jmp 0x1901
leaq -0x28(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x1090
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x1060
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x1ca0
testb $0x1, %al
jne 0x19b9
jmp 0x19e4
leaq -0xd8(%rbp), %rdi
callq 0x1ce0
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rax
movb $0x2a, (%rax)
leaq -0xd8(%rbp), %rdi
callq 0x1d00
jmp 0x19a0
movq 0x25ed(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x200(%rbp)
jmp 0x19fd
movq -0x200(%rbp), %rdi
movq 0x25bd(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1a12
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x1a21
movq $0x0, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movq %rax, -0x208(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1080
movq %rax, %rcx
movq -0x208(%rbp), %rax
cmpq %rcx, %rax
je 0x1ab8
movq -0xf0(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x210(%rbp)
jmp 0x1a6b
movq -0x210(%rbp), %rax
movsbl (%rax), %esi
movq 0x255c(%rip), %rdi      # 0x3fd8
callq 0x10e0
movq %rax, -0x218(%rbp)
jmp 0x1a8a
movq -0x218(%rbp), %rdi
movq 0x2530(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1a9f
jmp 0x1aa1
movq -0xf0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xf0(%rbp)
jmp 0x1a2c
movq $0x0, -0xf8(%rbp)
movq -0xf8(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1080
movq %rax, %rcx
movq -0x220(%rbp), %rax
cmpq %rcx, %rax
je 0x1b20
movq -0xf8(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x1150
movq %rax, -0x228(%rbp)
jmp 0x1b02
movq -0x228(%rbp), %rax
movb $0x2a, (%rax)
movq -0xf8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xf8(%rbp)
jmp 0x1ac3
movq 0x24b1(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x230(%rbp)
jmp 0x1b39
movq -0x230(%rbp), %rdi
movq 0x2481(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1b4e
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1030
jmp 0x1b5d
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0x100(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1060
movq %rax, -0x108(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x1ca0
testb $0x1, %al
jne 0x1b96
jmp 0x1bdf
leaq -0x100(%rbp), %rdi
callq 0x1ce0
movsbl (%rax), %esi
movq 0x242c(%rip), %rdi      # 0x3fd8
callq 0x10e0
movq %rax, -0x238(%rbp)
jmp 0x1bba
movq -0x238(%rbp), %rdi
movq 0x2400(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1bcf
jmp 0x1bd1
leaq -0x100(%rbp), %rdi
callq 0x1d00
jmp 0x1b6d
leaq -0x28(%rbp), %rdi
callq 0x1090
movq %rax, -0x110(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x1060
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x1ca0
testb $0x1, %al
jne 0x1c18
jmp 0x1c35
leaq -0x110(%rbp), %rdi
callq 0x1ce0
movb $0x2a, (%rax)
leaq -0x110(%rbp), %rdi
callq 0x1d00
jmp 0x1bef
movq 0x239c(%rip), %rdi      # 0x3fd8
leaq -0x28(%rbp), %rsi
callq 0x10b0
movq %rax, -0x240(%rbp)
jmp 0x1c4e
movq -0x240(%rbp), %rdi
movq 0x236c(%rip), %rsi      # 0x3fc8
callq 0x10c0
jmp 0x1c63
movl $0x0, -0x4(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x1070
leaq -0x28(%rbp), %rdi
callq 0x1070
movl -0x4(%rbp), %eax
addq $0x240, %rsp            # imm = 0x240
popq %rbp
retq
leaq -0x28(%rbp), %rdi
callq 0x1070
movq -0x38(%rbp), %rdi
callq 0x1120
nopw (%rax,%rax)