module HaskellWorks.Data.RankSelect.Base.Select1
( Select1(..)
) where
import qualified Data.Vector as DV
import qualified Data.Vector.Storable as DVS
import Data.Word
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.Bits.BitShown
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Bits.ElemFixedBitSize
import HaskellWorks.Data.Bits.PopCount.PopCount1
import HaskellWorks.Data.Int.Narrow
import HaskellWorks.Data.Positioning
import Prelude as P
class Select1 v where
select1 :: v -> Count -> Count
deriving instance Select1 a => Select1 (BitShown a)
instance Select1 Word8 where
select1 _ 0 = 0
select1 v p = select1 (fromIntegral v :: Word16) p
instance Select1 Word16 where
select1 _ 0 = 0
select1 v rn =
let a = (v .&. 0x5555) + ((v .>. 1) .&. 0x5555) in
let b = (a .&. 0x3333) + ((a .>. 2) .&. 0x3333) in
let c = (b .&. 0x0f0f) + ((b .>. 4) .&. 0x0f0f) in
let d = (c .&. 0x00ff) + ((c .>. 8) .&. 0x00ff) in
let r0 = d + 1 narrow16 rn in
let s0 = 64 :: Word16 in
let t0 = (d .>. 32) + (d .>. 48) in
let s1 = s0 ((t0 r0) .&. 256) .>. 3 in
let r1 = r0 (t0 .&. ((t0 r0) .>. 8)) in
let t1 = (d .>. fromIntegral (s1 16)) .&. 0xff in
let s2 = s1 ((t1 r1) .&. 256) .>. 4 in
let r2 = r1 (t1 .&. ((t1 r1) .>. 8)) in
let t2 = (c .>. fromIntegral (s2 8)) .&. 0xf in
let s3 = s2 ((t2 r2) .&. 256) .>. 5 in
let r3 = r2 (t2 .&. ((t2 r2) .>. 8)) in
let t3 = (b .>. fromIntegral (s3 4)) .&. 0x7 in
let s4 = s3 ((t3 r3) .&. 256) .>. 6 in
let r4 = r3 (t3 .&. ((t3 r3) .>. 8)) in
let t4 = (a .>. fromIntegral (s4 2)) .&. 0x3 in
let s5 = s4 ((t4 r4) .&. 256) .>. 7 in
let r5 = r4 (t4 .&. ((t4 r4) .>. 8)) in
let t5 = (v .>. fromIntegral (s5 1)) .&. 0x1 in
let s6 = s5 ((t5 r5) .&. 256) .>. 8 in
fromIntegral s6
instance Select1 Word32 where
select1 _ 0 = 0
select1 v rn =
let a = (v .&. 0x55555555) + ((v .>. 1) .&. 0x55555555) in
let b = (a .&. 0x33333333) + ((a .>. 2) .&. 0x33333333) in
let c = (b .&. 0x0f0f0f0f) + ((b .>. 4) .&. 0x0f0f0f0f) in
let d = (c .&. 0x00ff00ff) + ((c .>. 8) .&. 0x00ff00ff) in
let e = (d .&. 0x000000ff) + ((d .>. 16) .&. 0x000000ff) in
let r0 = e + 1 narrow32 rn in
let s0 = 64 :: Word32 in
let t0 = (d .>. 32) + (d .>. 48) in
let s1 = s0 ((t0 r0) .&. 256) .>. 3 in
let r1 = r0 (t0 .&. ((t0 r0) .>. 8)) in
let t1 = (d .>. fromIntegral (s1 16)) .&. 0xff in
let s2 = s1 ((t1 r1) .&. 256) .>. 4 in
let r2 = r1 (t1 .&. ((t1 r1) .>. 8)) in
let t2 = (c .>. fromIntegral (s2 8)) .&. 0xf in
let s3 = s2 ((t2 r2) .&. 256) .>. 5 in
let r3 = r2 (t2 .&. ((t2 r2) .>. 8)) in
let t3 = (b .>. fromIntegral (s3 4)) .&. 0x7 in
let s4 = s3 ((t3 r3) .&. 256) .>. 6 in
let r4 = r3 (t3 .&. ((t3 r3) .>. 8)) in
let t4 = (a .>. fromIntegral (s4 2)) .&. 0x3 in
let s5 = s4 ((t4 r4) .&. 256) .>. 7 in
let r5 = r4 (t4 .&. ((t4 r4) .>. 8)) in
let t5 = (v .>. fromIntegral (s5 1)) .&. 0x1 in
let s6 = s5 ((t5 r5) .&. 256) .>. 8 in
fromIntegral s6
instance Select1 Word64 where
select1 _ 0 = 0
select1 v rn =
let a = (v .&. 0x5555555555555555) + ((v .>. 1) .&. 0x5555555555555555) in
let b = (a .&. 0x3333333333333333) + ((a .>. 2) .&. 0x3333333333333333) in
let c = (b .&. 0x0f0f0f0f0f0f0f0f) + ((b .>. 4) .&. 0x0f0f0f0f0f0f0f0f) in
let d = (c .&. 0x00ff00ff00ff00ff) + ((c .>. 8) .&. 0x00ff00ff00ff00ff) in
let e = (d .&. 0x0000ffff0000ffff) + ((d .>. 16) .&. 0x0000ffff0000ffff) in
let f = (e .&. 0x00000000ffffffff) + ((e .>. 32) .&. 0x00000000ffffffff) in
let r0 = f + 1 narrow64 rn in
let s0 = 64 :: Word64 in
let t0 = (d .>. 32) + (d .>. 48) in
let s1 = s0 ((t0 r0) .&. 256) .>. 3 in
let r1 = r0 (t0 .&. ((t0 r0) .>. 8)) in
let t1 = (d .>. fromIntegral (s1 16)) .&. 0xff in
let s2 = s1 ((t1 r1) .&. 256) .>. 4 in
let r2 = r1 (t1 .&. ((t1 r1) .>. 8)) in
let t2 = (c .>. fromIntegral (s2 8)) .&. 0xf in
let s3 = s2 ((t2 r2) .&. 256) .>. 5 in
let r3 = r2 (t2 .&. ((t2 r2) .>. 8)) in
let t3 = (b .>. fromIntegral (s3 4)) .&. 0x7 in
let s4 = s3 ((t3 r3) .&. 256) .>. 6 in
let r4 = r3 (t3 .&. ((t3 r3) .>. 8)) in
let t4 = (a .>. fromIntegral (s4 2)) .&. 0x3 in
let s5 = s4 ((t4 r4) .&. 256) .>. 7 in
let r5 = r4 (t4 .&. ((t4 r4) .>. 8)) in
let t5 = (v .>. fromIntegral (s5 1)) .&. 0x1 in
let s6 = s5 ((t5 r5) .&. 256) .>. 8 in
fromIntegral s6
instance Select1 [Bool] where
select1 = go 0
where go r _ 0 = r
go r (True :bs) c = go (r + 1) bs (c 1)
go r (False:bs) c = go (r + 1) bs c
go _ [] _ = error "Out of range"
instance Select1 [Word8] where
select1 v c = go v c 0
where go :: [Word8] -> Count -> Count -> Count
go _ 0 acc = acc
go u d acc = let w = head u in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (tail u) (d pc) (acc + elemFixedBitSize u)
instance Select1 [Word16] where
select1 v c = go v c 0
where go :: [Word16] -> Count -> Count -> Count
go _ 0 acc = acc
go u d acc = let w = head u in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (tail u) (d pc) (acc + elemFixedBitSize u)
instance Select1 [Word32] where
select1 v c = go v c 0
where go :: [Word32] -> Count -> Count -> Count
go _ 0 acc = acc
go u d acc = let w = head u in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (tail u) (d pc) (acc + elemFixedBitSize u)
instance Select1 [Word64] where
select1 v c = go v c 0
where go :: [Word64] -> Count -> Count -> Count
go _ 0 acc = acc
go u d acc = let w = head u in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (tail u) (d pc) (acc + elemFixedBitSize u)
instance Select1 (DVS.Vector Word8) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DVS.Vector Word16) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DVS.Vector Word32) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DVS.Vector Word64) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DV.Vector Word8) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DV.Vector Word16) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DV.Vector Word32) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)
instance Select1 (DV.Vector Word64) where
select1 v c = go 0 c 0
where go _ 0 acc = acc
go n d acc = let w = (v !!! n) in
case popCount1 w of
pc | d <= pc -> select1 w d + acc
pc -> go (n + 1) (d pc) (acc + elemFixedBitSize v)