module Data.Vec.Packed where
import Prelude hiding (map,foldl,foldr,zipWith,length,head,tail,last,
reverse,take,drop)
import Data.Vec.Base as V
import Data.Vec.Nat
import Data.Vec.LinAlg
import Data.Word
import Data.Int
import Foreign
import Data.Array.Base as Array
import GHC.ST ( ST(..), runST )
import GHC.Prim
import GHC.Base ( Int(..) )
import GHC.Word ( Word(..) )
import GHC.Float ( Float(..), Double(..) )
import GHC.Int ( Int8(..), Int16(..), Int32(..), Int64(..) )
import GHC.Word ( Word8(..), Word16(..), Word32(..), Word64(..) )
class PackedVec v where
data Packed v
pack :: v -> Packed v
unpack :: Packed v -> v
instance PackedVec (Vec2 Bool) where
data Packed (Vec2 Bool) = Vec2B !Bool !Bool
pack (a:.b:.()) = Vec2B a b
unpack (Vec2B a b) = a:.b:.()
instance PackedVec (Vec3 Bool) where
data Packed (Vec3 Bool) = Vec3B !Bool !Bool !Bool
pack (a:.b:.c:.()) = Vec3B a b c
unpack (Vec3B a b c) = a:.b:.c:.()
instance PackedVec (Vec4 Bool) where
data Packed (Vec4 Bool) = Vec4B !Bool !Bool !Bool !Bool
pack (a:.b:.c:.d:.()) = Vec4B a b c d
unpack (Vec4B a b c d) = a:.b:.c:.d:.()
type Vec2B = Packed (Vec2 Bool)
type Vec3B = Packed (Vec3 Bool)
type Vec4B = Packed (Vec4 Bool)
instance PackedVec (Vec2 Int) where
data Packed (Vec2 Int) = Vec2I !Int !Int
pack (a:.b:.()) = Vec2I a b
unpack (Vec2I a b) = a:.b:.()
instance PackedVec (Vec3 Int) where
data Packed (Vec3 Int) = Vec3I !Int !Int !Int
pack (a:.b:.c:.()) = Vec3I a b c;
unpack (Vec3I a b c) = a:.b:.c:.();
instance PackedVec (Vec4 Int) where
data Packed (Vec4 Int) = Vec4I !Int !Int !Int !Int
pack (a:.b:.c:.d:.()) = Vec4I a b c d
unpack (Vec4I a b c d) = a:.b:.c:.d:.()
type Vec2I = Packed (Vec2 Int)
type Vec3I = Packed (Vec3 Int)
type Vec4I = Packed (Vec4 Int)
instance PackedVec (Vec2 Float) where
data Packed (Vec2 Float) = Vec2F !Float !Float
pack (a:.b:.()) = Vec2F a b
unpack (Vec2F a b) = a:.b:.()
instance PackedVec (Vec3 Float) where
data Packed (Vec3 Float) = Vec3F !Float !Float !Float
pack (a:.b:.c:.()) = Vec3F a b c;
unpack (Vec3F a b c) = a:.b:.c:.();
instance PackedVec (Vec4 Float) where
data Packed (Vec4 Float) = Vec4F !Float !Float !Float !Float
pack (a:.b:.c:.d:.()) = Vec4F a b c d
unpack (Vec4F a b c d) = a:.b:.c:.d:.()
type Vec2F = Packed (Vec2 Float)
type Vec3F = Packed (Vec3 Float)
type Vec4F = Packed (Vec4 Float)
instance PackedVec (Vec2 Double) where
data Packed (Vec2 Double) = Vec2D !Double !Double
pack (a:.b:.()) = Vec2D a b
unpack (Vec2D a b) = a:.b:.()
instance PackedVec (Vec3 Double) where
data Packed (Vec3 Double) = Vec3D !Double !Double !Double
pack (a:.b:.c:.()) = Vec3D a b c;
unpack (Vec3D a b c) = a:.b:.c:.();
instance PackedVec (Vec4 Double) where
data Packed (Vec4 Double) = Vec4D !Double !Double !Double !Double
pack (a:.b:.c:.d:.()) = Vec4D a b c d
unpack (Vec4D a b c d) = a:.b:.c:.d:.()
type Vec2D = Packed (Vec2 Double)
type Vec3D = Packed (Vec3 Double)
type Vec4D = Packed (Vec4 Double)
type Mat22D = Vec2 (Vec2D)
type Mat23D = Vec2 (Vec3D)
type Mat24D = Vec2 (Vec4D)
type Mat33D = Vec3 (Vec3D)
type Mat34D = Vec3 (Vec4D)
type Mat44D = Vec4 (Vec4D)
packMat :: (Map row (Packed row) mat packedMat, PackedVec row)
=> mat -> packedMat
packMat = map pack
unpackMat :: (Map (Packed row) row packedMat mat, PackedVec row)
=> packedMat -> mat
unpackMat = map unpack
instance (Eq v, PackedVec v) => Eq (Packed v) where
u == v = unpack u == unpack v
u /= v = unpack u /= unpack v
instance (Ord v, PackedVec v) => Ord (Packed v) where
compare u v = compare (unpack u) (unpack v)
instance (Show v, PackedVec v) => Show (Packed v) where
show v = show (unpack v)
instance (Map a b u v, PackedVec u, PackedVec v)
=> Map a b (Packed u) (Packed v)
where
map f = pack . map f . unpack
instance (Fold v a, PackedVec v) => Fold (Packed v) a
where
fold f = fold f . unpack
foldl f z = foldl f z . unpack
foldr f z = foldr f z . unpack
instance (ZipWith a b c u v w, PackedVec u, PackedVec v, PackedVec w)
=> ZipWith a b c (Packed u) (Packed v) (Packed w)
where
zipWith f u v = pack $ zipWith f (unpack u) (unpack v)
instance (Num v, PackedVec v) => Num (Packed v)
where
(+) u v = pack (unpack u + unpack v)
() u v = pack (unpack u unpack v)
(*) u v = pack (unpack u * unpack v)
abs u = pack (abs (unpack u))
signum u = pack (signum (unpack u))
fromInteger i = pack (fromInteger i)
instance (Fractional v, PackedVec v) => Fractional (Packed v)
where
(/) u v = pack (unpack u / unpack v)
recip u = pack (recip (unpack u))
fromRational r = pack (fromRational r)
instance (Storable v, PackedVec v) => Storable (Packed v)
where
sizeOf _ = sizeOf (undefined::v)
alignment _ = alignment (undefined::v)
peek p = peek (castPtr p) >>= \v -> return (pack v)
peekByteOff p o = peek (p`plusPtr`o)
peekElemOff p i = peek (p`plusPtr`(i*sizeOf(undefined::v)))
poke p v = poke (castPtr p) (unpack v)
pokeByteOff p o x = poke (p`plusPtr`o) x
pokeElemOff p i x = poke (p`plusPtr`(i*sizeOf(undefined::v))) x
instance (Length v n, PackedVec v) => Length (Packed v) n
where
length v = length (unpack v)
instance (Head v h, PackedVec v) => Head (Packed v) h
where
head v = head (unpack v)
instance (Tail v t, PackedVec v, PackedVec t) => Tail (Packed v) (Packed t)
where
tail v = pack (tail (unpack v))
instance (Last v l, PackedVec v) => Last (Packed v) l
where
last v = last (unpack v)
instance (Snoc v a v', PackedVec v, PackedVec v')
=> Snoc (Packed v) a (Packed v')
where
snoc v a = pack (snoc (unpack v) a)
instance (Reverse' () v v', PackedVec v, PackedVec v')
=> Reverse' () (Packed v) (Packed v')
where
reverse' _ v = pack (reverse (unpack v))
instance (Take (Succ n) v v', PackedVec v, PackedVec v')
=> Take (Succ n) (Packed v) (Packed v')
where
take n v = pack (take n (unpack v))
instance (Drop n v v', PackedVec v, PackedVec v')
=> Drop n (Packed v) (Packed v')
where
drop n v = pack (drop n (unpack v))
instance (Access n a v, PackedVec v) => Access n a (Packed v)
where
get n v = get n (unpack v)
set n a v = pack (set n a (unpack v))
instance (VecList a v, PackedVec v) => VecList a (Packed v)
where
fromList = pack . fromList
getElem i = getElem i . unpack
setElem i a = pack . setElem i a . unpack
instance (VecArrayRW (a:.v), PackedVec (a:.v)) => MArray (STUArray s) (Packed (a:.v)) (ST s) where
getBounds (STUArray l u _ _) = return (l,u)
getNumElements (STUArray _ _ n _) = return n
unsafeNewArray_ (l,u) =
unsafeNewArraySTUArray_ (l,u) (\x# -> x# *# vaSizeOf# (undefined::a:.v) )
newArray_ arrBounds = Array.newArray arrBounds (pack init#)
unsafeRead (STUArray _ _ _ marr#) (I# i#) = ST $ \s1# ->
case vaRead# marr# (vaLength# (undefined::a:.v) *# i#) s1# of
(# s2, v #) -> (# s2, pack v #)
unsafeWrite (STUArray _ _ _ marr#) (I# i#) v = ST $ \s1# ->
case vaWrite# marr# (vaLength# (undefined::a:.v) *# i#) (unpack v) s1# of
s2# -> (# s2#, () #)
instance (VecArrayRW (a:.v), PackedVec (a:.v)) => IArray UArray (Packed (a:.v)) where
bounds (UArray l u _ _) = (l,u)
numElements (UArray _ _ n _) = n
unsafeArray lu ies = runST (unsafeArrayUArray lu ies (pack init#) )
unsafeAt (UArray _ _ _ arr#) (I# i#) = pack $ vaIndex# arr# (vaLength# (undefined::a:.v) *# i#)
unsafeReplace arr ies = runST (unsafeReplaceUArray arr ies)
unsafeAccum f arr ies = runST (unsafeAccumUArray f arr ies)
unsafeAccumArray f initialValue lu ies = runST (unsafeAccumArrayUArray f initialValue lu ies)