{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
--------------------------------------------------------------------------------
-- |
-- Copyright   : (c) Edward Kmett 2015
-- License     : BSD-style
-- Maintainer  : Edward Kmett <ekmett@gmail.com>
-- Portability : non-portable
--
-- Small primitive boxed arrays
--
--------------------------------------------------------------------------------
module Data.Discrimination.Internal.SmallArray (
  SmallArray(..), SmallMutableArray(..),
  newSmallArray, readSmallArray, writeSmallArray, indexSmallArray, indexSmallArrayM,
  unsafeFreezeSmallArray, unsafeThawSmallArray, sameSmallMutableArray,
  copySmallArray, copySmallMutableArray,
  cloneSmallArray, cloneSmallMutableArray
) where

import Control.DeepSeq
import Control.Monad.Primitive
import Data.Foldable as Foldable
import GHC.Exts
import GHC.ST

-- | Boxed arrays
data SmallArray a = SmallArray (SmallArray# a)

-- | Mutable boxed arrays associated with a primitive state token.
data SmallMutableArray s a = SmallMutableArray (SmallMutableArray# s a)

-- | Create a new mutable array of the specified size and initialise all
-- elements with the given value.
newSmallArray :: PrimMonad m => Int -> a -> m (SmallMutableArray (PrimState m) a)
{-# INLINE newSmallArray #-}
newSmallArray :: Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray (I# Int#
n#) a
x = (State# (PrimState m)
 -> (# State# (PrimState m), SmallMutableArray (PrimState m) a #))
-> m (SmallMutableArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive
   (\State# (PrimState m)
s# -> case Int#
-> a
-> State# (PrimState m)
-> (# State# (PrimState m), SmallMutableArray# (PrimState m) a #)
forall a d.
Int# -> a -> State# d -> (# State# d, SmallMutableArray# d a #)
newSmallArray# Int#
n# a
x State# (PrimState m)
s# of
             (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
arr# #) -> (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
-> SmallMutableArray (PrimState m) a
forall s a. SmallMutableArray# s a -> SmallMutableArray s a
SmallMutableArray SmallMutableArray# (PrimState m) a
arr# #))

-- | Read a value from the array at the given index.
readSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> m a
{-# INLINE readSmallArray #-}
readSmallArray :: SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray (SmallMutableArray SmallMutableArray# (PrimState m) a
arr#) (I# Int#
i#) = (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (SmallMutableArray# (PrimState m) a
-> Int# -> State# (PrimState m) -> (# State# (PrimState m), a #)
forall d a.
SmallMutableArray# d a -> Int# -> State# d -> (# State# d, a #)
readSmallArray# SmallMutableArray# (PrimState m) a
arr# Int#
i#)

-- | Write a value to the array at the given index.
writeSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> a -> m ()
{-# INLINE writeSmallArray #-}
writeSmallArray :: SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray (SmallMutableArray SmallMutableArray# (PrimState m) a
arr#) (I# Int#
i#) a
x = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (SmallMutableArray# (PrimState m) a
-> Int# -> a -> State# (PrimState m) -> State# (PrimState m)
forall d a.
SmallMutableArray# d a -> Int# -> a -> State# d -> State# d
writeSmallArray# SmallMutableArray# (PrimState m) a
arr# Int#
i# a
x)

-- | Read a value from the immutable array at the given index.
indexSmallArray :: SmallArray a -> Int -> a
{-# INLINE indexSmallArray #-}
indexSmallArray :: SmallArray a -> Int -> a
indexSmallArray (SmallArray SmallArray# a
arr#) (I# Int#
i#) = case SmallArray# a -> Int# -> (# a #)
forall a. SmallArray# a -> Int# -> (# a #)
indexSmallArray# SmallArray# a
arr# Int#
i# of (# a
x #) -> a
x

-- | Monadically read a value from the immutable array at the given index.
-- This allows us to be strict in the array while remaining lazy in the read
-- element which is very useful for collective operations. Suppose we want to
-- copy an array. We could do something like this:
--
-- > copy marr arr ... = do ...
-- >                        writeSmallArray marr i (indexSmallArray arr i) ...
-- >                        ...
--
-- But since primitive arrays are lazy, the calls to 'indexSmallArray' will not be
-- evaluated. Rather, @marr@ will be filled with thunks each of which would
-- retain a reference to @arr@. This is definitely not what we want!
--
-- With 'indexSmallArrayM', we can instead write
--
-- > copy marr arr ... = do ...
-- >                        x <- indexSmallArrayM arr i
-- >                        writeSmallArray marr i x
-- >                        ...
--
-- Now, indexing is executed immediately although the returned element is
-- still not evaluated.
--
indexSmallArrayM :: Monad m => SmallArray a -> Int -> m a
{-# INLINE indexSmallArrayM #-}
indexSmallArrayM :: SmallArray a -> Int -> m a
indexSmallArrayM (SmallArray SmallArray# a
arr#) (I# Int#
i#)
  = case SmallArray# a -> Int# -> (# a #)
forall a. SmallArray# a -> Int# -> (# a #)
indexSmallArray# SmallArray# a
arr# Int#
i# of (# a
x #) -> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x

-- | Convert a mutable array to an immutable one without copying. The
-- array should not be modified after the conversion.
unsafeFreezeSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> m (SmallArray a)
{-# INLINE unsafeFreezeSmallArray #-}
unsafeFreezeSmallArray :: SmallMutableArray (PrimState m) a -> m (SmallArray a)
unsafeFreezeSmallArray (SmallMutableArray SmallMutableArray# (PrimState m) a
arr#)
  = (State# (PrimState m) -> (# State# (PrimState m), SmallArray a #))
-> m (SmallArray a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\State# (PrimState m)
s# -> case SmallMutableArray# (PrimState m) a
-> State# (PrimState m)
-> (# State# (PrimState m), SmallArray# a #)
forall d a.
SmallMutableArray# d a -> State# d -> (# State# d, SmallArray# a #)
unsafeFreezeSmallArray# SmallMutableArray# (PrimState m) a
arr# State# (PrimState m)
s# of
                        (# State# (PrimState m)
s'#, SmallArray# a
arr'# #) -> (# State# (PrimState m)
s'#, SmallArray# a -> SmallArray a
forall a. SmallArray# a -> SmallArray a
SmallArray SmallArray# a
arr'# #))

-- | Convert an immutable array to an mutable one without copying. The
-- immutable array should not be used after the conversion.
unsafeThawSmallArray :: PrimMonad m => SmallArray a -> m (SmallMutableArray (PrimState m) a)
{-# INLINE unsafeThawSmallArray #-}
unsafeThawSmallArray :: SmallArray a -> m (SmallMutableArray (PrimState m) a)
unsafeThawSmallArray (SmallArray SmallArray# a
arr#)
  = (State# (PrimState m)
 -> (# State# (PrimState m), SmallMutableArray (PrimState m) a #))
-> m (SmallMutableArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\State# (PrimState m)
s# -> case SmallArray# a
-> State# (PrimState m)
-> (# State# (PrimState m), SmallMutableArray# (PrimState m) a #)
forall a d.
SmallArray# a -> State# d -> (# State# d, SmallMutableArray# d a #)
unsafeThawSmallArray# SmallArray# a
arr# State# (PrimState m)
s# of
                        (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
arr'# #) -> (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
-> SmallMutableArray (PrimState m) a
forall s a. SmallMutableArray# s a -> SmallMutableArray s a
SmallMutableArray SmallMutableArray# (PrimState m) a
arr'# #))

-- | Check whether the two arrays refer to the same memory block.
sameSmallMutableArray :: SmallMutableArray s a -> SmallMutableArray s a -> Bool
{-# INLINE sameSmallMutableArray #-}
sameSmallMutableArray :: SmallMutableArray s a -> SmallMutableArray s a -> Bool
sameSmallMutableArray (SmallMutableArray SmallMutableArray# s a
arr#) (SmallMutableArray SmallMutableArray# s a
brr#)
  = Int# -> Bool
isTrue# (SmallMutableArray# s a -> SmallMutableArray# s a -> Int#
forall d a.
SmallMutableArray# d a -> SmallMutableArray# d a -> Int#
sameSmallMutableArray# SmallMutableArray# s a
arr# SmallMutableArray# s a
brr#)

-- | Copy a slice of an immutable array to a mutable array.
copySmallArray :: PrimMonad m
          => SmallMutableArray (PrimState m) a    -- ^ destination array
          -> Int                             -- ^ offset into destination array
          -> SmallArray a                         -- ^ source array
          -> Int                             -- ^ offset into source array
          -> Int                             -- ^ number of elements to copy
          -> m ()
{-# INLINE copySmallArray #-}
copySmallArray :: SmallMutableArray (PrimState m) a
-> Int -> SmallArray a -> Int -> Int -> m ()
copySmallArray (SmallMutableArray SmallMutableArray# (PrimState m) a
dst#) (I# Int#
doff#) (SmallArray SmallArray# a
src#) (I# Int#
soff#) (I# Int#
len#)
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (SmallArray# a
-> Int#
-> SmallMutableArray# (PrimState m) a
-> Int#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall a d.
SmallArray# a
-> Int#
-> SmallMutableArray# d a
-> Int#
-> Int#
-> State# d
-> State# d
copySmallArray# SmallArray# a
src# Int#
soff# SmallMutableArray# (PrimState m) a
dst# Int#
doff# Int#
len#)

-- | Copy a slice of a mutable array to another array. The two arrays may
-- not be the same.
copySmallMutableArray :: PrimMonad m
          => SmallMutableArray (PrimState m) a    -- ^ destination array
          -> Int                             -- ^ offset into destination array
          -> SmallMutableArray (PrimState m) a    -- ^ source array
          -> Int                             -- ^ offset into source array
          -> Int                             -- ^ number of elements to copy
          -> m ()
{-# INLINE copySmallMutableArray #-}
-- NOTE: copySmallArray# and copySmallMutableArray# are slightly broken in GHC 7.6.* and earlier
copySmallMutableArray :: SmallMutableArray (PrimState m) a
-> Int -> SmallMutableArray (PrimState m) a -> Int -> Int -> m ()
copySmallMutableArray (SmallMutableArray SmallMutableArray# (PrimState m) a
dst#) (I# Int#
doff#)
                 (SmallMutableArray SmallMutableArray# (PrimState m) a
src#) (I# Int#
soff#) (I# Int#
len#)
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (SmallMutableArray# (PrimState m) a
-> Int#
-> SmallMutableArray# (PrimState m) a
-> Int#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall d a.
SmallMutableArray# d a
-> Int#
-> SmallMutableArray# d a
-> Int#
-> Int#
-> State# d
-> State# d
copySmallMutableArray# SmallMutableArray# (PrimState m) a
src# Int#
soff# SmallMutableArray# (PrimState m) a
dst# Int#
doff# Int#
len#)

-- | Return a newly allocated SmallArray with the specified subrange of the
-- provided SmallArray. The provided SmallArray should contain the full subrange
-- specified by the two Ints, but this is not checked.
cloneSmallArray :: SmallArray a -- ^ source array
           -> Int     -- ^ offset into destination array
           -> Int     -- ^ number of elements to copy
           -> SmallArray a
{-# INLINE cloneSmallArray #-}
cloneSmallArray :: SmallArray a -> Int -> Int -> SmallArray a
cloneSmallArray (SmallArray SmallArray# a
arr#) (I# Int#
off#) (I# Int#
len#) 
  = case SmallArray# a -> Int# -> Int# -> SmallArray# a
forall a. SmallArray# a -> Int# -> Int# -> SmallArray# a
cloneSmallArray# SmallArray# a
arr# Int#
off# Int#
len# of SmallArray# a
arr'# -> SmallArray# a -> SmallArray a
forall a. SmallArray# a -> SmallArray a
SmallArray SmallArray# a
arr'#

-- | Return a newly allocated SmallMutableArray. with the specified subrange of
-- the provided SmallMutableArray. The provided SmallMutableArray should contain the
-- full subrange specified by the two Ints, but this is not checked.
cloneSmallMutableArray :: PrimMonad m
        => SmallMutableArray (PrimState m) a -- ^ source array
        -> Int                          -- ^ offset into destination array
        -> Int                          -- ^ number of elements to copy
        -> m (SmallMutableArray (PrimState m) a)
{-# INLINE cloneSmallMutableArray #-}
cloneSmallMutableArray :: SmallMutableArray (PrimState m) a
-> Int -> Int -> m (SmallMutableArray (PrimState m) a)
cloneSmallMutableArray (SmallMutableArray SmallMutableArray# (PrimState m) a
arr#) (I# Int#
off#) (I# Int#
len#) = (State# (PrimState m)
 -> (# State# (PrimState m), SmallMutableArray (PrimState m) a #))
-> m (SmallMutableArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive
   (\State# (PrimState m)
s# -> case SmallMutableArray# (PrimState m) a
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), SmallMutableArray# (PrimState m) a #)
forall d a.
SmallMutableArray# d a
-> Int#
-> Int#
-> State# d
-> (# State# d, SmallMutableArray# d a #)
cloneSmallMutableArray# SmallMutableArray# (PrimState m) a
arr# Int#
off# Int#
len# State# (PrimState m)
s# of
             (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
arr'# #) -> (# State# (PrimState m)
s'#, SmallMutableArray# (PrimState m) a
-> SmallMutableArray (PrimState m) a
forall s a. SmallMutableArray# s a -> SmallMutableArray s a
SmallMutableArray SmallMutableArray# (PrimState m) a
arr'# #))

instance IsList (SmallArray a) where
  type Item (SmallArray a) = a
  toList :: SmallArray a -> [Item (SmallArray a)]
toList = SmallArray a -> [Item (SmallArray a)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList
  fromListN :: Int -> [Item (SmallArray a)] -> SmallArray a
fromListN Int
n [Item (SmallArray a)]
xs0 = (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
$ do
    SmallMutableArray s a
arr <- Int -> a -> ST s (SmallMutableArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
n a
forall a. HasCallStack => a
undefined
    let go :: Int -> [a] -> ST s ()
go !Int
_ []     = () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        go Int
k (a
x:[a]
xs) = SmallMutableArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray s a
SmallMutableArray (PrimState (ST s)) a
arr Int
k a
x ST s () -> ST s () -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> [a] -> ST s ()
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [a]
xs
    Int -> [a] -> ST s ()
go Int
0 [a]
[Item (SmallArray a)]
xs0
    SmallMutableArray (PrimState (ST s)) a -> ST s (SmallArray a)
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> m (SmallArray a)
unsafeFreezeSmallArray SmallMutableArray s a
SmallMutableArray (PrimState (ST s)) a
arr
  fromList :: [Item (SmallArray a)] -> SmallArray a
fromList [Item (SmallArray a)]
xs = Int -> [Item (SmallArray a)] -> SmallArray a
forall l. IsList l => Int -> [Item l] -> l
fromListN ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length [a]
[Item (SmallArray a)]
xs) [Item (SmallArray a)]
xs

instance Functor SmallArray where
  fmap :: (a -> b) -> SmallArray a -> SmallArray b
fmap a -> b
f !SmallArray a
i = (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
$ do
    let n :: Int
n = SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
i
    SmallMutableArray s b
o <- Int -> b -> ST s (SmallMutableArray (PrimState (ST s)) b)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
n b
forall a. HasCallStack => a
undefined
    let go :: Int -> ST s ()
go !Int
k
          | Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n = () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
          | Bool
otherwise = do
            a
a <- SmallArray a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => SmallArray a -> Int -> m a
indexSmallArrayM SmallArray a
i Int
k
            SmallMutableArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray s b
SmallMutableArray (PrimState (ST s)) b
o Int
k (a -> b
f a
a)
            Int -> ST s ()
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
    Int -> ST s ()
go Int
0
    SmallMutableArray (PrimState (ST s)) b -> ST s (SmallArray b)
forall (m :: * -> *) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> m (SmallArray a)
unsafeFreezeSmallArray SmallMutableArray s b
SmallMutableArray (PrimState (ST s)) b
o

instance Foldable SmallArray where
  foldr :: (a -> b -> b) -> b -> SmallArray a -> b
foldr a -> b -> b
f b
z SmallArray a
arr = Int -> b
go Int
0 where
    n :: Int
n = SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
arr
    go :: Int -> b
go !Int
k
      | Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n    = b
z
      | Bool
otherwise = a -> b -> b
f (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
arr Int
k) (Int -> b
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))

  foldl :: (b -> a -> b) -> b -> SmallArray a -> b
foldl b -> a -> b
f b
z SmallArray a
arr = Int -> b
go (SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) where
    go :: Int -> b
go !Int
k
      | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = b
z
      | Bool
otherwise = b -> a -> b
f (Int -> b
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
arr Int
k)

  foldr' :: (a -> b -> b) -> b -> SmallArray a -> b
foldr' a -> b -> b
f b
z SmallArray a
arr = Int -> b
go Int
0 where
    n :: Int
n = SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
arr
    go :: Int -> b
go !Int
k
      | Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n    = b
z
      | a
r <- SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
arr Int
k = a
r a -> b -> b
`seq` a -> b -> b
f a
r (Int -> b
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))

  foldl' :: (b -> a -> b) -> b -> SmallArray a -> b
foldl' b -> a -> b
f b
z SmallArray a
arr = Int -> b
go (SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) where
    go :: Int -> b
go !Int
k
      | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = b
z
      | a
r <- SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
arr Int
k = a
r a -> b -> b
`seq` b -> a -> b
f (Int -> b
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) a
r

  length :: SmallArray a -> Int
length (SmallArray SmallArray# a
ary) = Int# -> Int
I# (SmallArray# a -> Int#
forall a. SmallArray# a -> Int#
sizeofSmallArray# SmallArray# a
ary)
  {-# INLINE length #-}

instance Traversable SmallArray where
  traverse :: (a -> f b) -> SmallArray a -> f (SmallArray b)
traverse a -> f b
f SmallArray a
a = Int -> [Item (SmallArray b)] -> SmallArray b
forall l. IsList l => Int -> [Item l] -> l
fromListN (SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
a) ([b] -> SmallArray b) -> f [b] -> f (SmallArray b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> [a] -> f [b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f (SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
a)

instance Show a => Show (SmallArray a) where
  showsPrec :: Int -> SmallArray a -> ShowS
showsPrec Int
d SmallArray a
as = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
    String -> ShowS
showString String
"fromList " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
as)

instance Read a => Read (SmallArray a) where
  readsPrec :: Int -> ReadS (SmallArray a)
readsPrec Int
d = Bool -> ReadS (SmallArray a) -> ReadS (SmallArray a)
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ReadS (SmallArray a) -> ReadS (SmallArray a))
-> ReadS (SmallArray a) -> ReadS (SmallArray a)
forall a b. (a -> b) -> a -> b
$ \String
s -> [([Item (SmallArray a)] -> SmallArray a
forall l. IsList l => [Item l] -> l
fromList [a]
[Item (SmallArray a)]
m, String
u) | (String
"fromList", String
t) <- ReadS String
lex String
s, ([a]
m,String
u) <- Int -> ReadS [a]
forall a. Read a => Int -> ReadS a
readsPrec Int
11 String
t]

instance Ord a => Ord (SmallArray a) where
  compare :: SmallArray a -> SmallArray a -> Ordering
compare SmallArray a
as SmallArray a
bs = [a] -> [a] -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
as) (SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
bs)

instance Eq a => Eq (SmallArray a) where
  SmallArray a
as == :: SmallArray a -> SmallArray a -> Bool
== SmallArray a
bs = SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
as [a] -> [a] -> Bool
forall a. Eq a => a -> a -> Bool
== SmallArray a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList SmallArray a
bs

instance NFData a => NFData (SmallArray a) where
  rnf :: SmallArray a -> ()
rnf SmallArray a
a0 = SmallArray a -> Int -> Int -> ()
forall a. NFData a => SmallArray a -> Int -> Int -> ()
go SmallArray a
a0 (SmallArray a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length SmallArray a
a0) Int
0 where
    go :: SmallArray a -> Int -> Int -> ()
go !SmallArray a
a !Int
n !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = ()
      | Bool
otherwise = a -> ()
forall a. NFData a => a -> ()
rnf (SmallArray a -> Int -> a
forall a. SmallArray a -> Int -> a
indexSmallArray SmallArray a
a Int
i) () -> () -> ()
`seq` SmallArray a -> Int -> Int -> ()
go SmallArray a
a Int
n (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
  {-# INLINE rnf #-}