twee-lib-2.1: src/Data/Primitive/Checked.hs
-- | A helper module for array bounds checking.
module Data.Primitive.Checked where
import Data.Primitive(Prim, sizeOf)
-- | A type class of things which have a size (e.g., arrays).
class Sized a where
-- | Read the size of the thing.
size :: a -> Int
-- | Check that a single access is in bounds.
{-# INLINE check #-}
check :: Sized a => a -> Int -> b -> b
check arr n x
| n >= 0 && n < size arr = x
| otherwise = error "out-of-bounds array access"
-- | Check that a range of accesses is in bounds.
-- The range is inclusive.
{-# INLINE range #-}
range :: Sized a => a -> Int -> Int -> b -> b
range arr n len x
| len < 0 = error "array slice has negative length"
| len == 0 = x
| otherwise =
check arr n $
check arr (n+len-1) $ x
-- | Check that a single access is in bounds.
-- The index accessed is computed by multiplying by the size
-- of the first argument.
{-# INLINE checkPrim #-}
checkPrim :: (Sized a, Prim b) => b -> a -> Int -> c -> c
checkPrim x arr n res =
range arr (n*sizeOf x) (sizeOf x) res
-- | Check that a range of accesses is in bounds.
-- The range is inclusive.
-- The index accessed is computed by multiplying by the size
-- of the first argument.
{-# INLINE rangePrim #-}
rangePrim :: (Sized a, Prim b) => b -> a -> Int -> Int -> c -> c
rangePrim x arr n len res =
range arr (n*sizeOf x) (len*sizeOf x) res