// File: /workspace/github_cpp_makefile_star2_O3/manschga[P]M5GB/./poly.h
// Function: polynomial::operator+(polynomial const&) const
polynomial operator+(const polynomial& rhs) const
  {
    //polynomial test_1 = *this;
    //polynomial test_2 = rhs;
    //cout << "Add " << test_1 << "and" << test_2 << endl;

    //compute *this+rhs = f+g (sum of polynomials)
    vector<monomial> f_mon = this->_monomials;

    if (this->Get_LC() == 0)
      {
	return rhs;
      }
    if (rhs.Get_LC() == 0)
      {
	return *this;
      }
    
    vector<monomial> g_mon = rhs._monomials;
    reverse(f_mon.begin(),f_mon.end());
    reverse(g_mon.begin(),g_mon.end());
    vector<monomial> h_mon = {};

    int f_i = f_mon.size()-1;
    int g_i = g_mon.size()-1;
    h_mon.reserve(f_i+g_i+2);
    vector<monomial> merged(f_i+g_i+2);
    std::merge(f_mon.begin(),f_mon.end(),g_mon.begin(),g_mon.end(),merged.begin());

    if (merged.size() > 1)
      {
	for (int i = 0; i < merged.size()-1; ++i)
	  {
	    //if (count(merged[i], merged[i+1], merged[i+1].Get_term()) == 1) 
	    if (merged[i].Get_term() != merged[i+1].Get_term())
	      {
		h_mon.push_back(merged[i]);
	      }
	    else
	      {
		++i;// do sum of both in one step
		//push_back sum of coeffs, case p != 2
	      }
	  }
	{
	  if (merged[merged.size()-2].Get_term() < merged[merged.size()-1].Get_term())
	    {
	      h_mon.push_back(merged[merged.size()-1]);
	    }
	}
      }
    else
      {
	h_mon = merged;
      }
    reverse(h_mon.begin(),h_mon.end());
    /*
    
   
    while (f_i >= 0 || g_i >= 0)//go through all terms of f and g
      {
	if (f_i < 0) //all terms of f done, avoid index crash!
	{
	  h_mon.emplace_back(g_mon[g_i]);
	  g_i--;
	}
      else if (g_i < 0)
	{
	  h_mon.emplace_back(f_mon[f_i]);
	  f_i--;
	}
	else
	{
	  if (f_mon[f_i].Get_term() == g_mon[g_i].Get_term())
	    {//same term appears in both, add up coefficients
	      h_mon.emplace_back(monomial(f_mon[f_i].Get_term(), (f_mon[f_i].Get_coeff() + g_mon[g_i].Get_coeff())%rhs._p, f_mon[f_i].Get_p()));
	      f_i--;
	      g_i--;
	    }
	  else
	    {
	      if (f_mon[f_i].Get_term()< g_mon[g_i].Get_term())
		{
		  h_mon.emplace_back(f_mon[f_i]);
		  f_i--;
		}
	      else
		{
		  h_mon.emplace_back(g_mon[g_i]);
		  g_i--;
		}
	    }
      }
      }
    */
    if (h_mon.size() == 0)
      {
	int p = this->Get_p();
	polynomial h({monomial(0,0,p)});
	//cout << "equals" << h << endl;
	return h;
      }
    polynomial h(h_mon);
    //cout << "in addtion, p:" << h.Get_p() << endl;
    //h = h.update();
    //reorder, remove zeros, do a function!
    return h;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xa0, %rsp
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x58(%rsp), %rdi
callq 0x68a4
movq (%r14), %rax
cmpl $0x0, 0x8(%rax)
je 0x6f1f
movq (%r15), %rax
cmpl $0x0, 0x8(%rax)
je 0x6f30
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x68a4
movq 0x58(%rsp), %rax
movq 0x60(%rsp), %rcx
cmpq %rcx, %rax
setne %dl
addq $-0x10, %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x6da5
addq $0x10, %rax
movups -0x10(%rax), %xmm0
movaps %xmm0, 0x10(%rsp)
movups (%rcx), %xmm0
movups %xmm0, -0x10(%rax)
movaps 0x10(%rsp), %xmm0
movups %xmm0, (%rcx)
addq $-0x10, %rcx
leaq 0x10(%rax), %rdx
cmpq %rcx, %rax
movq %rdx, %rax
jb 0x6d7d
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
cmpq %rcx, %rax
setne %sil
leaq -0x10(%rcx), %rdx
cmpq %rax, %rdx
seta %dil
andb %sil, %dil
cmpb $0x1, %dil
jne 0x6e00
addq $0x10, %rax
movups -0x10(%rax), %xmm0
movaps %xmm0, 0x10(%rsp)
movups (%rdx), %xmm0
movups %xmm0, -0x10(%rax)
movaps 0x10(%rsp), %xmm0
movups %xmm0, (%rdx)
addq $-0x10, %rdx
leaq 0x10(%rax), %rcx
cmpq %rdx, %rax
movq %rcx, %rax
jb 0x6dce
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
subq %rax, %rcx
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdi
movaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x60(%rsp), %rax
subq 0x58(%rsp), %rax
shrq $0x4, %rax
shrq $0x4, %rcx
addl %ecx, %eax
movslq %eax, %r15
movq %r15, %rsi
callq 0x725c
leaq 0x28(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %r15, %rsi
callq 0x7304
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x28(%rsp), %r8
callq 0x742a
movq 0x28(%rsp), %rdx
movq 0x30(%rsp), %rax
subq %rdx, %rax
cmpq $0x11, %rax
jb 0x6f47
xorl %r12d, %r12d
leaq 0x10(%rsp), %r15
xorl %ebp, %ebp
movq %r12, %rax
shlq $0x4, %rax
movq (%rdx,%rax), %rcx
movslq %ebp, %r12
incq %r12
movq %r12, %rsi
shlq $0x4, %rsi
cmpq (%rdx,%rsi), %rcx
jne 0x6eac
addl $0x2, %ebp
movslq %ebp, %r12
jmp 0x6ed3
addq %rax, %rdx
incl %ebp
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x6ecb
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x18(%rsp)
jmp 0x6ed3
movq %r15, %rdi
callq 0x74c4
movq 0x28(%rsp), %rdx
movq 0x30(%rsp), %rcx
subq %rdx, %rcx
movq %rcx, %rax
sarq $0x4, %rax
decq %rax
cmpq %r12, %rax
ja 0x6e86
movq -0x20(%rdx,%rcx), %rcx
shlq $0x4, %rax
cmpq (%rdx,%rax), %rcx
jge 0x6f56
addq %rax, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x708e
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x18(%rsp)
jmp 0x6f56
movq %rbx, %rdi
movq %r15, %rsi
callq 0x68a4
movl 0x18(%r15), %eax
jmp 0x6f3f
movq %rbx, %rdi
movq %r14, %rsi
callq 0x68a4
movl 0x18(%r14), %eax
movl %eax, 0x18(%rbx)
jmp 0x7064
leaq 0x10(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x6674
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rdx
cmpq %rdx, %rax
setne %sil
leaq -0x10(%rdx), %rcx
cmpq %rax, %rcx
seta %dil
andb %sil, %dil
cmpb $0x1, %dil
jne 0x6fb1
addq $0x10, %rax
movups -0x10(%rax), %xmm0
movaps %xmm0, 0x70(%rsp)
movups (%rcx), %xmm0
movups %xmm0, -0x10(%rax)
movaps 0x70(%rsp), %xmm0
movups %xmm0, (%rcx)
addq $-0x10, %rcx
leaq 0x10(%rax), %rdx
cmpq %rcx, %rax
movq %rdx, %rax
jb 0x6f7f
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rdx
cmpq %rax, %rdx
je 0x6fc5
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x10944
jmp 0x701f
movq (%r14), %rax
movl 0xc(%rax), %ecx
leaq 0x90(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x10848
leaq 0x70(%rsp), %rdi
leaq 0x90(%rsp), %rsi
leaq 0xf(%rsp), %rcx
movl $0x1, %edx
callq 0x7392
leaq 0x70(%rsp), %rsi
movq %rbx, %rdi
callq 0x10944
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x701f
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x7036
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x704d
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x7064
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x707b
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rax
addq $0xa0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10(%rsp), %rdi
callq 0x74c4
jmp 0x6f56
movq %rax, %rbx
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x70d3
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
jmp 0x70d3
jmp 0x70d0
jmp 0x70d0
jmp 0x70c2
movq %rax, %rbx
jmp 0x70ea
jmp 0x70c9
movq %rax, %rbx
jmp 0x7118
jmp 0x70d0
movq %rax, %rbx
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x70ea
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x7101
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x7118
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x712f
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rdi
callq 0x2240
nop