module Data.RangeMin.Common.Types.IPVector (IP(..), IPVector, IPMVector, unzipIPM) where
import Control.Monad
import Data.RangeMin.Common.ST
import Data.Primitive
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Primitive as P
data IP = IP !Int !Int
data IPVector a = IPVector !Int !Int !ByteArray
!ByteArray
data IPMVector s a = IPMVector !Int !Int !(MutableByteArray s)
!(MutableByteArray s)
type instance G.Mutable IPVector = IPMVector
unzipM :: IPMVector s IP -> (P.MVector s Int, P.MVector s Int)
unzipM (IPMVector i n xs ys) = (P.MVector i n xs, P.MVector i n ys)
unzipIPM :: (forall s . ST s (IPMVector s IP)) -> (P.Vector Int, P.Vector Int)
unzipIPM mvec = inlineRunST $ do
(!xs, !ys) <- unzipM `liftM` mvec
liftM2 (,) (G.unsafeFreeze xs) (G.unsafeFreeze ys)
instance G.Vector IPVector IP where
unsafeFreeze (IPMVector i n xs ys) = do
xs' <- unsafeFreezeByteArray xs
ys' <- unsafeFreezeByteArray ys
return (IPVector i n xs' ys')
basicLength (IPVector _ n _ _) = n
basicUnsafeSlice i k (IPVector j _ xs ys) = IPVector (i + j) k xs ys
basicUnsafeIndexM (IPVector i _ xs ys) j =
return (IP (indexByteArray xs k) (indexByteArray ys k))
where !k = i + j
basicUnsafeCopy (IPMVector i n dst1 dst2) (IPVector j _ src1 src2) = do
let !sz = sizeOf (1 :: Int)
memcpyByteArray' dst1 (i * sz) src1 (j * sz) (n * sz)
memcpyByteArray' dst2 (i * sz) src2 (j * sz) (n * sz)
elemseq _ = seq
instance GM.MVector IPMVector IP where
basicLength (IPMVector _ n _ _) = n
basicUnsafeSlice !k !m (IPMVector i _ xs ys) =
IPMVector (i + k) m xs ys
basicOverlaps (IPMVector i m xs1 ys1) (IPMVector j n xs2 ys2) =
(sameMutableByteArray xs1 xs2 || sameMutableByteArray ys1 ys2) && (between i j (j+n) || between j i (i+m))
where between x y z = x >= y && x < z
basicUnsafeNew !n = do
let m = n * sizeOf (0 :: Int)
liftM2 (IPMVector 0 n) (newByteArray m) (newByteArray m)
basicUnsafeRead (IPMVector i _ xs ys) j = do
let !k = i + j
liftM2 IP (readByteArray xs k) (readByteArray ys k)
basicUnsafeWrite (IPMVector i _ xs ys) j (IP x y) = do
let !k = i + j
writeByteArray xs k x
writeByteArray ys k y
basicClear _ = return ()
basicUnsafeCopy (IPMVector i n dst1 dst2) (IPMVector j _ src1 src2) = do
let !sz = sizeOf (0 :: Int)
memcpyByteArray dst1 (i * sz) src1 (j * sz) (n * sz)
memcpyByteArray dst2 (i * sz) src2 (j * sz) (n * sz)