module Data.Array.Repa.Repr.Vector
        ( V, Array (..)
        , computeVectorS,  computeVectorP
        , fromListVector
        , fromVector
        , toVector)
where
import Data.Array.Repa.Shape
import Data.Array.Repa.Base
import Data.Array.Repa.Eval
import qualified Data.Vector            as V
import qualified Data.Vector.Mutable    as VM
import Control.Monad

-- | Arrays represented as boxed vectors.
--
--   This representation should only be used when your element type doesn't
--   have an `Unbox` instsance. If it does, then use the Unboxed `U`
--   representation will be faster.
data V
        
-- | Read elements from a boxed vector array.
instance Source V a where
 data Array V sh a
        = AVector !sh !(V.Vector a)

 linearIndex :: Array V sh a -> Int -> a
linearIndex (AVector _ vec) Int
ix
        = Vector a
vec Vector a -> Int -> a
forall a. Vector a -> Int -> a
V.! Int
ix
 {-# INLINE linearIndex #-}

 unsafeLinearIndex :: Array V sh a -> Int -> a
unsafeLinearIndex (AVector _ vec) Int
ix
        = Vector a
vec Vector a -> Int -> a
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
ix
 {-# INLINE unsafeLinearIndex #-}

 extent :: Array V sh a -> sh
extent (AVector sh _)
        = sh
sh
 {-# INLINE extent #-}

 deepSeqArray :: Array V sh a -> b -> b
deepSeqArray (AVector sh vec) b
x 
  = sh
sh sh -> b -> b
forall sh a. Shape sh => sh -> a -> a
`deepSeq` Vector a
vec Vector a -> b -> b
`seq` b
x
 {-# INLINE deepSeqArray #-}


deriving instance (Show sh, Show e)
        => Show (Array V sh e)

deriving instance (Read sh, Read e)
        => Read (Array V sh e)


-- Fill -----------------------------------------------------------------------
-- | Filling of boxed vector arrays.
instance Target V e where
 data MVec V e 
  = MVector (VM.IOVector e)

 newMVec :: Int -> IO (MVec V e)
newMVec Int
n
  = (IOVector e -> MVec V e) -> IO (IOVector e) -> IO (MVec V e)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM IOVector e -> MVec V e
forall e. IOVector e -> MVec V e
MVector (Int -> IO (MVector (PrimState IO) e)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> m (MVector (PrimState m) a)
VM.new Int
n)
 {-# INLINE newMVec #-}

 unsafeWriteMVec :: MVec V e -> Int -> e -> IO ()
unsafeWriteMVec (MVector v) Int
ix
  = MVector (PrimState IO) e -> Int -> e -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
VM.unsafeWrite IOVector e
MVector (PrimState IO) e
v Int
ix
 {-# INLINE unsafeWriteMVec #-}

 unsafeFreezeMVec :: sh -> MVec V e -> IO (Array V sh e)
unsafeFreezeMVec sh
sh (MVector mvec)     
  = do  Vector e
vec     <- MVector (PrimState IO) e -> IO (Vector e)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze IOVector e
MVector (PrimState IO) e
mvec
        Array V sh e -> IO (Array V sh e)
forall (m :: * -> *) a. Monad m => a -> m a
return  (Array V sh e -> IO (Array V sh e))
-> Array V sh e -> IO (Array V sh e)
forall a b. (a -> b) -> a -> b
$  sh -> Vector e -> Array V sh e
forall sh a. sh -> Vector a -> Array V sh a
AVector sh
sh Vector e
vec
 {-# INLINE unsafeFreezeMVec #-}

 deepSeqMVec :: MVec V e -> a -> a
deepSeqMVec !MVec V e
_vec a
x
  = a
x
 {-# INLINE deepSeqMVec #-}

 touchMVec :: MVec V e -> IO ()
touchMVec MVec V e
_ 
  = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
 {-# INLINE touchMVec #-}


-- Conversions ----------------------------------------------------------------
-- | Sequential computation of array elements.
--
--   * This is an alias for `compute` with a more specific type.
--
computeVectorS
        :: Load r1 sh e
        => Array r1 sh e -> Array V sh e
computeVectorS :: Array r1 sh e -> Array V sh e
computeVectorS   = Array r1 sh e -> Array V sh e
forall r1 sh e r2.
(Load r1 sh e, Target r2 e) =>
Array r1 sh e -> Array r2 sh e
computeS
{-# INLINE computeVectorS #-}


-- | Parallel computation of array elements.
computeVectorP
        :: (Load r1 sh e, Monad m)
        => Array r1 sh e -> m (Array V sh e)
computeVectorP :: Array r1 sh e -> m (Array V sh e)
computeVectorP   = Array r1 sh e -> m (Array V sh e)
forall r1 sh e r2 (m :: * -> *).
(Load r1 sh e, Target r2 e, Source r2 e, Monad m) =>
Array r1 sh e -> m (Array r2 sh e)
computeP
{-# INLINE computeVectorP #-}


-- | O(n). Convert a list to a boxed vector array.
--
--   * This is an alias for `fromList` with a more specific type.
--
fromListVector :: Shape sh => sh -> [a] -> Array V sh a
fromListVector :: sh -> [a] -> Array V sh a
fromListVector  = sh -> [a] -> Array V sh a
forall sh r e. (Shape sh, Target r e) => sh -> [e] -> Array r sh e
fromList
{-# INLINE fromListVector #-}


-- | O(1). Wrap a boxed vector as an array.
fromVector :: sh -> V.Vector e -> Array V sh e
fromVector :: sh -> Vector e -> Array V sh e
fromVector sh
sh Vector e
vec
        = sh -> Vector e -> Array V sh e
forall sh a. sh -> Vector a -> Array V sh a
AVector sh
sh Vector e
vec
{-# INLINE fromVector #-}


-- | O(1). Unpack a boxed vector from an array.
toVector   :: Array V sh e -> V.Vector e
toVector :: Array V sh e -> Vector e
toVector (AVector _ vec)
        = Vector e
vec
{-# INLINE toVector #-}