module Streamly.Internal.Data.Array.Foreign
(
Array
, A.fromPtr
, A.fromAddr#
, A.fromCString#
, A.fromListN
, A.fromList
, fromStreamN
, fromStream
, A.writeN
, A.writeNAligned
, A.write
, writeLastN
, A.toList
, A.toStream
, A.toStreamRev
, read
, unsafeRead
, A.readRev
, producer
, getIndex
, A.unsafeIndex
, getIndexRev
, last
, getIndices
, getIndicesFromThenTo
, length
, null
, binarySearch
, findIndicesOf
, cast
, asBytes
, unsafeCast
, asPtrUnsafe
, unsafeAsCString
, A.unsafeFreeze
, A.unsafeThaw
, getSliceUnsafe
, genSlicesFromLen
, getSlicesFromLen
, splitOn
, streamTransform
, streamFold
, fold
)
where
#include "inline.hs"
#include "ArrayMacros.h"
import Control.Exception (assert)
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Functor.Identity (Identity)
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup ((<>))
#endif
import Data.Word (Word8)
import Foreign.C.String (CString)
import Foreign.Ptr (plusPtr, castPtr)
import Foreign.Storable (Storable(..))
import Prelude hiding (length, null, last, map, (!!), read, concat)
import Streamly.Internal.Data.Array.Foreign.Mut.Type (ReadUState(..), touch)
import Streamly.Internal.Data.Array.Foreign.Type
(Array(..), length, asPtrUnsafe)
import Streamly.Internal.Data.Fold.Type (Fold(..))
import Streamly.Internal.Data.Producer.Type (Producer(..))
import Streamly.Internal.Data.Stream.Serial (SerialT(..))
import Streamly.Internal.Data.Tuple.Strict (Tuple3Fused'(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import Streamly.Internal.System.IO (unsafeInlineIO)
import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
import qualified Streamly.Internal.Data.Array.Foreign.Mut as MA
import qualified Streamly.Internal.Data.Array.Foreign.Type as A
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Producer as Producer
import qualified Streamly.Internal.Data.Stream.Prelude as P
import qualified Streamly.Internal.Data.Stream.StreamD as D
import qualified Streamly.Internal.Data.Unfold as Unfold
import qualified Streamly.Internal.Data.Ring.Foreign as RB
{-# INLINE fromStreamN #-}
fromStreamN :: (MonadIO m, Storable a) => Int -> SerialT m a -> m (Array a)
fromStreamN :: forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> SerialT m a -> m (Array a)
fromStreamN Int
n (SerialT Stream m a
m) = do
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n forall a. Ord a => a -> a -> Bool
< Int
0) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => [Char] -> a
error [Char]
"writeN: negative write count specified"
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Stream m a -> m (Array a)
A.fromStreamDN Int
n forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Applicative m => Stream m a -> Stream m a
D.fromStreamK Stream m a
m
{-# INLINE fromStream #-}
fromStream :: (MonadIO m, Storable a) => SerialT m a -> m (Array a)
fromStream :: forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
SerialT m a -> m (Array a)
fromStream (SerialT Stream m a
m) = forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
P.fold forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Fold m a (Array a)
A.write Stream m a
m
{-# INLINE_NORMAL producer #-}
producer :: forall m a. (Monad m, Storable a) => Producer m (Array a) a
producer :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
Producer m (Array a) a
producer = forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> (s -> m a) -> Producer m a b
Producer forall {m :: * -> *} {a}.
(Monad m, Storable a) =>
ReadUState a -> m (Step (ReadUState a) a)
step forall {m :: * -> *} {a}. Monad m => Array a -> m (ReadUState a)
inject forall {m :: * -> *} {a}. Monad m => ReadUState a -> m (Array a)
extract
where
{-# INLINE inject #-}
inject :: Array a -> m (ReadUState a)
inject (Array ArrayContents
contents Ptr a
start Ptr a
end) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. ArrayContents -> Ptr a -> Ptr a -> ReadUState a
ReadUState ArrayContents
contents Ptr a
end Ptr a
start
{-# INLINE_LATE step #-}
step :: ReadUState a -> m (Step (ReadUState a) a)
step (ReadUState ArrayContents
contents Ptr a
end Ptr a
cur)
| forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
cur forall a. Ord a => a -> a -> Bool
<= Ptr a
end) (Ptr a
cur forall a. Eq a => a -> a -> Bool
== Ptr a
end) =
let x :: ()
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ ArrayContents -> IO ()
touch ArrayContents
contents
in ()
x seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop
step (ReadUState ArrayContents
contents Ptr a
end Ptr a
cur) = do
let !x :: a
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
cur
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
D.Yield a
x (forall a. ArrayContents -> Ptr a -> Ptr a -> ReadUState a
ReadUState ArrayContents
contents Ptr a
end (PTR_NEXT(cur,a)))
extract :: ReadUState a -> m (Array a)
extract (ReadUState ArrayContents
contents Ptr a
end Ptr a
cur) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. ArrayContents -> Ptr a -> Ptr a -> Array a
Array ArrayContents
contents Ptr a
cur Ptr a
end
{-# INLINE_NORMAL read #-}
read :: forall m a. (Monad m, Storable a) => Unfold m (Array a) a
read :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
Unfold m (Array a) a
read = forall (m :: * -> *) a b. Producer m a b -> Unfold m a b
Producer.simplify forall (m :: * -> *) a.
(Monad m, Storable a) =>
Producer m (Array a) a
producer
{-# INLINE_NORMAL unsafeRead #-}
unsafeRead :: forall m a. (Monad m, Storable a) => Unfold m (Array a) a
unsafeRead :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
Unfold m (Array a) a
unsafeRead = forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold forall {m :: * -> *} {a}.
(Monad m, Storable a) =>
ReadUState a -> m (Step (ReadUState a) a)
step forall {m :: * -> *} {a}. Monad m => Array a -> m (ReadUState a)
inject
where
inject :: Array a -> m (ReadUState a)
inject (Array ArrayContents
contents Ptr a
start Ptr a
end) =
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. ArrayContents -> Ptr a -> Ptr a -> ReadUState a
ReadUState ArrayContents
contents Ptr a
end Ptr a
start)
{-# INLINE_LATE step #-}
step :: ReadUState a -> m (Step (ReadUState a) a)
step (ReadUState ArrayContents
contents Ptr a
end Ptr a
p) = do
let !x :: a
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ do
a
r <- forall a. Storable a => Ptr a -> IO a
peek Ptr a
p
ArrayContents -> IO ()
touch ArrayContents
contents
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
let !p1 :: Ptr b
p1 = PTR_NEXT(p,a)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
D.Yield a
x (forall a. ArrayContents -> Ptr a -> Ptr a -> ReadUState a
ReadUState ArrayContents
contents Ptr a
end forall {b}. Ptr b
p1)
{-# INLINE null #-}
null :: Array a -> Bool
null :: forall a. Array a -> Bool
null Array a
arr = forall a. Array a -> Int
A.byteLength Array a
arr forall a. Eq a => a -> a -> Bool
== Int
0
{-# INLINE getIndexRev #-}
getIndexRev :: forall a. Storable a => Int -> Array a -> Maybe a
getIndexRev :: forall a. Storable a => Int -> Array a -> Maybe a
getIndexRev Int
i Array a
arr =
forall a. IO a -> a
unsafeInlineIO
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b.
MonadIO m =>
Array a -> (Ptr a -> m b) -> m b
asPtrUnsafe Array a
arr
forall a b. (a -> b) -> a -> b
$ \Ptr a
ptr -> do
let elemPtr :: Ptr b
elemPtr = PTR_RINDEX(aEnd arr,i,a)
if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& forall {b}. Ptr b
elemPtr forall a. Ord a => a -> a -> Bool
>= Ptr a
ptr
then forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> IO a
peek forall {b}. Ptr b
elemPtr
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
{-# INLINE last #-}
last :: Storable a => Array a -> Maybe a
last :: forall a. Storable a => Array a -> Maybe a
last = forall a. Storable a => Int -> Array a -> Maybe a
getIndexRev Int
0
{-# INLINE writeLastN #-}
writeLastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
writeLastN :: forall a (m :: * -> *).
(Storable a, MonadIO m) =>
Int -> Fold m a (Array a)
writeLastN Int
n
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> a
const forall a. Monoid a => a
mempty) forall (m :: * -> *) a. Monad m => Fold m a ()
FL.drain
| Bool
otherwise = forall a. Array a -> Array a
A.unsafeFreeze forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold forall {m :: * -> *} {a} {c} {b}.
(MonadIO m, Storable a, Num c) =>
Tuple3Fused' (Ring a) (Ptr a) c
-> a -> m (Step (Tuple3Fused' (Ring a) (Ptr a) c) b)
step forall {b}. m (Step (Tuple3Fused' (Ring a) (Ptr a) Int) b)
initial forall {m :: * -> *} {a}.
(MonadIO m, Storable a) =>
Tuple3Fused' (Ring a) (Ptr a) Int -> m (Array a)
done
where
step :: Tuple3Fused' (Ring a) (Ptr a) c
-> a -> m (Step (Tuple3Fused' (Ring a) (Ptr a) c) b)
step (Tuple3Fused' Ring a
rb Ptr a
rh c
i) a
a = do
Ptr a
rh1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
RB.unsafeInsert Ring a
rb Ptr a
rh a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3Fused' a b c
Tuple3Fused' Ring a
rb Ptr a
rh1 (c
i forall a. Num a => a -> a -> a
+ c
1)
initial :: m (Step (Tuple3Fused' (Ring a) (Ptr a) Int) b)
initial =
let f :: (a, b) -> Step (Tuple3Fused' a b Int) b
f (a
a, b
b) = forall s b. s -> Step s b
FL.Partial forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3Fused' a b c
Tuple3Fused' a
a b
b (Int
0 :: Int)
in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a} {b} {b}. (a, b) -> Step (Tuple3Fused' a b Int) b
f forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> IO (Ring a, Ptr a)
RB.new Int
n
done :: Tuple3Fused' (Ring a) (Ptr a) Int -> m (Array a)
done (Tuple3Fused' Ring a
rb Ptr a
rh Int
i) = do
Array a
arr <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> m (Array a)
MA.newArray Int
n
forall {m :: * -> *} {a} {b}.
(MonadIO m, Storable a) =>
Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
foldFunc Int
i Ptr a
rh forall {m :: * -> *} {a}.
(MonadIO m, Storable a) =>
Array a -> a -> m (Array a)
snoc' Array a
arr Ring a
rb
snoc' :: Array a -> a -> m (Array a)
snoc' Array a
b a
a = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {a}.
(MonadIO m, Storable a) =>
Array a -> a -> m (Array a)
MA.snocUnsafe Array a
b a
a
foldFunc :: Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
foldFunc Int
i
| Int
i forall a. Ord a => a -> a -> Bool
< Int
n = forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
RB.unsafeFoldRingM
| Bool
otherwise = forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
RB.unsafeFoldRingFullM
{-# INLINE binarySearch #-}
binarySearch :: a -> Array a -> Maybe Int
binarySearch :: forall a. a -> Array a -> Maybe Int
binarySearch = forall a. HasCallStack => a
undefined
findIndicesOf :: (a -> Bool) -> Unfold Identity (Array a) Int
findIndicesOf :: forall a. (a -> Bool) -> Unfold Identity (Array a) Int
findIndicesOf = forall a. HasCallStack => a
undefined
{-# INLINE getSliceUnsafe #-}
getSliceUnsafe ::
forall a. Storable a
=> Int
-> Int
-> Array a
-> Array a
getSliceUnsafe :: forall a. Storable a => Int -> Int -> Array a -> Array a
getSliceUnsafe Int
index Int
len (Array ArrayContents
contents Ptr a
start Ptr a
e) =
let size :: Int
size = SIZE_OF(a)
fp1 :: Ptr b
fp1 = Ptr a
start forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Int
index forall a. Num a => a -> a -> a
* Int
size)
end :: Ptr b
end = forall {b}. Ptr b
fp1 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Int
len forall a. Num a => a -> a -> a
* Int
size)
in forall a. HasCallStack => Bool -> a -> a
assert (forall {b}. Ptr b
end forall a. Ord a => a -> a -> Bool
<= Ptr a
e) (forall a. ArrayContents -> Ptr a -> Ptr a -> Array a
Array ArrayContents
contents forall {b}. Ptr b
fp1 forall {b}. Ptr b
end)
{-# INLINE splitOn #-}
splitOn :: (Monad m, Storable a) =>
(a -> Bool) -> Array a -> SerialT m (Array a)
splitOn :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
(a -> Bool) -> Array a -> SerialT m (Array a)
splitOn a -> Bool
predicate Array a
arr =
forall (m :: * -> *) a. Stream m a -> SerialT m a
SerialT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => Stream m a -> Stream m a
D.toStreamK
forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Int
i, Int
len) -> forall a. Storable a => Int -> Int -> Array a -> Array a
getSliceUnsafe Int
i Int
len Array a
arr)
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
Monad m =>
(a -> Bool) -> Stream m a -> Stream m (Int, Int)
D.sliceOnSuffix a -> Bool
predicate (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Array a -> Stream m a
A.toStreamD Array a
arr)
{-# INLINE genSlicesFromLen #-}
genSlicesFromLen :: forall m a. (Monad m, Storable a)
=> Int
-> Int
-> Unfold m (Array a) (Int, Int)
genSlicesFromLen :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
Int -> Int -> Unfold m (Array a) (Int, Int)
genSlicesFromLen Int
from Int
len =
forall a c (m :: * -> *) b.
(a -> c) -> Unfold m c b -> Unfold m a b
Unfold.lmap forall a. Array a -> Array a
A.unsafeThaw (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Int -> Int -> Unfold m (Array a) (Int, Int)
MA.genSlicesFromLen Int
from Int
len)
{-# INLINE getSlicesFromLen #-}
getSlicesFromLen :: forall m a. (Monad m, Storable a)
=> Int
-> Int
-> Unfold m (Array a) (Array a)
getSlicesFromLen :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
Int -> Int -> Unfold m (Array a) (Array a)
getSlicesFromLen Int
from Int
len =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Array a -> Array a
A.unsafeFreeze
forall a b. (a -> b) -> a -> b
$ forall a c (m :: * -> *) b.
(a -> c) -> Unfold m c b -> Unfold m a b
Unfold.lmap forall a. Array a -> Array a
A.unsafeThaw (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Int -> Int -> Unfold m (Array a) (Array a)
MA.getSlicesFromLen Int
from Int
len)
{-# INLINE getIndex #-}
getIndex :: forall a. Storable a => Array a -> Int -> Maybe a
getIndex :: forall a. Storable a => Array a -> Int -> Maybe a
getIndex Array a
arr Int
i =
forall a. IO a -> a
unsafeInlineIO
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b.
MonadIO m =>
Array a -> (Ptr a -> m b) -> m b
asPtrUnsafe Array a
arr
forall a b. (a -> b) -> a -> b
$ \Ptr a
ptr -> do
let elemPtr :: Ptr b
elemPtr = PTR_INDEX(ptr,i,a)
if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& PTR_VALID(elemPtr,aEnd arr,a)
then forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> IO a
peek forall {b}. Ptr b
elemPtr
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
{-# INLINE getIndices #-}
getIndices :: (Monad m, Storable a) => SerialT m Int -> Unfold m (Array a) a
getIndices :: forall (m :: * -> *) a.
(Monad m, Storable a) =>
SerialT m Int -> Unfold m (Array a) a
getIndices (SerialT Stream m Int
stream) =
let unf :: Unfold m (Array a) a
unf = forall (m :: * -> *) a.
(Monad m, Storable a) =>
(forall b. IO b -> m b) -> Stream m Int -> Unfold m (Array a) a
MA.getIndicesD (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IO a -> a
unsafeInlineIO) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Applicative m => Stream m a -> Stream m a
D.fromStreamK Stream m Int
stream
in forall a c (m :: * -> *) b.
(a -> c) -> Unfold m c b -> Unfold m a b
Unfold.lmap forall a. Array a -> Array a
A.unsafeThaw Unfold m (Array a) a
unf
{-# INLINE getIndicesFromThenTo #-}
getIndicesFromThenTo :: Unfold m (Int, Int, Int, Array a) a
getIndicesFromThenTo :: forall (m :: * -> *) a. Unfold m (Int, Int, Int, Array a) a
getIndicesFromThenTo = forall a. HasCallStack => a
undefined
{-# INLINE streamTransform #-}
streamTransform :: forall m a b. (MonadIO m, Storable a, Storable b)
=> (SerialT m a -> SerialT m b) -> Array a -> m (Array b)
streamTransform :: forall (m :: * -> *) a b.
(MonadIO m, Storable a, Storable b) =>
(SerialT m a -> SerialT m b) -> Array a -> m (Array b)
streamTransform SerialT m a -> SerialT m b
f Array a
arr =
forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
P.fold (forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Fold m a (Array a)
A.writeWith (forall a. Storable a => Array a -> Int
length Array a
arr)) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. SerialT m a -> Stream m a
getSerialT forall a b. (a -> b) -> a -> b
$ SerialT m a -> SerialT m b
f (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Array a -> SerialT m a
A.toStream Array a
arr)
unsafeCast ::
#ifdef DEVBUILD
Storable b =>
#endif
Array a -> Array b
unsafeCast :: forall a b. Array a -> Array b
unsafeCast (Array ArrayContents
contents Ptr a
start Ptr a
end) =
forall a. ArrayContents -> Ptr a -> Ptr a -> Array a
Array ArrayContents
contents (forall a b. Ptr a -> Ptr b
castPtr Ptr a
start) (forall a b. Ptr a -> Ptr b
castPtr Ptr a
end)
asBytes :: Array a -> Array Word8
asBytes :: forall a. Array a -> Array Word8
asBytes = forall a b. Array a -> Array b
unsafeCast
cast :: forall a b. (Storable b) => Array a -> Maybe (Array b)
cast :: forall a b. Storable b => Array a -> Maybe (Array b)
cast Array a
arr =
let len :: Int
len = forall a. Array a -> Int
A.byteLength Array a
arr
r :: Int
r = Int
len forall a. Integral a => a -> a -> a
`mod` SIZE_OF(b)
in if Int
r forall a. Eq a => a -> a -> Bool
/= Int
0
then forall a. Maybe a
Nothing
else forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a b. Array a -> Array b
unsafeCast Array a
arr
unsafeAsCString :: Array a -> (CString -> IO b) -> IO b
unsafeAsCString :: forall a b. Array a -> (CString -> IO b) -> IO b
unsafeAsCString Array a
arr CString -> IO b
act = do
let arr1 :: Array Word8
arr1 = forall a. Array a -> Array Word8
asBytes Array a
arr forall a. Semigroup a => a -> a -> a
<> forall a. Storable a => [a] -> Array a
A.fromList [Word8
0]
forall (m :: * -> *) a b.
MonadIO m =>
Array a -> (Ptr a -> m b) -> m b
asPtrUnsafe Array Word8
arr1 forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> CString -> IO b
act (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr)
{-# INLINE fold #-}
fold :: forall m a b. (MonadIO m, Storable a) => Fold m a b -> Array a -> m b
fold :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Fold m a b -> Array a -> m b
fold Fold m a b
f Array a
arr = forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
P.fold Fold m a b
f (forall (m :: * -> *) a. SerialT m a -> Stream m a
getSerialT (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Array a -> SerialT m a
A.toStream Array a
arr))
{-# INLINE streamFold #-}
streamFold :: (MonadIO m, Storable a) => (SerialT m a -> m b) -> Array a -> m b
streamFold :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
(SerialT m a -> m b) -> Array a -> m b
streamFold SerialT m a -> m b
f Array a
arr = SerialT m a -> m b
f (forall (m :: * -> *) a.
(Monad m, Storable a) =>
Array a -> SerialT m a
A.toStream Array a
arr)