module STMContainers.SizedArray where
import STMContainers.Prelude hiding (lookup, toList, foldM)
import Data.Primitive.Array
import qualified STMContainers.Prelude as Prelude
import qualified Focus
data SizedArray a =
SizedArray {-# UNPACK #-} !Int {-# UNPACK #-} !(Array a)
instance Foldable SizedArray where
{-# INLINE foldr #-}
foldr step r (SizedArray size array) =
foldr step r $ map (indexArray array) [0 .. pred size]
type Index = Int
{-# INLINE pair #-}
pair :: a -> a -> SizedArray a
pair e e' =
runST $ do
a <- newArray 2 e
writeArray a 1 e'
SizedArray 2 <$> unsafeFreezeArray a
{-# INLINE size #-}
size :: SizedArray a -> Int
size (SizedArray b _) = b
{-# INLINE null #-}
null :: SizedArray a -> Bool
null = (== 0) . size
{-# INLINE find #-}
find :: (a -> Bool) -> SizedArray a -> Maybe (Index, a)
find p (SizedArray s a) = loop 0
where
loop i = if i < s
then let e = indexArray a i in if p e
then Just (i, e)
else loop (succ i)
else Nothing
{-# INLINE insert #-}
insert :: Index -> a -> SizedArray a -> SizedArray a
insert i e (SizedArray s a) =
runST $ do
m' <- newArray s undefined
forM_ [0 .. pred s] $ \i' -> indexArrayM a i' >>= writeArray m' i'
writeArray m' i e
SizedArray s <$> unsafeFreezeArray m'
{-# INLINE delete #-}
delete :: Index -> SizedArray a -> SizedArray a
delete i (SizedArray s a) =
runST $ do
m' <- newArray (pred s) undefined
forM_ [0 .. pred i] $ \i' -> indexArrayM a i' >>= writeArray m' i'
forM_ [succ i .. pred s] $ \i' -> indexArrayM a i' >>= writeArray m' (pred i')
SizedArray (pred s) <$> unsafeFreezeArray m'
{-# INLINE append #-}
append :: a -> SizedArray a -> SizedArray a
append e (SizedArray s a) =
runST $ do
m' <- newArray (succ s) undefined
forM_ [0 .. pred s] $ \i -> indexArrayM a i >>= writeArray m' i
writeArray m' s e
SizedArray (succ s) <$> unsafeFreezeArray m'
{-# INLINE foldM #-}
foldM :: (Monad m) => (a -> b -> m a) -> a -> SizedArray b -> m a
foldM step acc (SizedArray size array) =
Prelude.foldM step' acc [0 .. pred size]
where
step' acc' i = indexArrayM array i >>= step acc'