// File: /workspace/github_cpp_makefile_star2_O1/BUSEC[P]RPKI_Downgrade_Detector/./exp.cpp
// Function: IntervalList<IPAddr>::subtractFromInterval(IPAddr, IPAddr, IntervalList<IPAddr>&)
void subtractFromInterval (T begin, T end, IntervalList<T> & ret) {
    ret.clear();    

    typename map<T,T>::iterator iter = m.lower_bound(begin);

    // iter now points to the first interval whose start is at or after begin
    // we need to also consider the previous interval, if it exists, because its end may be after begin
    T current;
    if (!m.empty() && iter!=m.begin()) {
      iter--;

      assert(iter->first < begin); //iter is previous of the lowerbound so this should always be true
      
      if (  end <=iter->second  ) return; //if true then begin-end contained completely within interval, ret should be empty

      // "if (  end <=iter->second  ) return;" prevents an overflow  in this line since
      // since we know end>iter->second at this point, and we work in multiples
      // of increment, so iter->second must be at least increment away from overflowing
      current = max(begin, iter->second+increment);
      iter++;
    }
    else current = begin; 
    // at any given point we have added to ret everything from begin (inclusive) to current (exclusive) that isn't covered by intervals in T
    // at any given point, iter->first is at or after current
    while (iter != m.end() && current <= end ) {

      // This line will not underflow since if current<iter->first then iter->first >= increment
      if (current<iter->first){
        ret.m[current]=min(iter->first-increment, end);
      }

      // We want to now move current to the right of the interval
      // [iter->first,iter->second].
      // However, we cannot do that if iter->second is at max value of T,
      // because current would overflow.
      // To avoid this problem, we observe that we are
      // done adding intervals if end<=iter->second, so we can return.
      // And  if end>iter>second, then iter-<second+increment cannot overflow.
      if (end<=iter->second) return;
      else current=iter->second+increment; // set current to be just beyond the interval

      ++iter; // advance the interval
    }
    if (current<=end) // no more intervals -- add everything until the end
      ret.m[current]=end;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movq %rsi, %r13
movq %rdi, %r15
movq %rcx, 0x10(%rsp)
movq %rcx, %rdi
callq 0x5f8a
movq 0x10(%r15), %rax
leaq 0x8(%r15), %rbp
movq %rbp, %r12
testq %rax, %rax
je 0x64cd
movl (%r13), %ecx
movq %rbp, %r12
xorl %edx, %edx
cmpl %ecx, 0x20(%rax)
setb %dl
cmovaeq %rax, %r12
movq 0x10(%rax,%rdx,8), %rax
testq %rax, %rax
jne 0x64b7
movl $0x0, 0xc(%rsp)
cmpq $0x0, 0x28(%r15)
je 0x6522
cmpq 0x18(%r15), %r12
je 0x6522
movq %r12, %rdi
callq 0x2250
movl (%r13), %ecx
cmpl %ecx, 0x20(%rax)
jae 0x65f4
movl 0x24(%rax), %edx
cmpl %edx, (%rbx)
jbe 0x65a7
addl 0x30(%r15), %edx
jb 0x65b6
cmpl %edx, %ecx
cmoval %ecx, %edx
movl %edx, 0xc(%rsp)
movq %rax, %rdi
callq 0x2180
movq %rax, %r12
jmp 0x652a
movl (%r13), %eax
movl %eax, 0xc(%rsp)
cmpq %rbp, %r12
je 0x658c
movl (%rbx), %r14d
movl 0xc(%rsp), %eax
cmpl %r14d, %eax
ja 0x658c
movl 0x20(%r12), %r13d
cmpl %r13d, %eax
jae 0x6569
subl 0x30(%r15), %r13d
jb 0x65d5
movq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0x5f26
cmpl %r13d, %r14d
jae 0x6566
movl (%rbx), %r13d
movl %r13d, (%rax)
movl 0x24(%r12), %eax
cmpl %eax, (%rbx)
jbe 0x65a7
addl 0x30(%r15), %eax
jb 0x65b6
movl %eax, 0xc(%rsp)
movq %r12, %rdi
callq 0x2180
movq %rax, %r12
cmpq %rbp, %rax
jne 0x652f
movl 0xc(%rsp), %eax
cmpl (%rbx), %eax
ja 0x65a7
leaq 0xc(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x5f26
movl (%rbx), %ecx
movl %ecx, (%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2cb0(%rip), %rdi      # 0x926d
leaq 0x2abc(%rip), %rsi      # 0x9080
leaq 0x2cab(%rip), %rcx      # 0x9276
movl $0x1c, %edx
callq 0x2150
leaq 0x2cc7(%rip), %rdi      # 0x92a3
leaq 0x2a9d(%rip), %rsi      # 0x9080
leaq 0x2cbf(%rip), %rcx      # 0x92a9
movl $0x1e, %edx
callq 0x2150
leaq 0x2c08(%rip), %rdi      # 0x9203
leaq 0x2a7e(%rip), %rsi      # 0x9080
leaq 0x2c0e(%rip), %rcx      # 0x9217
movl $0x120, %edx            # imm = 0x120
callq 0x2150
nop