module HaskellWorks.Data.BalancedParens.Internal.Vector.Storable
  ( lastOrZero
  , reword
  , dropTake
  , dropTakeFill
  , pageFill
  ) where

import qualified Data.Vector.Storable as DVS

lastOrZero :: (DVS.Storable a, Integral a) => DVS.Vector a -> a
lastOrZero :: forall a. (Storable a, Integral a) => Vector a -> a
lastOrZero Vector a
v = if Bool -> Bool
not (forall a. Storable a => Vector a -> Bool
DVS.null Vector a
v) then forall a. Storable a => Vector a -> a
DVS.last Vector a
v else a
0
{-# INLINE lastOrZero #-}

reword :: (DVS.Storable a, Integral a, DVS.Storable b, Num b) => DVS.Vector a -> DVS.Vector b
reword :: forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
reword Vector a
v = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate (forall a. Storable a => Vector a -> Int
DVS.length Vector a
v) (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector a
v forall a. Storable a => Vector a -> Int -> a
DVS.! Int
i))
{-# INLINE reword #-}

dropTake :: DVS.Storable a => Int -> Int -> DVS.Vector a -> DVS.Vector a
dropTake :: forall a. Storable a => Int -> Int -> Vector a -> Vector a
dropTake Int
n Int
o = forall a. Storable a => Int -> Vector a -> Vector a
DVS.take Int
o forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Int -> Vector a -> Vector a
DVS.drop Int
n
{-# INLINE dropTake #-}

dropTakeFill :: DVS.Storable a => Int -> Int -> a -> DVS.Vector a -> DVS.Vector a
dropTakeFill :: forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
dropTakeFill Int
n Int
o a
a Vector a
v =  let r :: Vector a
r = forall a. Storable a => Int -> Vector a -> Vector a
DVS.take Int
o (forall a. Storable a => Int -> Vector a -> Vector a
DVS.drop Int
n Vector a
v) in
                        let len :: Int
len = forall a. Storable a => Vector a -> Int
DVS.length Vector a
r in
                        if Int
len forall a. Eq a => a -> a -> Bool
== Int
o then Vector a
r else forall a. Storable a => [Vector a] -> Vector a
DVS.concat [Vector a
r, forall a. Storable a => [a] -> Vector a
DVS.fromList (forall a. Int -> a -> [a]
replicate (Int
o forall a. Num a => a -> a -> a
- Int
len) a
a)]
{-# INLINE dropTakeFill #-}

-- | Return the n-th page of size s from the input vector.  In the case where there isn't
-- sufficient data to fill the page from the input vector, then the remainder of the page
-- is filled with a.
pageFill :: DVS.Storable a
  => Int          -- ^ The n-th page to retrieve
  -> Int          -- ^ The page size
  -> a            -- ^ The element value to fill the page when input vector has insufficient values
  -> DVS.Vector a -- ^ The input vector
  -> DVS.Vector a -- ^ The page
pageFill :: forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
pageFill Int
n Int
s = forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
dropTakeFill (Int
n forall a. Num a => a -> a -> a
* Int
s) Int
s
{-# INLINE pageFill #-}