// File: /workspace/github_cpp_makefile_star2_O2/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 0x4aa6
movq %r15, %rdi
movq %r13, %rsi
callq 0x4d4e
movq %rax, %r12
cmpq $0x0, 0x28(%r15)
je 0x516d
cmpq 0x18(%r15), %r12
je 0x516d
movq %r12, %rdi
callq 0x2260
movq %rax, %r12
movl 0x20(%rax), %eax
cmpl (%r13), %eax
jae 0x521c
movl (%rbx), %eax
cmpl 0x24(%r12), %eax
jbe 0x520d
movq %r12, %rsi
addq $0x24, %rsi
movl 0x30(%r15), %edx
leaq 0xc(%rsp), %rbp
movq %rbp, %rdi
callq 0x52a6
movl (%rbp), %r14d
movl (%r13), %eax
cmpl %r14d, %eax
cmoval %eax, %r14d
movl %r14d, 0x8(%rsp)
movq %r12, %rdi
callq 0x2190
movq %rax, %r12
jmp 0x5176
movl (%r13), %r14d
movl %r14d, 0x8(%rsp)
leaq 0x8(%r15), %rbp
leaq 0xc(%rsp), %r13
movl (%rbx), %eax
cmpq %rbp, %r12
je 0x51f5
cmpl %eax, %r14d
ja 0x51f5
cmpl 0x20(%r12), %r14d
jae 0x51c6
leaq 0x20(%r12), %rsi
movl 0x30(%r15), %edx
movq %r13, %rdi
callq 0x52ce
movl (%rbx), %eax
cmpl 0xc(%rsp), %eax
movq %r13, %r14
cmovbq %rbx, %r14
movq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x4a58
movl (%r14), %ecx
movl %ecx, (%rax)
movl (%rbx), %eax
cmpl 0x24(%r12), %eax
jbe 0x520d
leaq 0x24(%r12), %rsi
movl 0x30(%r15), %edx
movq %r13, %rdi
callq 0x52a6
movl 0xc(%rsp), %r14d
movl %r14d, 0x8(%rsp)
movq %r12, %rdi
callq 0x2190
movq %rax, %r12
jmp 0x517f
cmpl %eax, %r14d
ja 0x520d
leaq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x4a58
movl (%rbx), %ecx
movl %ecx, (%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1fc4(%rip), %rdi      # 0x71e7
leaq 0x1e3a(%rip), %rsi      # 0x7064
leaq 0x1fca(%rip), %rcx      # 0x71fb
movl $0x120, %edx            # imm = 0x120
callq 0x2170
nop