// File: 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
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rsi, -0x90(%rbp)
movq %rdx, -0x98(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rdi
callq 0xb1a0
movq -0x90(%rbp), %rsi
movq -0x88(%rbp), %rdi
callq 0x95e0
movq %rax, -0x28(%rbp)
leaq -0x2c(%rbp), %rdi
callq 0x9f60
movq -0x88(%rbp), %rdi
callq 0x8670
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x79(%rbp)
jne 0xadf5
movq -0x88(%rbp), %rdi
callq 0x86b0
movq %rax, -0x38(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x8710
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0xae01
jmp 0xaee4
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0xb1c0
movq %rax, -0x40(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq -0x90(%rbp), %rsi
movq %rax, -0xa0(%rbp)
leaq -0x44(%rbp), %rdi
callq 0x5a00
movq -0xa0(%rbp), %rdi
leaq -0x44(%rbp), %rsi
callq 0x88b0
testb $0x1, %al
jne 0xae46
jmp 0xae48
jmp 0xae67
leaq 0x939c(%rip), %rdi      # 0x141eb
leaq 0x9212(%rip), %rsi      # 0x14068
movl $0x120, %edx            # imm = 0x120
leaq 0x939d(%rip), %rcx      # 0x141ff
callq 0x3180
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
addq $0x4, %rsi
leaq -0x48(%rbp), %rdi
callq 0x5a00
movq -0x98(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x8980
testb $0x1, %al
jne 0xae96
jmp 0xae9b
jmp 0xb06b
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
movq -0x88(%rbp), %rax
addq $0x4, %rsi
movl 0x30(%rax), %edx
leaq -0x4c(%rbp), %rdi
callq 0xb260
movq -0x90(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
callq 0xb200
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x87f0
movq %rax, -0x58(%rbp)
jmp 0xaef0
movq -0x90(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
jmp 0xaef2
movq -0x88(%rbp), %rdi
callq 0x8740
movq %rax, -0x60(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x8710
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa1(%rbp)
jne 0xaf20
jmp 0xaf43
movq -0x98(%rbp), %rsi
leaq -0x64(%rbp), %rdi
callq 0x5a00
leaq -0x2c(%rbp), %rdi
leaq -0x64(%rbp), %rsi
callq 0x8980
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0xaf52
jmp 0xb030
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
leaq -0x68(%rbp), %rdi
callq 0x5a00
leaq -0x2c(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x88b0
testb $0x1, %al
jne 0xaf7a
jmp 0xafc8
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
movq -0x88(%rbp), %rax
movl 0x30(%rax), %edx
leaq -0x6c(%rbp), %rdi
callq 0xb330
movq -0x98(%rbp), %rsi
leaq -0x6c(%rbp), %rdi
callq 0xb2d0
movq %rax, -0xb0(%rbp)
movq -0x20(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x89a0
movq -0xb0(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, (%rax)
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
addq $0x4, %rsi
leaq -0x70(%rbp), %rdi
callq 0x5a00
movq -0x98(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x8980
testb $0x1, %al
jne 0xaff7
jmp 0xaff9
jmp 0xb06b
leaq -0x28(%rbp), %rdi
callq 0x87d0
movq %rax, %rsi
movq -0x88(%rbp), %rax
addq $0x4, %rsi
movl 0x30(%rax), %edx
leaq -0x74(%rbp), %rdi
callq 0xb260
movl -0x74(%rbp), %eax
movl %eax, -0x2c(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xa240
jmp 0xaef2
movq -0x98(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x5a00
leaq -0x2c(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x8980
testb $0x1, %al
jne 0xb053
jmp 0xb06b
movq -0x20(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x89a0
movq -0x98(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, (%rax)
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop