-- | One step in inserting a new task into a priority-sorted array. If
-- the new task should go before the existing task, then exchange the
-- two; afterward, the existing task becomes a "new" task to insert
-- before the next element in the array.
shiftUp :: Def ('[ Ref s0 ('Stored Uint8)
                 , Ref s1 ('Stored Uint32), Ref s2 ('Stored Uint8)
                 , Ref s3 ('Stored Uint32), Ref s4 ('Stored Uint8)
                 ] ':-> IBool)
shiftUp = proc "shift_task_up" $ \ insert_position new_prio new_task current_prio current_task -> body $ do
  new <- deref new_prio
  when (new ==? maxBound) $ ret true
  current <- deref current_prio
  assert (new /=? current)
  ifte_ (new >? current) (insert_position %= (+ 1)) $ do
    temp_task <- deref current_task
    refCopy current_prio new_prio
    refCopy current_task new_task
    store new_prio current
    store new_task temp_task
  ret false

-- | One step in removing an old task from a sorted array. When we reach
-- the target element of the array, pull the next element down to this
-- one, overwriting it; afterward, the new deletion target is the
-- now-duplicated task that we just pulled forward.
shiftUp :: Def ('[ Ref s0 ('Stored Uint8)
                 , Ref s1 ('Stored Uint32), Ref s2 ('Stored Uint8)
                 , Ref s3 ('Stored Uint32), Ref s4 ('Stored Uint8)
                 ] ':-> IBool)
shiftUp = proc "shift_task_up" $ \ insert_position new_prio new_task current_prio current_task -> body $ do
  new <- deref new_prio
  when (new ==? maxBound) $ ret true
  current <- deref current_prio
  assert (new /=? current)
  ifte_ (new >? current) (insert_position %= (+ 1)) $ do
    temp_task <- deref current_task
    refCopy current_prio new_prio
    refCopy current_task new_task
    store new_prio current
    store new_task temp_task
  ret false

-- | One step in removing an old task from a sorted array. When we reach
-- the target element of the array, pull the next element down to this
-- one, overwriting it; afterward, the new deletion target is the
-- now-duplicated task that we just pulled forward.
shiftUp = proc "shift_task_up" $ \ insert_position new_prio new_task current_prio current_task -> body $ do
  new <- deref new_prio
  when (new ==? maxBound) $ ret true
  current <- deref current_prio
  assert (new /=? current)
  ifte_ (new >? current) (insert_position %= (+ 1)) $ do
    temp_task <- deref current_task
    refCopy current_prio new_prio
    refCopy current_task new_task
    store new_prio current
    store new_task temp_task
  ret false

-- | One step in removing an old task from a sorted array. When we reach
-- the target element of the array, pull the next element down to this
-- one, overwriting it; afterward, the new deletion target is the
-- now-duplicated task that we just pulled forward.