dph-base-0.6.0.1: Data/Array/Parallel/Base/Debug.hs
-- | Debugging infrastructure for the parallel arrays library.
module Data.Array.Parallel.Base.Debug
( check
, checkCritical
, checkLen
, checkSlice
, checkEq
, checkNotEmpty
, uninitialised)
where
import Data.Array.Parallel.Base.Config (debug, debugCritical)
-- | Throw an index-out-of-bounds error.
errorOfBounds :: String -> Int -> Int -> a
errorOfBounds loc n i
= error $ loc ++ ": Out of bounds "
++ "(vector length = " ++ show n
++ "; index = " ++ show i ++ ")"
-- | Throw a bad slice error.
errorBadSlice :: String -> Int -> Int -> Int -> a
errorBadSlice loc vecLen sliceStart sliceLen
= error $ loc ++ ": Bad slice "
++ "(vecLen = " ++ show vecLen
++ "; sliceStart = " ++ show sliceStart
++ "; sliceLen = " ++ show sliceLen ++ ")"
-- | Bounds check, enabled when `debug` = `True`.
--
-- The first integer is the length of the array, and the second
-- is the index. The second must be greater or equal to '0' and less than
-- the first integer. If the not then `error` with the `String`.
--
check :: String -> Int -> Int -> a -> a
check loc n i v
| debug
= if i >= 0 && i < n
then v
else errorOfBounds loc n i
| otherwise = v
{-# INLINE check #-}
-- | Bounds check, enabled when `debugCritical` = `True`.
--
-- This version is used to check operations that could corrupt the heap.
--
-- The first integer is the length of the array, and the second
-- is the index. The second must be greater or equal to '0' and less than
-- the first integer. If the not then `error` with the `String`.
--
checkCritical :: String -> Int -> Int -> a -> a
checkCritical loc n i v
| debugCritical
= if i >= 0 && i < n
then v
else errorOfBounds loc n i
| otherwise = v
{-# INLINE checkCritical #-}
-- | Length check, enabled when `debug` = `True`.
--
-- Check that the second integer is greater or equal to `0' and less or equal
-- than the first integer. If the not then `error` with the `String`.
--
checkLen :: String -> Int -> Int -> a -> a
checkLen loc n i v
| debug
= if i >= 0 && i <= n
then v
else errorOfBounds loc n i
| otherwise = v
{-# INLINE checkLen #-}
-- | Slice check, enable when `debug` = `True`.
--
-- The vector must contain at least `sliceStart` + `sliceLen` elements.
--
checkSlice :: String -> Int -> Int -> Int -> a -> a
checkSlice loc vecLen sliceStart sliceLen v
| debug
= if ( sliceStart >= 0 && sliceStart <= vecLen
&& sliceStart + sliceLen >= 0 && sliceStart + sliceLen <= vecLen )
then v
else errorBadSlice loc vecLen sliceStart sliceLen
| otherwise = v
{-# INLINE checkSlice #-}
-- | Equality check, enabled when `debug` = `True`.
--
-- The two `a` values must be equal, else `error`.
--
-- The first `String` gives the location of the error,
-- and the second some helpful message.
--
checkEq :: (Eq a, Show a) => String -> String -> a -> a -> b -> b
checkEq loc msg x y v
| debug
= if x == y
then v
else error $ loc ++ ": " ++ msg
++ " (first = " ++ show x
++ "; second = " ++ show y ++ ")"
| otherwise = v
{-# INLINE checkEq #-}
-- | Given an array length, check it is not zero.
checkNotEmpty :: String -> Int -> a -> a
checkNotEmpty loc n v
| debug
= if n /= 0
then v
else error $ loc ++ ": Empty array"
| otherwise = v
{-# INLINE checkNotEmpty #-}
-- | Throw an error saying something was not intitialised.
--
-- The `String` must contain a helpful message saying what module
-- the error occured in, and the possible reasons for it.
-- If not then a puppy dies at compile time.
--
uninitialised :: String -> a
uninitialised loc
= error $ loc ++ ": Touched an uninitialised value"