{-# LANGUAGE FlexibleInstances #-}
module HaskellWorks.Data.BalancedParens.FindClose
( FindClose(..)
) where
import Data.Word
import HaskellWorks.Data.BalancedParens.CloseAt
import HaskellWorks.Data.BalancedParens.FindCloseN
import HaskellWorks.Data.Bits.BitShown
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Bits.Broadword.Type
import HaskellWorks.Data.Naive
import HaskellWorks.Data.Positioning
import qualified Data.Vector.Storable as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.FindClose.Vector16 as BWV16
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.FindClose.Vector32 as BWV32
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.FindClose.Vector64 as BWV64
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.FindClose.Vector8 as BWV8
import qualified HaskellWorks.Data.BalancedParens.Internal.Broadword.Word64 as W64
class FindClose v where
findClose :: v -> Count -> Maybe Count
instance (FindClose a) => FindClose (BitShown a) where
findClose = findClose . bitShown
{-# INLINE findClose #-}
instance FindClose [Bool] where
findClose v p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose (DVS.Vector Word8) where
findClose = BWV8.findClose
{-# INLINE findClose #-}
instance FindClose (DVS.Vector Word16) where
findClose = BWV16.findClose
{-# INLINE findClose #-}
instance FindClose (DVS.Vector Word32) where
findClose = BWV32.findClose
{-# INLINE findClose #-}
instance FindClose (DVS.Vector Word64) where
findClose = BWV64.findClose
{-# INLINE findClose #-}
instance FindClose (Naive (DVS.Vector Word8)) where
findClose (Naive v) p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose (Naive (DVS.Vector Word16)) where
findClose (Naive v) p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose (Naive (DVS.Vector Word32)) where
findClose (Naive v) p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose (Naive (DVS.Vector Word64)) where
findClose (Naive v) p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose Word8 where
findClose v p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose Word16 where
findClose v p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose Word32 where
findClose v p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose Word64 where
findClose = findClose . Broadword
{-# INLINE findClose #-}
instance FindClose (Naive Word64) where
findClose v p = if v `closeAt` p then Just p else findCloseN v 1 (p + 1)
{-# INLINE findClose #-}
instance FindClose (Broadword Word64) where
findClose (Broadword w) p = let x = w .>. (p - 1) in
case negate (x .&. 1) .&. W64.findUnmatchedClose x of
127 -> Nothing
r -> let r' = fromIntegral r + p in if r' > 64 then Nothing else Just r'
{-# INLINE findClose #-}