{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ImplicitPrelude #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}

-- | Small-array
module GHC.Data.SmallArray
  ( SmallMutableArray (..)
  , SmallArray (..)
  , newSmallArray
  , writeSmallArray
  , freezeSmallArray
  , unsafeFreezeSmallArray
  , indexSmallArray
  , sizeofSmallArray
  , listToArray
  , smallArrayFromList
  , smallArrayToList
  , mapSmallArray
  , foldMapSmallArray
  , replicateSmallArrayIO
  , mapSmallArrayIO
  , mapSmallArrayM_
  , imapSmallArrayM_
  , rnfSmallArray

  -- * IO Operations
  , SmallMutableArrayIO
  , newSmallArrayIO
  , writeSmallArrayIO
  , unsafeFreezeSmallArrayIO
  )
where

import GHC.Exts
import GHC.IO
import GHC.ST
import Control.DeepSeq
import Control.Monad
import Data.Binary
import Data.Foldable
import Data.List (unfoldr)

data SmallArray a = SmallArray (SmallArray# a)

data SmallMutableArray s a = SmallMutableArray (SmallMutableArray# s a)

type SmallMutableArrayIO a = SmallMutableArray RealWorld a

instance Binary a => Binary (SmallArray a) where
  put :: SmallArray a -> Put
put SmallArray a
sa = Int -> Put
forall t. Binary t => t -> Put
put (SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa) Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (a -> Put) -> SmallArray a -> Put
forall m a. Monoid m => (a -> m) -> SmallArray a -> m
foldMapSmallArray a -> Put
forall t. Binary t => t -> Put
put SmallArray a
sa

  get :: Get (SmallArray a)
get = do
    n <- Get Int
forall t. Binary t => Get t
get
    smallArrayFromList <$> replicateM n get


instance Show a => Show (SmallArray a) where
  showsPrec :: Int -> SmallArray a -> ShowS
showsPrec Int
p = Int -> [a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p ([a] -> ShowS) -> (SmallArray a -> [a]) -> SmallArray a -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmallArray a -> [a]
forall a. SmallArray a -> [a]
smallArrayToList

newSmallArray
  :: Int  -- ^ size
  -> a    -- ^ initial contents
  -> State# s
  -> (# State# s, SmallMutableArray s a #)
{-# INLINE newSmallArray #-}
newSmallArray :: forall a s.
Int -> a -> State# s -> (# State# s, SmallMutableArray s a #)
newSmallArray (I# Int#
sz) a
x State# s
s = case Int# -> a -> State# s -> (# State# s, SmallMutableArray# s a #)
forall a d.
Int# -> a -> State# d -> (# State# d, SmallMutableArray# d a #)
newSmallArray# Int#
sz a
x State# s
s of
  (# State# s
s', SmallMutableArray# s a
a #) -> (# State# s
s', SmallMutableArray# s a -> SmallMutableArray s a
forall s a. SmallMutableArray# s a -> SmallMutableArray s a
SmallMutableArray SmallMutableArray# s a
a #)

newSmallArrayIO :: Int -> a -> IO (SmallMutableArrayIO a)
newSmallArrayIO :: forall a. Int -> a -> IO (SmallMutableArrayIO a)
newSmallArrayIO Int
sz a
x = (State# RealWorld -> (# State# RealWorld, SmallMutableArrayIO a #))
-> IO (SmallMutableArrayIO a)
(State# RealWorld -> (# State# RealWorld, SmallMutableArrayIO a #))
-> IO (SmallMutableArrayIO a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld
  -> (# State# RealWorld, SmallMutableArrayIO a #))
 -> IO (SmallMutableArrayIO a))
-> (State# RealWorld
    -> (# State# RealWorld, SmallMutableArrayIO a #))
-> IO (SmallMutableArrayIO a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> Int
-> a
-> State# RealWorld
-> (# State# RealWorld, SmallMutableArrayIO a #)
forall a s.
Int -> a -> State# s -> (# State# s, SmallMutableArray s a #)
newSmallArray Int
sz a
x State# RealWorld
s

writeSmallArray
  :: SmallMutableArray s a -- ^ array
  -> Int                   -- ^ index
  -> a                     -- ^ new element
  -> State# s
  -> State# s
{-# INLINE writeSmallArray #-}
writeSmallArray :: forall s a.
SmallMutableArray s a -> Int -> a -> State# s -> State# s
writeSmallArray (SmallMutableArray SmallMutableArray# s a
a) (I# Int#
i) a
x = SmallMutableArray# s a -> Int# -> a -> State# s -> State# s
forall d a.
SmallMutableArray# d a -> Int# -> a -> State# d -> State# d
writeSmallArray# SmallMutableArray# s a
a Int#
i a
x

writeSmallArrayIO :: SmallMutableArrayIO a
                  -> Int
                  -> a
                  -> IO ()
writeSmallArrayIO :: forall a. SmallMutableArrayIO a -> Int -> a -> IO ()
writeSmallArrayIO SmallMutableArrayIO a
a Int
ix a
v = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
(State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> (# SmallMutableArrayIO a
-> Int -> a -> State# RealWorld -> State# RealWorld
forall s a.
SmallMutableArray s a -> Int -> a -> State# s -> State# s
writeSmallArray SmallMutableArrayIO a
a Int
ix a
v State# RealWorld
s, () #)


-- | Copy and freeze a slice of a mutable array.
freezeSmallArray
  :: SmallMutableArray s a -- ^ source
  -> Int                   -- ^ offset
  -> Int                   -- ^ length
  -> State# s
  -> (# State# s, SmallArray a #)
{-# INLINE freezeSmallArray #-}
freezeSmallArray :: forall s a.
SmallMutableArray s a
-> Int -> Int -> State# s -> (# State# s, SmallArray a #)
freezeSmallArray (SmallMutableArray SmallMutableArray# s a
ma) (I# Int#
offset) (I# Int#
len) State# s
s =
  case SmallMutableArray# s a
-> Int# -> Int# -> State# s -> (# State# s, SmallArray# a #)
forall d a.
SmallMutableArray# d a
-> Int# -> Int# -> State# d -> (# State# d, SmallArray# a #)
freezeSmallArray# SmallMutableArray# s a
ma Int#
offset Int#
len State# s
s of
    (# State# s
s', SmallArray# a
a #) -> (# State# s
s', SmallArray# a -> SmallArray a
forall a. SmallArray# a -> SmallArray a
SmallArray SmallArray# a
a #)

-- | Freeze a mutable array (no copy!)
unsafeFreezeSmallArray
  :: SmallMutableArray s a
  -> State# s
  -> (# State# s, SmallArray a #)
{-# INLINE unsafeFreezeSmallArray #-}
unsafeFreezeSmallArray :: forall s a.
SmallMutableArray s a -> State# s -> (# State# s, SmallArray a #)
unsafeFreezeSmallArray (SmallMutableArray SmallMutableArray# s a
ma) State# s
s =
  case SmallMutableArray# s a -> State# s -> (# State# s, SmallArray# a #)
forall d a.
SmallMutableArray# d a -> State# d -> (# State# d, SmallArray# a #)
unsafeFreezeSmallArray# SmallMutableArray# s a
ma State# s
s of
    (# State# s
s', SmallArray# a
a #) -> (# State# s
s', SmallArray# a -> SmallArray a
forall a. SmallArray# a -> SmallArray a
SmallArray SmallArray# a
a #)

unsafeFreezeSmallArrayIO :: SmallMutableArrayIO a -> IO (SmallArray a)
unsafeFreezeSmallArrayIO :: forall a. SmallMutableArrayIO a -> IO (SmallArray a)
unsafeFreezeSmallArrayIO SmallMutableArrayIO a
arr = (State# RealWorld -> (# State# RealWorld, SmallArray a #))
-> IO (SmallArray a)
(State# RealWorld -> (# State# RealWorld, SmallArray a #))
-> IO (SmallArray a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, SmallArray a #))
 -> IO (SmallArray a))
-> (State# RealWorld -> (# State# RealWorld, SmallArray a #))
-> IO (SmallArray a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> SmallMutableArrayIO a
-> State# RealWorld -> (# State# RealWorld, SmallArray a #)
forall s a.
SmallMutableArray s a -> State# s -> (# State# s, SmallArray a #)
unsafeFreezeSmallArray SmallMutableArrayIO a
arr State# RealWorld
s

-- | Get the size of a 'SmallArray'
sizeofSmallArray
  :: SmallArray a
  -> Int
{-# INLINE sizeofSmallArray #-}
sizeofSmallArray :: forall a. SmallArray a -> Int
sizeofSmallArray (SmallArray SmallArray# a
sa#) =
  case SmallArray# a -> Int#
forall a. SmallArray# a -> Int#
sizeofSmallArray# SmallArray# a
sa# of
    Int#
s -> Int# -> Int
I# Int#
s

-- | Index a small-array (no bounds checking!)
indexSmallArray
  :: SmallArray a -- ^ array
  -> Int          -- ^ index
  -> a
{-# INLINE indexSmallArray #-}
indexSmallArray :: forall a. SmallArray a -> Int -> a
indexSmallArray (SmallArray SmallArray# a
sa#) (I# Int#
i) =
  case SmallArray# a -> Int# -> (# a #)
forall a. SmallArray# a -> Int# -> (# a #)
indexSmallArray# SmallArray# a
sa# Int#
i of
    (# a
v #) -> a
v

-- | Map a function over the elements of a 'SmallArray'
--
mapSmallArray :: (a -> b) -> SmallArray a -> SmallArray b
{-# INLINE mapSmallArray #-}
mapSmallArray :: forall a b. (a -> b) -> SmallArray a -> SmallArray b
mapSmallArray a -> b
f SmallArray a
sa = (forall s. ST s (SmallArray b)) -> SmallArray b
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (SmallArray b)) -> SmallArray b)
-> (forall s. ST s (SmallArray b)) -> SmallArray b
forall a b. (a -> b) -> a -> b
$ STRep s (SmallArray b) -> ST s (SmallArray b)
STRep s (SmallArray b) -> ST s (SmallArray b)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallArray b) -> ST s (SmallArray b))
-> STRep s (SmallArray b) -> ST s (SmallArray b)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
  let
    n :: Int
n = SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa
    go :: Int -> SmallMutableArray s b -> State# s -> State# s
go !Int
i SmallMutableArray s b
saMut# State# s
state#
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n =
        let
          a :: a
a = SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
sa Int
i
          newState# :: State# s
newState# = SmallMutableArray s b -> Int -> b -> State# s -> State# s
forall s a.
SmallMutableArray s a -> Int -> a -> State# s -> State# s
writeSmallArray SmallMutableArray s b
saMut# Int
i (a -> b
f a
a) State# s
state#
        in
          Int -> SmallMutableArray s b -> State# s -> State# s
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SmallMutableArray s b
saMut# State# s
newState#
      | Bool
otherwise = State# s
state#
  in
  case Int -> b -> State# s -> (# State# s, SmallMutableArray s b #)
forall a s.
Int -> a -> State# s -> (# State# s, SmallMutableArray s a #)
newSmallArray Int
n (String -> b
forall a. HasCallStack => String -> a
error String
"SmallArray: internal error, uninitialised elements") State# s
s of
    (# State# s
s', SmallMutableArray s b
mutArr #) ->
      case Int -> SmallMutableArray s b -> State# s -> State# s
go Int
0 SmallMutableArray s b
mutArr State# s
s' of
        State# s
s'' -> SmallMutableArray s b -> STRep s (SmallArray b)
forall s a.
SmallMutableArray s a -> State# s -> (# State# s, SmallArray a #)
unsafeFreezeSmallArray SmallMutableArray s b
mutArr State# s
s''

-- | Fold the values of a 'SmallArray' into a 'Monoid m' of choice
foldMapSmallArray :: Monoid m => (a -> m) -> SmallArray a -> m
{-# INLINE foldMapSmallArray #-}
foldMapSmallArray :: forall m a. Monoid m => (a -> m) -> SmallArray a -> m
foldMapSmallArray a -> m
f SmallArray a
sa = Int -> m
go Int
0
  where
    n :: Int
n = SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa
    go :: Int -> m
go Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = a -> m
f (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
sa Int
i) m -> m -> m
forall a. Monoid a => a -> a -> a
`mappend` Int -> m
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      | Bool
otherwise = m
forall a. Monoid a => a
mempty

-- | Execute the 'IO' action the given number of times and store the
-- results in a 'SmallArray'.
{-# INLINE replicateSmallArrayIO #-}
replicateSmallArrayIO :: Int -> IO a -> IO (SmallArray a)
replicateSmallArrayIO :: forall a. Int -> IO a -> IO (SmallArray a)
replicateSmallArrayIO Int
n IO a
m = do
  arr <- Int -> a -> IO (SmallMutableArrayIO a)
forall a. Int -> a -> IO (SmallMutableArrayIO a)
newSmallArrayIO Int
n a
forall a. HasCallStack => a
undefined
  let go Int
i
        | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = do
            SmallMutableArrayIO a -> Int -> a -> IO ()
forall a. SmallMutableArrayIO a -> Int -> a -> IO ()
writeSmallArrayIO SmallMutableArrayIO a
arr Int
i (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO a
m
            Int -> IO ()
go (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a. Enum a => a -> a
succ Int
i
        | Bool
otherwise = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  go 0
  unsafeFreezeSmallArrayIO arr

-- | Apply the 'IO' action to every element, producing a new
-- 'SmallArray'.
{-# INLINE mapSmallArrayIO #-}
mapSmallArrayIO :: (a -> IO b) -> SmallArray a -> IO (SmallArray b)
mapSmallArrayIO :: forall a b. (a -> IO b) -> SmallArray a -> IO (SmallArray b)
mapSmallArrayIO a -> IO b
f SmallArray a
sa = do
  ma <- Int -> b -> IO (SmallMutableArrayIO b)
forall a. Int -> a -> IO (SmallMutableArrayIO a)
newSmallArrayIO (SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa) b
forall a. HasCallStack => a
undefined
  flip imapSmallArrayM_ sa $ \Int
i a
v -> SmallMutableArrayIO b -> Int -> b -> IO ()
forall a. SmallMutableArrayIO a -> Int -> a -> IO ()
writeSmallArrayIO SmallMutableArrayIO b
ma Int
i (b -> IO ()) -> IO b -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO b
f a
v
  unsafeFreezeSmallArrayIO ma

-- | Apply the monadic action to every element, ignoring the results.
{-# INLINE mapSmallArrayM_ #-}
mapSmallArrayM_ :: Applicative f => (a -> f b) -> SmallArray a -> f ()
mapSmallArrayM_ :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SmallArray a -> f ()
mapSmallArrayM_ a -> f b
f = (Int -> a -> f b) -> SmallArray a -> f ()
forall (f :: * -> *) a b.
Applicative f =>
(Int -> a -> f b) -> SmallArray a -> f ()
imapSmallArrayM_ (\Int
_ a
v -> a -> f b
f a
v)

-- | Apply the monadic action to every element and its index, ignoring
-- the results.
{-# INLINE imapSmallArrayM_ #-}
imapSmallArrayM_ :: Applicative f => (Int -> a -> f b) -> SmallArray a -> f ()
imapSmallArrayM_ :: forall (f :: * -> *) a b.
Applicative f =>
(Int -> a -> f b) -> SmallArray a -> f ()
imapSmallArrayM_ Int -> a -> f b
f SmallArray a
sa = Int -> f ()
go Int
0
  where
    n :: Int
n = SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa
    go :: Int -> f ()
go Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = Int -> a -> f b
f Int
i (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
sa Int
i) f b -> f () -> f ()
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> f ()
go (Int -> Int
forall a. Enum a => a -> a
succ Int
i)
      | Bool
otherwise = () -> f ()
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Force the elements of the given 'SmallArray'
--
rnfSmallArray :: NFData a => SmallArray a -> ()
{-# INLINE rnfSmallArray #-}
rnfSmallArray :: forall a. NFData a => SmallArray a -> ()
rnfSmallArray SmallArray a
sa = Int -> ()
go Int
0
  where
    n :: Int
n = SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa
    go :: Int -> ()
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = a -> ()
forall a. NFData a => a -> ()
rnf (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
sa Int
i) () -> () -> ()
forall a b. a -> b -> b
`seq` Int -> ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      | Bool
otherwise = ()

-- | Convert a list into an array.
listToArray :: Int -> (e -> Int) -> (e -> a) -> [e] -> SmallArray a
{-# INLINE listToArray #-}
listToArray :: forall e a. Int -> (e -> Int) -> (e -> a) -> [e] -> SmallArray a
listToArray (I# Int#
size) e -> Int
index_of e -> a
value_of [e]
xs = (forall s. ST s (SmallArray a)) -> SmallArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (SmallArray a)) -> SmallArray a)
-> (forall s. ST s (SmallArray a)) -> SmallArray a
forall a b. (a -> b) -> a -> b
$ STRep s (SmallArray a) -> ST s (SmallArray a)
forall s a. STRep s a -> ST s a
ST \State# s
s ->
  let
    index_of' :: e -> Int#
index_of' e
e = case e -> Int
index_of e
e of I# Int#
i -> Int#
i
    write_elems :: SmallMutableArray# s a -> [e] -> State# s -> State# s
write_elems SmallMutableArray# s a
ma [e]
es State# s
s = case [e]
es of
      []    -> State# s
s
      e
e:[e]
es' -> case SmallMutableArray# s a -> Int# -> a -> State# s -> State# s
forall d a.
SmallMutableArray# d a -> Int# -> a -> State# d -> State# d
writeSmallArray# SmallMutableArray# s a
ma (e -> Int#
index_of' e
e) (e -> a
value_of e
e) State# s
s of
                 State# s
s' -> SmallMutableArray# s a -> [e] -> State# s -> State# s
write_elems SmallMutableArray# s a
ma [e]
es' State# s
s'
  in
  case Int# -> a -> State# s -> (# State# s, SmallMutableArray# s a #)
forall a d.
Int# -> a -> State# d -> (# State# d, SmallMutableArray# d a #)
newSmallArray# Int#
size a
forall a. HasCallStack => a
undefined State# s
s of
    (# State# s
s', SmallMutableArray# s a
ma #) -> case SmallMutableArray# s a -> [e] -> State# s -> State# s
write_elems SmallMutableArray# s a
ma [e]
xs State# s
s' of
      State# s
s'' -> case SmallMutableArray# s a -> State# s -> (# State# s, SmallArray# a #)
forall d a.
SmallMutableArray# d a -> State# d -> (# State# d, SmallArray# a #)
unsafeFreezeSmallArray# SmallMutableArray# s a
ma State# s
s'' of
        (# State# s
s''', SmallArray# a
a #) -> (# State# s
s''', SmallArray# a -> SmallArray a
forall a. SmallArray# a -> SmallArray a
SmallArray SmallArray# a
a #)

-- | Construct a 'SmallArray' from a list. This is different from
-- 'listToArray' since the list elements fill the 'SmallArray'
-- sequentially without recalculating the indices or remapping to
-- other element types.
{-# INLINE smallArrayFromList #-}
smallArrayFromList :: [a] -> SmallArray a
smallArrayFromList :: forall a. [a] -> SmallArray a
smallArrayFromList [a]
vs = (forall s. ST s (SmallArray a)) -> SmallArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (SmallArray a)) -> SmallArray a)
-> (forall s. ST s (SmallArray a)) -> SmallArray a
forall a b. (a -> b) -> a -> b
$ STRep s (SmallArray a) -> ST s (SmallArray a)
STRep s (SmallArray a) -> ST s (SmallArray a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallArray a) -> ST s (SmallArray a))
-> STRep s (SmallArray a) -> ST s (SmallArray a)
forall a b. (a -> b) -> a -> b
$ \State# s
s0 ->
  case Int -> a -> State# s -> (# State# s, SmallMutableArray s a #)
forall a s.
Int -> a -> State# s -> (# State# s, SmallMutableArray s a #)
newSmallArray ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
vs) a
forall a. HasCallStack => a
undefined State# s
s0 of
    (# State# s
s1, SmallMutableArray s a
ma #) ->
      case (Int -> a -> ST s Int) -> Int -> [a] -> ST s Int
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (\Int
i a
v -> STRep s Int -> ST s Int
STRep s Int -> ST s Int
forall s a. STRep s a -> ST s a
ST (STRep s Int -> ST s Int) -> STRep s Int -> ST s Int
forall a b. (a -> b) -> a -> b
$ \State# s
s0 ->
        case SmallMutableArray s a -> Int -> a -> State# s -> State# s
forall s a.
SmallMutableArray s a -> Int -> a -> State# s -> State# s
writeSmallArray SmallMutableArray s a
ma Int
i a
v State# s
s0 of
          State# s
s1 -> (# State# s
s1, Int -> Int
forall a. Enum a => a -> a
succ Int
i #)) Int
0 [a]
vs of
            ST STRep s Int
m -> case STRep s Int
m State# s
s1 of
              (# State# s
s2, Int
_ #) -> SmallMutableArray s a -> STRep s (SmallArray a)
forall s a.
SmallMutableArray s a -> State# s -> (# State# s, SmallArray a #)
unsafeFreezeSmallArray SmallMutableArray s a
ma State# s
s2

-- | Construct a list from a 'SmallArray'.
{-# INLINE smallArrayToList #-}
smallArrayToList :: SmallArray a -> [a]
smallArrayToList :: forall a. SmallArray a -> [a]
smallArrayToList SmallArray a
sa = (Int -> Maybe (a, Int)) -> Int -> [a]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr Int -> Maybe (a, Int)
go Int
0
  where
    n :: Int
n = SmallArray a -> Int
forall a. SmallArray a -> Int
sizeofSmallArray SmallArray a
sa
    go :: Int -> Maybe (a, Int)
go Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = (a, Int) -> Maybe (a, Int)
forall a. a -> Maybe a
Just (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
sa Int
i, Int -> Int
forall a. Enum a => a -> a
succ Int
i)
      | Bool
otherwise = Maybe (a, Int)
forall a. Maybe a
Nothing