{-|
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
    xs <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
n
    sz <- getSizeofMutablePrimArray xs
    setPrimArray xs 0 sz x
    return 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
    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
    cloneMutablePrimArray xs 0 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 
    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
    sz <- getSizeofMutablePrimArray xs
    setPrimArray r sz delta a
    return 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
    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
    resizeMutablePrimArray xs (sz + 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 
    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
    return $ clonePrimArray r 0 (sizeofPrimArray 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 #-}