{-# LANGUAGE MagicHash #-}

module HaskellWorks.Data.Streams.Stream.Ops where

import Data.Word
import GHC.Int
import GHC.Prim
import GHC.Word                         hiding (ltWord)
import HaskellWorks.Data.Bits.BitWise   ((.&.), (.<.), (.>.), (.^.), (.|.))
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.Streams.Stream

import qualified HaskellWorks.Data.Bits.BitWise   as BW
import qualified HaskellWorks.Data.Streams.Stream as HW

ltWord :: Word64 -> Word64 -> Word64
ltWord :: Word64 -> Word64 -> Word64
ltWord (W64# Word64#
a#) (W64# Word64#
b#) = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int# -> Int
I# (Word64# -> Word64# -> Int#
ltWord64# Word64#
a# Word64#
b#))
{-# INLINE ltWord #-}

comp :: Stream Word64 -> Stream Word64
comp :: Stream Word64 -> Stream Word64
comp = (Word64 -> Word64) -> Stream Word64 -> Stream Word64
forall a b. (a -> b) -> Stream a -> Stream b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word64 -> Word64
forall a. BitWise a => a -> a
BW.comp

bitwiseAnd :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseAnd :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseAnd = (Word64 -> Word64 -> Word64)
-> Stream Word64 -> Stream Word64 -> Stream Word64
forall a b c. (a -> b -> c) -> Stream a -> Stream b -> Stream c
HW.zipWith Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
(.&.)

bitwiseOr :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseOr :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseOr = (Word64 -> Word64 -> Word64)
-> Stream Word64 -> Stream Word64 -> Stream Word64
forall a b c. (a -> b -> c) -> Stream a -> Stream b -> Stream c
HW.zipWith Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
(.|.)

bitwiseXor :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseXor :: Stream Word64 -> Stream Word64 -> Stream Word64
bitwiseXor = (Word64 -> Word64 -> Word64)
-> Stream Word64 -> Stream Word64 -> Stream Word64
forall a b c. (a -> b -> c) -> Stream a -> Stream b -> Stream c
HW.zipWith Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
(.^.)

bitwiseShiftDown :: Count -> Stream Word64 -> Stream Word64
bitwiseShiftDown :: Word64 -> Stream Word64 -> Stream Word64
bitwiseShiftDown Word64
n Stream Word64
as = (Word64 -> Word64 -> Word64)
-> Stream Word64 -> Stream Word64 -> Stream Word64
forall a b c. (a -> b -> c) -> Stream a -> Stream b -> Stream c
HW.zipWith Word64 -> Word64 -> Word64
splice Stream Word64
bs (Int -> Stream Word64 -> Stream Word64
forall a. Int -> Stream a -> Stream a
HW.drop Int
1 Stream Word64
bs Stream Word64 -> Stream Word64 -> Stream Word64
forall a. Stream a -> Stream a -> Stream a
`append` Word64 -> Stream Word64
forall a. a -> Stream a
HW.singleton Word64
0)
  where bs :: Stream Word64
bs = Int -> Stream Word64 -> Stream Word64
forall a. Int -> Stream a -> Stream a
HW.drop Int
i Stream Word64
as Stream Word64 -> Stream Word64 -> Stream Word64
forall a. Stream a -> Stream a -> Stream a
`append` Int -> Word64 -> Stream Word64
forall a. Int -> a -> Stream a
HW.repeat Int
i Word64
0
        o :: Word64
o = Word64
n Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` Word64
64
        i :: Int
i = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
n Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
64)
        splice :: Word64 -> Word64 -> Word64
        splice :: Word64 -> Word64 -> Word64
splice Word64
a Word64
b = (Word64
a Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
o) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. (Word64
b Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.<. (Word64
64 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
o))

add :: Stream Word64 -> Stream Word64 -> Stream Word64
add :: Stream Word64 -> Stream Word64 -> Stream Word64
add = (Word64 -> Word64 -> Word64 -> (Word64, Word64))
-> Word64 -> Stream Word64 -> Stream Word64 -> Stream Word64
forall a b s c.
(a -> b -> s -> (c, s)) -> s -> Stream a -> Stream b -> Stream c
HW.zipWithState (\Word64
a Word64
b Word64
c ->
    let d :: Word64
d = Word64
a Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
b Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
c     in
    let e :: Word64
e = Word64
d Word64 -> Word64 -> Word64
`ltWord` Word64
a  in
    (Word64
d, Word64
e)) Word64
0