{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.Simd.Logical.Stock where

import Data.Word
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.Bits.BitWise

import qualified Data.Vector.Storable as DVS

class XorBits a where
  xorBits :: a -> a -> a

instance XorBits (DVS.Vector Word64) where
  xorBits :: Vector Word64 -> Vector Word64 -> Vector Word64
xorBits Vector Word64
a Vector Word64
b = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a Int -> Int -> Int
forall a. Ord a => a -> a -> a
`min` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) Vector Word64 -> Word64
forall v. Length v => v -> Word64
go
    where go :: v -> Word64
go v
v = (Vector Word64
a Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.^. (Vector Word64
b Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = v -> Position
forall v. Length v => v -> Position
end v
v
  {-# INLINE xorBits #-}

instance XorBits [DVS.Vector Word64] where
  xorBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
xorBits = (Vector Word64 -> Vector Word64 -> Vector Word64)
-> [Vector Word64] -> [Vector Word64] -> [Vector Word64]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vector Word64 -> Vector Word64 -> Vector Word64
forall a. XorBits a => a -> a -> a
xorBits
  {-# INLINE xorBits #-}

class OrBits a where
  orBits :: a -> a -> a

instance OrBits (DVS.Vector Word64) where
  orBits :: Vector Word64 -> Vector Word64 -> Vector Word64
orBits Vector Word64
a Vector Word64
b = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a Int -> Int -> Int
forall a. Ord a => a -> a -> a
`min` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) Vector Word64 -> Word64
forall v. Length v => v -> Word64
go
    where go :: v -> Word64
go v
v = (Vector Word64
a Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. (Vector Word64
b Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = v -> Position
forall v. Length v => v -> Position
end v
v
  {-# INLINE orBits #-}

instance OrBits [DVS.Vector Word64] where
  orBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
orBits = (Vector Word64 -> Vector Word64 -> Vector Word64)
-> [Vector Word64] -> [Vector Word64] -> [Vector Word64]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vector Word64 -> Vector Word64 -> Vector Word64
forall a. OrBits a => a -> a -> a
orBits
  {-# INLINE orBits #-}

class AndBits a where
  andBits :: a -> a -> a

instance AndBits (DVS.Vector Word64) where
  andBits :: Vector Word64 -> Vector Word64 -> Vector Word64
andBits Vector Word64
a Vector Word64
b = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a Int -> Int -> Int
forall a. Ord a => a -> a -> a
`min` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) Vector Word64 -> Word64
forall v. Length v => v -> Word64
go
    where go :: v -> Word64
go v
v = (Vector Word64
a Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. (Vector Word64
b Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = v -> Position
forall v. Length v => v -> Position
end v
v
  {-# INLINE andBits #-}

instance AndBits [DVS.Vector Word64] where
  andBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
andBits = (Vector Word64 -> Vector Word64 -> Vector Word64)
-> [Vector Word64] -> [Vector Word64] -> [Vector Word64]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vector Word64 -> Vector Word64 -> Vector Word64
forall a. AndBits a => a -> a -> a
andBits
  {-# INLINE andBits #-}

class AndNotBits a where
  andNotBits :: a -> a -> a

instance AndNotBits (DVS.Vector Word64) where
  andNotBits :: Vector Word64 -> Vector Word64 -> Vector Word64
andNotBits Vector Word64
a Vector Word64
b = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a Int -> Int -> Int
forall a. Ord a => a -> a -> a
`min` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) Vector Word64 -> Word64
forall v. Length v => v -> Word64
go
    where go :: v -> Word64
go v
v = (Vector Word64
a Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64 -> Word64
forall a. BitWise a => a -> a
comp (Vector Word64
b Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = v -> Position
forall v. Length v => v -> Position
end v
v
  {-# INLINE andNotBits #-}

instance AndNotBits [DVS.Vector Word64] where
  andNotBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
andNotBits = (Vector Word64 -> Vector Word64 -> Vector Word64)
-> [Vector Word64] -> [Vector Word64] -> [Vector Word64]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vector Word64 -> Vector Word64 -> Vector Word64
forall a. AndBits a => a -> a -> a
andBits
  {-# INLINE andNotBits #-}

class NotBits a where
  notBits :: a -> a

instance NotBits (DVS.Vector Word64) where
  notBits :: Vector Word64 -> Vector Word64
notBits Vector Word64
a = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a) Vector Word64 -> Word64
forall v. Length v => v -> Word64
go
    where go :: v -> Word64
go v
v = Word64 -> Word64
forall a. BitWise a => a -> a
comp (Vector Word64
a Vector Word64 -> Position -> Elem (Vector Word64)
forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = v -> Position
forall v. Length v => v -> Position
end v
v
  {-# INLINE notBits #-}

instance NotBits [DVS.Vector Word64] where
  notBits :: [Vector Word64] -> [Vector Word64]
notBits = (Vector Word64 -> Vector Word64)
-> [Vector Word64] -> [Vector Word64]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector Word64 -> Vector Word64
forall a. NotBits a => a -> a
notBits
  {-# INLINE notBits #-}