{-# language BangPatterns #-}
{-# language MagicHash #-}
{-# language RankNTypes #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language TypeInType #-}
{-# language StandaloneKindSignatures #-}
{-# language UnboxedTuples #-}

module Int
  ( R
  , A#
  , M#
  , empty#
  , index#
  , write#
  , read#
  , unsafeFreeze#
  , initialized#
  , set#
  , unsafeShrinkFreeze#
  , thaw#
  , freeze#
  , copy#
    -- Comparison
  , lt
  , gt
  , eq
  , lt#
  , gt#
  , eq#
  , max
  ) where

import Prelude hiding (max)

import GHC.Exts
import Data.Kind (Type)
import Data.Unlifted (PrimArray#(..),MutablePrimArray#(..))
import EmptyPrimArray (emptyPrimArray#)

import qualified GHC.Exts as Exts

type A# = PrimArray# @'IntRep
type M# = MutablePrimArray# @'IntRep
type R = 'IntRep

max :: forall (a :: TYPE R). a -> a -> a
{-# inline max #-}
max :: forall (a :: TYPE R). a -> a -> a
max a
x a
y = if a -> a -> Bool
forall (a :: TYPE R). a -> a -> Bool
gt a
x a
y then a
x else a
y

lt :: forall (a :: TYPE R). a -> a -> Bool
{-# inline lt #-}
lt :: forall (a :: TYPE R). a -> a -> Bool
lt a
x a
y = Int# -> Bool
isTrue# (a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
<# a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y)

gt :: forall (a :: TYPE R). a -> a -> Bool
{-# inline gt #-}
gt :: forall (a :: TYPE R). a -> a -> Bool
gt a
x a
y = Int# -> Bool
isTrue# (a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
># a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y)

eq :: forall (a :: TYPE R). a -> a -> Bool
{-# inline eq #-}
eq :: forall (a :: TYPE R). a -> a -> Bool
eq a
x a
y = Int# -> Bool
isTrue# (a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
==# a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y)

lt# :: forall (a :: TYPE R). a -> a -> Int#
{-# inline lt# #-}
lt# :: forall (a :: TYPE R). a -> a -> Int#
lt# a
x a
y = a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
<# a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y

gt# :: forall (a :: TYPE R). a -> a -> Int#
{-# inline gt# #-}
gt# :: forall (a :: TYPE R). a -> a -> Int#
gt# a
x a
y = a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
># a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y

eq# :: forall (a :: TYPE R). a -> a -> Int#
{-# inline eq# #-}
eq# :: forall (a :: TYPE R). a -> a -> Int#
eq# a
x a
y = a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
x Int# -> Int# -> Int#
==# a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
y

unsafeFromI :: forall (a :: TYPE 'IntRep). Int# -> a
unsafeFromI :: forall (a :: TYPE R). Int# -> a
unsafeFromI Int#
x = Int# -> a
forall a b. a -> b
unsafeCoerce# Int#
x

unsafeToI:: forall (a :: TYPE 'IntRep). a -> Int#
unsafeToI :: forall (a :: TYPE R). a -> Int#
unsafeToI a
x = a -> Int#
forall a b. a -> b
unsafeCoerce# a
x

index# :: forall (a :: TYPE R). A# a -> Int# -> a
index# :: forall (a :: TYPE R). A# a -> Int# -> a
index# (PrimArray# ByteArray#
a) Int#
i = Int# -> a
forall (a :: TYPE R). Int# -> a
unsafeFromI (ByteArray# -> Int# -> Int#
indexIntArray# ByteArray#
a Int#
i)

write# :: forall (s :: Type) (a :: TYPE R).
  M# s a -> Int# -> a -> State# s -> State# s
write# :: forall s (a :: TYPE R). M# s a -> Int# -> a -> State# s -> State# s
write# (MutablePrimArray# MutableByteArray# s
m) Int#
ix a
a State# s
s = MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
writeIntArray# MutableByteArray# s
m Int#
ix (a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
a) State# s
s

read# :: forall (s :: Type) (a :: TYPE R).
  M# s a -> Int# -> State# s -> (# State# s, a #)
read# :: forall s (a :: TYPE R).
M# s a -> Int# -> State# s -> (# State# s, a #)
read# (MutablePrimArray# MutableByteArray# s
m) Int#
ix State# s
s = case MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)
readIntArray# MutableByteArray# s
m Int#
ix State# s
s of
  (# State# s
s', Int#
r #) -> case Int# -> a
forall (a :: TYPE R). Int# -> a
unsafeFromI Int#
r of
    a
r' -> (# State# s
s', a
r' #)

unsafeFreeze# :: forall (s :: Type) (a :: TYPE R).
     M# s a
  -> State# s
  -> (# State# s, A# a #)
unsafeFreeze# :: forall s (a :: TYPE R). M# s a -> State# s -> (# State# s, A# a #)
unsafeFreeze# (MutablePrimArray# MutableByteArray# s
m) State# s
s0 = case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# s
m State# s
s0 of
  (# State# s
s1, ByteArray#
v #) -> (# State# s
s1, ByteArray# -> A# a
forall a. ByteArray# -> PrimArray# a
PrimArray# ByteArray#
v #)

empty# :: forall (a :: TYPE R). (# #) -> A# a
empty# :: forall (a :: TYPE R). (# #) -> A# a
empty# = (# #) -> PrimArray# a
forall a. (# #) -> PrimArray# a
emptyPrimArray#

initialized# :: forall (s :: Type) (a :: TYPE R).
     Int#
  -> a
  -> State# s
  -> (# State# s, M# s a #)
initialized# :: forall s (a :: TYPE R).
Int# -> a -> State# s -> (# State# s, M# s a #)
initialized# Int#
n a
a State# s
s0 = case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# (Int#
n Int# -> Int# -> Int#
*# Int#
8# ) State# s
s0 of
  (# State# s
s1, MutableByteArray# s
b #) -> case a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
a of
    Int#
0# -> case MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d
Exts.setByteArray# MutableByteArray# s
b Int#
0# (Int#
n Int# -> Int# -> Int#
*# Int#
8#) Int#
0# State# s
s1 of
      State# s
s2 -> (# State# s
s2, MutableByteArray# s -> M# s a
forall a b. MutableByteArray# a -> MutablePrimArray# a b
MutablePrimArray# MutableByteArray# s
b #)
    Int#
_ -> case M# s a -> Int# -> Int# -> a -> State# s -> State# s
forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> a -> State# s -> State# s
setLoop# (MutableByteArray# s -> M# s a
forall a b. MutableByteArray# a -> MutablePrimArray# a b
MutablePrimArray# MutableByteArray# s
b) Int#
0# Int#
n a
a State# s
s1 of
      State# s
s2 -> (# State# s
s2, MutableByteArray# s -> M# s a
forall a b. MutableByteArray# a -> MutablePrimArray# a b
MutablePrimArray# MutableByteArray# s
b #)

-- Not exported. Offset and length are counts of elements, not bytes
setLoop# :: forall (s :: Type) (a :: TYPE R). M# s a -> Int# -> Int# -> a -> State# s -> State# s
setLoop# :: forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> a -> State# s -> State# s
setLoop# M# s a
marr Int#
off Int#
len a
x State# s
s = case Int#
len of                                    
  Int#
0# -> State# s
s
  Int#
_ -> M# s a -> Int# -> Int# -> a -> State# s -> State# s
forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> a -> State# s -> State# s
setLoop# M# s a
marr (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) (Int#
len Int# -> Int# -> Int#
-# Int#
1# ) a
x (M# s a -> Int# -> a -> State# s -> State# s
forall s (a :: TYPE R). M# s a -> Int# -> a -> State# s -> State# s
write# M# s a
marr Int#
off a
x State# s
s)                         

set# :: forall (s :: Type) (a :: TYPE R).
     M# s a
  -> Int#
  -> Int#
  -> a
  -> State# s
  -> State# s
set# :: forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> a -> State# s -> State# s
set# m :: M# s a
m@(MutablePrimArray# MutableByteArray# s
b) Int#
off0 Int#
len0 a
a State# s
s0 = case a -> Int#
forall (a :: TYPE R). a -> Int#
unsafeToI a
a of
  Int#
0# -> MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d
Exts.setByteArray# MutableByteArray# s
b (Int#
off0 Int# -> Int# -> Int#
*# Int#
8# ) (Int#
len0 Int# -> Int# -> Int#
*# Int#
8# ) Int#
0# State# s
s0
  Int#
_ -> M# s a -> Int# -> Int# -> a -> State# s -> State# s
forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> a -> State# s -> State# s
setLoop# M# s a
m Int#
off0 Int#
len0 a
a State# s
s0

-- shrink and freeze, all at once
unsafeShrinkFreeze# ::
     M# s a
  -> Int# -- number of elements to preserve
  -> State# s
  -> (# State# s, A# a #)
unsafeShrinkFreeze# :: forall s (a :: TYPE R).
M# s a -> Int# -> State# s -> (# State# s, A# a #)
unsafeShrinkFreeze# (MutablePrimArray# MutableByteArray# s
m) Int#
elemCount State# s
s0Alpha =
  let !byteCount :: Int#
byteCount = Int#
elemCount Int# -> Int# -> Int#
*# Int#
8#
   in case MutableByteArray# s -> State# s -> (# State# s, Int# #)
forall d. MutableByteArray# d -> State# d -> (# State# d, Int# #)
getSizeofMutableByteArray# MutableByteArray# s
m State# s
s0Alpha of
        (# State# s
s0, Int#
sz #) -> case Int#
sz Int# -> Int# -> Int#
==# Int#
byteCount of
          Int#
1# -> case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
Exts.unsafeFreezeByteArray# MutableByteArray# s
m State# s
s0 of
            (# State# s
s1, ByteArray#
v #) -> (# State# s
s1, ByteArray# -> A# a
forall a. ByteArray# -> PrimArray# a
PrimArray# ByteArray#
v #)
          Int#
_ -> case MutableByteArray# s -> Int# -> State# s -> State# s
forall d. MutableByteArray# d -> Int# -> State# d -> State# d
Exts.shrinkMutableByteArray# MutableByteArray# s
m Int#
byteCount State# s
s0 of
            State# s
s1 -> case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
Exts.unsafeFreezeByteArray# MutableByteArray# s
m State# s
s1 of
              (# State# s
s2, ByteArray#
v #) -> (# State# s
s2, ByteArray# -> A# a
forall a. ByteArray# -> PrimArray# a
PrimArray# ByteArray#
v #)

thaw# :: forall (s :: Type) (a :: TYPE R).
     A# a
  -> Int#
  -> Int#
  -> State# s
  -> (# State# s, M# s a #)
thaw# :: forall s (a :: TYPE R).
A# a -> Int# -> Int# -> State# s -> (# State# s, M# s a #)
thaw# (PrimArray# ByteArray#
v) Int#
off Int#
len State# s
s0 = case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
Exts.newByteArray# (Int#
len Int# -> Int# -> Int#
*# Int#
8# ) State# s
s0 of
  (# State# s
s1, MutableByteArray# s
m #) -> case ByteArray#
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
ByteArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
Exts.copyByteArray# ByteArray#
v (Int#
off Int# -> Int# -> Int#
*# Int#
8# ) MutableByteArray# s
m Int#
0# (Int#
len Int# -> Int# -> Int#
*# Int#
8# ) State# s
s1 of
    State# s
s2 -> (# State# s
s2, MutableByteArray# s -> M# s a
forall a b. MutableByteArray# a -> MutablePrimArray# a b
MutablePrimArray# MutableByteArray# s
m #)

freeze# :: forall (s :: Type) (a :: TYPE R).
     M# s a
  -> Int#
  -> Int#
  -> State# s
  -> (# State# s, A# a #)
freeze# :: forall s (a :: TYPE R).
M# s a -> Int# -> Int# -> State# s -> (# State# s, A# a #)
freeze# (MutablePrimArray# MutableByteArray# s
v) Int#
off Int#
len State# s
s0 = case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
Exts.newByteArray# (Int#
len Int# -> Int# -> Int#
*# Int#
8# ) State# s
s0 of
  (# State# s
s1, MutableByteArray# s
m #) -> case MutableByteArray# s
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
MutableByteArray# d
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
Exts.copyMutableByteArray# MutableByteArray# s
v (Int#
off Int# -> Int# -> Int#
*# Int#
8# ) MutableByteArray# s
m Int#
0# (Int#
len Int# -> Int# -> Int#
*# Int#
8# ) State# s
s1 of
    State# s
s2 -> case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
Exts.unsafeFreezeByteArray# MutableByteArray# s
m State# s
s2 of
      (# State# s
s3, ByteArray#
x #) -> (# State# s
s3, ByteArray# -> A# a
forall a. ByteArray# -> PrimArray# a
PrimArray# ByteArray#
x #)

copy# :: forall (s :: Type) (a :: TYPE R).
     M# s a
  -> Int#
  -> A# a
  -> Int#
  -> Int#
  -> State# s
  -> State# s
copy# :: forall s (a :: TYPE R).
M# s a -> Int# -> A# a -> Int# -> Int# -> State# s -> State# s
copy# (MutablePrimArray# MutableByteArray# s
m) Int#
doff (PrimArray# ByteArray#
v) Int#
soff Int#
len State# s
s0 =
  ByteArray#
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
ByteArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
Exts.copyByteArray# ByteArray#
v (Int#
8# Int# -> Int# -> Int#
*# Int#
soff) MutableByteArray# s
m (Int#
8# Int# -> Int# -> Int#
*# Int#
doff) (Int#
8# Int# -> Int# -> Int#
*# Int#
len) State# s
s0