hsc3-server-0.3.0: Sound/SC3/Server/Allocator/Range.hs
module Sound.SC3.Server.Allocator.Range (
Range
, range
, sized
, empty
, begin
, end
, last
, size
, null
, toList
-- *Interval operations
, within
, adjoins
, overlaps
, contains
, split
, join
) where
import Control.DeepSeq (NFData(..))
import Prelude hiding (last, null)
-- | Model intervals [begin, end[
data Range a = Range {
begin :: !a
, end :: !a
} deriving (Eq, Show)
instance NFData a => NFData (Range a) where
rnf (Range x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
mkRange :: a -> a -> Range a
mkRange a b = Range a b
range :: Ord a => a -> a -> Range a
range a b | a <= b = mkRange a b
| otherwise = mkRange b a
sized :: Num a => Int -> a -> Range a
sized n a = mkRange a (a + fromIntegral n)
empty :: Num a => a -> Range a
empty a = mkRange a a
last :: Enum a => Range a -> a
last = pred . end
size :: Integral a => Range a -> Int
size a = fromIntegral (end a - begin a)
null :: Eq a => Range a -> Bool
null a = begin a == end a
toList :: Enum a => Range a -> [a]
toList a = [begin a..last a]
within :: Ord a => a -> Range a -> Bool
x `within` a = x >= begin a && x < end a
adjoins :: Eq a => Range a -> Range a -> Bool
a `adjoins` b = (end a == begin b) || (end b == begin a)
overlaps :: Ord a => Range a -> Range a -> Bool
a `overlaps` b = (end a > begin b) || (end b > begin a)
contains :: Ord a => Range a -> Range a -> Bool
a `contains` b = begin b >= begin a && end b <= end a
split :: Integral a => Int -> Range a -> (Range a, Range a)
split n r@(Range l u)
| n <= 0 = (empty l, r)
| n >= size r = (r, empty u)
| otherwise = (mkRange l (l+k), mkRange (l+k) u)
where k = fromIntegral n
join :: Ord a => Range a -> Range a -> Range a
join a b = mkRange (min (begin a) (begin b)) (max (end a) (end b))