module Data.RRBVector.Internal.Buffer
( Buffer
, new
, push
, get
, size
) where
import Control.Monad.ST
import Data.Primitive.SmallArray
import Data.RRBVector.Internal.IntRef
import qualified Data.RRBVector.Internal.Array as A
data Buffer s a = Buffer !(SmallMutableArray s a) !(IntRef s)
new :: Int -> ST s (Buffer s a)
new :: forall s a. Int -> ST s (Buffer s a)
new Int
capacity = do
SmallMutableArray s a
buffer <- Int -> a -> ST s (SmallMutableArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
capacity a
forall a. a
uninitialized
IntRef s
offset <- Int -> ST s (IntRef s)
forall s. Int -> ST s (IntRef s)
newIntRef Int
0
Buffer s a -> ST s (Buffer s a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SmallMutableArray s a -> IntRef s -> Buffer s a
forall s a. SmallMutableArray s a -> IntRef s -> Buffer s a
Buffer SmallMutableArray s a
buffer IntRef s
offset)
uninitialized :: a
uninitialized :: forall a. a
uninitialized = [Char] -> a
forall a. [Char] -> a
errorWithoutStackTrace [Char]
"uninitialized"
push :: Buffer s a -> a -> ST s ()
push :: forall s a. Buffer s a -> a -> ST s ()
push (Buffer SmallMutableArray s a
buffer IntRef s
offset) a
x = do
Int
idx <- IntRef s -> ST s Int
forall s. IntRef s -> ST s Int
readIntRef IntRef s
offset
SmallMutableArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray s a
SmallMutableArray (PrimState (ST s)) a
buffer Int
idx a
x
IntRef s -> Int -> ST s ()
forall s. IntRef s -> Int -> ST s ()
writeIntRef IntRef s
offset (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
get :: Buffer s a -> ST s (A.Array a)
get :: forall s a. Buffer s a -> ST s (Array a)
get (Buffer SmallMutableArray s a
buffer IntRef s
offset) = do
Int
len <- IntRef s -> ST s Int
forall s. IntRef s -> ST s Int
readIntRef IntRef s
offset
SmallArray a
result <- SmallMutableArray (PrimState (ST s)) a
-> Int -> Int -> ST s (SmallArray a)
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> Int -> m (SmallArray a)
freezeSmallArray SmallMutableArray s a
SmallMutableArray (PrimState (ST s)) a
buffer Int
0 Int
len
IntRef s -> Int -> ST s ()
forall s. IntRef s -> Int -> ST s ()
writeIntRef IntRef s
offset Int
0
Array a -> ST s (Array a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SmallArray a -> Array a
forall a. SmallArray a -> Array a
A.wrap SmallArray a
result)
size :: Buffer s a -> ST s Int
size :: forall s a. Buffer s a -> ST s Int
size (Buffer SmallMutableArray s a
_ IntRef s
offset) = IntRef s -> ST s Int
forall s. IntRef s -> ST s Int
readIntRef IntRef s
offset
{-# INLInE size #-}