module Data.Array.Comfort.Storable.Memory where

import Foreign.Marshal.Array (advancePtr)
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable, peek, peekElemOff)

import Control.Monad (foldM)

import Prelude hiding (foldl, foldl1)


{-# INLINE foldl #-}
foldl ::
   (Storable a) => (Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
foldl :: forall a b.
Storable a =>
(Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
foldl Int -> b -> a -> b
op b
b Int
n Ptr a
xPtr Int
incx =
   forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (\b
x Int
k -> do a
y <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
xPtr (Int
kforall a. Num a => a -> a -> a
*Int
incx); forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Int -> b -> a -> b
op Int
k b
x a
y) b
b forall a b. (a -> b) -> a -> b
$
   forall a. Int -> [a] -> [a]
take Int
n forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> [a]
iterate (forall a. Num a => a -> a -> a
+Int
1) Int
0

{-# INLINE foldl1 #-}
foldl1 ::
   (Storable a) =>
   (Int -> a -> b) -> (b -> b -> b) -> Int -> Ptr a -> Int -> IO b
foldl1 :: forall a b.
Storable a =>
(Int -> a -> b) -> (b -> b -> b) -> Int -> Ptr a -> Int -> IO b
foldl1 Int -> a -> b
f b -> b -> b
op Int
n Ptr a
xPtr Int
incx =
   if Int
nforall a. Ord a => a -> a -> Bool
<Int
1
      then forall a. HasCallStack => [Char] -> a
error [Char]
"foldl1: empty vector"
      else do
         a
x0 <- forall a. Storable a => Ptr a -> IO a
peek Ptr a
xPtr
         forall a b.
Storable a =>
(Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
foldl (\Int
k b
b a
a -> b -> b -> b
op b
b (Int -> a -> b
f (Int
kforall a. Num a => a -> a -> a
+Int
1) a
a))
            (Int -> a -> b
f Int
0 a
x0) (Int
nforall a. Num a => a -> a -> a
-Int
1) (forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
xPtr Int
incx) Int
incx