geomancy-0.4.0.0: src/Geomancy/I64Vec4.hs
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
#ifdef TH_LIFT
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE DerivingStrategies #-}
#endif
module Geomancy.I64Vec4
( I64Vec4
, i64vec4
, withI64Vec4
, pattern WithI64Vec4
, convert
, fromTuple
, dot
) where
import Control.DeepSeq (NFData(rnf))
import Data.Coerce (Coercible, coerce)
import Data.Int (Int64)
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Foreign (Storable(..))
import Foreign.Ptr.Diff (peekDiffOff, pokeDiffOff)
import GHC.Ix (Ix(..))
import GHC.Records (HasField(..))
#ifdef TH_LIFT
import Language.Haskell.TH.Syntax (Lift)
#endif
#ifdef SERIALISE
import Codec.Serialise (Serialise(..))
import qualified Codec.Serialise.Encoding as Serialise
import qualified Codec.Serialise.Decoding as Serialise
#endif
import Geomancy.Elementwise (Elementwise(..))
import Graphics.Gl.Block (Block(..))
data I64Vec4 = I64Vec4
{-# UNPACK #-} !Int64
{-# UNPACK #-} !Int64
{-# UNPACK #-} !Int64
{-# UNPACK #-} !Int64
deriving (Eq, Ord, Show)
#ifdef TH_LIFT
deriving Lift
#endif
{-# INLINE i64vec4 #-}
i64vec4 :: Int64 -> Int64 -> Int64 -> Int64 -> I64Vec4
i64vec4 = I64Vec4
{-# INLINE withI64Vec4 #-}
withI64Vec4
:: I64Vec4
-> (Int64 -> Int64 -> Int64 -> Int64 -> r)
-> r
withI64Vec4 (I64Vec4 a b c d) f = f a b c d
pattern WithI64Vec4 :: Int64 -> Int64 -> Int64 -> Int64 -> I64Vec4
pattern WithI64Vec4 a b c d <- ((`withI64Vec4` (,,,)) -> (a, b, c, d))
{-# COMPLETE WithI64Vec4 #-}
instance HasField "x" I64Vec4 Int64 where
{-# INLINE getField #-}
getField v = withI64Vec4 v \x _ _ _ -> x
instance HasField "y" I64Vec4 Int64 where
{-# INLINE getField #-}
getField v = withI64Vec4 v \_ y _ _ -> y
instance HasField "z" I64Vec4 Int64 where
{-# INLINE getField #-}
getField v = withI64Vec4 v \_ _ z _ -> z
instance HasField "w" I64Vec4 Int64 where
{-# INLINE getField #-}
getField v = withI64Vec4 v \_ _ _ w -> w
{-# INLINE convert #-}
convert :: Coercible v I64Vec4 => (Int64 -> a) -> (a -> a -> a -> a -> r) -> v -> r
convert f t v =
withI64Vec4 (coerce v) \a b c d ->
t (f a) (f b) (f c) (f d)
{-# INLINE fromTuple #-}
fromTuple :: (Int64, Int64, Int64, Int64) -> I64Vec4
fromTuple (x, y, z, w) = i64vec4 x y z w
{-# INLINE dot #-}
dot :: I64Vec4 -> I64Vec4 -> Int64
dot (I64Vec4 l1 l2 l3 l4) (I64Vec4 r1 r2 r3 r4) =
l1 * r1 + l2 * r2 + l3 * r3 + l4 * r4
instance NFData I64Vec4 where
rnf I64Vec4{} = ()
type instance Element I64Vec4 = Int64
instance MonoFunctor I64Vec4 where
{-# INLINE omap #-}
omap f v =
withI64Vec4 v \x y z w ->
i64vec4 (f x) (f y) (f z) (f w)
instance MonoPointed I64Vec4 where
opoint x = i64vec4 x x x x
instance Elementwise I64Vec4 where
{-# INLINE emap2 #-}
emap2 f p0 p1 =
withI64Vec4 p0 \x0 y0 z0 w0 ->
withI64Vec4 p1 \x1 y1 z1 w1 ->
i64vec4
(f x0 x1)
(f y0 y1)
(f z0 z1)
(f w0 w1)
{-# INLINE emap3 #-}
emap3 f p0 p1 p2 =
withI64Vec4 p0 \x0 y0 z0 w0 ->
withI64Vec4 p1 \x1 y1 z1 w1 ->
withI64Vec4 p2 \x2 y2 z2 w2 ->
i64vec4
(f x0 x1 x2)
(f y0 y1 y2)
(f z0 z1 z2)
(f w0 w1 w2)
{-# INLINE emap4 #-}
emap4 f p0 p1 p2 p3 =
withI64Vec4 p0 \x0 y0 z0 w0 ->
withI64Vec4 p1 \x1 y1 z1 w1 ->
withI64Vec4 p2 \x2 y2 z2 w2 ->
withI64Vec4 p3 \x3 y3 z3 w3 ->
i64vec4
(f x0 x1 x2 x3)
(f y0 y1 y2 y3)
(f z0 z1 z2 z3)
(f w0 w1 w2 w3)
{-# INLINE emap5 #-}
emap5 f p0 p1 p2 p3 p4 =
withI64Vec4 p0 \x0 y0 z0 w0 ->
withI64Vec4 p1 \x1 y1 z1 w1 ->
withI64Vec4 p2 \x2 y2 z2 w2 ->
withI64Vec4 p3 \x3 y3 z3 w3 ->
withI64Vec4 p4 \x4 y4 z4 w4 ->
i64vec4
(f x0 x1 x2 x3 x4)
(f y0 y1 y2 y3 y4)
(f z0 z1 z2 z3 z4)
(f w0 w1 w2 w3 w4)
instance Num I64Vec4 where
{-# INLINE (+) #-}
I64Vec4 l1 l2 l3 l4 + I64Vec4 r1 r2 r3 r4 =
I64Vec4
(l1 + r1)
(l2 + r2)
(l3 + r3)
(l4 + r4)
{-# INLINE (-) #-}
I64Vec4 l1 l2 l3 l4 - I64Vec4 r1 r2 r3 r4 =
I64Vec4
(l1 - r1)
(l2 - r2)
(l3 - r3)
(l4 - r4)
{-# INLINE (*) #-}
I64Vec4 l1 l2 l3 l4 * I64Vec4 r1 r2 r3 r4 =
I64Vec4
(l1 * r1)
(l2 * r2)
(l3 * r3)
(l4 * r4)
{-# INLINE abs #-}
abs v4 = withI64Vec4 v4 \a b c d ->
i64vec4 (abs a) (abs b) (abs c) (abs d)
{-# INLINE signum #-}
signum v4 = withI64Vec4 v4 \a b c d ->
i64vec4 (signum a) (signum b) (signum c) (signum d)
{-# INLINE fromInteger #-}
fromInteger x = I64Vec4 x' x' x' x'
where
x' = fromInteger x
instance Storable I64Vec4 where
{-# INLINE sizeOf #-}
sizeOf _ = 32
{-# INLINE alignment #-}
alignment _ = 8
{-# INLINE poke #-}
poke ptr v4 =
withI64Vec4 v4 \a b c d -> do
pokeByteOff ptr 0 a
pokeByteOff ptr 8 b
pokeByteOff ptr 16 c
pokeByteOff ptr 24 d
{-# INLINE peek #-}
peek ptr = i64vec4
<$> peekByteOff ptr 0
<*> peekByteOff ptr 8
<*> peekByteOff ptr 16
<*> peekByteOff ptr 24
instance Block I64Vec4 where
type PackedSize I64Vec4 = 32
alignment140 _ = 32
sizeOf140 _ = 32
alignment430 = alignment140
sizeOf430 = sizeOf140
isStruct _ = False
read140 = peekDiffOff
write140 = pokeDiffOff
read430 = read140
write430 = write140
readPacked = read140
writePacked = write140
{-# INLINE alignment140 #-}
{-# INLINE sizeOf140 #-}
{-# INLINE alignment430 #-}
{-# INLINE sizeOf430 #-}
{-# INLINE isStruct #-}
{-# INLINE read140 #-}
{-# INLINE write140 #-}
{-# INLINE read430 #-}
{-# INLINE write430 #-}
{-# INLINE readPacked #-}
{-# INLINE writePacked #-}
instance Ix I64Vec4 where
{-# INLINE range #-}
range (l, u) =
withI64Vec4 l \l1 l2 l3 l4 ->
withI64Vec4 u \u1 u2 u3 u4 ->
i64vec4
<$> range (l1, u1)
<*> range (l2, u2)
<*> range (l3, u3)
<*> range (l4, u4)
{-# INLINE unsafeIndex #-}
unsafeIndex (l, u) i =
withI64Vec4 l \l1 l2 l3 l4 ->
withI64Vec4 u \u1 u2 u3 u4 ->
withI64Vec4 i \i1 i2 i3 i4 ->
unsafeIndex (l4, u4) i4 + unsafeRangeSize (l4, u4) * (
unsafeIndex (l3, u3) i3 + unsafeRangeSize (l3, u3) * (
unsafeIndex (l2, u2) i2 + unsafeRangeSize (l2, u2) * (
unsafeIndex (l1, u1) i1)))
{-# INLINE inRange #-}
inRange (l, u) i =
withI64Vec4 l \l1 l2 l3 l4 ->
withI64Vec4 u \u1 u2 u3 u4 ->
withI64Vec4 i \i1 i2 i3 i4 ->
inRange (l1, u1) i1 &&
inRange (l2, u2) i2 &&
inRange (l3, u3) i3 &&
inRange (l4, u4) i4
#ifdef SERIALISE
instance Serialise I64Vec4 where
encode v = withI64Vec4 v \x y z w ->
Serialise.encodeListLen 4 <> encode x <> encode y <> encode z <> encode w
decode =
Serialise.decodeListLenOf 4 *> (i64vec4 <$> decode <*> decode <*> decode <*> decode)
#endif