module Streamly.Internal.Data.Ring.Foreign
    ( Ring(..)
    
    , new
    , newRing
    , writeN
    , advance
    , moveBy
    , startOf
    
    , unsafeInsert
    , slide
    , putIndex
    , modifyIndex
    
    , read
    , readRev
    
    , getIndex
    , getIndexUnsafe
    , getIndexRev
    
    , length
    , byteLength
    
    , byteCapacity
    , bytesFree
    
    , cast
    , castUnsafe
    , asBytes
    , fromArray
    
    , unsafeFoldRing
    , unsafeFoldRingM
    , unsafeFoldRingFullM
    , unsafeFoldRingNM
    
    , ringsOf
    
    , unsafeEqArray
    , unsafeEqArrayN
    , slidingWindow
    ) where
#include "ArrayMacros.h"
#include "inline.hs"
import Control.Exception (assert)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Word (Word8)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, touchForeignPtr)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.Ptr (plusPtr, minusPtr, castPtr)
import Foreign.Storable (Storable(..))
import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes)
import GHC.Ptr (Ptr(..))
import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array, memcmp)
import Streamly.Internal.Data.Fold.Type (Fold(..), Step(..))
import Streamly.Internal.Data.Stream.Serial (SerialT(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import Streamly.Internal.System.IO (unsafeInlineIO)
import qualified Streamly.Internal.Data.Array.Foreign.Type as A
import Prelude hiding (length, concat, read)
data Ring a = Ring
    { Ring a -> ForeignPtr a
ringStart :: {-# UNPACK #-} !(ForeignPtr a) 
    , Ring a -> Ptr a
ringBound :: {-# UNPACK #-} !(Ptr a)        
    }
startOf :: Ring a -> Ptr a
startOf :: Ring a -> Ptr a
startOf = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr (ForeignPtr a -> Ptr a)
-> (Ring a -> ForeignPtr a) -> Ring a -> Ptr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ring a -> ForeignPtr a
forall a. Ring a -> ForeignPtr a
ringStart
{-# INLINE new #-}
new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
new :: Int -> IO (Ring a, Ptr a)
new Int
count = do
    let size :: Int
size = Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* SIZE_OF(a)
    ForeignPtr a
fptr <- Int -> Int -> IO (ForeignPtr a)
forall a. Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes Int
size (a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined :: a))
    let p :: Ptr a
p = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fptr
    (Ring a, Ptr a) -> IO (Ring a, Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ring :: forall a. ForeignPtr a -> Ptr a -> Ring a
Ring
        { ringStart :: ForeignPtr a
ringStart = ForeignPtr a
fptr
        , ringBound :: Ptr a
ringBound = Ptr a
p Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
size
        }, Ptr a
p)
{-# INLINE newRing #-}
newRing :: Int -> m (Ring a)
newRing :: Int -> m (Ring a)
newRing = Int -> m (Ring a)
forall a. HasCallStack => a
undefined
{-# INLINE advance #-}
advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance :: Ring a -> Ptr a -> Ptr a
advance Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
ringHead =
    let ptr :: Ptr b
ptr = Ptr a
PTR_NEXT(ringHead,a)
    in if Ptr a
forall b. Ptr b
ptr Ptr a -> Ptr a -> Bool
forall a. Ord a => a -> a -> Bool
<  Ptr a
ringBound
       then Ptr a
forall b. Ptr b
ptr
       else ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
{-# INLINE moveBy #-}
moveBy :: forall a. Storable a => Int -> Ring a -> Ptr a -> Ptr a
moveBy :: Int -> Ring a -> Ptr a -> Ptr a
moveBy Int
by Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
ringHead = Ptr a
ringStartPtr Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
advanceFromHead
    where
    elemSize :: Int
elemSize = SIZE_OF(a)
    ringStartPtr :: Ptr a
ringStartPtr = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
    lenInBytes :: Int
lenInBytes = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
    offInBytes :: Int
offInBytes = Ptr a
ringHead Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
    len :: Int
len = Bool -> Int -> Int
forall a. HasCallStack => Bool -> a -> a
assert (Int
lenInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
elemSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
lenInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
elemSize
    off :: Int
off = Bool -> Int -> Int
forall a. HasCallStack => Bool -> a -> a
assert (Int
offInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
elemSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
offInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
elemSize
    advanceFromHead :: Int
advanceFromHead = (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
by Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
elemSize
{-# INLINE writeN #-}
writeN :: 
    Int -> Fold m a (Ring a)
writeN :: Int -> Fold m a (Ring a)
writeN = Int -> Fold m a (Ring a)
forall a. HasCallStack => a
undefined
fromArray :: Array a -> Ring a
fromArray :: Array a -> Ring a
fromArray = Array a -> Ring a
forall a. HasCallStack => a
undefined
modifyIndex :: 
    Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex :: Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex = Ring a -> Int -> (a -> (a, b)) -> m b
forall a. HasCallStack => a
undefined
{-# INLINE putIndex #-}
putIndex :: 
    Ring a -> Int -> a -> m ()
putIndex :: Ring a -> Int -> a -> m ()
putIndex = Ring a -> Int -> a -> m ()
forall a. HasCallStack => a
undefined
{-# INLINE unsafeInsert #-}
unsafeInsert :: Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert :: Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
ringHead a
newVal = do
    Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
ringHead a
newVal
    
    Ptr a -> IO (Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr a -> IO (Ptr a)) -> Ptr a -> IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Ptr a
forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
ringHead
slide :: 
    Ring a -> a -> m (Ring a)
slide :: Ring a -> a -> m (Ring a)
slide = Ring a -> a -> m (Ring a)
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL getIndexUnsafe #-}
getIndexUnsafe :: 
    Ring a -> Int -> m a
getIndexUnsafe :: Ring a -> Int -> m a
getIndexUnsafe = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE getIndex #-}
getIndex :: 
    Ring a -> Int -> m a
getIndex :: Ring a -> Int -> m a
getIndex = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE getIndexRev #-}
getIndexRev :: 
    Ring a -> Int -> m a
getIndexRev :: Ring a -> Int -> m a
getIndexRev = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE byteLength #-}
byteLength :: Ring a -> Int
byteLength :: Ring a -> Int
byteLength = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE length #-}
length :: 
    Ring a -> Int
length :: Ring a -> Int
length = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE byteCapacity #-}
byteCapacity :: Ring a -> Int
byteCapacity :: Ring a -> Int
byteCapacity = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE bytesFree #-}
bytesFree :: Ring a -> Int
bytesFree :: Ring a -> Int
bytesFree = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL read #-}
read :: 
    Unfold m (Ring a) a
read :: Unfold m (Ring a) a
read = Unfold m (Ring a) a
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL readRev #-}
readRev :: 
    Unfold m (Array a) a
readRev :: Unfold m (Array a) a
readRev = Unfold m (Array a) a
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL ringsOf #-}
ringsOf :: 
    Int -> SerialT m a -> SerialT m (Array a)
ringsOf :: Int -> SerialT m a -> SerialT m (Array a)
ringsOf = Int -> SerialT m a -> SerialT m (Array a)
forall a. HasCallStack => a
undefined 
castUnsafe :: Ring a -> Ring b
castUnsafe :: Ring a -> Ring b
castUnsafe = Ring a -> Ring b
forall a. HasCallStack => a
undefined
asBytes :: Ring a -> Ring Word8
asBytes :: Ring a -> Ring Word8
asBytes = Ring a -> Ring Word8
forall a b. Ring a -> Ring b
castUnsafe
cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)
cast :: Ring a -> Maybe (Ring b)
cast Ring a
arr =
    let len :: Int
len = Ring a -> Int
forall a. Ring a -> Int
byteLength Ring a
arr
        r :: Int
r = Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` SIZE_OF(b)
     in if Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
        then Maybe (Ring b)
forall a. Maybe a
Nothing
        else Ring b -> Maybe (Ring b)
forall a. a -> Maybe a
Just (Ring b -> Maybe (Ring b)) -> Ring b -> Maybe (Ring b)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ring b
forall a b. Ring a -> Ring b
castUnsafe Ring a
arr
{-# INLINE unsafeEqArrayN #-}
unsafeEqArrayN :: Ring a -> Ptr a -> A.Array a -> Int -> Bool
unsafeEqArrayN :: Ring a -> Ptr a -> Array a -> Int -> Bool
unsafeEqArrayN Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
rh A.Array{Ptr a
ArrayContents
aEnd :: forall a. Array a -> Ptr a
arrStart :: forall a. Array a -> Ptr a
arrContents :: forall a. Array a -> ArrayContents
aEnd :: Ptr a
arrStart :: Ptr a
arrContents :: ArrayContents
..} Int
n =
    let !res :: Bool
res = IO Bool -> Bool
forall a. IO a -> a
unsafeInlineIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
            let rs :: Ptr a
rs = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
                as :: Ptr a
as = Ptr a
arrStart
            Bool -> IO () -> IO ()
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
            let len :: Int
len = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
            Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
len Int
n)
            Bool
r2 <- if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
len
                then Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (Ptr Any -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
                              (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Ptr a
rh Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len))
                else Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
            
            
            
            Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
r1 Bool -> Bool -> Bool
&& Bool
r2)
    in Bool
res
{-# INLINE unsafeEqArray #-}
unsafeEqArray :: Ring a -> Ptr a -> A.Array a -> Bool
unsafeEqArray :: Ring a -> Ptr a -> Array a -> Bool
unsafeEqArray Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
rh A.Array{Ptr a
ArrayContents
aEnd :: Ptr a
arrStart :: Ptr a
arrContents :: ArrayContents
aEnd :: forall a. Array a -> Ptr a
arrStart :: forall a. Array a -> Ptr a
arrContents :: forall a. Array a -> ArrayContents
..} =
    let !res :: Bool
res = IO Bool -> Bool
forall a. IO a -> a
unsafeInlineIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
            let rs :: Ptr a
rs = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
            let as :: Ptr a
as = Ptr a
arrStart
            Bool -> IO () -> IO ()
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
                   (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
            let len :: Int
len = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
            Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) Int
len
            Bool
r2 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (Ptr Any -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
                           (Ptr a
rh Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
            
            
            
            Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
r1 Bool -> Bool -> Bool
&& Bool
r2)
    in Bool
res
{-# INLINE unsafeFoldRing #-}
unsafeFoldRing :: forall a b. Storable a
    => Ptr a -> (b -> a -> b) -> b -> Ring a -> b
unsafeFoldRing :: Ptr a -> (b -> a -> b) -> b -> Ring a -> b
unsafeFoldRing Ptr a
ptr b -> a -> b
f b
z Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
    let !res :: b
res = IO b -> b
forall a. IO a -> a
unsafeInlineIO (IO b -> b) -> IO b -> b
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
ringStart ((Ptr a -> IO b) -> IO b) -> (Ptr a -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr a
p ->
                    b -> Ptr a -> Ptr a -> IO b
go b
z Ptr a
p Ptr a
ptr
    in b
res
    where
      go :: b -> Ptr a -> Ptr a -> IO b
go !b
acc !Ptr a
p !Ptr a
q
        | Ptr a
p Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
q = b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
        | Bool
otherwise = do
            a
x <- Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
p
            b -> Ptr a -> Ptr a -> IO b
go (b -> a -> b
f b
acc a
x) (PTR_NEXT(p,a)) q
withForeignPtrM :: MonadIO m => ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM :: ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
fp Ptr a -> m b
fn = do
    b
r <- Ptr a -> m b
fn (Ptr a -> m b) -> Ptr a -> m b
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fp
    IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
fp
    b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
{-# INLINE unsafeFoldRingM #-}
unsafeFoldRingM :: forall m a b. (MonadIO m, Storable a)
    => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingM :: Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingM Ptr a
ptr b -> a -> m b
f b
z Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
    ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
forall a b. (a -> b) -> a -> b
$ \Ptr a
x -> b -> Ptr a -> Ptr a -> m b
go b
z Ptr a
x Ptr a
ptr
  where
    go :: b -> Ptr a -> Ptr a -> m b
go !b
acc !Ptr a
start !Ptr a
end
        | Ptr a
start Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
end = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
        | Bool
otherwise = do
            let !x :: a
x = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
            b
acc1 <- b -> a -> m b
f b
acc a
x
            b -> Ptr a -> Ptr a -> m b
go b
acc1 (PTR_NEXT(start,a)) end
{-# INLINE unsafeFoldRingFullM #-}
unsafeFoldRingFullM :: forall m a b. (MonadIO m, Storable a)
    => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingFullM :: Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingFullM Ptr a
rh b -> a -> m b
f b
z rb :: Ring a
rb@Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
    ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
forall a b. (a -> b) -> a -> b
$ \Ptr a
_ -> b -> Ptr a -> m b
go b
z Ptr a
rh
  where
    go :: b -> Ptr a -> m b
go !b
acc !Ptr a
start = do
        let !x :: a
x = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
        b
acc' <- b -> a -> m b
f b
acc a
x
        let ptr :: Ptr a
ptr = Ring a -> Ptr a -> Ptr a
forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
        if Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
rh
            then b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc'
            else b -> Ptr a -> m b
go b
acc' Ptr a
ptr
{-# INLINE unsafeFoldRingNM #-}
unsafeFoldRingNM :: forall m a b. (MonadIO m, Storable a)
    => Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingNM :: Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingNM Int
count Ptr a
rh b -> a -> m b
f b
z rb :: Ring a
rb@Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
    ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
forall a b. (a -> b) -> a -> b
$ \Ptr a
_ -> Int -> b -> Ptr a -> m b
forall t. (Eq t, Num t) => t -> b -> Ptr a -> m b
go Int
count b
z Ptr a
rh
    where
    go :: t -> b -> Ptr a -> m b
go t
0 b
acc Ptr a
_ = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
    go !t
n !b
acc !Ptr a
start = do
        let !x :: a
x = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
        b
acc' <- b -> a -> m b
f b
acc a
x
        let ptr :: Ptr a
ptr = Ring a -> Ptr a -> Ptr a
forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
        if Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
rh Bool -> Bool -> Bool
|| t
n t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0
            then b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc'
            else t -> b -> Ptr a -> m b
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) b
acc' Ptr a
ptr
data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Int -> Tuple4' a b c d -> ShowS
[Tuple4' a b c d] -> ShowS
Tuple4' a b c d -> String
(Int -> Tuple4' a b c d -> ShowS)
-> (Tuple4' a b c d -> String)
-> ([Tuple4' a b c d] -> ShowS)
-> Show (Tuple4' a b c d)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showList :: [Tuple4' a b c d] -> ShowS
$cshowList :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
show :: Tuple4' a b c d -> String
$cshow :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showsPrec :: Int -> Tuple4' a b c d -> ShowS
$cshowsPrec :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
Show
{-# INLINE slidingWindow #-}
slidingWindow :: forall m a b. (MonadIO m, Storable a)
    => Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow :: Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow Int
n (Fold s -> (a, Maybe a) -> m (Step s b)
step1 m (Step s b)
initial1 s -> m b
extract1)= (Tuple4' (Ring a) (Ptr a) Int s
 -> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> (Tuple4' (Ring a) (Ptr a) Int s -> m b)
-> Fold m a b
forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold Tuple4' (Ring a) (Ptr a) Int s
-> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
step m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
initial Tuple4' (Ring a) (Ptr a) Int s -> m b
forall a b c. Tuple4' a b c s -> m b
extract
    where
    initial :: m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
initial = do
        Step s b
r <- m (Step s b)
initial1
        (Ring a
rb, Ptr a
rh) <- IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ring a, Ptr a) -> m (Ring a, Ptr a))
-> IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (Ring a, Ptr a)
forall a. Storable a => Int -> IO (Ring a, Ptr a)
new Int
n
        Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
 -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
            case Step s b
r of
                Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
 -> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh (Int
0 :: Int) s
s
                Done b
b -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. b -> Step s b
Done b
b
    step :: Tuple4' (Ring a) (Ptr a) Int s
-> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
step (Tuple4' Ring a
rb Ptr a
rh Int
i s
st) a
a
        | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = do
            Ptr a
rh1 <- IO (Ptr a) -> m (Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr a) -> m (Ptr a)) -> IO (Ptr a) -> m (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> a -> IO (Ptr a)
forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
            IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr (Ring a -> ForeignPtr a
forall a. Ring a -> ForeignPtr a
ringStart Ring a
rb)
            Step s b
r <- s -> (a, Maybe a) -> m (Step s b)
step1 s
st (a
a, Maybe a
forall a. Maybe a
Nothing)
            Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
 -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
                case Step s b
r of
                    Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
 -> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) s
s
                    Done b
b -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. b -> Step s b
Done b
b
        | Bool
otherwise = do
            a
old <- IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
rh
            Ptr a
rh1 <- IO (Ptr a) -> m (Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr a) -> m (Ptr a)) -> IO (Ptr a) -> m (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> a -> IO (Ptr a)
forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
            IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr (Ring a -> ForeignPtr a
forall a. Ring a -> ForeignPtr a
ringStart Ring a
rb)
            Step s b
r <- s -> (a, Maybe a) -> m (Step s b)
step1 s
st (a
a, a -> Maybe a
forall a. a -> Maybe a
Just a
old)
            Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
 -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
                case Step s b
r of
                    Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
 -> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) s
s
                    Done b
b -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. b -> Step s b
Done b
b
    extract :: Tuple4' a b c s -> m b
extract (Tuple4' a
_ b
_ c
_ s
st) = s -> m b
extract1 s
st