{-# LANGUAGE Rank2Types #-}
module Data.StorableVector.ST.Strict (
Vector,
new,
new_,
read,
write,
modify,
maybeRead,
maybeWrite,
maybeModify,
unsafeRead,
unsafeWrite,
unsafeModify,
freeze,
unsafeFreeze,
thaw,
length,
runSTVector,
mapST,
mapSTLazy,
) where
import Data.StorableVector.ST.Private
(Vector(SV), create, unsafeCreate, unsafeToVector, )
import qualified Data.StorableVector.Base as V
import qualified Data.StorableVector as VS
import qualified Data.StorableVector.Lazy as VL
import Control.Monad.ST.Strict (ST, runST, )
import Foreign.Ptr (Ptr, )
import Foreign.ForeignPtr (withForeignPtr, )
import Foreign.Storable (Storable(peek, poke))
import Foreign.Marshal.Array (advancePtr, copyArray, )
import qualified System.Unsafe as Unsafe
import qualified Data.Traversable as Traversable
import Data.Maybe.HT (toMaybe, )
import Data.Maybe (isJust, )
import Prelude hiding (read, length, )
{-# INLINE new #-}
new :: (Storable e) =>
Int -> e -> ST s (Vector s e)
new :: forall e s. Storable e => Int -> e -> ST s (Vector s e)
new Int
n e
x =
forall a s.
Storable a =>
Int -> (Ptr a -> IO ()) -> ST s (Vector s a)
unsafeCreate Int
n forall a b. (a -> b) -> a -> b
$
let {-# INLINE go #-}
go :: t -> Ptr e -> IO ()
go t
m Ptr e
p =
if t
mforall a. Ord a => a -> a -> Bool
>t
0
then forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr e
p e
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> t -> Ptr e -> IO ()
go (forall a. Enum a => a -> a
pred t
m) (forall a. Storable a => Ptr a -> Ptr a
V.incPtr Ptr e
p)
else forall (m :: * -> *) a. Monad m => a -> m a
return ()
in forall {t}. (Ord t, Num t, Enum t) => t -> Ptr e -> IO ()
go Int
n
{-# INLINE new_ #-}
new_ :: (Storable e) =>
Int -> ST s (Vector s e)
new_ :: forall e s. Storable e => Int -> ST s (Vector s e)
new_ Int
n =
forall a s.
Storable a =>
Int -> (Ptr a -> IO ()) -> ST s (Vector s a)
unsafeCreate Int
n (forall a b. a -> b -> a
const (forall (m :: * -> *) a. Monad m => a -> m a
return ()))
{-# INLINE read #-}
read :: (Storable e) =>
Vector s e -> Int -> ST s e
read :: forall e s. Storable e => Vector s e -> Int -> ST s e
read Vector s e
v Int
n =
forall e s a.
Storable e =>
String -> Vector s e -> Int -> ST s a -> ST s a
access String
"read" Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> ST s e
unsafeRead Vector s e
v Int
n
{-# INLINE write #-}
write :: (Storable e) =>
Vector s e -> Int -> e -> ST s ()
write :: forall e s. Storable e => Vector s e -> Int -> e -> ST s ()
write Vector s e
v Int
n e
x =
forall e s a.
Storable e =>
String -> Vector s e -> Int -> ST s a -> ST s a
access String
"write" Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> e -> ST s ()
unsafeWrite Vector s e
v Int
n e
x
{-# INLINE modify #-}
modify :: (Storable e) =>
Vector s e -> Int -> (e -> e) -> ST s ()
modify :: forall e s. Storable e => Vector s e -> Int -> (e -> e) -> ST s ()
modify Vector s e
v Int
n e -> e
f =
forall e s a.
Storable e =>
String -> Vector s e -> Int -> ST s a -> ST s a
access String
"modify" Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> (e -> e) -> ST s ()
unsafeModify Vector s e
v Int
n e -> e
f
{-# INLINE access #-}
access :: (Storable e) =>
String -> Vector s e -> Int -> ST s a -> ST s a
access :: forall e s a.
Storable e =>
String -> Vector s e -> Int -> ST s a -> ST s a
access String
name (SV ForeignPtr e
_v Int
l) Int
n ST s a
act =
if Int
0forall a. Ord a => a -> a -> Bool
<=Int
n Bool -> Bool -> Bool
&& Int
nforall a. Ord a => a -> a -> Bool
<Int
l
then ST s a
act
else forall a. HasCallStack => String -> a
error (String
"StorableVector.ST." forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
": index out of range")
{-# INLINE maybeRead #-}
maybeRead :: (Storable e) =>
Vector s e -> Int -> ST s (Maybe e)
maybeRead :: forall e s. Storable e => Vector s e -> Int -> ST s (Maybe e)
maybeRead Vector s e
v Int
n =
forall e s a.
Storable e =>
Vector s e -> Int -> ST s a -> ST s (Maybe a)
maybeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> ST s e
unsafeRead Vector s e
v Int
n
{-# INLINE maybeWrite #-}
maybeWrite :: (Storable e) =>
Vector s e -> Int -> e -> ST s Bool
maybeWrite :: forall e s. Storable e => Vector s e -> Int -> e -> ST s Bool
maybeWrite Vector s e
v Int
n e
x =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall e s a.
Storable e =>
Vector s e -> Int -> ST s a -> ST s (Maybe a)
maybeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> e -> ST s ()
unsafeWrite Vector s e
v Int
n e
x
{-# INLINE maybeModify #-}
maybeModify :: (Storable e) =>
Vector s e -> Int -> (e -> e) -> ST s Bool
maybeModify :: forall e s.
Storable e =>
Vector s e -> Int -> (e -> e) -> ST s Bool
maybeModify Vector s e
v Int
n e -> e
f =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall e s a.
Storable e =>
Vector s e -> Int -> ST s a -> ST s (Maybe a)
maybeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall e s. Storable e => Vector s e -> Int -> (e -> e) -> ST s ()
unsafeModify Vector s e
v Int
n e -> e
f
{-# INLINE maybeAccess #-}
maybeAccess :: (Storable e) =>
Vector s e -> Int -> ST s a -> ST s (Maybe a)
maybeAccess :: forall e s a.
Storable e =>
Vector s e -> Int -> ST s a -> ST s (Maybe a)
maybeAccess (SV ForeignPtr e
_v Int
l) Int
n ST s a
act =
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
Traversable.sequence forall a b. (a -> b) -> a -> b
$ forall a. Bool -> a -> Maybe a
toMaybe (Int
0forall a. Ord a => a -> a -> Bool
<=Int
n Bool -> Bool -> Bool
&& Int
nforall a. Ord a => a -> a -> Bool
<Int
l) ST s a
act
{-# INLINE unsafeRead #-}
unsafeRead :: (Storable e) =>
Vector s e -> Int -> ST s e
unsafeRead :: forall e s. Storable e => Vector s e -> Int -> ST s e
unsafeRead Vector s e
v Int
n =
forall e s a.
Storable e =>
Vector s e -> Int -> (Ptr e -> IO a) -> ST s a
unsafeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek
{-# INLINE unsafeWrite #-}
unsafeWrite :: (Storable e) =>
Vector s e -> Int -> e -> ST s ()
unsafeWrite :: forall e s. Storable e => Vector s e -> Int -> e -> ST s ()
unsafeWrite Vector s e
v Int
n e
x =
forall e s a.
Storable e =>
Vector s e -> Int -> (Ptr e -> IO a) -> ST s a
unsafeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ \Ptr e
p -> forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr e
p e
x
{-# INLINE unsafeModify #-}
unsafeModify :: (Storable e) =>
Vector s e -> Int -> (e -> e) -> ST s ()
unsafeModify :: forall e s. Storable e => Vector s e -> Int -> (e -> e) -> ST s ()
unsafeModify Vector s e
v Int
n e -> e
f =
forall e s a.
Storable e =>
Vector s e -> Int -> (Ptr e -> IO a) -> ST s a
unsafeAccess Vector s e
v Int
n forall a b. (a -> b) -> a -> b
$ \Ptr e
p -> forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr e
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> e
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Storable a => Ptr a -> IO a
peek Ptr e
p
{-# INLINE unsafeAccess #-}
unsafeAccess :: (Storable e) =>
Vector s e -> Int -> (Ptr e -> IO a) -> ST s a
unsafeAccess :: forall e s a.
Storable e =>
Vector s e -> Int -> (Ptr e -> IO a) -> ST s a
unsafeAccess (SV ForeignPtr e
v Int
_l) Int
n Ptr e -> IO a
act =
forall a s. IO a -> ST s a
Unsafe.ioToST (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr e
v forall a b. (a -> b) -> a -> b
$ \Ptr e
p -> Ptr e -> IO a
act (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr e
p Int
n))
{-# INLINE freeze #-}
freeze :: (Storable e) =>
Vector s e -> ST s (VS.Vector e)
freeze :: forall e s. Storable e => Vector s e -> ST s (Vector e)
freeze (SV ForeignPtr e
x Int
l) =
forall a s. IO a -> ST s a
Unsafe.ioToST forall a b. (a -> b) -> a -> b
$
forall a. Storable a => Int -> (Ptr a -> IO ()) -> IO (Vector a)
V.create Int
l forall a b. (a -> b) -> a -> b
$ \Ptr e
p ->
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr e
x forall a b. (a -> b) -> a -> b
$ \Ptr e
f ->
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr e
p Ptr e
f (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l)
{-# INLINE unsafeFreeze #-}
unsafeFreeze :: (Storable e) =>
Vector s e -> ST s (VS.Vector e)
unsafeFreeze :: forall e s. Storable e => Vector s e -> ST s (Vector e)
unsafeFreeze = forall s a. Vector s a -> ST s (Vector a)
unsafeToVector
{-# INLINE thaw #-}
thaw :: (Storable e) =>
VS.Vector e -> ST s (Vector s e)
thaw :: forall e s. Storable e => Vector e -> ST s (Vector s e)
thaw Vector e
v =
forall a s. IO a -> ST s a
Unsafe.ioToST forall a b. (a -> b) -> a -> b
$
forall a b.
Storable a =>
Vector a -> (Ptr a -> Int -> IO b) -> IO b
V.withStartPtr Vector e
v forall a b. (a -> b) -> a -> b
$ \Ptr e
f Int
l ->
forall a s.
Storable a =>
Int -> (Ptr a -> IO ()) -> IO (Vector s a)
create Int
l forall a b. (a -> b) -> a -> b
$ \Ptr e
p ->
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr e
p Ptr e
f (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l)
{-# INLINE length #-}
length ::
Vector s e -> Int
length :: forall s e. Vector s e -> Int
length (SV ForeignPtr e
_v Int
l) = Int
l
{-# INLINE runSTVector #-}
runSTVector :: (Storable e) =>
(forall s. ST s (Vector s e)) -> VS.Vector e
runSTVector :: forall e. Storable e => (forall s. ST s (Vector s e)) -> Vector e
runSTVector forall s. ST s (Vector s e)
m =
forall a. (forall s. ST s a) -> a
runST (forall s a. Vector s a -> ST s (Vector a)
unsafeToVector forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s. ST s (Vector s e)
m)
{-# INLINE mapST #-}
mapST :: (Storable a, Storable b) =>
(a -> ST s b) -> VS.Vector a -> ST s (VS.Vector b)
mapST :: forall a b s.
(Storable a, Storable b) =>
(a -> ST s b) -> Vector a -> ST s (Vector b)
mapST a -> ST s b
f (V.SV ForeignPtr a
px Int
sx Int
n) =
let {-# INLINE go #-}
go :: t -> Ptr a -> Ptr b -> ST s ()
go t
l Ptr a
q Ptr b
p =
if t
lforall a. Ord a => a -> a -> Bool
>t
0
then
do forall a s. IO a -> ST s a
Unsafe.ioToST forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr b
p forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> ST s b
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a s. IO a -> ST s a
Unsafe.ioToST (forall a. Storable a => Ptr a -> IO a
peek Ptr a
q)
t -> Ptr a -> Ptr b -> ST s ()
go (forall a. Enum a => a -> a
pred t
l) (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
q Int
1) (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr b
p Int
1)
else forall (m :: * -> *) a. Monad m => a -> m a
return ()
in do ys :: Vector s b
ys@(SV ForeignPtr b
py Int
_) <- forall e s. Storable e => Int -> ST s (Vector s e)
new_ Int
n
forall {t}.
(Ord t, Num t, Enum t) =>
t -> Ptr a -> Ptr b -> ST s ()
go Int
n
(forall a. ForeignPtr a -> Ptr a
Unsafe.foreignPtrToPtr ForeignPtr a
px forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
sx)
(forall a. ForeignPtr a -> Ptr a
Unsafe.foreignPtrToPtr ForeignPtr b
py)
forall s a. Vector s a -> ST s (Vector a)
unsafeToVector Vector s b
ys
{-# INLINE mapSTLazy #-}
mapSTLazy :: (Storable a, Storable b) =>
(a -> ST s b) -> VL.Vector a -> ST s (VL.Vector b)
mapSTLazy :: forall a b s.
(Storable a, Storable b) =>
(a -> ST s b) -> Vector a -> ST s (Vector b)
mapSTLazy a -> ST s b
f (VL.SV [Vector a]
xs) =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [Vector a] -> Vector a
VL.SV forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a b s.
(Storable a, Storable b) =>
(a -> ST s b) -> Vector a -> ST s (Vector b)
mapST a -> ST s b
f) [Vector a]
xs