{-|
Module      : Data.Primitive.PrimArray.Utils
Description : Provides useful utilities for operating with mutable primitive arrays.
Copyright   : (c) klapaucius, swamp_agr, 2016-2021
License     : BSD3
-}
module Data.Primitive.PrimArray.Utils where

import Data.Primitive.PrimArray
import Control.Monad.Primitive
import Data.Primitive

replicate :: (PrimMonad m, Prim a) 
          => Int -> a -> m (MutablePrimArray (PrimState m) a)
replicate :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> a -> m (MutablePrimArray (PrimState m) a)
replicate Int
n a
x = do
    MutablePrimArray (PrimState m) a
xs <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
n
    Int
sz <- MutablePrimArray (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray MutablePrimArray (PrimState m) a
xs
    MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
setPrimArray MutablePrimArray (PrimState m) a
xs Int
0 Int
sz a
x
    MutablePrimArray (PrimState m) a
-> m (MutablePrimArray (PrimState m) a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return MutablePrimArray (PrimState m) a
xs

{-# INLINE replicate #-}

clone :: (PrimMonad m, Prim a) 
      => MutablePrimArray (PrimState m) a -> m (MutablePrimArray (PrimState m) a)
clone :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> m (MutablePrimArray (PrimState m) a)
clone MutablePrimArray (PrimState m) a
xs = do
    Int
sz <- MutablePrimArray (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray MutablePrimArray (PrimState m) a
xs
    MutablePrimArray (PrimState m) a
-> Int -> Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> Int -> m (MutablePrimArray (PrimState m) a)
cloneMutablePrimArray MutablePrimArray (PrimState m) a
xs Int
0 Int
sz

{-# INLINE clone #-}

unsafeFreeze :: PrimMonad m 
             => MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreeze :: forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreeze = MutablePrimArray (PrimState m) a -> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray

{-# INLINE unsafeFreeze #-}

unsafeThaw :: PrimMonad m 
           => PrimArray a -> m (MutablePrimArray (PrimState m) a)
unsafeThaw :: forall (m :: * -> *) a.
PrimMonad m =>
PrimArray a -> m (MutablePrimArray (PrimState m) a)
unsafeThaw = PrimArray a -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
PrimArray a -> m (MutablePrimArray (PrimState m) a)
unsafeThawPrimArray

{-# INLINE unsafeThaw #-}

growWith :: (PrimMonad m, Prim a) 
     => a -> MutablePrimArray (PrimState m) a -> Int -> m (MutablePrimArray (PrimState m) a)
growWith :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a
-> MutablePrimArray (PrimState m) a
-> Int
-> m (MutablePrimArray (PrimState m) a)
growWith a
a MutablePrimArray (PrimState m) a
xs Int
delta = do 
    MutablePrimArray (PrimState m) a
r <- MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
growNoZ MutablePrimArray (PrimState m) a
xs Int
delta
    Int
sz <- MutablePrimArray (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray MutablePrimArray (PrimState m) a
xs
    MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
setPrimArray MutablePrimArray (PrimState m) a
r Int
sz Int
delta a
a
    MutablePrimArray (PrimState m) a
-> m (MutablePrimArray (PrimState m) a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return MutablePrimArray (PrimState m) a
r

{-# INLINE growWith #-}

growNoZ :: (PrimMonad m, Prim a) 
     => MutablePrimArray (PrimState m) a -> Int -> m (MutablePrimArray (PrimState m) a)
growNoZ :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
growNoZ MutablePrimArray (PrimState m) a
xs Int
delta = do
    Int
sz <- MutablePrimArray (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray MutablePrimArray (PrimState m) a
xs
    MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray (PrimState m) a
xs (Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
delta)

{-# INLINE growNoZ #-}

freeze :: (PrimMonad m, Prim a) 
       => MutablePrimArray (PrimState m) a -> m (PrimArray a)
freeze :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
freeze MutablePrimArray (PrimState m) a
xs = do 
    PrimArray a
r <- MutablePrimArray (PrimState m) a -> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) a
xs
    PrimArray a -> m (PrimArray a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (PrimArray a -> m (PrimArray a)) -> PrimArray a -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ PrimArray a -> Int -> Int -> PrimArray a
forall a. Prim a => PrimArray a -> Int -> Int -> PrimArray a
clonePrimArray PrimArray a
r Int
0 (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
r)

{-# INLINE freeze #-}

length :: (PrimMonad m, Prim a) => MutablePrimArray (PrimState m) a -> m Int
length :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
length = MutablePrimArray (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray

{-# INLINE length #-}