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 :: (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 =
   (b -> Int -> IO b) -> b -> [Int] -> IO b
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 <- Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
xPtr (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
incx); b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> IO b) -> b -> IO b
forall a b. (a -> b) -> a -> b
$! Int -> b -> a -> b
op Int
k b
x a
y) b
b ([Int] -> IO b) -> [Int] -> IO b
forall a b. (a -> b) -> a -> b
$
   Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int -> Int -> Int
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 :: (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
nInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
1
      then [Char] -> IO b
forall a. HasCallStack => [Char] -> a
error [Char]
"foldl1: empty vector"
      else do
         a
x0 <- Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
xPtr
         (Int -> b -> a -> b) -> b -> Int -> Ptr a -> Int -> IO b
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
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) a
a))
            (Int -> a -> b
f Int
0 a
x0) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Ptr a -> Int -> Ptr a
forall a. Storable a => Ptr a -> Int -> Ptr a
advancePtr Ptr a
xPtr Int
incx) Int
incx