// File: /workspace/github_cpp_makefile_star2_O3/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, 0x8(%rsp)
movq %rsi, %r13
movq %rdi, %r15
movq %rcx, 0x10(%rsp)
movq %rcx, %rdi
callq 0x5cf4
movq 0x10(%r15), %rax
leaq 0x8(%r15), %rbp
movq %rbp, %r12
testq %rax, %rax
je 0x624d
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 0x6237
cmpq $0x0, 0x28(%r15)
je 0x62a7
cmpq 0x18(%r15), %r12
je 0x62a7
movq %r12, %rdi
callq 0x2250
movl (%r13), %ecx
cmpl %ecx, 0x20(%rax)
jae 0x638a
movl 0x24(%rax), %r14d
movq 0x8(%rsp), %rdx
movl (%rdx), %r13d
cmpl %r14d, %r13d
jbe 0x633d
addl 0x30(%r15), %r14d
jb 0x634c
cmpl %r14d, %ecx
cmoval %ecx, %r14d
movl %r14d, 0x4(%rsp)
movq %rax, %rdi
callq 0x2180
movq %rax, %r12
jmp 0x62b8
movl (%r13), %r14d
movl %r14d, 0x4(%rsp)
movq 0x8(%rsp), %rax
movl (%rax), %r13d
cmpq %rbp, %r12
je 0x6320
cmpl %r13d, %r14d
ja 0x6320
movl 0x20(%r12), %ebx
cmpl %ebx, %r14d
jae 0x62fb
subl 0x30(%r15), %ebx
jb 0x636b
movq 0x10(%rsp), %rdi
leaq 0x4(%rsp), %rsi
callq 0x5c8e
cmpl %ebx, %r13d
jae 0x62f1
movq 0x8(%rsp), %rcx
movl (%rcx), %ebx
movl %ebx, (%rax)
movq 0x8(%rsp), %rax
movl (%rax), %r13d
movl 0x24(%r12), %r14d
cmpl %r14d, %r13d
jbe 0x633d
addl 0x30(%r15), %r14d
jb 0x634c
movl %r14d, 0x4(%rsp)
movq %r12, %rdi
callq 0x2180
movq %rax, %r12
cmpq %rbp, %rax
jne 0x62bd
cmpl %r13d, %r14d
ja 0x633d
leaq 0x4(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x5c8e
movq 0x8(%rsp), %rcx
movl (%rcx), %ecx
movl %ecx, (%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1f1a(%rip), %rdi      # 0x826d
leaq 0x1d26(%rip), %rsi      # 0x8080
leaq 0x1f15(%rip), %rcx      # 0x8276
movl $0x1c, %edx
callq 0x2150
leaq 0x1f31(%rip), %rdi      # 0x82a3
leaq 0x1d07(%rip), %rsi      # 0x8080
leaq 0x1f29(%rip), %rcx      # 0x82a9
movl $0x1e, %edx
callq 0x2150
leaq 0x1e72(%rip), %rdi      # 0x8203
leaq 0x1ce8(%rip), %rsi      # 0x8080
leaq 0x1e78(%rip), %rcx      # 0x8217
movl $0x120, %edx            # imm = 0x120
callq 0x2150
nop