{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
module Streamly.Internal.Data.Prim.Array.Types
(
PrimArray(..)
, MutablePrimArray(..)
, newPrimArray
, resizeMutablePrimArray
, shrinkMutablePrimArray
, writePrimArray
, indexPrimArray
, unsafeFreezePrimArray
, sizeofPrimArray
, foldrPrimArray
, foldlPrimArray'
) where
import GHC.Exts
import Data.Primitive.Types
import Data.Primitive.ByteArray (ByteArray(..))
import Control.Monad.Primitive
import qualified Data.Primitive.ByteArray as PB
data PrimArray a = PrimArray ByteArray#
data MutablePrimArray s a = MutablePrimArray (MutableByteArray# s)
sameByteArray :: ByteArray# -> ByteArray# -> Bool
sameByteArray :: ByteArray# -> ByteArray# -> Bool
sameByteArray ByteArray#
ba1 ByteArray#
ba2 =
case () -> () -> Int#
forall a. a -> a -> Int#
reallyUnsafePtrEquality# (ByteArray# -> ()
unsafeCoerce# ByteArray#
ba1 :: ()) (ByteArray# -> ()
unsafeCoerce# ByteArray#
ba2 :: ()) of
Int#
r -> Int# -> Bool
isTrue# Int#
r
instance (Eq a, Prim a) => Eq (PrimArray a) where
a1 :: PrimArray a
a1@(PrimArray ByteArray#
ba1#) == :: PrimArray a -> PrimArray a -> Bool
== a2 :: PrimArray a
a2@(PrimArray ByteArray#
ba2#)
| ByteArray# -> ByteArray# -> Bool
sameByteArray ByteArray#
ba1# ByteArray#
ba2# = Bool
True
| Int
sz1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
sz2 = Bool
False
| Bool
otherwise = Int -> Bool
loop (Int -> Int -> Int
forall a. Integral a => a -> a -> a
quot Int
sz1 (a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
sz1 :: Int
sz1 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba1#)
sz2 :: Int
sz2 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba2#)
loop :: Int -> Bool
loop !Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Bool
True
| Bool
otherwise = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a1 Int
i a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a2 Int
i Bool -> Bool -> Bool
&& Int -> Bool
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
{-# INLINE (==) #-}
instance (Ord a, Prim a) => Ord (PrimArray a) where
compare :: PrimArray a -> PrimArray a -> Ordering
compare a1 :: PrimArray a
a1@(PrimArray ByteArray#
ba1#) a2 :: PrimArray a
a2@(PrimArray ByteArray#
ba2#)
| ByteArray# -> ByteArray# -> Bool
sameByteArray ByteArray#
ba1# ByteArray#
ba2# = Ordering
EQ
| Bool
otherwise = Int -> Ordering
loop Int
0
where
cmp :: Ordering -> Ordering -> Ordering
cmp Ordering
LT Ordering
_ = Ordering
LT
cmp Ordering
EQ Ordering
y = Ordering
y
cmp Ordering
GT Ordering
_ = Ordering
GT
sz1 :: Int
sz1 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba1#)
sz2 :: Int
sz2 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba2#)
sz :: Int
sz = Int -> Int -> Int
forall a. Integral a => a -> a -> a
quot (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
sz1 Int
sz2) (a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))
loop :: Int -> Ordering
loop !Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a1 Int
i) (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a2 Int
i) Ordering -> Ordering -> Ordering
`cmp` Int -> Ordering
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
| Bool
otherwise = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
sz1 Int
sz2
{-# INLINE compare #-}
instance (Show a, Prim a) => Show (PrimArray a) where
showsPrec :: Int -> PrimArray a -> ShowS
showsPrec Int
p PrimArray a
a = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"fromListN " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
a) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall a. Show a => a -> ShowS
shows (PrimArray a -> [a]
forall a. Prim a => PrimArray a -> [a]
primArrayToList PrimArray a
a)
{-# INLINE primArrayToList #-}
primArrayToList :: forall a. Prim a => PrimArray a -> [a]
primArrayToList :: PrimArray a -> [a]
primArrayToList PrimArray a
xs = (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build (\a -> b -> b
c b
n -> (a -> b -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray a -> b -> b
c b
n PrimArray a
xs)
newPrimArray :: forall m a. (PrimMonad m, Prim a) => Int -> m (MutablePrimArray (PrimState m) a)
{-# INLINE newPrimArray #-}
newPrimArray :: Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (I# Int#
n#)
= (State# (PrimState m)
-> (# State# (PrimState m), MutablePrimArray (PrimState m) a #))
-> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\State# (PrimState m)
s# ->
case Int#
-> State# (PrimState m)
-> (# State# (PrimState m), MutableByteArray# (PrimState m) #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)) State# (PrimState m)
s# of
(# State# (PrimState m)
s'#, MutableByteArray# (PrimState m)
arr# #) -> (# State# (PrimState m)
s'#, MutableByteArray# (PrimState m) -> MutablePrimArray (PrimState m) a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# (PrimState m)
arr# #)
)
resizeMutablePrimArray :: forall m a. (PrimMonad m, Prim a)
=> MutablePrimArray (PrimState m) a
-> Int
-> m (MutablePrimArray (PrimState m) a)
{-# INLINE resizeMutablePrimArray #-}
resizeMutablePrimArray :: MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray (MutablePrimArray MutableByteArray# (PrimState m)
arr#) (I# Int#
n#)
= (State# (PrimState m)
-> (# State# (PrimState m), MutablePrimArray (PrimState m) a #))
-> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\State# (PrimState m)
s# -> case MutableByteArray# (PrimState m)
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), MutableByteArray# (PrimState m) #)
forall d.
MutableByteArray# d
-> Int# -> State# d -> (# State# d, MutableByteArray# d #)
resizeMutableByteArray# MutableByteArray# (PrimState m)
arr# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)) State# (PrimState m)
s# of
(# State# (PrimState m)
s'#, MutableByteArray# (PrimState m)
arr'# #) -> (# State# (PrimState m)
s'#, MutableByteArray# (PrimState m) -> MutablePrimArray (PrimState m) a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# (PrimState m)
arr'# #))
shrinkMutablePrimArray :: forall m a. (PrimMonad m, Prim a)
=> MutablePrimArray (PrimState m) a
-> Int
-> m ()
{-# INLINE shrinkMutablePrimArray #-}
shrinkMutablePrimArray :: MutablePrimArray (PrimState m) a -> Int -> m ()
shrinkMutablePrimArray (MutablePrimArray MutableByteArray# (PrimState m)
arr#) (I# Int#
n#)
= (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int# -> State# (PrimState m) -> State# (PrimState m)
forall d. MutableByteArray# d -> Int# -> State# d -> State# d
shrinkMutableByteArray# MutableByteArray# (PrimState m)
arr# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
writePrimArray ::
(Prim a, PrimMonad m)
=> MutablePrimArray (PrimState m) a
-> Int
-> a
-> m ()
{-# INLINE writePrimArray #-}
writePrimArray :: MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutablePrimArray MutableByteArray# (PrimState m)
arr#) (I# Int#
i#) a
x
= (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int# -> a -> State# (PrimState m) -> State# (PrimState m)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# (PrimState m)
arr# Int#
i# a
x)
unsafeFreezePrimArray
:: PrimMonad m => MutablePrimArray (PrimState m) a -> m (PrimArray a)
{-# INLINE unsafeFreezePrimArray #-}
unsafeFreezePrimArray :: MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutablePrimArray MutableByteArray# (PrimState m)
arr#)
= (State# (PrimState m) -> (# State# (PrimState m), PrimArray a #))
-> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\State# (PrimState m)
s# -> case MutableByteArray# (PrimState m)
-> State# (PrimState m) -> (# State# (PrimState m), ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# (PrimState m)
arr# State# (PrimState m)
s# of
(# State# (PrimState m)
s'#, ByteArray#
arr'# #) -> (# State# (PrimState m)
s'#, ByteArray# -> PrimArray a
forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
arr'# #))
indexPrimArray :: forall a. Prim a => PrimArray a -> Int -> a
{-# INLINE indexPrimArray #-}
indexPrimArray :: PrimArray a -> Int -> a
indexPrimArray (PrimArray ByteArray#
arr#) (I# Int#
i#) = ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# Int#
i#
sizeofPrimArray :: forall a. Prim a => PrimArray a -> Int
{-# INLINE sizeofPrimArray #-}
sizeofPrimArray :: PrimArray a -> Int
sizeofPrimArray (PrimArray ByteArray#
arr#) = Int# -> Int
I# (Int# -> Int# -> Int#
quotInt# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
arr#) (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
{-# INLINE foldrPrimArray #-}
foldrPrimArray :: forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray :: (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray a -> b -> b
f b
z PrimArray a
arr = Int -> b
go Int
0
where
!sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
go :: Int -> b
go !Int
i
| Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
i = a -> b -> b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (Int -> b
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))
| Bool
otherwise = b
z
{-# INLINE foldlPrimArray' #-}
foldlPrimArray' :: forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray' :: (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray' b -> a -> b
f b
z0 PrimArray a
arr = Int -> b -> b
go Int
0 b
z0
where
!sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
go :: Int -> b -> b
go !Int
i !b
acc
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = Int -> b -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (b -> a -> b
f b
acc (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i))
| Bool
otherwise = b
acc