// File: /workspace/github_cpp_makefile_star2_O1/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 %rbx
subq $0x98, %rsp
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x58(%rsp), %rdi
callq 0x6314
movq (%r14), %rax
cmpl $0x0, 0x8(%rax)
je 0x6995
movq (%r15), %rax
cmpl $0x0, 0x8(%rax)
je 0x69a6
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x6314
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 0x6813
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 0x67eb
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
cmpq %rcx, %rax
setne %dl
addq $-0x10, %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x6863
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 0x683b
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdi
movaps %xmm0, (%rdi)
movq 0x60(%rsp), %rax
subq 0x58(%rsp), %rax
movq $0x0, 0x10(%rdi)
movq 0x48(%rsp), %rcx
subq 0x40(%rsp), %rcx
shrq $0x4, %rax
shrq $0x4, %rcx
addl %eax, %ecx
movslq %ecx, %r15
movq %r15, %rsi
callq 0x6ccc
leaq 0x28(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %r15, %rsi
callq 0x6d74
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x28(%rsp), %r8
callq 0x6e9a
movq 0x30(%rsp), %rax
subq 0x28(%rsp), %rax
cmpq $0x11, %rax
jb 0x69bd
movq 0x28(%rsp), %rdx
movq 0x30(%rsp), %rsi
subq %rdx, %rsi
movq %rsi, %rcx
sarq $0x4, %rcx
decq %rcx
je 0x6965
xorl %eax, %eax
leaq 0x10(%rsp), %r15
xorl %ebp, %ebp
shlq $0x4, %rax
movq (%rdx,%rax), %rcx
movslq %ebp, %rsi
shlq $0x4, %rsi
cmpq 0x10(%rsi,%rdx), %rcx
jne 0x691f
incl %ebp
jmp 0x6944
addq %rax, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x693c
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x18(%rsp)
jmp 0x6944
movq %r15, %rdi
callq 0x6f34
incl %ebp
movslq %ebp, %rax
movq 0x28(%rsp), %rdx
movq 0x30(%rsp), %rsi
subq %rdx, %rsi
movq %rsi, %rcx
sarq $0x4, %rcx
decq %rcx
cmpq %rax, %rcx
ja 0x6905
movq -0x20(%rdx,%rsi), %rax
shlq $0x4, %rcx
cmpq (%rdx,%rcx), %rax
jge 0x69cc
addq %rcx, %rdx
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x6afe
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x18(%rsp)
jmp 0x69cc
movq %rbx, %rdi
movq %r15, %rsi
callq 0x6314
movl 0x18(%r15), %eax
jmp 0x69b5
movq %rbx, %rdi
movq %r14, %rsi
callq 0x6314
movl 0x18(%r14), %eax
movl %eax, 0x18(%rbx)
jmp 0x6ad6
leaq 0x10(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x60e8
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
cmpq %rcx, %rax
setne %dl
addq $-0x10, %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x6a1c
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 0x69f4
movq 0x18(%rsp), %rax
cmpq 0x10(%rsp), %rax
je 0x6a37
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x103e8
jmp 0x6a91
movq (%r14), %rax
movl 0xc(%rax), %ecx
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x102ec
leaq 0x70(%rsp), %rdi
leaq 0x88(%rsp), %rsi
leaq 0xf(%rsp), %rcx
movl $0x1, %edx
callq 0x6e02
leaq 0x70(%rsp), %rsi
movq %rbx, %rdi
callq 0x103e8
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x6a91
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x6aa8
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x6abf
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x6ad6
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x6aed
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10(%rsp), %rdi
callq 0x6f34
jmp 0x69cc
movq %rax, %rbx
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x6b43
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
jmp 0x6b43
jmp 0x6b40
jmp 0x6b40
jmp 0x6b32
movq %rax, %rbx
jmp 0x6b5a
jmp 0x6b39
movq %rax, %rbx
jmp 0x6b88
jmp 0x6b40
movq %rax, %rbx
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x6b5a
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x6b71
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x6b88
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x6b9f
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rdi
callq 0x2240
nop