{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.BalancedParens.FindOpen
  ( FindOpen(..)
  ) where

import Data.Word
import HaskellWorks.Data.BalancedParens.FindOpenN
import HaskellWorks.Data.BalancedParens.OpenAt
import HaskellWorks.Data.Bits.BitShown
import HaskellWorks.Data.Naive
import HaskellWorks.Data.Positioning

import qualified Data.Vector.Storable as DVS

class FindOpen v where
  findOpen :: v -> Count -> Maybe Count

instance (FindOpen a) => FindOpen (BitShown a) where
  findOpen :: BitShown a -> Count -> Maybe Count
findOpen = forall v. FindOpen v => v -> Count -> Maybe Count
findOpen forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. BitShown a -> a
bitShown
  {-# INLINE findOpen #-}

instance FindOpen [Bool] where
  findOpen :: [Bool] -> Count -> Maybe Count
findOpen [Bool]
v Count
p = if [Bool]
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  [Bool]
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word8) where
  findOpen :: Vector Word8 -> Count -> Maybe Count
findOpen Vector Word8
v Count
p = if Vector Word8
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word8
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word16) where
  findOpen :: Vector Word16 -> Count -> Maybe Count
findOpen Vector Word16
v Count
p = if Vector Word16
v forall v. OpenAt v => v -> Count -> Bool
`openAt` Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word16
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word32) where
  findOpen :: Vector Word32 -> Count -> Maybe Count
findOpen Vector Word32
v Count
p = if Vector Word32
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word32
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word64) where
  findOpen :: Vector Count -> Count -> Maybe Count
findOpen Vector Count
v Count
p = if Vector Count
v forall v. OpenAt v => v -> Count -> Bool
`openAt` Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Count
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word8 where
  findOpen :: Word8 -> Count -> Maybe Count
findOpen Word8
v Count
p = if Word8
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word8
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word16 where
  findOpen :: Word16 -> Count -> Maybe Count
findOpen Word16
v Count
p = if Word16
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word16
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word32 where
  findOpen :: Word32 -> Count -> Maybe Count
findOpen Word32
v Count
p = if Word32
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word32
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word64 where
  findOpen :: Count -> Count -> Maybe Count
findOpen Count
v Count
p = if Count
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Count
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (Naive Word64) where
  findOpen :: Naive Count -> Count -> Maybe Count
findOpen Naive Count
v Count
p = if Naive Count
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Naive Count
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}