{-# LANGUAGE FlexibleInstances #-} module HaskellWorks.Data.Excess.MinMaxExcess1 ( MinMaxExcess1(..) ) where import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.FixedBitSize import HaskellWorks.Data.Excess.Internal.Table import HaskellWorks.Data.Excess.Triplet import HaskellWorks.Data.Naive import qualified Data.Vector.Storable as DVS import qualified HaskellWorks.Data.Excess.Internal.Branchless as BL class MinMaxExcess1 a where minMaxExcess1 :: a -> Triplet instance MinMaxExcess1 [Bool] where minMaxExcess1 = go 0 0 0 where go minE maxE allE (x:xs) = let ne = if x then allE + 1 else allE - 1 in go (BL.minInt minE ne) (BL.maxInt maxE ne) ne xs go minE maxE allE _ = Triplet minE allE maxE {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (Naive Word8) where minMaxExcess1 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE + 1 else allE - 1 in go (BL.minInt minE ne) (BL.maxInt maxE ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (Naive Word16) where minMaxExcess1 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE + 1 else allE - 1 in go (BL.minInt minE ne) (BL.maxInt maxE ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (Naive Word32) where minMaxExcess1 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE + 1 else allE - 1 in go (BL.minInt minE ne) (BL.maxInt maxE ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (Naive Word64) where minMaxExcess1 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE + 1 else allE - 1 in go (BL.minInt minE ne) (BL.maxInt maxE ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word8 where minMaxExcess1 w = Triplet (DVS.unsafeIndex word8Excess1Min (fromIntegral w)) (DVS.unsafeIndex word8Excess1 (fromIntegral w)) (DVS.unsafeIndex word8Excess1Max (fromIntegral w)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word16 where minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB) (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word8) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 8) :: Word8) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word32 where minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB) (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word16) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 16) :: Word16) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word64 where minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB) (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word32) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 32) :: Word32) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word8) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word8 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in Triplet (BL.minInt minE (wMinE + allE)) ( wAllE + allE ) (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word16) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word16 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in Triplet (BL.minInt minE (wMinE + allE)) ( wAllE + allE ) (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word32) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word32 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in Triplet (BL.minInt minE (wMinE + allE)) ( wAllE + allE ) (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word64) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word64 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in Triplet (BL.minInt minE (wMinE + allE)) ( wAllE + allE ) (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-}