module Data.RangeMin.Common.Vector ((!), vec, unsafeVec, G.stream, streamRI, unsafeBackpermute', streamM, fillSlice,
buildSliced) where
import Control.Monad.ST (ST)
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Fusion.Stream as S
import qualified Data.Vector.Fusion.Stream.Monadic as SM
import Data.Vector.Fusion.Util
streamM :: (G.Vector v a, Monad m) => v a -> SM.Stream m a
streamM = S.liftStream . G.stream
(!) :: G.Vector v a => v a -> Int -> a
(!) = G.unsafeIndex
fillSlice :: G.Vector v a => Int -> Int -> G.Mutable v s a -> SM.Stream (ST s) a -> ST s (v a)
fillSlice !i !n !arr stream = do
let slice = GM.unsafeSlice i n arr
G.unsafeFreeze =<< GM.fill slice stream
buildSliced :: G.Vector v a => Int -> Int -> Maybe a -> v a ->
(Int -> v a -> v a) -> v a
buildSliced !rows !cols !def initStream mkStream = G.create $ do
let !size = rows * cols
!arr <- maybe (GM.unsafeNew size) (GM.unsafeNewWith size) def
!ini <- fillSlice 0 cols arr (streamM initStream)
let filler !z !off !prev
| z < rows = do
!next <- fillSlice off cols arr (streamM (mkStream z prev))
filler (z+1) (off+cols) next
| otherwise = return ()
filler 1 cols ini
return arr
unsafeVec :: G.Vector v a => Int -> S.Stream (Int, a) -> v a
unsafeVec !n str = G.create $ do
vec <- GM.unsafeNew n
GM.unsafeUpdate vec str
return vec
vec :: G.Vector v a => Int -> S.Stream (Int, a) -> v a
vec !n str = G.create $ do
vec <- GM.new n
GM.update vec str
return vec
unsafeBackpermute' :: (G.Vector v a, G.Vector v' Int) => v a -> v' Int -> v a
unsafeBackpermute' !v is = G.unstream
$ S.unbox
$ S.map (G.unsafeIndexM v)
$ G.stream is
streamRI :: G.Vector v a => v a -> S.Stream (Int, a)
streamRI !v = S.unfoldrN n get n
where
!n = G.length v
get 0 = Nothing
get i = let !i' = i1
in
case G.basicUnsafeIndexM v i' of Box x -> Just ((i', x), i')