// File: dlcgold[P]sparsematrix-unimib/./sparsematrix.h
// Function: sparse_matrix<float>::add(float const&, int, int)
void add(const T &v, const int i, const int j) {
    if(i < 0 || j < 0)
      throw  NegativeIndexSparseMatrixException();
    // se la matrice è di dimensioni definite controllo di essere
    // nelle dimensioni definite dall'utente (usando l'implicazione logica)
    if(!dim || ((i < size_row) && (j < size_column))){
      node *elem;
      try{
	elem = new node(v, i, j);
      }catch(...){
	throw noNodeException{};
      }
      // parto iterando dalla testa per capire dove inserie il nuovo nodo
      node *temp = head;
      // di base aumento di 1 la size in quanto sto inserendo un nodo
      // ci sarà un -1 in caso di cambio di nodo
      size++;
      if(head == nullptr){
	head = elem;
      }else {
	// indice della testa maggiore quindi il nodo diventa la testa
	if((head->ret->x == i && head->ret->y > j) || (head->ret->x > i)) {
	  elem->next = head;
	  head = elem;
        	  
	}else {
	  // nodo iteratore che cicla fino alla fine
	  // o fino a che sono sulla stessa riga ma ho trovato un valore
	  // di colonna maggiore o sono finito sulla stessa riga
	
	  while(temp->next != nullptr &&
		((temp->next->ret->x == i && temp->next->ret->y <= j)
		 || (temp->next->ret->x < i))) {
	    temp = temp->next;
	  }

	  // se sono arrivato alla fine aggiungo il valore alla fine
	  // o se l'ultimo valore è identico tengo l'ultimo valore aggiunto
	  if(temp->next == nullptr) {
	    if(elem->ret->x == temp->ret->x && elem->ret->y == temp->ret->y) {
	      temp->ret->v = elem->ret->v;
	      size--;
	      // avendo sovrascritto cancello elem e la struct con i valori
	      delete elem->ret;
	      elem->ret = nullptr;
	      delete elem;
	      elem = nullptr;
	    }else{
	      elem->next = nullptr;
	      temp->next = elem;
	    }
	  }else {
	    // aggiungo il valore in mezzo
	    // se sono uguali tengo l'ultimo valore aggiunto
	    if(elem->ret->x == temp->ret->x && elem->ret->y == temp->ret->y) {
	      temp->ret->v = elem->ret->v;
	      size--;
	      // avendo sovrascritto cancello elem e la struct con i valori
	      delete elem->ret;
	      elem->ret = nullptr;      
	      delete elem;
	      elem = nullptr;
	    }else {
	      // altrimenti inserisco in mezzo
	      elem->next = temp->next;
	      temp->next = elem;
	    }
	  }	
	}
      }
    }else{
      throw IndexOutOfBoundsException();
    }
    // conto massima riga e colonna se non definite dall'utente
    if(!dim){
      int max_row_current = 0;
      int max_column_current = 0;
      node *iter = head;
      while(iter != nullptr){
	if(iter->ret->x > max_row_current)
	  max_row_current = iter->ret->x;
	if(iter->ret->y > max_column_current)
	  max_column_current = iter->ret->y;
	iter = iter->next;
      }
      size_row = max_row_current;
      size_column = max_column_current;
    }
    
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x381d
cmpl $0x0, -0x18(%rbp)
jge 0x385a
movl $0x8, %edi
callq 0x2050
movq %rax, %rdi
movq %rdi, -0x58(%rbp)
xorl %esi, %esi
movl $0x8, %edx
callq 0x2060
movq -0x58(%rbp), %rdi
callq 0x5f00
movq -0x58(%rbp), %rdi
leaq 0x841a(%rip), %rsi      # 0xbc68
leaq 0x26eb(%rip), %rdx      # 0x5f40
callq 0x2100
movq -0x50(%rbp), %rax
testb $0x1, 0x4(%rax)
je 0x3884
movq -0x50(%rbp), %rcx
movl -0x14(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x3bea
movq -0x50(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0x3bea
movl $0x10, %edi
callq 0x20c0
movq %rax, -0x60(%rbp)
jmp 0x3894
movq -0x60(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x5f60
jmp 0x38a9
movq -0x60(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x3930
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x38d6
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
callq 0x20a0
movq -0x28(%rbp), %rdi
callq 0x2040
movl $0x8, %edi
callq 0x2050
movq %rax, %rdi
movq %rdi, -0x68(%rbp)
movq $0x0, (%rdi)
callq 0x6050
movq -0x68(%rbp), %rdi
leaq 0x8379(%rip), %rsi      # 0xbc80
leaq 0x2782(%rip), %rdx      # 0x6090
callq 0x2100
jmp 0x3cce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
callq 0x20f0
jmp 0x392b
jmp 0x3cbd
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x38(%rbp)
movl 0x18(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x18(%rax)
cmpq $0x0, 0x10(%rax)
jne 0x395d
movq -0x50(%rbp), %rax
movq -0x20(%rbp), %rcx
movq %rcx, 0x10(%rax)
jmp 0x3be8
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
cmpl -0x14(%rbp), %eax
jne 0x3985
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
cmpl -0x18(%rbp), %eax
jg 0x3999
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
cmpl -0x14(%rbp), %eax
jle 0x39b5
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x20(%rbp), %rcx
movq %rdx, (%rcx)
movq -0x20(%rbp), %rcx
movq %rcx, 0x10(%rax)
jmp 0x3be6
jmp 0x39b7
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, (%rcx)
movb %al, -0x69(%rbp)
je 0x3a0e
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
cmpl -0x14(%rbp), %eax
jne 0x39f1
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %ecx
movb $0x1, %al
cmpl -0x18(%rbp), %ecx
movb %al, -0x6a(%rbp)
jle 0x3a08
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
cmpl -0x14(%rbp), %eax
setl %al
movb %al, -0x6a(%rbp)
movb -0x6a(%rbp), %al
movb %al, -0x69(%rbp)
movb -0x69(%rbp), %al
testb $0x1, %al
jne 0x3a17
jmp 0x3a24
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x39b7
movq -0x38(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x3b00
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpl 0x4(%rcx), %eax
jne 0x3ae5
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpl 0x8(%rcx), %eax
jne 0x3ae5
movq -0x50(%rbp), %rax
movq -0x20(%rbp), %rcx
movq 0x8(%rcx), %rcx
movss (%rcx), %xmm0
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
movss %xmm0, (%rcx)
movl 0x18(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x18(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, %rax
je 0x3aaf
movq -0x78(%rbp), %rdi
callq 0x5ed0
movq -0x78(%rbp), %rdi
callq 0x20a0
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, %rax
je 0x3adb
movq -0x80(%rbp), %rdi
callq 0x5ee0
movq -0x80(%rbp), %rdi
callq 0x20a0
movq $0x0, -0x20(%rbp)
jmp 0x3afb
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
jmp 0x3be4
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpl 0x4(%rcx), %eax
jne 0x3bc9
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpl 0x8(%rcx), %eax
jne 0x3bc9
movq -0x50(%rbp), %rax
movq -0x20(%rbp), %rcx
movq 0x8(%rcx), %rcx
movss (%rcx), %xmm0
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rcx
movss %xmm0, (%rcx)
movl 0x18(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x18(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x3b8a
movq -0x88(%rbp), %rdi
callq 0x5ed0
movq -0x88(%rbp), %rdi
callq 0x20a0
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, %rax
je 0x3bbf
movq -0x90(%rbp), %rdi
callq 0x5ee0
movq -0x90(%rbp), %rdi
callq 0x20a0
movq $0x0, -0x20(%rbp)
jmp 0x3be2
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
jmp 0x3be4
jmp 0x3be6
jmp 0x3be8
jmp 0x3c30
movl $0x8, %edi
callq 0x2050
movq %rax, %rdi
movq %rdi, -0x98(%rbp)
xorl %esi, %esi
movl $0x8, %edx
callq 0x2060
movq -0x98(%rbp), %rdi
callq 0x60b0
movq -0x98(%rbp), %rdi
leaq 0x8074(%rip), %rsi      # 0xbc98
leaq 0x24c5(%rip), %rdx      # 0x60f0
callq 0x2100
movq -0x50(%rbp), %rax
testb $0x1, 0x4(%rax)
jne 0x3cb4
movq -0x50(%rbp), %rax
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x3ca4
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
cmpl -0x3c(%rbp), %eax
jle 0x3c79
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
cmpl -0x40(%rbp), %eax
jle 0x3c97
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x3c54
movq -0x50(%rbp), %rax
movl -0x3c(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl -0x40(%rbp), %ecx
movl %ecx, 0xc(%rax)
addq $0xa0, %rsp
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x2120
movq %rax, %rdi
callq 0x5e20
nop