{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE TypeFamilies          #-}

module HaskellWorks.Data.BalancedParens.RangeMin
  ( RangeMin(..)
  , mkRangeMin
  ) where

import Control.DeepSeq
import Data.Int
import GHC.Generics
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.BalancedParens.BalancedParens
import HaskellWorks.Data.BalancedParens.CloseAt
import HaskellWorks.Data.BalancedParens.Enclose
import HaskellWorks.Data.BalancedParens.FindClose
import HaskellWorks.Data.BalancedParens.FindCloseN
import HaskellWorks.Data.BalancedParens.FindOpen
import HaskellWorks.Data.BalancedParens.FindOpenN
import HaskellWorks.Data.BalancedParens.NewCloseAt
import HaskellWorks.Data.BalancedParens.OpenAt
import HaskellWorks.Data.Bits.AllExcess.AllExcess1
import HaskellWorks.Data.Bits.BitLength
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Excess.MinExcess
import HaskellWorks.Data.Excess.MinExcess1
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.RankSelect.Base.Rank0
import HaskellWorks.Data.RankSelect.Base.Rank1
import HaskellWorks.Data.Vector.AsVector64
import Prelude                                         hiding (length)

import qualified Data.Vector.Storable                                      as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.Vector.Storable as DVS

data RangeMin a = RangeMin
  { forall a. RangeMin a -> a
rangeMinBP       :: !a
  , forall a. RangeMin a -> Vector Int8
rangeMinL0Min    :: !(DVS.Vector Int8)
  , forall a. RangeMin a -> Vector Int8
rangeMinL0Excess :: !(DVS.Vector Int8)
  , forall a. RangeMin a -> Vector Int16
rangeMinL1Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin a -> Vector Int16
rangeMinL1Excess :: !(DVS.Vector Int16)
  , forall a. RangeMin a -> Vector Int16
rangeMinL2Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin a -> Vector Int16
rangeMinL2Excess :: !(DVS.Vector Int16)
  } deriving (RangeMin a -> RangeMin a -> Bool
forall a. Eq a => RangeMin a -> RangeMin a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RangeMin a -> RangeMin a -> Bool
$c/= :: forall a. Eq a => RangeMin a -> RangeMin a -> Bool
== :: RangeMin a -> RangeMin a -> Bool
$c== :: forall a. Eq a => RangeMin a -> RangeMin a -> Bool
Eq, Int -> RangeMin a -> ShowS
forall a. Show a => Int -> RangeMin a -> ShowS
forall a. Show a => [RangeMin a] -> ShowS
forall a. Show a => RangeMin a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RangeMin a] -> ShowS
$cshowList :: forall a. Show a => [RangeMin a] -> ShowS
show :: RangeMin a -> String
$cshow :: forall a. Show a => RangeMin a -> String
showsPrec :: Int -> RangeMin a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> RangeMin a -> ShowS
Show, forall a. NFData a => RangeMin a -> ()
forall a. (a -> ()) -> NFData a
rnf :: RangeMin a -> ()
$crnf :: forall a. NFData a => RangeMin a -> ()
NFData, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (RangeMin a) x -> RangeMin a
forall a x. RangeMin a -> Rep (RangeMin a) x
$cto :: forall a x. Rep (RangeMin a) x -> RangeMin a
$cfrom :: forall a x. RangeMin a -> Rep (RangeMin a) x
Generic)

factorL0 :: Integral a => a
factorL0 :: forall a. Integral a => a
factorL0 = a
1
{-# INLINE factorL0 #-}

factorL1 :: Integral a => a
factorL1 :: forall a. Integral a => a
factorL1 = a
32
{-# INLINE factorL1 #-}

factorL2 :: Integral a => a
factorL2 :: forall a. Integral a => a
factorL2 = a
32
{-# INLINE factorL2 #-}

pageSizeL0 :: Integral a => a
pageSizeL0 :: forall a. Integral a => a
pageSizeL0 = forall a. Integral a => a
factorL0
{-# INLINE pageSizeL0 #-}

pageSizeL1 :: Integral a => a
pageSizeL1 :: forall a. Integral a => a
pageSizeL1 = forall a. Integral a => a
pageSizeL0 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL1
{-# INLINE pageSizeL1 #-}

pageSizeL2 :: Integral a => a
pageSizeL2 :: forall a. Integral a => a
pageSizeL2 = forall a. Integral a => a
pageSizeL1 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL2
{-# INLINE pageSizeL2 #-}

mkRangeMin :: AsVector64 a => a -> RangeMin a
mkRangeMin :: forall a. AsVector64 a => a -> RangeMin a
mkRangeMin a
bp = RangeMin
  { $sel:rangeMinBP:RangeMin :: a
rangeMinBP       = a
bp
  , $sel:rangeMinL0Min:RangeMin :: Vector Int8
rangeMinL0Min    = Vector Int8
rmL0Min
  , $sel:rangeMinL0Excess:RangeMin :: Vector Int8
rangeMinL0Excess = forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL0Excess
  , $sel:rangeMinL1Min:RangeMin :: Vector Int16
rangeMinL1Min    = Vector Int16
rmL1Min
  , $sel:rangeMinL1Excess:RangeMin :: Vector Int16
rangeMinL1Excess = forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL1Excess
  , $sel:rangeMinL2Min:RangeMin :: Vector Int16
rangeMinL2Min    = Vector Int16
rmL2Min
  , $sel:rangeMinL2Excess:RangeMin :: Vector Int16
rangeMinL2Excess = Vector Int16
rmL2Excess
  }
  where bpv :: Vector Count
bpv           = forall a. AsVector64 a => a -> Vector Count
asVector64 a
bp
        lenBP :: Int
lenBP         = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall v. Length v => v -> Count
length Vector Count
bpv) :: Int
        lenL0 :: Int
lenL0         = Int
lenBP
        lenL1 :: Int
lenL1         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int8
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL1) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL2 :: Int
lenL2         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int8
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL2) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        allMinL0 :: Vector MinExcess
allMinL0      = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> if Int
i forall a. Eq a => a -> a -> Bool
== Int
lenBP then Int -> Int -> MinExcess
MinExcess (-Int
64) (-Int
64) else forall a. MinExcess1 a => a -> MinExcess
minExcess1 (Vector Count
bpv forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i))
        allMinL1 :: Vector MinExcess
allMinL1      = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> forall a. MinExcess1 a => a -> MinExcess
minExcess1 (forall a. Storable a => Int -> Int -> Vector a -> Vector a
DVS.dropTake (Int
i forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1) forall a. Integral a => a
pageSizeL1 Vector Count
bpv))
        allMinL2 :: Vector MinExcess
allMinL2      = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> forall a. MinExcess1 a => a -> MinExcess
minExcess1 (forall a. Storable a => Int -> Int -> Vector a -> Vector a
DVS.dropTake (Int
i forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2) forall a. Integral a => a
pageSizeL2 Vector Count
bpv))
        -- Note: (0xffffffffffffffc0 :: Int64) = -64
        rmL0Excess :: Vector Int16
rmL0Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL0 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL1Excess :: Vector Int16
rmL1Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL1 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL2Excess :: Vector Int16
rmL2Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL2 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL0Min :: Vector Int8
rmL0Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> let MinExcess Int
minE Int
_ = Vector MinExcess
allMinL0 forall a. Storable a => Vector a -> Int -> a
DVS.! Int
i in forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minE)
        rmL1Min :: Vector Int16
rmL1Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> let MinExcess Int
minE Int
_ = Vector MinExcess
allMinL1 forall a. Storable a => Vector a -> Int -> a
DVS.! Int
i in forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minE)
        rmL2Min :: Vector Int16
rmL2Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> let MinExcess Int
minE Int
_ = Vector MinExcess
allMinL2 forall a. Storable a => Vector a -> Int -> a
DVS.! Int
i in forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minE)

data FindState = FindBP
  | FindL0 | FindFromL0
  | FindL1 | FindFromL1
  | FindL2 | FindFromL2

rm2FindClose  :: (BitLength a, NewCloseAt a) => RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose :: forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindBP = if RangeMin a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p
  then if Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
    then forall a. a -> Maybe a
Just Count
p
    else forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (Int
s forall a. Num a => a -> a -> a
- Int
1) (Count
p forall a. Num a => a -> a -> a
+ Count
1) FindState
FindFromL0
  else forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (Int
s forall a. Num a => a -> a -> a
+ Int
1) (Count
p forall a. Num a => a -> a -> a
+ Count
1) FindState
FindFromL0
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL0 =
  let i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` Count
64 in
  let mins :: Vector Int8
mins = forall a. RangeMin a -> Vector Int8
rangeMinL0Min RangeMin a
v in
  let minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindBP
    else if RangeMin a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
      then forall a. a -> Maybe a
Just Count
p
      else  let excesses :: Vector Int8
excesses  = forall a. RangeMin a -> Vector Int8
rangeMinL0Excess RangeMin a
v in
            let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
            forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ Count
64) FindState
FindFromL0
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL1 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1) in
  let !mins :: Vector Int16
mins = forall a. RangeMin a -> Vector Int16
rangeMinL1Min RangeMin a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL0
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v
      then if RangeMin a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin a -> Vector Int16
rangeMinL1Excess RangeMin a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1)) FindState
FindFromL1
      else forall a. Maybe a
Nothing
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL2 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2) in
  let !mins :: Vector Int16
mins = forall a. RangeMin a -> Vector Int16
rangeMinL2Min RangeMin a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL1
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v
      then if RangeMin a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin a -> Vector Int16
rangeMinL2Excess RangeMin a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2)) FindState
FindFromL2
      else forall a. Maybe a
Nothing
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindFromL0
  | Count
p forall a. Integral a => a -> a -> a
`mod` Count
64 forall a. Eq a => a -> a -> Bool
== Count
0             = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindFromL1
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v   = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindBP
  | Bool
otherwise                   = forall a. Maybe a
Nothing
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindFromL1
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindFromL2 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL0
  | Bool
otherwise                       = forall a. Maybe a
Nothing
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindFromL2
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL2 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v Int
s Count
p FindState
FindL1
  | Bool
otherwise                       = forall a. Maybe a
Nothing
{-# INLINE rm2FindClose #-}

instance TestBit a => TestBit (RangeMin a) where
  .?. :: RangeMin a -> Position -> Bool
(.?.) = forall a. TestBit a => a -> Position -> Bool
(.?.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE (.?.) #-}

instance Rank1 a => Rank1 (RangeMin a) where
  rank1 :: RangeMin a -> Count -> Count
rank1 = forall v. Rank1 v => v -> Count -> Count
rank1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE rank1 #-}

instance Rank0 a => Rank0 (RangeMin a) where
  rank0 :: RangeMin a -> Count -> Count
rank0 = forall v. Rank0 v => v -> Count -> Count
rank0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE rank0 #-}

instance BitLength a => BitLength (RangeMin a) where
  bitLength :: RangeMin a -> Count
bitLength = forall v. BitLength v => v -> Count
bitLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE bitLength #-}

instance OpenAt a => OpenAt (RangeMin a) where
  openAt :: RangeMin a -> Count -> Bool
openAt = forall v. OpenAt v => v -> Count -> Bool
openAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE openAt #-}

instance CloseAt a => CloseAt (RangeMin a) where
  closeAt :: RangeMin a -> Count -> Bool
closeAt = forall v. CloseAt v => v -> Count -> Bool
closeAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE closeAt #-}

instance NewCloseAt a => NewCloseAt (RangeMin a) where
  newCloseAt :: RangeMin a -> Count -> Bool
newCloseAt = forall v. NewCloseAt v => v -> Count -> Bool
newCloseAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE newCloseAt #-}

instance FindOpenN a => FindOpenN (RangeMin a) where
  findOpenN :: RangeMin a -> Count -> Count -> Maybe Count
findOpenN = forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin a -> a
rangeMinBP
  {-# INLINE findOpenN #-}

instance (BitLength a, NewCloseAt a) => FindCloseN (RangeMin a) where
  findCloseN :: RangeMin a -> Count -> Count -> Maybe Count
findCloseN RangeMin a
v Count
s Count
p  = (forall a. Num a => a -> a -> a
+ Count
1) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a.
(BitLength a, NewCloseAt a) =>
RangeMin a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
s) (Count
p forall a. Num a => a -> a -> a
- Count
1) FindState
FindFromL0
  {-# INLINE findCloseN  #-}

instance (BitLength a, CloseAt a, NewCloseAt a, FindCloseN a) => FindClose (RangeMin a) where
  findClose :: RangeMin a -> Count -> Maybe Count
findClose RangeMin a
v Count
p = if RangeMin a
v forall v. CloseAt v => v -> Count -> Bool
`closeAt` Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindCloseN v => v -> Count -> Count -> Maybe Count
findCloseN RangeMin a
v Count
1 (Count
p forall a. Num a => a -> a -> a
+ Count
1)
  {-# INLINE findClose #-}

instance (OpenAt a, FindOpenN a) => FindOpen (RangeMin a) where
  findOpen :: RangeMin a -> Count -> Maybe Count
findOpen RangeMin a
v Count
p = if RangeMin a
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  RangeMin a
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpenN a => Enclose (RangeMin a) where
  enclose :: RangeMin a -> Count -> Maybe Count
enclose RangeMin a
v = forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN RangeMin a
v Count
1
  {-# INLINE enclose #-}

instance (BitLength a, NewCloseAt a, CloseAt a, OpenAt a, FindOpenN a, FindCloseN a) => BalancedParens (RangeMin a)