-- |
-- Module      : Foundation.Array.Chunked.Unboxed
-- License     : BSD-style -- Maintainer  : Alfredo Di Napoli <alfredo.dinapoli@gmail.com>
-- Stability   : experimental
-- Portability : portable
--
-- Simple array-of-arrays abstraction
--
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
module Foundation.Array.Chunked.Unboxed
    ( ChunkedUArray
    ) where

import           Data.Typeable
import           Control.Arrow ((***))
import           Basement.BoxedArray (Array)
import qualified Basement.BoxedArray as A
import           Basement.Exception
import           Basement.UArray (UArray)
import qualified Basement.UArray as U
import           Basement.Compat.Bifunctor
import           Basement.Compat.Semigroup
import           Basement.Compat.Base
import           Basement.Types.OffsetSize
import           Basement.PrimType
import           GHC.ST

import           Foundation.Numerical
import           Foundation.Primitive
import qualified Foundation.Collection as C


newtype ChunkedUArray ty = ChunkedUArray (Array (UArray ty))
                      deriving (Int -> ChunkedUArray ty -> ShowS
[ChunkedUArray ty] -> ShowS
ChunkedUArray ty -> String
(Int -> ChunkedUArray ty -> ShowS)
-> (ChunkedUArray ty -> String)
-> ([ChunkedUArray ty] -> ShowS)
-> Show (ChunkedUArray ty)
forall ty.
(PrimType ty, Show ty) =>
Int -> ChunkedUArray ty -> ShowS
forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall ty.
(PrimType ty, Show ty) =>
Int -> ChunkedUArray ty -> ShowS
showsPrec :: Int -> ChunkedUArray ty -> ShowS
$cshow :: forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
show :: ChunkedUArray ty -> String
$cshowList :: forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
showList :: [ChunkedUArray ty] -> ShowS
Show, Eq (ChunkedUArray ty)
Eq (ChunkedUArray ty) =>
(ChunkedUArray ty -> ChunkedUArray ty -> Ordering)
-> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
-> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
-> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
-> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
-> (ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty)
-> (ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty)
-> Ord (ChunkedUArray ty)
ChunkedUArray ty -> ChunkedUArray ty -> Bool
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall ty. (PrimType ty, Ord ty) => Eq (ChunkedUArray ty)
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
$ccompare :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Ordering
compare :: ChunkedUArray ty -> ChunkedUArray ty -> Ordering
$c< :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
< :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c<= :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
<= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c> :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
> :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$c>= :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
>= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
$cmax :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
max :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
$cmin :: forall ty.
(PrimType ty, Ord ty) =>
ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
min :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
Ord, Typeable)

instance PrimType ty => Eq (ChunkedUArray ty) where
  == :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
(==) = ChunkedUArray ty -> ChunkedUArray ty -> Bool
forall ty.
PrimType ty =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal
instance NormalForm (ChunkedUArray ty) where
    toNormalForm :: ChunkedUArray ty -> ()
toNormalForm (ChunkedUArray Array (UArray ty)
spine) = Array (UArray ty) -> ()
forall a. NormalForm a => a -> ()
toNormalForm Array (UArray ty)
spine

instance Semigroup (ChunkedUArray a) where
    <> :: ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
(<>) = ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
append
instance Monoid (ChunkedUArray a) where
    mempty :: ChunkedUArray a
mempty  = ChunkedUArray a
forall a. ChunkedUArray a
empty
    mconcat :: [ChunkedUArray a] -> ChunkedUArray a
mconcat = [ChunkedUArray a] -> ChunkedUArray a
forall a. [ChunkedUArray a] -> ChunkedUArray a
concat

type instance C.Element (ChunkedUArray ty) = ty

instance PrimType ty => IsList (ChunkedUArray ty) where
    type Item (ChunkedUArray ty) = ty
    fromList :: [Item (ChunkedUArray ty)] -> ChunkedUArray ty
fromList = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall ty. PrimType ty => [ty] -> ChunkedUArray ty
vFromList
    toList :: ChunkedUArray ty -> [Item (ChunkedUArray ty)]
toList = ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall ty. PrimType ty => ChunkedUArray ty -> [ty]
vToList

instance PrimType ty => C.Foldable (ChunkedUArray ty) where
    foldl' :: forall a.
(a -> Element (ChunkedUArray ty) -> a)
-> a -> ChunkedUArray ty -> a
foldl' = (a -> ty -> a) -> a -> ChunkedUArray ty -> a
(a -> Element (ChunkedUArray ty) -> a)
-> a -> ChunkedUArray ty -> a
forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl'
    foldr :: forall a.
(Element (ChunkedUArray ty) -> a -> a)
-> a -> ChunkedUArray ty -> a
foldr = (ty -> a -> a) -> a -> ChunkedUArray ty -> a
(Element (ChunkedUArray ty) -> a -> a)
-> a -> ChunkedUArray ty -> a
forall ty a.
PrimType ty =>
(ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr
    -- Use the default foldr' instance

instance PrimType ty => C.Collection (ChunkedUArray ty) where
    null :: ChunkedUArray ty -> Bool
null = ChunkedUArray ty -> Bool
forall ty. PrimType ty => ChunkedUArray ty -> Bool
null
    length :: ChunkedUArray ty -> CountOf (Element (ChunkedUArray ty))
length = ChunkedUArray ty -> CountOf ty
ChunkedUArray ty -> CountOf (Element (ChunkedUArray ty))
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length
    elem :: forall a.
(Eq a, a ~ Element (ChunkedUArray ty)) =>
Element (ChunkedUArray ty) -> ChunkedUArray ty -> Bool
elem   = ty -> ChunkedUArray ty -> Bool
Element (ChunkedUArray ty) -> ChunkedUArray ty -> Bool
forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
elem
    minimum :: forall a.
(Ord a, a ~ Element (ChunkedUArray ty)) =>
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
minimum = NonEmpty (ChunkedUArray ty) -> ty
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
minimum
    maximum :: forall a.
(Ord a, a ~ Element (ChunkedUArray ty)) =>
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
maximum = NonEmpty (ChunkedUArray ty) -> ty
NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
maximum
    all :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
all Element (ChunkedUArray ty) -> Bool
p (ChunkedUArray Array (UArray ty)
cua) = (UArray ty -> Bool) -> Array (UArray ty) -> Bool
forall ty. (ty -> Bool) -> Array ty -> Bool
A.all ((ty -> Bool) -> UArray ty -> Bool
forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
U.all ty -> Bool
Element (ChunkedUArray ty) -> Bool
p) Array (UArray ty)
cua
    any :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
any Element (ChunkedUArray ty) -> Bool
p (ChunkedUArray Array (UArray ty)
cua) = (UArray ty -> Bool) -> Array (UArray ty) -> Bool
forall ty. (ty -> Bool) -> Array ty -> Bool
A.any ((ty -> Bool) -> UArray ty -> Bool
forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
U.any ty -> Bool
Element (ChunkedUArray ty) -> Bool
p) Array (UArray ty)
cua

instance PrimType ty => C.Sequential (ChunkedUArray ty) where
    take :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
take = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take
    drop :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
drop = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop
    splitAt :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt = CountOf ty
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
forall ty.
PrimType ty =>
CountOf ty
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt
    revTake :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
revTake = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake
    revDrop :: CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
revDrop = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
CountOf (Element (ChunkedUArray ty))
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop
    splitOn :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn = (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
(Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> [ChunkedUArray ty]
forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn
    break :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break = (ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
(Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break
    breakEnd :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd = (ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
(Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd
    intersperse :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
intersperse = ty -> ChunkedUArray ty -> ChunkedUArray ty
Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse
    filter :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> ChunkedUArray ty
filter = (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
(Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter
    reverse :: ChunkedUArray ty -> ChunkedUArray ty
reverse = ChunkedUArray ty -> ChunkedUArray ty
forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse
    unsnoc :: ChunkedUArray ty
-> Maybe (ChunkedUArray ty, Element (ChunkedUArray ty))
unsnoc = ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
ChunkedUArray ty
-> Maybe (ChunkedUArray ty, Element (ChunkedUArray ty))
forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc
    uncons :: ChunkedUArray ty
-> Maybe (Element (ChunkedUArray ty), ChunkedUArray ty)
uncons = ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
ChunkedUArray ty
-> Maybe (Element (ChunkedUArray ty), ChunkedUArray ty)
forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons
    snoc :: ChunkedUArray ty -> Element (ChunkedUArray ty) -> ChunkedUArray ty
snoc = ChunkedUArray ty -> ty -> ChunkedUArray ty
ChunkedUArray ty -> Element (ChunkedUArray ty) -> ChunkedUArray ty
forall ty.
PrimType ty =>
ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc
    cons :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
cons = ty -> ChunkedUArray ty -> ChunkedUArray ty
Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
cons
    find :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> Maybe (Element (ChunkedUArray ty))
find = (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
(Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> Maybe (Element (ChunkedUArray ty))
forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find
    sortBy :: (Element (ChunkedUArray ty)
 -> Element (ChunkedUArray ty) -> Ordering)
-> ChunkedUArray ty -> ChunkedUArray ty
sortBy = (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
(Element (ChunkedUArray ty)
 -> Element (ChunkedUArray ty) -> Ordering)
-> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
(ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy
    singleton :: Element (ChunkedUArray ty) -> ChunkedUArray ty
singleton = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ty -> [ty]) -> ty -> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ty -> [ty] -> [ty]
forall a. a -> [a] -> [a]
:[])
    replicate :: CountOf (Element (ChunkedUArray ty))
-> Element (ChunkedUArray ty) -> ChunkedUArray ty
replicate CountOf (Element (ChunkedUArray ty))
n = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ty -> [ty]) -> ty -> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. CountOf (Element [ty]) -> Element [ty] -> [ty]
forall c. Sequential c => CountOf (Element c) -> Element c -> c
C.replicate CountOf (Element [ty])
CountOf (Element (ChunkedUArray ty))
n

instance PrimType ty => C.IndexedCollection (ChunkedUArray ty) where
    ! :: ChunkedUArray ty
-> Offset (Element (ChunkedUArray ty))
-> Maybe (Element (ChunkedUArray ty))
(!) ChunkedUArray ty
l Offset (Element (ChunkedUArray ty))
n
        | Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
Offset (Element (ChunkedUArray ty))
n (ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
l) = Maybe ty
Maybe (Element (ChunkedUArray ty))
forall a. Maybe a
Nothing
        | Bool
otherwise                     = Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty))
forall a. a -> Maybe a
Just (Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty)))
-> Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty))
forall a b. (a -> b) -> a -> b
$ ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index ChunkedUArray ty
l Offset ty
Offset (Element (ChunkedUArray ty))
n
    findIndex :: (Element (ChunkedUArray ty) -> Bool)
-> ChunkedUArray ty -> Maybe (Offset (Element (ChunkedUArray ty)))
findIndex Element (ChunkedUArray ty) -> Bool
predicate ChunkedUArray ty
c = Offset ty -> Maybe (Offset ty)
loop Offset ty
0
      where
        !len :: CountOf ty
len = ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c
        loop :: Offset ty -> Maybe (Offset ty)
loop Offset ty
i
            | Offset ty
i Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = Maybe (Offset ty)
forall a. Maybe a
Nothing
            | Bool
otherwise  =
                if Element (ChunkedUArray ty) -> Bool
predicate (ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
c Offset ty
i) then Offset ty -> Maybe (Offset ty)
forall a. a -> Maybe a
Just Offset ty
i else Maybe (Offset ty)
forall a. Maybe a
Nothing

empty :: ChunkedUArray ty
empty :: forall a. ChunkedUArray a
empty = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray Array (UArray ty)
forall a. Array a
A.empty

append :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
append :: forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
append (ChunkedUArray Array (UArray ty)
a1) (ChunkedUArray Array (UArray ty)
a2) = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (Array (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall a. Monoid a => a -> a -> a
mappend Array (UArray ty)
a1 Array (UArray ty)
a2)

concat :: [ChunkedUArray ty] -> ChunkedUArray ty
concat :: forall a. [ChunkedUArray a] -> ChunkedUArray a
concat [ChunkedUArray ty]
x = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray ([Array (UArray ty)] -> Array (UArray ty)
forall a. Monoid a => [a] -> a
mconcat ([Array (UArray ty)] -> Array (UArray ty))
-> [Array (UArray ty)] -> Array (UArray ty)
forall a b. (a -> b) -> a -> b
$ (ChunkedUArray ty -> Array (UArray ty))
-> [ChunkedUArray ty] -> [Array (UArray ty)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(ChunkedUArray Array (UArray ty)
spine) -> Array (UArray ty)
spine) [ChunkedUArray ty]
x)

vFromList :: PrimType ty => [ty] -> ChunkedUArray ty
vFromList :: forall ty. PrimType ty => [ty] -> ChunkedUArray ty
vFromList [ty]
l = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
-> Array (UArray ty) -> ChunkedUArray ty
forall a b. (a -> b) -> a -> b
$ UArray ty -> Array (UArray ty)
forall ty. ty -> Array ty
A.singleton (UArray ty -> Array (UArray ty)) -> UArray ty -> Array (UArray ty)
forall a b. (a -> b) -> a -> b
$ [Item (UArray ty)] -> UArray ty
forall l. IsList l => [Item l] -> l
fromList [ty]
[Item (UArray ty)]
l

vToList :: PrimType ty => ChunkedUArray ty -> [ty]
vToList :: forall ty. PrimType ty => ChunkedUArray ty -> [ty]
vToList (ChunkedUArray Array (UArray ty)
a) = [[ty]] -> [ty]
forall a. Monoid a => [a] -> a
mconcat ([[ty]] -> [ty]) -> [[ty]] -> [ty]
forall a b. (a -> b) -> a -> b
$ Array [ty] -> [Item (Array [ty])]
forall l. IsList l => l -> [Item l]
toList (Array [ty] -> [Item (Array [ty])])
-> Array [ty] -> [Item (Array [ty])]
forall a b. (a -> b) -> a -> b
$ UArray ty -> [ty]
UArray ty -> [Item (UArray ty)]
forall l. IsList l => l -> [Item l]
toList (UArray ty -> [ty]) -> Array (UArray ty) -> Array [ty]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array (UArray ty)
a

null :: PrimType ty => ChunkedUArray ty -> Bool
null :: forall ty. PrimType ty => ChunkedUArray ty -> Bool
null (ChunkedUArray Array (UArray ty)
array) =
    Array (UArray ty) -> Bool
forall c. Collection c => c -> Bool
C.null Array (UArray ty)
array Bool -> Bool -> Bool
|| Offset (UArray ty) -> Bool
allNulls Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = Array (UArray ty) -> CountOf (UArray ty)
forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    allNulls :: Offset (UArray ty) -> Bool
allNulls !Offset (UArray ty)
idx
      | Offset (UArray ty)
idx Offset (UArray ty) -> CountOf (UArray ty) -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = Bool
True
      | Bool
otherwise    = UArray ty -> Bool
forall c. Collection c => c -> Bool
C.null (Array (UArray ty)
array Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
`A.unsafeIndex` Offset (UArray ty)
idx) Bool -> Bool -> Bool
&& Offset (UArray ty) -> Bool
allNulls (Offset (UArray ty)
idx Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)

-- | Returns the length of this `ChunkedUArray`, by summing each inner length.
-- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
length :: PrimType ty => ChunkedUArray ty -> CountOf ty
length :: forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length (ChunkedUArray Array (UArray ty)
array) = (CountOf ty -> Element (Array (UArray ty)) -> CountOf ty)
-> CountOf ty -> Array (UArray ty) -> CountOf ty
forall collection a.
Foldable collection =>
(a -> Element collection -> a) -> a -> collection -> a
forall a.
(a -> Element (Array (UArray ty)) -> a)
-> a -> Array (UArray ty) -> a
C.foldl' (\CountOf ty
acc Element (Array (UArray ty))
l -> CountOf ty
acc CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
U.length UArray ty
Element (Array (UArray ty))
l) CountOf ty
0 Array (UArray ty)
array

-- | Returns `True` if the given element is contained in the `ChunkedUArray`.
-- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
elem :: PrimType ty => ty -> ChunkedUArray ty -> Bool
elem :: forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
elem ty
el (ChunkedUArray Array (UArray ty)
array) = Offset (UArray ty) -> Bool
loop Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = Array (UArray ty) -> CountOf (UArray ty)
forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    loop :: Offset (UArray ty) -> Bool
loop Offset (UArray ty)
i
        | Offset (UArray ty)
i Offset (UArray ty) -> CountOf (UArray ty) -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = Bool
False
        | Bool
otherwise  =
            case Element (UArray ty) -> UArray ty -> Bool
forall a.
(Eq a, a ~ Element (UArray ty)) =>
Element (UArray ty) -> UArray ty -> Bool
forall c a.
(Collection c, Eq a, a ~ Element c) =>
Element c -> c -> Bool
C.elem ty
Element (UArray ty)
el (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
i) of
                Bool
True  -> Bool
True
                Bool
False -> Offset (UArray ty) -> Bool
loop (Offset (UArray ty)
iOffset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+Offset (UArray ty)
1)

-- | Fold a `ChunkedUArray' leftwards strictly. Implemented internally using a double
-- fold on the nested Array structure. Other folds implemented analogously.
foldl' :: PrimType ty => (a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' :: forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' a -> ty -> a
f a
initialAcc (ChunkedUArray Array (UArray ty)
cua) = (a -> UArray ty -> a) -> a -> Array (UArray ty) -> a
forall a ty. (a -> ty -> a) -> a -> Array ty -> a
A.foldl' ((a -> ty -> a) -> a -> UArray ty -> a
forall ty a. PrimType ty => (a -> ty -> a) -> a -> UArray ty -> a
U.foldl' a -> ty -> a
f) a
initialAcc Array (UArray ty)
cua

foldr :: PrimType ty => (ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr :: forall ty a.
PrimType ty =>
(ty -> a -> a) -> a -> ChunkedUArray ty -> a
foldr ty -> a -> a
f a
initialAcc (ChunkedUArray Array (UArray ty)
cua) = (UArray ty -> a -> a) -> a -> Array (UArray ty) -> a
forall ty a. (ty -> a -> a) -> a -> Array ty -> a
A.foldr ((a -> UArray ty -> a) -> UArray ty -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> UArray ty -> a) -> UArray ty -> a -> a)
-> (a -> UArray ty -> a) -> UArray ty -> a -> a
forall a b. (a -> b) -> a -> b
$ (ty -> a -> a) -> a -> UArray ty -> a
forall ty a. PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
U.foldr ty -> a -> a
f) a
initialAcc Array (UArray ty)
cua

minimum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
minimum :: forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
minimum NonEmpty (ChunkedUArray ty)
cua = (ty -> ty -> ty) -> ty -> ChunkedUArray ty -> ty
forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' ty -> ty -> ty
forall a. Ord a => a -> a -> a
min (ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
cua' Offset ty
0) (CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
1 ChunkedUArray ty
cua')
  where
    cua' :: ChunkedUArray ty
cua' = NonEmpty (ChunkedUArray ty) -> ChunkedUArray ty
forall a. NonEmpty a -> a
C.getNonEmpty NonEmpty (ChunkedUArray ty)
cua

maximum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
maximum :: forall ty.
(Ord ty, PrimType ty) =>
NonEmpty (ChunkedUArray ty) -> ty
maximum NonEmpty (ChunkedUArray ty)
cua = (ty -> ty -> ty) -> ty -> ChunkedUArray ty -> ty
forall ty a.
PrimType ty =>
(a -> ty -> a) -> a -> ChunkedUArray ty -> a
foldl' ty -> ty -> ty
forall a. Ord a => a -> a -> a
max (ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
cua' Offset ty
0) (CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
1 ChunkedUArray ty
cua')
  where
    cua' :: ChunkedUArray ty
cua' = NonEmpty (ChunkedUArray ty) -> ChunkedUArray ty
forall a. NonEmpty a -> a
C.getNonEmpty NonEmpty (ChunkedUArray ty)
cua

-- | Equality between `ChunkedUArray`.
-- This function is fiddly to write as is not enough to compare for
-- equality the inner `UArray`(s), we need an element-by-element
-- comparison.
equal :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal :: forall ty.
PrimType ty =>
ChunkedUArray ty -> ChunkedUArray ty -> Bool
equal ChunkedUArray ty
ca1 ChunkedUArray ty
ca2 =
    CountOf ty
len1 CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
len2 Bool -> Bool -> Bool
&& Offset ty -> Bool
go Offset ty
0
  where
    len1 :: CountOf ty
len1 = ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
ca1
    len2 :: CountOf ty
len2 = ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
ca2

    go :: Offset ty -> Bool
go !Offset ty
x
      | Offset ty
x Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len1 = Bool
True
      | Bool
otherwise   = (ChunkedUArray ty
ca1 ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
x ty -> ty -> Bool
forall a. Eq a => a -> a -> Bool
== ChunkedUArray ty
ca2 ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
x) Bool -> Bool -> Bool
&& Offset ty -> Bool
go (Offset ty
x Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1)

-- given an offset express in element of ty, return the offset in array in the spine,
-- plus the relative offset in element on this array
findPos :: PrimType ty => Offset ty -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos :: forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos Offset ty
absOfs (ChunkedUArray Array (UArray ty)
array)
    | Array (UArray ty) -> Bool
forall ty. Array ty -> Bool
A.null Array (UArray ty)
array = Maybe (Offset (UArray ty), Offset ty)
forall a. Maybe a
Nothing
    | Bool
otherwise    = Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
absOfs Offset (UArray ty)
0
  where
    !len :: CountOf (UArray ty)
len = Array (UArray ty) -> CountOf (UArray ty)
forall a. Array a -> CountOf a
A.length Array (UArray ty)
array
    loop :: Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
relOfs Offset (UArray ty)
outerI
        | Offset (UArray ty)
outerI Offset (UArray ty) -> CountOf (UArray ty) -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf (UArray ty)
len = Maybe (Offset (UArray ty), Offset ty)
forall a. Maybe a
Nothing -- haven't found what to do
        | Offset ty
relOfs Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
0     = (Offset (UArray ty), Offset ty)
-> Maybe (Offset (UArray ty), Offset ty)
forall a. a -> Maybe a
Just (Offset (UArray ty)
outerI, Offset ty
0)
        | Bool
otherwise       =
            let !innera :: UArray ty
innera   = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
outerI
                !innerLen :: CountOf ty
innerLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
U.length UArray ty
innera
             in case Offset ty -> CountOf ty -> Maybe (Offset ty)
forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize Offset ty
relOfs CountOf ty
innerLen of
                        Maybe (Offset ty)
Nothing      -> (Offset (UArray ty), Offset ty)
-> Maybe (Offset (UArray ty), Offset ty)
forall a. a -> Maybe a
Just (Offset (UArray ty)
outerI, Offset ty
relOfs)
                        Just Offset ty
relOfs' -> Offset ty
-> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
loop Offset ty
relOfs' (Offset (UArray ty)
outerI Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)

splitChunk :: Offset (UArray ty) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk :: forall ty.
Offset (UArray ty)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk Offset (UArray ty)
ofs (ChunkedUArray Array (UArray ty)
c) = (Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
-> (Array (UArray ty) -> ChunkedUArray ty)
-> (Array (UArray ty), Array (UArray ty))
-> (ChunkedUArray ty, ChunkedUArray ty)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray) ((Array (UArray ty), Array (UArray ty))
 -> (ChunkedUArray ty, ChunkedUArray ty))
-> (Array (UArray ty), Array (UArray ty))
-> (ChunkedUArray ty, ChunkedUArray ty)
forall a b. (a -> b) -> a -> b
$ CountOf (UArray ty)
-> Array (UArray ty) -> (Array (UArray ty), Array (UArray ty))
forall ty. CountOf ty -> Array ty -> (Array ty, Array ty)
A.splitAt (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
c

take :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = ChunkedUArray ty
forall a. ChunkedUArray a
empty
    | Bool
otherwise =
        case Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> ChunkedUArray ty
c
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.take (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine)
            Just (Offset (UArray ty)
ofs, Offset ty
r) ->
                let uarr :: UArray ty
uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.take (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine Array (UArray ty) -> UArray ty -> Array (UArray ty)
forall ty. Array ty -> ty -> Array ty
`A.snoc` CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
U.take (Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
r) UArray ty
uarr)

drop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = ChunkedUArray ty
c
    | Bool
otherwise =
        case Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> ChunkedUArray ty
forall a. ChunkedUArray a
empty
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.drop (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine)
            Just (Offset (UArray ty)
ofs, Offset ty
r) ->
                let uarr :: UArray ty
uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
U.drop (Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
r) UArray ty
uarr UArray ty -> Array (UArray ty) -> Array (UArray ty)
forall ty. ty -> Array ty -> Array ty
`A.cons` CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.drop (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofsCountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
forall a. Additive a => a -> a -> a
+CountOf (UArray ty)
1) Array (UArray ty)
spine)

splitAt :: PrimType ty => CountOf ty -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt :: forall ty.
PrimType ty =>
CountOf ty
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitAt CountOf ty
n c :: ChunkedUArray ty
c@(ChunkedUArray Array (UArray ty)
spine)
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = (ChunkedUArray ty
forall a. ChunkedUArray a
empty, ChunkedUArray ty
c)
    | Bool
otherwise =
        case Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
forall ty.
PrimType ty =>
Offset ty
-> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
findPos (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) ChunkedUArray ty
c of
            Maybe (Offset (UArray ty), Offset ty)
Nothing       -> (ChunkedUArray ty
c, ChunkedUArray ty
forall a. ChunkedUArray a
empty)
            Just (Offset (UArray ty)
ofs, Offset ty
0) -> Offset (UArray ty)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
forall ty.
Offset (UArray ty)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
splitChunk Offset (UArray ty)
ofs ChunkedUArray ty
c
            Just (Offset (UArray ty)
ofs, Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize -> CountOf ty
r) ->
                let uarr :: UArray ty
uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
spine Offset (UArray ty)
ofs
                 in ( Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.take (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofs) Array (UArray ty)
spine Array (UArray ty) -> UArray ty -> Array (UArray ty)
forall ty. Array ty -> ty -> Array ty
`A.snoc` CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
U.take CountOf ty
r UArray ty
uarr)
                    , Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
U.drop CountOf ty
r UArray ty
uarr UArray ty -> Array (UArray ty) -> Array (UArray ty)
forall ty. ty -> Array ty -> Array ty
`A.cons` CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
forall ty. CountOf ty -> Array ty -> Array ty
A.drop (Offset (UArray ty) -> CountOf (UArray ty)
forall a. Offset a -> CountOf a
offsetAsSize Offset (UArray ty)
ofsCountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
forall a. Additive a => a -> a -> a
+CountOf (UArray ty)
1) Array (UArray ty)
spine)
                    )

revTake :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revTake CountOf ty
n ChunkedUArray ty
c = case ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
n of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> ChunkedUArray ty
c
    Just CountOf ty
elems -> CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
drop CountOf ty
elems ChunkedUArray ty
c

revDrop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop :: forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
revDrop CountOf ty
n ChunkedUArray ty
c = case ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
c CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
n of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> ChunkedUArray ty
forall a. ChunkedUArray a
empty
    Just CountOf ty
keepElems -> CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
forall ty.
PrimType ty =>
CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
take CountOf ty
keepElems ChunkedUArray ty
c

-- TODO: Improve implementation.
splitOn :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
splitOn ty -> Bool
p = ([ty] -> ChunkedUArray ty) -> [[ty]] -> [ChunkedUArray ty]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([[ty]] -> [ChunkedUArray ty])
-> (ChunkedUArray ty -> [[ty]])
-> ChunkedUArray ty
-> [ChunkedUArray ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Element [ty] -> Bool) -> [ty] -> [[ty]]
forall c. Sequential c => (Element c -> Bool) -> c -> [c]
C.splitOn ty -> Bool
Element [ty] -> Bool
p ([ty] -> [[ty]])
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [[ty]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
break :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break :: forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
break ty -> Bool
p = ([ty] -> ChunkedUArray ty)
-> ([ty] -> ChunkedUArray ty)
-> ([ty], [ty])
-> (ChunkedUArray ty, ChunkedUArray ty)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList (([ty], [ty]) -> (ChunkedUArray ty, ChunkedUArray ty))
-> (ChunkedUArray ty -> ([ty], [ty]))
-> ChunkedUArray ty
-> (ChunkedUArray ty, ChunkedUArray ty)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Element [ty] -> Bool) -> [ty] -> ([ty], [ty])
forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.break ty -> Bool
Element [ty] -> Bool
p ([ty] -> ([ty], [ty]))
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> ([ty], [ty])
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
breakEnd :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd :: forall ty.
PrimType ty =>
(ty -> Bool)
-> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
breakEnd ty -> Bool
p = ([ty] -> ChunkedUArray ty)
-> ([ty] -> ChunkedUArray ty)
-> ([ty], [ty])
-> (ChunkedUArray ty, ChunkedUArray ty)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList (([ty], [ty]) -> (ChunkedUArray ty, ChunkedUArray ty))
-> (ChunkedUArray ty -> ([ty], [ty]))
-> ChunkedUArray ty
-> (ChunkedUArray ty, ChunkedUArray ty)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Element [ty] -> Bool) -> [ty] -> ([ty], [ty])
forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.breakEnd ty -> Bool
Element [ty] -> Bool
p ([ty] -> ([ty], [ty]))
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> ([ty], [ty])
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
intersperse :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse :: forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
intersperse ty
el = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ChunkedUArray ty -> [ty])
-> ChunkedUArray ty
-> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Element [ty] -> [ty] -> [ty]
forall c. Sequential c => Element c -> c -> c
C.intersperse ty
Element [ty]
el ([ty] -> [ty])
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
reverse :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse :: forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
reverse = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ChunkedUArray ty -> [ty])
-> ChunkedUArray ty
-> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ty] -> [ty]
forall c. Sequential c => c -> c
C.reverse ([ty] -> [ty])
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
filter :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
filter ty -> Bool
p = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ChunkedUArray ty -> [ty])
-> ChunkedUArray ty
-> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Element [ty] -> Bool) -> [ty] -> [ty]
forall c. Sequential c => (Element c -> Bool) -> c -> c
C.filter ty -> Bool
Element [ty] -> Bool
p ([ty] -> [ty])
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

-- TODO: Improve implementation.
unsnoc :: PrimType ty => ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc :: forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
unsnoc ChunkedUArray ty
v = ([ty] -> ChunkedUArray ty) -> ([ty], ty) -> (ChunkedUArray ty, ty)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList (([ty], ty) -> (ChunkedUArray ty, ty))
-> Maybe ([ty], ty) -> Maybe (ChunkedUArray ty, ty)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([ty] -> Maybe ([ty], Element [ty])
forall c. Sequential c => c -> Maybe (c, Element c)
C.unsnoc ([ty] -> Maybe ([ty], Element [ty]))
-> [ty] -> Maybe ([ty], Element [ty])
forall a b. (a -> b) -> a -> b
$ ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList ChunkedUArray ty
v)

-- TODO: Improve implementation.
uncons :: PrimType ty => ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons :: forall ty.
PrimType ty =>
ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
uncons ChunkedUArray ty
v = ([ty] -> ChunkedUArray ty) -> (ty, [ty]) -> (ty, ChunkedUArray ty)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ((ty, [ty]) -> (ty, ChunkedUArray ty))
-> Maybe (ty, [ty]) -> Maybe (ty, ChunkedUArray ty)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([ty] -> Maybe (Element [ty], [ty])
forall c. Sequential c => c -> Maybe (Element c, c)
C.uncons ([ty] -> Maybe (Element [ty], [ty]))
-> [ty] -> Maybe (Element [ty], [ty])
forall a b. (a -> b) -> a -> b
$ ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList ChunkedUArray ty
v)

cons :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
cons :: forall ty.
PrimType ty =>
ty -> ChunkedUArray ty -> ChunkedUArray ty
cons ty
el (ChunkedUArray Array (UArray ty)
inner) = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
-> Array (UArray ty) -> ChunkedUArray ty
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Array (UArray ty))) -> Array (UArray ty))
-> (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
forall a b. (a -> b) -> a -> b
$ do
  let newLen :: CountOf (UArray ty)
newLen = Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
inner CountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
forall a. Additive a => a -> a -> a
+ CountOf (UArray ty)
1
  MArray (UArray ty) s
newArray   <- CountOf (UArray ty) -> ST s (MArray (UArray ty) (PrimState (ST s)))
forall (prim :: * -> *) ty.
PrimMonad prim =>
CountOf ty -> prim (MArray ty (PrimState prim))
A.new CountOf (UArray ty)
newLen
  let single :: UArray ty
single = [Item (UArray ty)] -> UArray ty
forall l. IsList l => [Item l] -> l
fromList [ty
Item (UArray ty)
el]
  MArray (UArray ty) (PrimState (ST s))
-> Offset (UArray ty) -> UArray ty -> ST s ()
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
A.unsafeWrite MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray Offset (UArray ty)
0 UArray ty
single
  MArray (UArray ty) (PrimState (ST s))
-> Offset (UArray ty)
-> Array (UArray ty)
-> Offset (UArray ty)
-> CountOf (UArray ty)
-> ST s ()
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim)
-> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
A.unsafeCopyAtRO MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray (Int -> Offset (UArray ty)
forall ty. Int -> Offset ty
Offset Int
1) Array (UArray ty)
inner (Int -> Offset (UArray ty)
forall ty. Int -> Offset ty
Offset Int
0) (Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
inner)
  MArray (UArray ty) (PrimState (ST s)) -> ST s (Array (UArray ty))
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> prim (Array ty)
A.unsafeFreeze MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray

snoc :: PrimType ty => ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc :: forall ty.
PrimType ty =>
ChunkedUArray ty -> ty -> ChunkedUArray ty
snoc (ChunkedUArray Array (UArray ty)
spine) ty
el = Array (UArray ty) -> ChunkedUArray ty
forall ty. Array (UArray ty) -> ChunkedUArray ty
ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
-> Array (UArray ty) -> ChunkedUArray ty
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Array (UArray ty))) -> Array (UArray ty))
-> (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
forall a b. (a -> b) -> a -> b
$ do
  MArray (UArray ty) s
newArray  <- CountOf (UArray ty) -> ST s (MArray (UArray ty) (PrimState (ST s)))
forall (prim :: * -> *) ty.
PrimMonad prim =>
CountOf ty -> prim (MArray ty (PrimState prim))
A.new (Array (UArray ty) -> CountOf (UArray ty)
forall a. Array a -> CountOf a
A.length Array (UArray ty)
spine CountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
forall a. Additive a => a -> a -> a
+ CountOf (UArray ty)
1)
  let single :: UArray ty
single = ty -> UArray ty
forall ty. PrimType ty => ty -> UArray ty
U.singleton ty
el
  MArray (UArray ty) (PrimState (ST s))
-> Offset (UArray ty)
-> Array (UArray ty)
-> Offset (UArray ty)
-> CountOf (UArray ty)
-> ST s ()
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim)
-> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
A.unsafeCopyAtRO MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray (Int -> Offset (UArray ty)
forall ty. Int -> Offset ty
Offset Int
0) Array (UArray ty)
spine (Int -> Offset (UArray ty)
forall ty. Int -> Offset ty
Offset Int
0) (Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
forall c. Collection c => c -> CountOf (Element c)
C.length Array (UArray ty)
spine)
  MArray (UArray ty) (PrimState (ST s))
-> Offset (UArray ty) -> UArray ty -> ST s ()
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
A.unsafeWrite MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray (CountOf (UArray ty) -> Offset (UArray ty)
forall a. CountOf a -> Offset a
sizeAsOffset (CountOf (UArray ty) -> Offset (UArray ty))
-> CountOf (UArray ty) -> Offset (UArray ty)
forall a b. (a -> b) -> a -> b
$ Array (UArray ty) -> CountOf (UArray ty)
forall a. Array a -> CountOf a
A.length Array (UArray ty)
spine) UArray ty
single
  MArray (UArray ty) (PrimState (ST s)) -> ST s (Array (UArray ty))
forall (prim :: * -> *) ty.
PrimMonad prim =>
MArray ty (PrimState prim) -> prim (Array ty)
A.unsafeFreeze MArray (UArray ty) s
MArray (UArray ty) (PrimState (ST s))
newArray

-- TODO optimise
find :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find :: forall ty.
PrimType ty =>
(ty -> Bool) -> ChunkedUArray ty -> Maybe ty
find ty -> Bool
fn ChunkedUArray ty
v = Offset ty -> Maybe ty
loop Offset ty
0
  where
    len :: CountOf ty
len = ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
v
    loop :: Offset ty -> Maybe ty
loop !Offset ty
idx
      | Offset ty
idx Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = Maybe ty
forall a. Maybe a
Nothing
      | Bool
otherwise    =
        let currentElem :: ty
currentElem = ChunkedUArray ty
v ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
`unsafeIndex` Offset ty
idx
        in case ty -> Bool
fn ty
currentElem of
          Bool
True  -> ty -> Maybe ty
forall a. a -> Maybe a
Just ty
currentElem
          Bool
False -> Offset ty -> Maybe ty
loop (Offset ty
idx Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1)

-- TODO: Improve implementation.
sortBy :: PrimType ty => (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy :: forall ty.
PrimType ty =>
(ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
sortBy ty -> ty -> Ordering
p = [ty] -> ChunkedUArray ty
[Item (ChunkedUArray ty)] -> ChunkedUArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> ChunkedUArray ty)
-> (ChunkedUArray ty -> [ty])
-> ChunkedUArray ty
-> ChunkedUArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Element [ty] -> Element [ty] -> Ordering) -> [ty] -> [ty]
forall c.
Sequential c =>
(Element c -> Element c -> Ordering) -> c -> c
C.sortBy ty -> ty -> Ordering
Element [ty] -> Element [ty] -> Ordering
p ([ty] -> [ty])
-> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ChunkedUArray ty -> [ty]
ChunkedUArray ty -> [Item (ChunkedUArray ty)]
forall l. IsList l => l -> [Item l]
toList

index :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
index ChunkedUArray ty
array Offset ty
n
    | Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = OutOfBoundOperation -> Offset ty -> CountOf ty -> ty
forall ty a. OutOfBoundOperation -> Offset ty -> CountOf ty -> a
outOfBound OutOfBoundOperation
OOB_Index Offset ty
n CountOf ty
len
    | Bool
otherwise          = ChunkedUArray ty -> Offset ty -> ty
forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex ChunkedUArray ty
array Offset ty
n
  where len :: CountOf ty
len = ChunkedUArray ty -> CountOf ty
forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
length ChunkedUArray ty
array
{-# INLINE index #-}

unsafeIndex :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
unsafeIndex (ChunkedUArray Array (UArray ty)
array) Offset ty
idx = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array Offset (UArray ty)
0) Offset (UArray ty)
0 Offset ty
idx
  where
    go :: UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go UArray ty
u Offset (UArray ty)
globalIndex Offset ty
0 = case UArray ty -> Bool
forall c. Collection c => c -> Bool
C.null UArray ty
u of
      -- Skip empty chunks.
      Bool
True  -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
0
      Bool
False -> UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
U.unsafeIndex UArray ty
u Offset ty
0
    go UArray ty
u !Offset (UArray ty)
globalIndex !Offset ty
i
      -- Skip empty chunks.
      | UArray ty -> Bool
forall c. Collection c => c -> Bool
C.null UArray ty
u  = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
i
      | Bool
otherwise =
          case Offset ty -> CountOf ty -> Maybe (Offset ty)
forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize Offset ty
i (UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
U.length UArray ty
u) of
              Just Offset ty
i' -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
forall ty. Array ty -> Offset ty -> ty
A.unsafeIndex Array (UArray ty)
array (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1)) (Offset (UArray ty)
globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
forall a. Additive a => a -> a -> a
+ Offset (UArray ty)
1) Offset ty
i'
              Maybe (Offset ty)
Nothing -> UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
U.unsafeIndex UArray ty
u Offset ty
i

{-# INLINE unsafeIndex #-}

removeArraySize :: Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize :: forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
removeArraySize (Offset Int
ty) (CountOf Int
s)
    | Int
ty Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
s   = Offset ty -> Maybe (Offset ty)
forall a. a -> Maybe a
Just (Int -> Offset ty
forall ty. Int -> Offset ty
Offset (Int
ty Int -> Int -> Difference Int
forall a. Subtractive a => a -> a -> Difference a
- Int
s))
    | Bool
otherwise = Maybe (Offset ty)
forall a. Maybe a
Nothing