// File: /workspace/github_cpp_makefile_star2_O2/iZhangHui[P]CppPrimer/CH03_StringsVectorsAndArrays/examples/multidim.cc
// Function: main
int main()
{
	// array of size 3; each element is an array of 4 uninitailzed ints 
	int ia1[3][4];
	
	// array of size 10; each element is a 20-element array 
	// whose elements are arrays of 30 ints
	int arr[10][20][30] = {0}; // initialize all elements to 0
	
	// assigns the first element of arr to the last element 
	// in the last row of ia
	ia1[2][3] = arr[0][0][0];
	
	// binds row to the second four-element array in ia 
	int (&row)[4] = ia1[1];
	
	// three elements, each element is an array of size 4
	int ia2[3][4] = { 
	    {0, 1, 2, 3},   // initializers for the row indexed by 0
	    {4, 5, 6, 7},   // initializers for the row indexed by 1
	    {8, 9, 10, 11}  // initializers for the row indexed by 2
	};
	
	// equivalent initialization without the optional 
	// nested braces for each row
	int ia3[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
	
	// explicitly initialize only element 0 in each row
	int ia4[3][4] = {{ 0 }, { 4 }, { 8 }};
	
	// explicitly initialize row 0; the remaining elements 
	// are value initialized
	int ix[3][4] = {0, 3, 6, 9};
	
	// prints 9 0 0 
	cout << ix[0][3] << ' ' << ix[1][0] << ' ' << ix[2][0] << endl;
	
	constexpr size_t rowCnt = 3, colCnt = 4;
	int ia[rowCnt][colCnt];   // 12 uninitialized elements 
	
    // for each row
    for (size_t i = 0; i != rowCnt; ++i) {
        // for each column within the row
        for (size_t j = 0; j != colCnt; ++j) {
            // assign the element's positional index as its value
            ia[i][j] = i * colCnt + j;   
		}
	}

	// four ways to print the contents of ia
	// 1. using nested range for loops
	for (const auto &row : ia) // for every element in the outer array
		for (auto col : row)   // for every element in the inner array
			cout << col << endl; // print the element's value
    cout << ia[0][0] << ' ' << ia[2][3] << endl; // prints 0 11


	// 2. using pointers and a traditional for loop
	//    with pointer arithmetic to calculate the end pointers 
	for (auto p = ia; p != ia + rowCnt; ++p) {
		// q points to the first element of an array of four ints; 
		// that is, q points to an int
	    for (auto q = *p; q != *p + colCnt; ++q)
	         cout << *q << ' ';
		cout << endl;
	}
	
	// 3. using pointers and a traditional for loop
	//    with the library begin and end functions to manage the pointers
	for (auto p = begin(ia); p != end(ia); ++p) {
		// q points to the first element in an inner array
		for (auto q = begin(*p); q != end(*p); ++q)
			cout << *q << ' ';  // prints the int value to which q points
		cout << endl;
	}
	
	// 4. using a type alias to declare the loop control variable
	using int_array = int[4]; // new style type alias declaration 

	for (int_array *p = ia; p != ia + 3; ++p) {
	    for (int *q = *p; q != *p + 4; ++q)
	         cout << *q << ' ';
		cout << endl;
	}

	// alternative way to assign positional index to elements 
	// in a two-dimensional array
	int alt_ia[rowCnt][colCnt]; // 12 uninitialized elements 
	size_t cnt = 0;
	for (auto &row : alt_ia)    // for every element in the outer array
		for (auto &col : row) { // for every element in the inner array
			col = cnt;          // give this element the next value
			++cnt;              // increment cnt
		}
	// now print the value of the array
	for (const auto &row : alt_ia) // for every element in the outer array
		for (auto col : row)     // for every element in the inner array
			cout << col << endl;

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq 0x2e04(%rip), %rdi      # 0x3fd8
pushq $0x9
popq %rsi
callq 0x1070
pushq $0x20
popq %rbx
movq %rax, %rdi
movl %ebx, %esi
callq 0x1050
xorl %r14d, %r14d
movq %rax, %rdi
xorl %esi, %esi
callq 0x1070
movq %rax, %rdi
movl %ebx, %esi
callq 0x1050
movq %rax, %rdi
xorl %esi, %esi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq -0x60(%rbp), %rax
xorl %ecx, %ecx
cmpq $0x3, %rcx
je 0x123f
xorl %edx, %edx
cmpq $0x4, %rdx
je 0x1232
leal (%r14,%rdx), %esi
movl %esi, (%rax,%rdx,4)
incq %rdx
jmp 0x1220
incq %rcx
addq $0x10, %rax
addq $0x4, %r14
jmp 0x1218
leaq -0x60(%rbp), %r14
xorl %r15d, %r15d
movq 0x2d8b(%rip), %rbx      # 0x3fd8
cmpq $0x30, %r15
je 0x1280
addq $0x10, %r15
xorl %r12d, %r12d
cmpq $0x10, %r12
je 0x127a
movl (%r14,%r12), %esi
movq %rbx, %rdi
callq 0x1070
movq %rax, %rdi
callq 0x1030
addq $0x4, %r12
jmp 0x125a
addq $0x10, %r14
jmp 0x124d
leaq -0x60(%rbp), %r15
movl (%r15), %esi
movq %rbx, %rdi
callq 0x1070
pushq $0x20
popq %r14
movq %rax, %rdi
movl %r14d, %esi
callq 0x1050
movl 0x2c(%r15), %esi
movq %rax, %rdi
callq 0x1070
movq %rax, %rdi
xorl %r12d, %r12d
callq 0x1030
cmpq $0x30, %r12
je 0x12ee
addq $0x10, %r12
xorl %r13d, %r13d
cmpq $0x10, %r13
je 0x12e5
movl (%r15,%r13), %esi
movq %rbx, %rdi
callq 0x1070
movq %rax, %rdi
movl %r14d, %esi
callq 0x1050
addq $0x4, %r13
jmp 0x12c2
addq $0x10, %r15
movq %rbx, %rdi
jmp 0x12b0
leaq -0x60(%rbp), %r15
xorl %r12d, %r12d
movq 0x2cdc(%rip), %rbx      # 0x3fd8
pushq $0x20
popq %r14
cmpq $0x30, %r12
je 0x133e
addq $0x10, %r12
xorl %r13d, %r13d
cmpq $0x10, %r13
je 0x1330
movl (%r15,%r13), %esi
movq %rbx, %rdi
callq 0x1070
movq %rax, %rdi
movl %r14d, %esi
callq 0x1050
addq $0x4, %r13
jmp 0x130d
movq %rbx, %rdi
callq 0x1030
addq $0x10, %r15
jmp 0x1300
leaq -0x60(%rbp), %r15
xorl %r12d, %r12d
movq 0x2c8c(%rip), %rbx      # 0x3fd8
pushq $0x20
popq %r14
cmpq $0x30, %r12
je 0x138e
addq $0x10, %r12
xorl %r13d, %r13d
cmpq $0x10, %r13
je 0x1380
movl (%r15,%r13), %esi
movq %rbx, %rdi
callq 0x1070
movq %rax, %rdi
movl %r14d, %esi
callq 0x1050
addq $0x4, %r13
jmp 0x135d
movq %rbx, %rdi
callq 0x1030
addq $0x10, %r15
jmp 0x1350
xorl %eax, %eax
leaq -0x90(%rbp), %rcx
xorl %edx, %edx
cmpq $0x30, %rdx
je 0x13bc
addq $0x10, %rdx
xorl %esi, %esi
cmpq $0x10, %rsi
je 0x13b6
movl %eax, (%rcx,%rsi)
incl %eax
addq $0x4, %rsi
jmp 0x13a5
addq $0x10, %rcx
jmp 0x1399
leaq -0x90(%rbp), %r14
xorl %r15d, %r15d
movq 0x2c0b(%rip), %rbx      # 0x3fd8
cmpq $0x30, %r15
je 0x1400
addq $0x10, %r15
xorl %r12d, %r12d
cmpq $0x10, %r12
je 0x13fa
movl (%r14,%r12), %esi
movq %rbx, %rdi
callq 0x1070
movq %rax, %rdi
callq 0x1030
addq $0x4, %r12
jmp 0x13da
addq $0x10, %r14
jmp 0x13cd
xorl %eax, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq