module HaskellWorks.Data.BalancedParens.Internal.Broadword.FindUnmatchedCloseFar.Vector64
( findUnmatchedCloseFar
) where
import Data.Int
import Data.Word
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.Bits.BitLength
import HaskellWorks.Data.Int.Unsigned
import HaskellWorks.Data.Positioning
import qualified Data.Vector.Storable as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.FindUnmatchedCloseFar.Word64 as BWW64
import qualified HaskellWorks.Data.Drop as HW
import qualified HaskellWorks.Data.Length as HW
findUnmatchedCloseCont :: Int64 -> Count -> DVS.Vector Word64 -> Count
findUnmatchedCloseCont i c v = if i < HW.end v
then case BWW64.findUnmatchedCloseFar c 0 w of
q -> if q >= bitLength w
then findUnmatchedCloseCont (i + 1) (q - bitLength w) v
else b + q
else b + c
where b = unsigned i * bitLength w
w = v !!! fromIntegral i
{-# INLINE findUnmatchedCloseCont #-}
findUnmatchedClose' :: Word64 -> Word64 -> DVS.Vector Word64 -> Count
findUnmatchedClose' c p v = if DVS.length v > 0
then case BWW64.findUnmatchedCloseFar c p w of
q -> if q >= bitLength w
then findUnmatchedCloseCont 1 (q - bitLength w) v
else q
else p * 2 + c
where w = v !!! 0
{-# INLINE findUnmatchedClose' #-}
findUnmatchedCloseFar :: Word64 -> Word64 -> DVS.Vector Word64 -> Count
findUnmatchedCloseFar c p v = findUnmatchedClose' c (p - vd) (HW.drop vi v) + vd
where vi = p `div` elemBitLength v
vd = vi * elemBitLength v
{-# INLINE findUnmatchedCloseFar #-}