{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE BangPatterns #-}

-- | Helper functions for SmallArray#
--
-- This module exposes _unsafe_ functions to work with SmallArrays.  That means
-- that specifically neither index bounds nor element types are checked So this
-- functionality should only be used in a context that enforces them by some
-- other means, e.g. ARec's type index

module Data.Vinyl.ARec.Internal.SmallArray where

import GHC.Prim
import GHC.Types
import Unsafe.Coerce
import GHC.ST

data SmallArray = SmallArray !(SmallArray# Any)
data SmallMutableArray s = SmallMutableArray !(SmallMutableArray# s Any)

indexSmallArray :: SmallArray -> Int -> a
indexSmallArray :: SmallArray -> Int -> a
indexSmallArray (SmallArray SmallArray# Any
arr) (I# Int#
ix) =
  case SmallArray# Any -> Int# -> (# Any #)
forall a. SmallArray# a -> Int# -> (# a #)
indexSmallArray# SmallArray# Any
arr Int#
ix of
    (# Any
v #) -> Any -> a
forall a b. a -> b
unsafeCoerce Any
v
{-# INLINE indexSmallArray #-}

withNewSmallArray :: Int -> (SmallMutableArray s -> ST s ()) -> ST s SmallArray
withNewSmallArray :: Int -> (SmallMutableArray s -> ST s ()) -> ST s SmallArray
withNewSmallArray (I# Int#
len#) SmallMutableArray s -> ST s ()
f =
  STRep s SmallArray -> ST s SmallArray
forall s a. STRep s a -> ST s a
ST (STRep s SmallArray -> ST s SmallArray)
-> STRep s SmallArray -> ST s SmallArray
forall a b. (a -> b) -> a -> b
$ \State# s
s0 ->  case Int# -> Any -> State# s -> (# State# s, SmallMutableArray# s Any #)
forall a d.
Int# -> a -> State# d -> (# State# d, SmallMutableArray# d a #)
newSmallArray# Int#
len# ([Char] -> Any
forall a. HasCallStack => [Char] -> a
error [Char]
"withNewSmallArray exploded") State# s
s0 of
       (# State# s
s1, SmallMutableArray# s Any
mArr #) ->
         case SmallMutableArray s -> ST s ()
f (SmallMutableArray# s Any -> SmallMutableArray s
forall s. SmallMutableArray# s Any -> SmallMutableArray s
SmallMutableArray SmallMutableArray# s Any
mArr) of
           ST STRep s ()
st -> case STRep s ()
st State# s
s1 of
             (# State# s
s2, () #) -> case SmallMutableArray# s Any
-> State# s -> (# State# s, SmallArray# Any #)
forall d a.
SmallMutableArray# d a -> State# d -> (# State# d, SmallArray# a #)
unsafeFreezeSmallArray# SmallMutableArray# s Any
mArr State# s
s2 of
               (# State# s
s3, SmallArray# Any
ar #) -> (# State# s
s3, SmallArray# Any -> SmallArray
SmallArray SmallArray# Any
ar #)
{-# INLINE withNewSmallArray #-}

writeSmallArray :: SmallMutableArray s -> Int -> a -> ST s ()
writeSmallArray :: SmallMutableArray s -> Int -> a -> ST s ()
writeSmallArray (SmallMutableArray SmallMutableArray# s Any
mArr) (I# Int#
n#) a
x = STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
  case SmallMutableArray# s Any -> Int# -> Any -> State# s -> State# s
forall d a.
SmallMutableArray# d a -> Int# -> a -> State# d -> State# d
writeSmallArray# SmallMutableArray# s Any
mArr Int#
n# (a -> Any
forall a b. a -> b
unsafeCoerce a
x) State# s
s of
    State# s
s' -> (# State# s
s', () #)
{-# INLINE writeSmallArray #-}

withThawedSmallArray :: SmallArray
               -> (SmallMutableArray s -> ST s ())
               -> ST s SmallArray
withThawedSmallArray :: SmallArray -> (SmallMutableArray s -> ST s ()) -> ST s SmallArray
withThawedSmallArray (SmallArray SmallArray# Any
arr) SmallMutableArray s -> ST s ()
f = STRep s SmallArray -> ST s SmallArray
forall s a. STRep s a -> ST s a
ST (STRep s SmallArray -> ST s SmallArray)
-> STRep s SmallArray -> ST s SmallArray
forall a b. (a -> b) -> a -> b
$ \State# s
s0 ->
  let !(I# Int#
z#) = Int
0
  in case SmallArray# Any
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallMutableArray# s Any #)
forall a d.
SmallArray# a
-> Int#
-> Int#
-> State# d
-> (# State# d, SmallMutableArray# d a #)
thawSmallArray# SmallArray# Any
arr Int#
z# (SmallArray# Any -> Int#
forall a. SmallArray# a -> Int#
sizeofSmallArray# SmallArray# Any
arr) State# s
s0 of
       (# State# s
s1, SmallMutableArray# s Any
mArr #) ->
         case SmallMutableArray s -> ST s ()
f (SmallMutableArray# s Any -> SmallMutableArray s
forall s. SmallMutableArray# s Any -> SmallMutableArray s
SmallMutableArray SmallMutableArray# s Any
mArr) of
           ST STRep s ()
st -> case STRep s ()
st State# s
s1 of
             (# State# s
s2, () #) -> case SmallMutableArray# s Any
-> State# s -> (# State# s, SmallArray# Any #)
forall d a.
SmallMutableArray# d a -> State# d -> (# State# d, SmallArray# a #)
unsafeFreezeSmallArray# SmallMutableArray# s Any
mArr State# s
s2 of
               (# State# s
s3, SmallArray# Any
ar #) -> (# State# s
s3, SmallArray# Any -> SmallArray
SmallArray SmallArray# Any
ar #)
{-# INLINE withThawedSmallArray #-}