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

instance XorBits [DVS.Vector Word64] where
  xorBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
xorBits = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 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 = forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a forall a. Ord a => a -> a -> a
`min` forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) forall {p}. Length p => p -> Word64
go
    where go :: p -> Word64
go p
v = (Vector Word64
a forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) forall a. BitWise a => a -> a -> a
.|. (Vector Word64
b forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = forall v. Length v => v -> Position
end p
v
  {-# INLINE orBits #-}

instance OrBits [DVS.Vector Word64] where
  orBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
orBits = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 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 = forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a forall a. Ord a => a -> a -> a
`min` forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) forall {p}. Length p => p -> Word64
go
    where go :: p -> Word64
go p
v = (Vector Word64
a forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) forall a. BitWise a => a -> a -> a
.&. (Vector Word64
b forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = forall v. Length v => v -> Position
end p
v
  {-# INLINE andBits #-}

instance AndBits [DVS.Vector Word64] where
  andBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
andBits = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 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 = forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a forall a. Ord a => a -> a -> a
`min` forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
b) forall {p}. Length p => p -> Word64
go
    where go :: p -> Word64
go p
v = (Vector Word64
a forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i) forall a. BitWise a => a -> a -> a
.&. forall a. BitWise a => a -> a
comp (Vector Word64
b forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = forall v. Length v => v -> Position
end p
v
  {-# INLINE andNotBits #-}

instance AndNotBits [DVS.Vector Word64] where
  andNotBits :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
andNotBits = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 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 = forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
a) forall {p}. Length p => p -> Word64
go
    where go :: p -> Word64
go p
v = forall a. BitWise a => a -> a
comp (Vector Word64
a forall v. AtIndex v => v -> Position -> Elem v
!!! Position
i)
            where i :: Position
i = forall v. Length v => v -> Position
end p
v
  {-# INLINE notBits #-}

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