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

module HaskellWorks.Data.BalancedParens.RangeMin2
  ( RangeMin2(..)
  , mkRangeMin2
  ) 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                                               as DV
import qualified Data.Vector.Storable                                      as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.Vector.Storable as DVS

data RangeMin2 a = RangeMin2
  { RangeMin2 a -> a
rangeMin2BP       :: !a
  , RangeMin2 a -> Vector Int8
rangeMin2L0Min    :: !(DVS.Vector Int8)
  , RangeMin2 a -> Vector Int8
rangeMin2L0Excess :: !(DVS.Vector Int8)
  , RangeMin2 a -> Vector Int16
rangeMin2L1Min    :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L1Excess :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L2Min    :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L2Excess :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L3Min    :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L3Excess :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L4Min    :: !(DVS.Vector Int16)
  , RangeMin2 a -> Vector Int16
rangeMin2L4Excess :: !(DVS.Vector Int16)
  } deriving (RangeMin2 a -> ()
(RangeMin2 a -> ()) -> NFData (RangeMin2 a)
forall a. NFData a => RangeMin2 a -> ()
forall a. (a -> ()) -> NFData a
rnf :: RangeMin2 a -> ()
$crnf :: forall a. NFData a => RangeMin2 a -> ()
NFData, (forall x. RangeMin2 a -> Rep (RangeMin2 a) x)
-> (forall x. Rep (RangeMin2 a) x -> RangeMin2 a)
-> Generic (RangeMin2 a)
forall x. Rep (RangeMin2 a) x -> RangeMin2 a
forall x. RangeMin2 a -> Rep (RangeMin2 a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (RangeMin2 a) x -> RangeMin2 a
forall a x. RangeMin2 a -> Rep (RangeMin2 a) x
$cto :: forall a x. Rep (RangeMin2 a) x -> RangeMin2 a
$cfrom :: forall a x. RangeMin2 a -> Rep (RangeMin2 a) x
Generic)

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

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

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

factorL3 :: Integral a => a
factorL3 :: a
factorL3 = a
32
{-# INLINE factorL3 #-}

factorL4 :: Integral a => a
factorL4 :: a
factorL4 = a
32
{-# INLINE factorL4 #-}

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

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

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

pageSizeL3 :: Integral a => a
pageSizeL3 :: a
pageSizeL3 = a
forall a. Integral a => a
pageSizeL2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Integral a => a
factorL3
{-# INLINE pageSizeL3 #-}

pageSizeL4 :: Integral a => a
pageSizeL4 :: a
pageSizeL4 = a
forall a. Integral a => a
pageSizeL3 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Integral a => a
factorL4
{-# INLINE pageSizeL4 #-}

mkRangeMin2 :: AsVector64 a => a -> RangeMin2 a
mkRangeMin2 :: a -> RangeMin2 a
mkRangeMin2 a
bp = RangeMin2 :: forall a.
a
-> Vector Int8
-> Vector Int8
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> Vector Int16
-> RangeMin2 a
RangeMin2
  { rangeMin2BP :: a
rangeMin2BP       = a
bp
  , rangeMin2L0Min :: Vector Int8
rangeMin2L0Min    = Vector Int16 -> Vector Int8
forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL0Min
  , rangeMin2L0Excess :: Vector Int8
rangeMin2L0Excess = Vector Int16 -> Vector Int8
forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL0Excess
  , rangeMin2L1Min :: Vector Int16
rangeMin2L1Min    = Vector Int16
rmL1Min
  , rangeMin2L1Excess :: Vector Int16
rangeMin2L1Excess = Vector Int16
rmL1Excess
  , rangeMin2L2Min :: Vector Int16
rangeMin2L2Min    = Vector Int16
rmL2Min
  , rangeMin2L2Excess :: Vector Int16
rangeMin2L2Excess = Vector Int16
rmL2Excess
  , rangeMin2L3Min :: Vector Int16
rangeMin2L3Min    = Vector Int16
rmL3Min
  , rangeMin2L3Excess :: Vector Int16
rangeMin2L3Excess = Vector Int16
rmL3Excess
  , rangeMin2L4Min :: Vector Int16
rangeMin2L4Min    = Vector Int16
rmL4Min
  , rangeMin2L4Excess :: Vector Int16
rangeMin2L4Excess = Vector Int16
rmL4Excess
  }
  where bpv :: Vector Word64
bpv           = a -> Vector Word64
forall a. AsVector64 a => a -> Vector Word64
asVector64 a
bp
        lenBP :: Int
lenBP         = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Word64
forall v. Length v => v -> Word64
length Vector Word64
bpv) :: Int
        lenL0 :: Int
lenL0         = Int
lenBP
        lenL1 :: Int
lenL1         = (Vector Int16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
forall a. Integral a => a
pageSizeL1) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL2 :: Int
lenL2         = (Vector Int16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
forall a. Integral a => a
pageSizeL2) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL3 :: Int
lenL3         = (Vector Int16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
forall a. Integral a => a
pageSizeL3) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL4 :: Int
lenL4         = (Vector Int16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
forall a. Integral a => a
pageSizeL4) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 :: Int
        allMinL0 :: Vector MinExcess
allMinL0      = Int -> (Int -> MinExcess) -> Vector MinExcess
forall a. Int -> (Int -> a) -> Vector a
DV.generate  Int
lenL0 (\Int
i -> if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lenBP then Int -> Int -> MinExcess
MinExcess (-Int
64) (-Int
64) else Word64 -> MinExcess
forall a. MinExcess1 a => a -> MinExcess
minExcess1 (Vector Word64
bpv Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Int -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i))
        -- Note: (0xffffffffffffffc0 :: Int64) = -64
        rmL0Excess :: Vector Int16
rmL0Excess    = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Int
forall a. AllExcess1 a => a -> Int
allExcess1 (Int -> Int -> Word64 -> Vector Word64 -> Vector Word64
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
pageSizeL0 Word64
0xffffffffffffffc0 Vector Word64
bpv))) :: DVS.Vector Int16
        rmL1Excess :: Vector Int16
rmL1Excess    = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Int
forall a. AllExcess1 a => a -> Int
allExcess1 (Int -> Int -> Word64 -> Vector Word64 -> Vector Word64
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
pageSizeL1 Word64
0xffffffffffffffc0 Vector Word64
bpv))) :: DVS.Vector Int16
        rmL2Excess :: Vector Int16
rmL2Excess    = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Int
forall a. AllExcess1 a => a -> Int
allExcess1 (Int -> Int -> Word64 -> Vector Word64 -> Vector Word64
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
pageSizeL2 Word64
0xffffffffffffffc0 Vector Word64
bpv))) :: DVS.Vector Int16
        rmL3Excess :: Vector Int16
rmL3Excess    = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL3 (\Int
i -> Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Int
forall a. AllExcess1 a => a -> Int
allExcess1 (Int -> Int -> Word64 -> Vector Word64 -> Vector Word64
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
pageSizeL3 Word64
0xffffffffffffffc0 Vector Word64
bpv))) :: DVS.Vector Int16
        rmL4Excess :: Vector Int16
rmL4Excess    = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL4 (\Int
i -> Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Int
forall a. AllExcess1 a => a -> Int
allExcess1 (Int -> Int -> Word64 -> Vector Word64 -> Vector Word64
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
pageSizeL4 Word64
0xffffffffffffffc0 Vector Word64
bpv))) :: DVS.Vector Int16
        rmL0Min :: Vector Int16
rmL0Min       = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> let MinExcess Int
minE Int
_ = Vector MinExcess
allMinL0 Vector MinExcess -> Int -> MinExcess
forall a. Vector a -> Int -> a
DV.! Int
i in Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minE) :: DVS.Vector Int16
        rmL1Min :: Vector Int16
rmL1Min       = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> Int16 -> Vector Int16 -> Vector Int16 -> Int16
forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL1 Int16
0 Vector Int16
rmL0Min) (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL1 Int16
0 Vector Int16
rmL0Excess))
        rmL2Min :: Vector Int16
rmL2Min       = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> Int16 -> Vector Int16 -> Vector Int16 -> Int16
forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL2 Int16
0 Vector Int16
rmL1Min) (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL2 Int16
0 Vector Int16
rmL1Excess))
        rmL3Min :: Vector Int16
rmL3Min       = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL3 (\Int
i -> Int16 -> Vector Int16 -> Vector Int16 -> Int16
forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL3 Int16
0 Vector Int16
rmL2Min) (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL3 Int16
0 Vector Int16
rmL2Excess))
        rmL4Min :: Vector Int16
rmL4Min       = Int -> (Int -> Int16) -> Vector Int16
forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL4 (\Int
i -> Int16 -> Vector Int16 -> Vector Int16 -> Int16
forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL4 Int16
0 Vector Int16
rmL3Min) (Int -> Int -> Int16 -> Vector Int16 -> Vector Int16
forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i Int
forall a. Integral a => a
factorL4 Int16
0 Vector Int16
rmL3Excess))

genMin :: (Integral a, DVS.Storable a) => a -> DVS.Vector a -> DVS.Vector a -> a
genMin :: a -> Vector a -> Vector a -> a
genMin a
mL Vector a
mins Vector a
excesses = if Bool -> Bool
not (Vector a -> Bool
forall a. Storable a => Vector a -> Bool
DVS.null Vector a
mins) Bool -> Bool -> Bool
|| Bool -> Bool
not (Vector a -> Bool
forall a. Storable a => Vector a -> Bool
DVS.null Vector a
excesses)
  then a -> Vector a -> Vector a -> a
forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin (Vector a -> a
forall a. (Storable a, Integral a) => Vector a -> a
DVS.lastOrZero Vector a
mins a -> a -> a
forall a. Ord a => a -> a -> a
`min` (a
mL a -> a -> a
forall a. Num a => a -> a -> a
+ Vector a -> a
forall a. (Storable a, Integral a) => Vector a -> a
DVS.lastOrZero Vector a
excesses)) (Vector a -> Vector a
forall a. Storable a => Vector a -> Vector a
DVS.init Vector a
mins) (Vector a -> Vector a
forall a. Storable a => Vector a -> Vector a
DVS.init Vector a
excesses)
  else a
mL

data FindState = FindBP
  | FindL0 | FindFromL0
  | FindL1 | FindFromL1
  | FindL2 | FindFromL2
  | FindL3 | FindFromL3
  | FindL4 | FindFromL4

rm2FindClose  :: (BitLength a, NewCloseAt a) => RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose :: RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindBP = if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p
  then if Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
    then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
    else RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1) FindState
FindFromL0
  else RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1) FindState
FindFromL0
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL0 =
  let i :: Word64
i = Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
64 in
  let mins :: Vector Int8
mins = RangeMin2 a -> Vector Int8
forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Min RangeMin2 a
v in
  let minE :: Int
minE = Int8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
mins Vector Int8 -> Position -> Elem (Vector Int8)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) :: Int in
  if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
minE Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindBP
    else if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p Bool -> Bool -> Bool
&& Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
      then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
      else  let excesses :: Vector Int8
excesses  = RangeMin2 a -> Vector Int8
forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Excess RangeMin2 a
v in
            let excess :: Int
excess    = Int8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
excesses Vector Int8 -> Position -> Elem (Vector Int8)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)  :: Int in
            RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
64) FindState
FindFromL0
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL1 =
  let !i :: Word64
i = Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL1) in
  let !mins :: Vector Int16
mins = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Min RangeMin2 a
v in
  let !minE :: Int
minE = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) :: Int in
  if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
minE Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL0
    else if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v
      then if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p Bool -> Bool -> Bool
&& Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
        then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
        else  let excesses :: Vector Int16
excesses  = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Excess RangeMin2 a
v in
              let excess :: Int
excess    = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)  :: Int in
              RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL1)) FindState
FindFromL1
      else Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL2 =
  let !i :: Word64
i = Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL2) in
  let !mins :: Vector Int16
mins = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Min RangeMin2 a
v in
  let !minE :: Int
minE = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) :: Int in
  if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
minE Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL1
    else if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v
      then if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p Bool -> Bool -> Bool
&& Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
        then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
        else  let excesses :: Vector Int16
excesses  = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Excess RangeMin2 a
v in
              let excess :: Int
excess    = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)  :: Int in
              RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL2)) FindState
FindFromL2
      else Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL3 =
  let !i :: Word64
i = Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL3) in
  let !mins :: Vector Int16
mins = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Min RangeMin2 a
v in
  let !minE :: Int
minE = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) :: Int in
  if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
minE Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL2
    else if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v
      then if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p Bool -> Bool -> Bool
&& Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
        then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
        else  let excesses :: Vector Int16
excesses  = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Excess RangeMin2 a
v in
              let excess :: Int
excess    = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)  :: Int in
              RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL3)) FindState
FindFromL3
        else Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL4 =
  let !i :: Word64
i = Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL4) in
  let !mins :: Vector Int16
mins = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Min RangeMin2 a
v in
  let !minE :: Int
minE = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) :: Int in
  if Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
minE Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL3
    else if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v
      then if RangeMin2 a
v RangeMin2 a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
`newCloseAt` Word64
p Bool -> Bool -> Bool
&& Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
        then Word64 -> Maybe Word64
forall a. a -> Maybe a
Just Word64
p
        else  let excesses :: Vector Int16
excesses  = RangeMin2 a -> Vector Int16
forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Excess RangeMin2 a
v in
              let excess :: Int
excess    = Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses Vector Int16 -> Position -> Elem (Vector Int16)
forall v. AtIndex v => v -> Position -> Elem v
!!! Word64 -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)  :: Int in
              RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Word64
p Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL4)) FindState
FindFromL4
        else Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL0
  | Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` Word64
64 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0             = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL1
  | Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v   = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindBP
  | Bool
otherwise                   = Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL1
  | Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL1) Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0  = if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL2 else Maybe Word64
forall a. Maybe a
Nothing
  | Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v       = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL0
  | Bool
otherwise                       = Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL2
  | Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL2) Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0  = if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL3 else Maybe Word64
forall a. Maybe a
Nothing
  | Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v       = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL1
  | Bool
otherwise                       = Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL3
  | Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL3) Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0  = if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL4 else Maybe Word64
forall a. Maybe a
Nothing
  | Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v       = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL2
  | Bool
otherwise                       = Maybe Word64
forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindFromL4
  | Word64
p Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
forall a. Integral a => a
pageSizeL4) Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0  = if Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v then RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL4 else Maybe Word64
forall a. Maybe a
Nothing
  | Word64
0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
p Bool -> Bool -> Bool
&& Word64
p Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< RangeMin2 a -> Word64
forall v. BitLength v => v -> Word64
bitLength RangeMin2 a
v       = RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Word64 -> FindState -> Maybe Word64
rm2FindClose RangeMin2 a
v Int
s Word64
p FindState
FindL3
  | Bool
otherwise                       = Maybe Word64
forall a. Maybe a
Nothing
{-# INLINE rm2FindClose #-}

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

instance Rank1 a => Rank1 (RangeMin2 a) where
  rank1 :: RangeMin2 a -> Word64 -> Word64
rank1 = a -> Word64 -> Word64
forall v. Rank1 v => v -> Word64 -> Word64
rank1 (a -> Word64 -> Word64)
-> (RangeMin2 a -> a) -> RangeMin2 a -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE rank1 #-}

instance Rank0 a => Rank0 (RangeMin2 a) where
  rank0 :: RangeMin2 a -> Word64 -> Word64
rank0 = a -> Word64 -> Word64
forall v. Rank0 v => v -> Word64 -> Word64
rank0 (a -> Word64 -> Word64)
-> (RangeMin2 a -> a) -> RangeMin2 a -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE rank0 #-}

instance BitLength a => BitLength (RangeMin2 a) where
  bitLength :: RangeMin2 a -> Word64
bitLength = a -> Word64
forall v. BitLength v => v -> Word64
bitLength (a -> Word64) -> (RangeMin2 a -> a) -> RangeMin2 a -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE bitLength #-}

instance OpenAt a => OpenAt (RangeMin2 a) where
  openAt :: RangeMin2 a -> Word64 -> Bool
openAt = a -> Word64 -> Bool
forall v. OpenAt v => v -> Word64 -> Bool
openAt (a -> Word64 -> Bool)
-> (RangeMin2 a -> a) -> RangeMin2 a -> Word64 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE openAt #-}

instance CloseAt a => CloseAt (RangeMin2 a) where
  closeAt :: RangeMin2 a -> Word64 -> Bool
closeAt = a -> Word64 -> Bool
forall v. CloseAt v => v -> Word64 -> Bool
closeAt (a -> Word64 -> Bool)
-> (RangeMin2 a -> a) -> RangeMin2 a -> Word64 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE closeAt #-}

instance NewCloseAt a => NewCloseAt (RangeMin2 a) where
  newCloseAt :: RangeMin2 a -> Word64 -> Bool
newCloseAt = a -> Word64 -> Bool
forall v. NewCloseAt v => v -> Word64 -> Bool
newCloseAt (a -> Word64 -> Bool)
-> (RangeMin2 a -> a) -> RangeMin2 a -> Word64 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE newCloseAt #-}

instance FindOpenN a => FindOpenN (RangeMin2 a) where
  findOpenN :: RangeMin2 a -> Word64 -> Word64 -> Maybe Word64
findOpenN = a -> Word64 -> Word64 -> Maybe Word64
forall v. FindOpenN v => v -> Word64 -> Word64 -> Maybe Word64
findOpenN (a -> Word64 -> Word64 -> Maybe Word64)
-> (RangeMin2 a -> a)
-> RangeMin2 a
-> Word64
-> Word64
-> Maybe Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RangeMin2 a -> a
forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE findOpenN #-}

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

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

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

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

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