module Data.Array.Repa.Series.Vector ( Vector , length , new , read , write , take -- * Conversions , fromUnboxed , toUnboxed) where import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as UM import Data.Vector.Unboxed (Unbox) import System.IO.Unsafe import GHC.Exts import Prelude hiding (length, read, take) -- | Abstract mutable vector type that supports random access indexing. -- -- Use `fromUnboxed` and `toUnboxed` to convert to and from regular -- immutable unboxed vectors. data Vector a = Vector { vectorLength :: Int# , vectorData :: !(UM.IOVector a) } instance (Unbox a, Show a) => Show (Vector a) where show vec = unsafePerformIO $ do fvec <- U.unsafeFreeze (vectorData vec) return $ show fvec -- | Take the length of a vector. length :: Vector a -> Int# length vec = vectorLength vec {-# INLINE length #-} -- | Create a new vector of the given length. new :: Unbox a => Int# -> IO (Vector a) new len = do vec <- UM.new (I# len) return $ Vector len vec {-# INLINE new #-} -- | Read a value from a vector. read :: Unbox a => Vector a -> Int# -> IO a read vec ix = UM.unsafeRead (vectorData vec) (I# ix) {-# INLINE read #-} -- | Write a value into a vector. write :: Unbox a => Vector a -> Int# -> a -> IO () write vec ix val = UM.unsafeWrite (vectorData vec) (I# ix) val {-# INLINE write #-} -- | Take the first n elements of a vector take :: Unbox a => Int# -> Vector a -> IO (Vector a) take len (Vector _ mvec) = do return $ Vector len $ UM.unsafeTake (I# len) mvec {-# INLINE take #-} -- | O(1). Convert from an Unboxed vector. fromUnboxed :: Unbox a => U.Vector a -> IO (Vector a) fromUnboxed vec = do let !(I# len) = U.length vec mvec <- U.unsafeThaw vec return $ Vector len mvec {-# INLINE fromUnboxed #-} -- | O(1). Convert to an Unboxed vector. toUnboxed :: Unbox a => Vector a -> IO (U.Vector a) toUnboxed (Vector _ mvec) = U.unsafeFreeze mvec {-# INLINE toUnboxed #-}