{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-}

module Agda.Utils.MinimalArray.Prim where

import GHC.Exts
import qualified Data.Primitive.PrimArray as A
import Data.Primitive.Types
import Control.Monad.Primitive

newtype Array a = Array {forall a. Array a -> PrimArray a
unwrap :: A.PrimArray a}
  deriving (Array a -> Array a -> Bool
(Array a -> Array a -> Bool)
-> (Array a -> Array a -> Bool) -> Eq (Array a)
forall a. (Eq a, Prim a) => Array a -> Array a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. (Eq a, Prim a) => Array a -> Array a -> Bool
== :: Array a -> Array a -> Bool
$c/= :: forall a. (Eq a, Prim a) => Array a -> Array a -> Bool
/= :: Array a -> Array a -> Bool
Eq, Int -> Array a -> ShowS
[Array a] -> ShowS
Array a -> String
(Int -> Array a -> ShowS)
-> (Array a -> String) -> ([Array a] -> ShowS) -> Show (Array a)
forall a. (Show a, Prim a) => Int -> Array a -> ShowS
forall a. (Show a, Prim a) => [Array a] -> ShowS
forall a. (Show a, Prim a) => Array a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. (Show a, Prim a) => Int -> Array a -> ShowS
showsPrec :: Int -> Array a -> ShowS
$cshow :: forall a. (Show a, Prim a) => Array a -> String
show :: Array a -> String
$cshowList :: forall a. (Show a, Prim a) => [Array a] -> ShowS
showList :: [Array a] -> ShowS
Show, Int -> [Item (Array a)] -> Array a
[Item (Array a)] -> Array a
Array a -> [Item (Array a)]
([Item (Array a)] -> Array a)
-> (Int -> [Item (Array a)] -> Array a)
-> (Array a -> [Item (Array a)])
-> IsList (Array a)
forall a. Prim a => Int -> [Item (Array a)] -> Array a
forall a. Prim a => [Item (Array a)] -> Array a
forall a. Prim a => Array a -> [Item (Array a)]
forall l.
([Item l] -> l)
-> (Int -> [Item l] -> l) -> (l -> [Item l]) -> IsList l
$cfromList :: forall a. Prim a => [Item (Array a)] -> Array a
fromList :: [Item (Array a)] -> Array a
$cfromListN :: forall a. Prim a => Int -> [Item (Array a)] -> Array a
fromListN :: Int -> [Item (Array a)] -> Array a
$ctoList :: forall a. Prim a => Array a -> [Item (Array a)]
toList :: Array a -> [Item (Array a)]
IsList)

{-# INLINE size #-}
size :: Prim a => Array a -> Int
size :: forall a. Prim a => Array a -> Int
size (Array PrimArray a
arr) = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
A.sizeofPrimArray PrimArray a
arr

{-# INLINE unsafeIndex #-}
unsafeIndex :: Prim a => Array a -> Int -> a
unsafeIndex :: forall a. Prim a => Array a -> Int -> a
unsafeIndex (Array PrimArray a
arr) Int
i = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
A.indexPrimArray PrimArray a
arr Int
i

{-# INLINE index #-}
index :: Prim a => Array a -> Int -> a
index :: forall a. Prim a => Array a -> Int -> a
index Array a
arr Int
i | Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Array a -> Int
forall a. Prim a => Array a -> Int
size Array a
arr = Array a -> Int -> a
forall a. Prim a => Array a -> Int -> a
unsafeIndex Array a
arr Int
i
            | Bool
otherwise = String -> a
forall a. HasCallStack => String -> a
error String
"Array: out of bounds"

{-# INLINE foldr' #-}
foldr' :: forall a b. Prim a => (a -> b -> b) -> b -> Array a -> b
foldr' :: forall a b. Prim a => (a -> b -> b) -> b -> Array a -> b
foldr' a -> b -> b
f b
b (Array PrimArray a
arr) = (a -> b -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
A.foldrPrimArray' a -> b -> b
f b
b PrimArray a
arr

{-# INLINE foldl' #-}
foldl' :: forall a b. Prim a => (b -> a -> b) -> b -> Array a -> b
foldl' :: forall a b. Prim a => (b -> a -> b) -> b -> Array a -> b
foldl' b -> a -> b
f b
b (Array PrimArray a
arr) = (b -> a -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
A.foldlPrimArray' b -> a -> b
f b
b PrimArray a
arr

{-# INLINE map #-}
map :: (Prim a, Prim b) => (Int -> a -> b) -> Array a -> Array b
map :: forall a b.
(Prim a, Prim b) =>
(Int -> a -> b) -> Array a -> Array b
map Int -> a -> b
f (Array PrimArray a
arr) = PrimArray b -> Array b
forall a. PrimArray a -> Array a
Array ((Int -> a -> b) -> PrimArray a -> PrimArray b
forall a b.
(Prim a, Prim b) =>
(Int -> a -> b) -> PrimArray a -> PrimArray b
A.imapPrimArray Int -> a -> b
f PrimArray a
arr)

toList :: Prim a => Array a -> [a]
toList :: forall a. Prim a => Array a -> [a]
toList = Array a -> [a]
Array a -> [Item (Array a)]
forall l. IsList l => l -> [Item l]
GHC.Exts.toList

fromList :: Prim a => [a] -> Array a
fromList :: forall a. Prim a => [a] -> Array a
fromList = [a] -> Array a
[Item (Array a)] -> Array a
forall l. IsList l => [Item l] -> l
GHC.Exts.fromList

fromListN :: Prim a => Int -> [a] -> Array a
fromListN :: forall a. Prim a => Int -> [a] -> Array a
fromListN = Int -> [a] -> Array a
Int -> [Item (Array a)] -> Array a
forall l. IsList l => Int -> [Item l] -> l
GHC.Exts.fromListN