{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MagicHash #-} module Basement.Alg.PrimArray ( Indexable, index , findIndexElem , revFindIndexElem , findIndexPredicate , revFindIndexPredicate , foldl , foldr , foldl1 , all , any , filter ) where import GHC.Types import GHC.Prim import Basement.Alg.Class import Basement.Compat.Base import Basement.Numerical.Additive import Basement.Numerical.Multiplicative import Basement.Types.OffsetSize import Basement.PrimType import Basement.Monad findIndexElem :: (Indexable container ty, Eq ty) => ty -> container -> Offset ty -> Offset ty -> Offset ty findIndexElem :: forall container ty. (Indexable container ty, Eq ty) => ty -> container -> Offset ty -> Offset ty -> Offset ty findIndexElem ty ty container ba Offset ty startIndex Offset ty endIndex = Offset ty -> Offset ty loop Offset ty startIndex where loop :: Offset ty -> Offset ty loop !Offset ty i | Offset ty i forall a. Ord a => a -> a -> Bool >= Offset ty endIndex = forall {ty}. Offset ty sentinel | forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i forall a. Eq a => a -> a -> Bool == ty ty = Offset ty i | Bool otherwise = Offset ty -> Offset ty loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) {-# INLINE findIndexElem #-} revFindIndexElem :: (Indexable container ty, Eq ty) => ty -> container -> Offset ty -> Offset ty -> Offset ty revFindIndexElem :: forall container ty. (Indexable container ty, Eq ty) => ty -> container -> Offset ty -> Offset ty -> Offset ty revFindIndexElem ty ty container ba Offset ty startIndex Offset ty endIndex = Offset ty -> Offset ty loop Offset ty endIndex where loop :: Offset ty -> Offset ty loop !Offset ty iplus1 | Offset ty iplus1 forall a. Ord a => a -> a -> Bool <= Offset ty startIndex = forall {ty}. Offset ty sentinel | forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i forall a. Eq a => a -> a -> Bool == ty ty = Offset ty i | Bool otherwise = Offset ty -> Offset ty loop Offset ty i where !i :: Offset ty i = Offset ty iplus1 forall ty. Offset ty -> CountOf ty -> Offset ty `offsetMinusE` CountOf ty 1 {-# INLINE revFindIndexElem #-} findIndexPredicate :: Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty findIndexPredicate :: forall container ty. Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty findIndexPredicate ty -> Bool predicate container ba Offset ty startIndex Offset ty endIndex = Offset ty -> Offset ty loop Offset ty startIndex where loop :: Offset ty -> Offset ty loop !Offset ty i | Offset ty i forall a. Ord a => a -> a -> Bool >= Offset ty endIndex = forall {ty}. Offset ty sentinel | ty -> Bool predicate (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i) = Offset ty i | Bool otherwise = Offset ty -> Offset ty loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) {-# INLINE findIndexPredicate #-} revFindIndexPredicate :: Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty revFindIndexPredicate :: forall container ty. Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty revFindIndexPredicate ty -> Bool predicate container ba Offset ty startIndex Offset ty endIndex = Offset ty -> Offset ty loop Offset ty endIndex where loop :: Offset ty -> Offset ty loop !Offset ty iplus1 | Offset ty iplus1 forall a. Ord a => a -> a -> Bool <= Offset ty startIndex = forall {ty}. Offset ty sentinel | ty -> Bool predicate (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i) = Offset ty i | Bool otherwise = Offset ty -> Offset ty loop Offset ty i where !i :: Offset ty i = Offset ty iplus1 forall ty. Offset ty -> CountOf ty -> Offset ty `offsetMinusE` CountOf ty 1 {-# INLINE revFindIndexPredicate #-} foldl :: Indexable container ty => (a -> ty -> a) -> a -> container -> Offset ty -> Offset ty -> a foldl :: forall container ty a. Indexable container ty => (a -> ty -> a) -> a -> container -> Offset ty -> Offset ty -> a foldl a -> ty -> a f !a initialAcc container ba !Offset ty startIndex !Offset ty endIndex = Offset ty -> a -> a loop Offset ty startIndex a initialAcc where loop :: Offset ty -> a -> a loop !Offset ty i !a acc | Offset ty i forall a. Eq a => a -> a -> Bool == Offset ty endIndex = a acc | Bool otherwise = Offset ty -> a -> a loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) (a -> ty -> a f a acc (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i)) {-# INLINE foldl #-} foldr :: Indexable container ty => (ty -> a -> a) -> a -> container -> Offset ty -> Offset ty -> a foldr :: forall container ty a. Indexable container ty => (ty -> a -> a) -> a -> container -> Offset ty -> Offset ty -> a foldr ty -> a -> a f !a initialAcc container ba Offset ty startIndex Offset ty endIndex = Offset ty -> a loop Offset ty startIndex where loop :: Offset ty -> a loop !Offset ty i | Offset ty i forall a. Eq a => a -> a -> Bool == Offset ty endIndex = a initialAcc | Bool otherwise = forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i ty -> a -> a `f` Offset ty -> a loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) {-# INLINE foldr #-} foldl1 :: Indexable container ty => (ty -> ty -> ty) -> container -> Offset ty -> Offset ty -> ty foldl1 :: forall container ty. Indexable container ty => (ty -> ty -> ty) -> container -> Offset ty -> Offset ty -> ty foldl1 ty -> ty -> ty f container ba Offset ty startIndex Offset ty endIndex = Offset ty -> ty -> ty loop (Offset ty startIndexforall a. Additive a => a -> a -> a +Offset ty 1) (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty startIndex) where loop :: Offset ty -> ty -> ty loop !Offset ty i !ty acc | Offset ty i forall a. Eq a => a -> a -> Bool == Offset ty endIndex = ty acc | Bool otherwise = Offset ty -> ty -> ty loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) (ty -> ty -> ty f ty acc (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i)) {-# INLINE foldl1 #-} filter :: (PrimMonad prim, PrimType ty, Indexable container ty) => (ty -> Bool) -> MutableByteArray# (PrimState prim) -> container -> Offset ty -> Offset ty -> prim (CountOf ty) filter :: forall (prim :: * -> *) ty container. (PrimMonad prim, PrimType ty, Indexable container ty) => (ty -> Bool) -> MutableByteArray# (PrimState prim) -> container -> Offset ty -> Offset ty -> prim (CountOf ty) filter ty -> Bool predicate MutableByteArray# (PrimState prim) dst container src Offset ty start Offset ty end = Offset ty -> Offset ty -> prim (CountOf ty) loop forall a. Additive a => a azero Offset ty start where loop :: Offset ty -> Offset ty -> prim (CountOf ty) loop !Offset ty d !Offset ty s | Offset ty s forall a. Eq a => a -> a -> Bool == Offset ty end = forall (f :: * -> *) a. Applicative f => a -> f a pure (forall a. Offset a -> CountOf a offsetAsSize Offset ty d) | ty -> Bool predicate ty v = forall ty (prim :: * -> *). (PrimType ty, PrimMonad prim) => MutableByteArray# (PrimState prim) -> Offset ty -> ty -> prim () primMbaWrite MutableByteArray# (PrimState prim) dst Offset ty d ty v forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> Offset ty -> Offset ty -> prim (CountOf ty) loop (Offset ty dforall a. Additive a => a -> a -> a +forall ty. Int -> Offset ty Offset Int 1) (Offset ty sforall a. Additive a => a -> a -> a +forall ty. Int -> Offset ty Offset Int 1) | Bool otherwise = Offset ty -> Offset ty -> prim (CountOf ty) loop Offset ty d (Offset ty sforall a. Additive a => a -> a -> a +forall ty. Int -> Offset ty Offset Int 1) where v :: ty v = forall container ty. Indexable container ty => container -> Offset ty -> ty index container src Offset ty s {-# INLINE filter #-} all :: Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool all :: forall container ty. Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool all ty -> Bool predicate container ba Offset ty start Offset ty end = Offset ty -> Bool loop Offset ty start where loop :: Offset ty -> Bool loop !Offset ty i | Offset ty i forall a. Eq a => a -> a -> Bool == Offset ty end = Bool True | ty -> Bool predicate (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i) = Offset ty -> Bool loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) | Bool otherwise = Bool False {-# INLINE all #-} any :: Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool any :: forall container ty. Indexable container ty => (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool any ty -> Bool predicate container ba Offset ty start Offset ty end = Offset ty -> Bool loop Offset ty start where loop :: Offset ty -> Bool loop !Offset ty i | Offset ty i forall a. Eq a => a -> a -> Bool == Offset ty end = Bool False | ty -> Bool predicate (forall container ty. Indexable container ty => container -> Offset ty -> ty index container ba Offset ty i) = Bool True | Bool otherwise = Offset ty -> Bool loop (Offset ty iforall a. Additive a => a -> a -> a +Offset ty 1) {-# INLINE any #-}