///|
pub(all) struct RouteBitSet {
  mut w0 : UInt
  mut w1 : UInt
  mut w2 : UInt
  mut w3 : UInt
  mut w4 : UInt
  mut w5 : UInt
  mut w6 : UInt
  mut w7 : UInt
} derive(Eq, Debug)

///|
pub fn RouteBitSet::empty() -> RouteBitSet {
  { w0: 0U, w1: 0U, w2: 0U, w3: 0U, w4: 0U, w5: 0U, w6: 0U, w7: 0U }
}

///|
pub fn RouteBitSet::set(self : RouteBitSet, bit : Int) -> Unit {
  if bit < 0 || bit >= 256 {
    return
  }
  let word_idx = bit / 32
  let bit_offset = bit % 32
  let mask = 1U << bit_offset
  match word_idx {
    0 => self.w0 = self.w0 | mask
    1 => self.w1 = self.w1 | mask
    2 => self.w2 = self.w2 | mask
    3 => self.w3 = self.w3 | mask
    4 => self.w4 = self.w4 | mask
    5 => self.w5 = self.w5 | mask
    6 => self.w6 = self.w6 | mask
    7 => self.w7 = self.w7 | mask
    _ => ()
  }
}

///|
pub fn RouteBitSet::clear(self : RouteBitSet, bit : Int) -> Unit {
  if bit < 0 || bit >= 256 {
    return
  }
  let word_idx = bit / 32
  let bit_offset = bit % 32
  let mask = (1U << bit_offset).lnot()
  match word_idx {
    0 => self.w0 = self.w0 & mask
    1 => self.w1 = self.w1 & mask
    2 => self.w2 = self.w2 & mask
    3 => self.w3 = self.w3 & mask
    4 => self.w4 = self.w4 & mask
    5 => self.w5 = self.w5 & mask
    6 => self.w6 = self.w6 & mask
    7 => self.w7 = self.w7 & mask
    _ => ()
  }
}

///|
pub fn RouteBitSet::get(self : RouteBitSet, bit : Int) -> Bool {
  if bit < 0 || bit >= 256 {
    return false
  }
  let word_idx = bit / 32
  let bit_offset = bit % 32
  let mask = 1U << bit_offset
  match word_idx {
    0 => (self.w0 & mask) != 0U
    1 => (self.w1 & mask) != 0U
    2 => (self.w2 & mask) != 0U
    3 => (self.w3 & mask) != 0U
    4 => (self.w4 & mask) != 0U
    5 => (self.w5 & mask) != 0U
    6 => (self.w6 & mask) != 0U
    7 => (self.w7 & mask) != 0U
    _ => false
  }
}

///|
pub fn RouteBitSet::intersects(self : RouteBitSet, other : RouteBitSet) -> Bool {
  (self.w0 & other.w0) != 0U ||
  (self.w1 & other.w1) != 0U ||
  (self.w2 & other.w2) != 0U ||
  (self.w3 & other.w3) != 0U ||
  (self.w4 & other.w4) != 0U ||
  (self.w5 & other.w5) != 0U ||
  (self.w6 & other.w6) != 0U ||
  (self.w7 & other.w7) != 0U
}

///|
pub fn RouteBitSet::union_with(self : RouteBitSet, other : RouteBitSet) -> Unit {
  self.w0 = self.w0 | other.w0
  self.w1 = self.w1 | other.w1
  self.w2 = self.w2 | other.w2
  self.w3 = self.w3 | other.w3
  self.w4 = self.w4 | other.w4
  self.w5 = self.w5 | other.w5
  self.w6 = self.w6 | other.w6
  self.w7 = self.w7 | other.w7
}

///|
pub fn RouteBitSet::is_empty(self : RouteBitSet) -> Bool {
  self.w0 == 0U &&
  self.w1 == 0U &&
  self.w2 == 0U &&
  self.w3 == 0U &&
  self.w4 == 0U &&
  self.w5 == 0U &&
  self.w6 == 0U &&
  self.w7 == 0U
}

///|
pub fn RouteBitSet::count_ones(self : RouteBitSet) -> Int {
  let mut count = 0
  for i = 0; i < 256; i = i + 1 {
    if self.get(i) {
      count = count + 1
    }
  }
  count
}