packages feed

rangeset-0.1.0.0: src/ghc/Data/RangeSet/Internal/Inserters.hs

{-# LANGUAGE BangPatterns, UnboxedTuples, Safe #-}
module Data.RangeSet.Internal.Inserters (module Data.RangeSet.Internal.Inserters) where

import Prelude

import Data.RangeSet.Internal.Types
import Data.RangeSet.Internal.SmartConstructors
import Data.RangeSet.Internal.Extractors

{-|
Inserts an range at the left-most position in the tree.
It *must* not overlap with any other range within the tree.
It *must* be /known/ not to exist within the tree.
-}
{-# INLINEABLE unsafeInsertL #-}
unsafeInsertL :: E -> E -> RangeSet a -> RangeSet a
unsafeInsertL !l !u = go
  where
    go :: RangeSet a -> RangeSet a
    go Tip = single l u
    go (Fork _ l' u' lt rt) = balanceL l' u' (go lt) rt

{-|
Inserts an range at the right-most position in the tree.
It *must* not overlap with any other range within the tree.
It *must* be /known/ not to exist within the tree.
-}
{-# INLINEABLE unsafeInsertR #-}
unsafeInsertR :: E -> E -> RangeSet a -> RangeSet a
unsafeInsertR !l !u = go
  where
    go :: RangeSet a -> RangeSet a
    go Tip = single l u
    go (Fork _ l' u' lt rt) = balanceR l' u' lt (go rt)

{-# INLINEABLE insertLAdj #-}
insertLAdj :: E -> E -> H -> E -> E -> RangeSet a -> RangeSet a -> RangeSet a
insertLAdj !l !u !th !tl !tu !tlt !trt = case minRange tl tu tlt of
  (# !l', _ #) | l' == succ u -> fuseL l th tl tu tlt trt
               | otherwise    -> balanceL tl tu (unsafeInsertL l u tlt) trt
  where
    {-# INLINEABLE fuseL #-}
    fuseL :: E -> H -> E -> E -> RangeSet a -> RangeSet a -> RangeSet a
    fuseL !l' !h !l !u lt rt = case lt of
      Tip -> Fork h l' u Tip rt
      Fork lh ll lu llt lrt  -> Fork h l u (fuseL l' lh ll lu llt lrt) rt

{-# INLINEABLE insertRAdj #-}
insertRAdj :: E -> E -> H -> E -> E -> RangeSet a -> RangeSet a -> RangeSet a
insertRAdj !l !u !th !tl !tu !tlt !trt = case maxRange tl tu trt of
  (# _, !u' #) | u' == pred l -> fuseR u th tl tu tlt trt
               | otherwise    -> balanceR tl tu tlt (unsafeInsertR l u trt)
  where
    {-# INLINEABLE fuseR #-}
    fuseR :: E -> H -> E -> E -> RangeSet a -> RangeSet a -> RangeSet a
    fuseR !u' !h !l !u lt rt = case rt of
      Tip -> Fork h l u' lt Tip
      Fork rh rl ru rlt rrt  -> Fork h l u lt (fuseR u' rh rl ru rlt rrt)