{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{- |
Transfer values between Haskell and JIT generated code
in an LLVM-compatible format.
E.g. 'Bool' is stored as 'i1' and occupies a byte,
@'Vector' n 'Bool'@ is stored as a bit vector,
@'Vector' n 'Word8'@ is stored in an order depending on machine endianess,
and Haskell tuples are stored as LLVM structs.
-}
module LLVM.Extra.Multi.Value.Marshal (
   C(..),
   Struct,
   peek,
   poke,

   VectorStruct,
   Vector(..),

   with,
   EE.alloca,
   ) where

import qualified LLVM.Extra.Multi.Vector as MultiVector
import qualified LLVM.Extra.Multi.Value.Private as MultiValue
import qualified LLVM.Extra.Memory as Memory
import LLVM.Extra.Multi.Vector.Instance ()

import qualified LLVM.ExecutionEngine as EE
import qualified LLVM.Core as LLVM

import qualified Type.Data.Num.Decimal as TypeNum

import qualified Control.Functor.HT as FuncHT
import Control.Applicative (liftA2, liftA3, (<$>))

import Foreign.Storable (Storable)
import Foreign.StablePtr (StablePtr)
import Foreign.Ptr (FunPtr, Ptr)

import Data.Complex (Complex((:+)))
import Data.Word (Word8, Word16, Word32, Word64, Word)
import Data.Int  (Int8,  Int16,  Int32,  Int64)



peek ::
   (C a, Struct a ~ struct, EE.Marshal struct) => LLVM.Ptr struct -> IO a
peek :: forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> IO a
peek Ptr struct
ptr = struct -> a
Struct a -> a
forall a. C a => Struct a -> a
unpack (struct -> a) -> IO struct -> IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr struct -> IO struct
forall a. Marshal a => Ptr a -> IO a
EE.peek Ptr struct
ptr

poke ::
   (C a, Struct a ~ struct, EE.Marshal struct) => LLVM.Ptr struct -> a -> IO ()
poke :: forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> a -> IO ()
poke Ptr struct
ptr = Ptr struct -> struct -> IO ()
forall a. Marshal a => Ptr a -> a -> IO ()
EE.poke Ptr struct
ptr (struct -> IO ()) -> (a -> struct) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> struct
a -> Struct a
forall a. C a => a -> Struct a
pack


type Struct a = Memory.Struct (MultiValue.Repr a)

class
   (MultiValue.C a, Memory.C (MultiValue.Repr a),
    EE.Marshal (Struct a), LLVM.IsConst (Struct a)) =>
      C a where
   pack :: a -> Struct a
   unpack :: Struct a -> a

instance C Bool   where pack :: Bool -> Struct Bool
pack = Bool -> Bool
Bool -> Struct Bool
forall a. a -> a
id; unpack :: Struct Bool -> Bool
unpack = Bool -> Bool
Struct Bool -> Bool
forall a. a -> a
id
instance C Float  where pack :: Float -> Struct Float
pack = Float -> Float
Float -> Struct Float
forall a. a -> a
id; unpack :: Struct Float -> Float
unpack = Float -> Float
Struct Float -> Float
forall a. a -> a
id
instance C Double where pack :: Double -> Struct Double
pack = Double -> Double
Double -> Struct Double
forall a. a -> a
id; unpack :: Struct Double -> Double
unpack = Double -> Double
Struct Double -> Double
forall a. a -> a
id
instance C Word   where pack :: Word -> Struct Word
pack = Word -> Word
Word -> Struct Word
forall a. a -> a
id; unpack :: Struct Word -> Word
unpack = Word -> Word
Struct Word -> Word
forall a. a -> a
id
instance C Word8  where pack :: Word8 -> Struct Word8
pack = Word8 -> Word8
Word8 -> Struct Word8
forall a. a -> a
id; unpack :: Struct Word8 -> Word8
unpack = Word8 -> Word8
Struct Word8 -> Word8
forall a. a -> a
id
instance C Word16 where pack :: Word16 -> Struct Word16
pack = Word16 -> Word16
Word16 -> Struct Word16
forall a. a -> a
id; unpack :: Struct Word16 -> Word16
unpack = Word16 -> Word16
Struct Word16 -> Word16
forall a. a -> a
id
instance C Word32 where pack :: Word32 -> Struct Word32
pack = Word32 -> Word32
Word32 -> Struct Word32
forall a. a -> a
id; unpack :: Struct Word32 -> Word32
unpack = Word32 -> Word32
Struct Word32 -> Word32
forall a. a -> a
id
instance C Word64 where pack :: Word64 -> Struct Word64
pack = Word64 -> Word64
Word64 -> Struct Word64
forall a. a -> a
id; unpack :: Struct Word64 -> Word64
unpack = Word64 -> Word64
Struct Word64 -> Word64
forall a. a -> a
id
instance C Int    where pack :: Int -> Struct Int
pack = Int -> Int
Int -> Struct Int
forall a. a -> a
id; unpack :: Struct Int -> Int
unpack = Int -> Int
Struct Int -> Int
forall a. a -> a
id
instance C Int8   where pack :: Int8 -> Struct Int8
pack = Int8 -> Int8
Int8 -> Struct Int8
forall a. a -> a
id; unpack :: Struct Int8 -> Int8
unpack = Int8 -> Int8
Struct Int8 -> Int8
forall a. a -> a
id
instance C Int16  where pack :: Int16 -> Struct Int16
pack = Int16 -> Int16
Int16 -> Struct Int16
forall a. a -> a
id; unpack :: Struct Int16 -> Int16
unpack = Int16 -> Int16
Struct Int16 -> Int16
forall a. a -> a
id
instance C Int32  where pack :: Int32 -> Struct Int32
pack = Int32 -> Int32
Int32 -> Struct Int32
forall a. a -> a
id; unpack :: Struct Int32 -> Int32
unpack = Int32 -> Int32
Struct Int32 -> Int32
forall a. a -> a
id
instance C Int64  where pack :: Int64 -> Struct Int64
pack = Int64 -> Int64
Int64 -> Struct Int64
forall a. a -> a
id; unpack :: Struct Int64 -> Int64
unpack = Int64 -> Int64
Struct Int64 -> Int64
forall a. a -> a
id

instance (Storable a)        => C (Ptr a)       where pack :: Ptr a -> Struct (Ptr a)
pack = Ptr a -> Ptr a
Ptr a -> Struct (Ptr a)
forall a. a -> a
id; unpack :: Struct (Ptr a) -> Ptr a
unpack = Ptr a -> Ptr a
Struct (Ptr a) -> Ptr a
forall a. a -> a
id
instance (LLVM.IsType a)     => C (LLVM.Ptr a)  where pack :: Ptr a -> Struct (Ptr a)
pack = Ptr a -> Ptr a
Ptr a -> Struct (Ptr a)
forall a. a -> a
id; unpack :: Struct (Ptr a) -> Ptr a
unpack = Ptr a -> Ptr a
Struct (Ptr a) -> Ptr a
forall a. a -> a
id
instance (LLVM.IsFunction a) => C (FunPtr a)    where pack :: FunPtr a -> Struct (FunPtr a)
pack = FunPtr a -> FunPtr a
FunPtr a -> Struct (FunPtr a)
forall a. a -> a
id; unpack :: Struct (FunPtr a) -> FunPtr a
unpack = FunPtr a -> FunPtr a
Struct (FunPtr a) -> FunPtr a
forall a. a -> a
id
instance                        C (StablePtr a) where pack :: StablePtr a -> Struct (StablePtr a)
pack = StablePtr a -> StablePtr a
StablePtr a -> Struct (StablePtr a)
forall a. a -> a
id; unpack :: Struct (StablePtr a) -> StablePtr a
unpack = StablePtr a -> StablePtr a
Struct (StablePtr a) -> StablePtr a
forall a. a -> a
id

instance C () where
   pack :: () -> Struct ()
pack = () -> Struct ()
() -> Struct ()
forall a. a -> Struct a
LLVM.Struct
   unpack :: Struct () -> ()
unpack (LLVM.Struct ()
unit) = ()
unit

instance (C a, C b) => C (a,b) where
   pack :: (a, b) -> Struct (a, b)
pack (a
a,b
b) = Struct (Repr a)
-> Struct (Repr b)
-> Struct (Struct (Repr a), (Struct (Repr b), ()))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (a -> Struct (Repr a)
forall a. C a => a -> Struct a
pack a
a) (b -> Struct (Repr b)
forall a. C a => a -> Struct a
pack b
b)
   unpack :: Struct (a, b) -> (a, b)
unpack = Curried (Struct (Repr a), (Struct (Repr b), ())) (a, b)
-> Struct (Struct (Repr a), (Struct (Repr b), ())) -> (a, b)
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried (Struct (Repr a), (Struct (Repr b), ())) (a, b)
 -> Struct (Struct (Repr a), (Struct (Repr b), ())) -> (a, b))
-> Curried (Struct (Repr a), (Struct (Repr b), ())) (a, b)
-> Struct (Struct (Repr a), (Struct (Repr b), ()))
-> (a, b)
forall a b. (a -> b) -> a -> b
$ \Struct (Repr a)
a Struct (Repr b)
b -> (Struct (Repr a) -> a
forall a. C a => Struct a -> a
unpack Struct (Repr a)
a, Struct (Repr b) -> b
forall a. C a => Struct a -> a
unpack Struct (Repr b)
b)

instance (C a, C b, C c) => C (a,b,c) where
   pack :: (a, b, c) -> Struct (a, b, c)
pack (a
a,b
b,c
c) = Struct (Repr a)
-> Struct (Repr b)
-> Struct (Repr c)
-> Struct
     (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (a -> Struct (Repr a)
forall a. C a => a -> Struct a
pack a
a) (b -> Struct (Repr b)
forall a. C a => a -> Struct a
pack b
b) (c -> Struct (Repr c)
forall a. C a => a -> Struct a
pack c
c)
   unpack :: Struct (a, b, c) -> (a, b, c)
unpack = Curried
  (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
  (a, b, c)
-> Struct
     (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
-> (a, b, c)
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried
   (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
   (a, b, c)
 -> Struct
      (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
 -> (a, b, c))
-> Curried
     (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
     (a, b, c)
-> Struct
     (Struct (Repr a), (Struct (Repr b), (Struct (Repr c), ())))
-> (a, b, c)
forall a b. (a -> b) -> a -> b
$ \Struct (Repr a)
a Struct (Repr b)
b Struct (Repr c)
c -> (Struct (Repr a) -> a
forall a. C a => Struct a -> a
unpack Struct (Repr a)
a, Struct (Repr b) -> b
forall a. C a => Struct a -> a
unpack Struct (Repr b)
b, Struct (Repr c) -> c
forall a. C a => Struct a -> a
unpack Struct (Repr c)
c)

instance (C a, C b, C c, C d) => C (a,b,c,d) where
   pack :: (a, b, c, d) -> Struct (a, b, c, d)
pack (a
a,b
b,c
c,d
d) = Struct (Repr a)
-> Struct (Repr b)
-> Struct (Repr c)
-> Struct (Repr d)
-> Struct
     (Struct (Repr a),
      (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (a -> Struct (Repr a)
forall a. C a => a -> Struct a
pack a
a) (b -> Struct (Repr b)
forall a. C a => a -> Struct a
pack b
b) (c -> Struct (Repr c)
forall a. C a => a -> Struct a
pack c
c) (d -> Struct (Repr d)
forall a. C a => a -> Struct a
pack d
d)
   unpack :: Struct (a, b, c, d) -> (a, b, c, d)
unpack =
      Curried
  (Struct (Repr a),
   (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
  (a, b, c, d)
-> Struct
     (Struct (Repr a),
      (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
-> (a, b, c, d)
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried
   (Struct (Repr a),
    (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
   (a, b, c, d)
 -> Struct
      (Struct (Repr a),
       (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
 -> (a, b, c, d))
-> Curried
     (Struct (Repr a),
      (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
     (a, b, c, d)
-> Struct
     (Struct (Repr a),
      (Struct (Repr b), (Struct (Repr c), (Struct (Repr d), ()))))
-> (a, b, c, d)
forall a b. (a -> b) -> a -> b
$ \Struct (Repr a)
a Struct (Repr b)
b Struct (Repr c)
c Struct (Repr d)
d -> (Struct (Repr a) -> a
forall a. C a => Struct a -> a
unpack Struct (Repr a)
a, Struct (Repr b) -> b
forall a. C a => Struct a -> a
unpack Struct (Repr b)
b, Struct (Repr c) -> c
forall a. C a => Struct a -> a
unpack Struct (Repr c)
c, Struct (Repr d) -> d
forall a. C a => Struct a -> a
unpack Struct (Repr d)
d)


instance (C a) => C (Complex a) where
   pack :: Complex a -> Struct (Complex a)
pack (a
a:+a
b) = Struct (Repr a)
-> Struct (Repr a)
-> Struct (Struct (Repr a), (Struct (Repr a), ()))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (a -> Struct (Repr a)
forall a. C a => a -> Struct a
pack a
a) (a -> Struct (Repr a)
forall a. C a => a -> Struct a
pack a
b)
   unpack :: Struct (Complex a) -> Complex a
unpack = Curried (Struct (Repr a), (Struct (Repr a), ())) (Complex a)
-> Struct (Struct (Repr a), (Struct (Repr a), ())) -> Complex a
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried (Struct (Repr a), (Struct (Repr a), ())) (Complex a)
 -> Struct (Struct (Repr a), (Struct (Repr a), ())) -> Complex a)
-> Curried (Struct (Repr a), (Struct (Repr a), ())) (Complex a)
-> Struct (Struct (Repr a), (Struct (Repr a), ()))
-> Complex a
forall a b. (a -> b) -> a -> b
$ \Struct (Repr a)
a Struct (Repr a)
b -> Struct (Repr a) -> a
forall a. C a => Struct a -> a
unpack Struct (Repr a)
a a -> a -> Complex a
forall a. a -> a -> Complex a
:+ Struct (Repr a) -> a
forall a. C a => Struct a -> a
unpack Struct (Repr a)
b



type VectorStruct n a = Memory.Struct (MultiVector.Repr n a)

class
   (TypeNum.Positive n, C a,
    MultiVector.C a, Memory.C (MultiVector.Repr n a),
    EE.Marshal (VectorStruct n a),
    LLVM.IsConst (VectorStruct n a)) =>
      Vector n a where
   packVector :: LLVM.Vector n a -> VectorStruct n a
   unpackVector :: VectorStruct n a -> LLVM.Vector n a

instance (TypeNum.Positive n, Vector n a) => C (LLVM.Vector n a) where
   pack :: Vector n a -> Struct (Vector n a)
pack = Vector n a -> Struct (Vector n a)
Vector n a -> VectorStruct n a
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector; unpack :: Struct (Vector n a) -> Vector n a
unpack = Struct (Vector n a) -> Vector n a
VectorStruct n a -> Vector n a
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector


instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D1)) =>
      Vector n Bool where
   packVector :: Vector n Bool -> VectorStruct n Bool
packVector = Vector n Bool -> Vector n Bool
Vector n Bool -> VectorStruct n Bool
forall a. a -> a
id
   unpackVector :: VectorStruct n Bool -> Vector n Bool
unpackVector = Vector n Bool -> Vector n Bool
VectorStruct n Bool -> Vector n Bool
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>
      Vector n Float where
   packVector :: Vector n Float -> VectorStruct n Float
packVector = Vector n Float -> Vector n Float
Vector n Float -> VectorStruct n Float
forall a. a -> a
id
   unpackVector :: VectorStruct n Float -> Vector n Float
unpackVector = Vector n Float -> Vector n Float
VectorStruct n Float -> Vector n Float
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>
      Vector n Double where
   packVector :: Vector n Double -> VectorStruct n Double
packVector = Vector n Double -> Vector n Double
Vector n Double -> VectorStruct n Double
forall a. a -> a
id
   unpackVector :: VectorStruct n Double -> Vector n Double
unpackVector = Vector n Double -> Vector n Double
VectorStruct n Double -> Vector n Double
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: LLVM.IntSize)) =>
      Vector n Word where
   packVector :: Vector n Word -> VectorStruct n Word
packVector = Vector n Word -> Vector n Word
Vector n Word -> VectorStruct n Word
forall a. a -> a
id
   unpackVector :: VectorStruct n Word -> Vector n Word
unpackVector = Vector n Word -> Vector n Word
VectorStruct n Word -> Vector n Word
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D8)) =>
      Vector n Word8 where
   packVector :: Vector n Word8 -> VectorStruct n Word8
packVector = Vector n Word8 -> Vector n Word8
Vector n Word8 -> VectorStruct n Word8
forall a. a -> a
id
   unpackVector :: VectorStruct n Word8 -> Vector n Word8
unpackVector = Vector n Word8 -> Vector n Word8
VectorStruct n Word8 -> Vector n Word8
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D16)) =>
      Vector n Word16 where
   packVector :: Vector n Word16 -> VectorStruct n Word16
packVector = Vector n Word16 -> Vector n Word16
Vector n Word16 -> VectorStruct n Word16
forall a. a -> a
id
   unpackVector :: VectorStruct n Word16 -> Vector n Word16
unpackVector = Vector n Word16 -> Vector n Word16
VectorStruct n Word16 -> Vector n Word16
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>
      Vector n Word32 where
   packVector :: Vector n Word32 -> VectorStruct n Word32
packVector = Vector n Word32 -> Vector n Word32
Vector n Word32 -> VectorStruct n Word32
forall a. a -> a
id
   unpackVector :: VectorStruct n Word32 -> Vector n Word32
unpackVector = Vector n Word32 -> Vector n Word32
VectorStruct n Word32 -> Vector n Word32
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>
      Vector n Word64 where
   packVector :: Vector n Word64 -> VectorStruct n Word64
packVector = Vector n Word64 -> Vector n Word64
Vector n Word64 -> VectorStruct n Word64
forall a. a -> a
id
   unpackVector :: VectorStruct n Word64 -> Vector n Word64
unpackVector = Vector n Word64 -> Vector n Word64
VectorStruct n Word64 -> Vector n Word64
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: LLVM.IntSize)) =>
      Vector n Int where
   packVector :: Vector n Int -> VectorStruct n Int
packVector = Vector n Int -> Vector n Int
Vector n Int -> VectorStruct n Int
forall a. a -> a
id
   unpackVector :: VectorStruct n Int -> Vector n Int
unpackVector = Vector n Int -> Vector n Int
VectorStruct n Int -> Vector n Int
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D8)) =>
      Vector n Int8 where
   packVector :: Vector n Int8 -> VectorStruct n Int8
packVector = Vector n Int8 -> Vector n Int8
Vector n Int8 -> VectorStruct n Int8
forall a. a -> a
id
   unpackVector :: VectorStruct n Int8 -> Vector n Int8
unpackVector = Vector n Int8 -> Vector n Int8
VectorStruct n Int8 -> Vector n Int8
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D16)) =>
      Vector n Int16 where
   packVector :: Vector n Int16 -> VectorStruct n Int16
packVector = Vector n Int16 -> Vector n Int16
Vector n Int16 -> VectorStruct n Int16
forall a. a -> a
id
   unpackVector :: VectorStruct n Int16 -> Vector n Int16
unpackVector = Vector n Int16 -> Vector n Int16
VectorStruct n Int16 -> Vector n Int16
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>
      Vector n Int32 where
   packVector :: Vector n Int32 -> VectorStruct n Int32
packVector = Vector n Int32 -> Vector n Int32
Vector n Int32 -> VectorStruct n Int32
forall a. a -> a
id
   unpackVector :: VectorStruct n Int32 -> Vector n Int32
unpackVector = Vector n Int32 -> Vector n Int32
VectorStruct n Int32 -> Vector n Int32
forall a. a -> a
id

instance
   (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>
      Vector n Int64 where
   packVector :: Vector n Int64 -> VectorStruct n Int64
packVector = Vector n Int64 -> Vector n Int64
Vector n Int64 -> VectorStruct n Int64
forall a. a -> a
id
   unpackVector :: VectorStruct n Int64 -> Vector n Int64
unpackVector = Vector n Int64 -> Vector n Int64
VectorStruct n Int64 -> Vector n Int64
forall a. a -> a
id

instance (Vector n a, Vector n b) => Vector n (a,b) where
   packVector :: Vector n (a, b) -> VectorStruct n (a, b)
packVector Vector n (a, b)
x =
      case Vector n (a, b) -> (Vector n a, Vector n b)
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
FuncHT.unzip Vector n (a, b)
x of
         (Vector n a
a,Vector n b
b) -> Struct (Repr n a)
-> Struct (Repr n b)
-> Struct (Struct (Repr n a), (Struct (Repr n b), ()))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (Vector n a -> Struct (Repr n a)
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector Vector n a
a) (Vector n b -> Struct (Repr n b)
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector Vector n b
b)
   unpackVector :: VectorStruct n (a, b) -> Vector n (a, b)
unpackVector = Curried
  (Struct (Repr n a), (Struct (Repr n b), ())) (Vector n (a, b))
-> Struct (Struct (Repr n a), (Struct (Repr n b), ()))
-> Vector n (a, b)
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried
   (Struct (Repr n a), (Struct (Repr n b), ())) (Vector n (a, b))
 -> Struct (Struct (Repr n a), (Struct (Repr n b), ()))
 -> Vector n (a, b))
-> Curried
     (Struct (Repr n a), (Struct (Repr n b), ())) (Vector n (a, b))
-> Struct (Struct (Repr n a), (Struct (Repr n b), ()))
-> Vector n (a, b)
forall a b. (a -> b) -> a -> b
$ \Struct (Repr n a)
a Struct (Repr n b)
b ->
      (a -> b -> (a, b)) -> Vector n a -> Vector n b -> Vector n (a, b)
forall a b c.
(a -> b -> c) -> Vector n a -> Vector n b -> Vector n c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Struct (Repr n a) -> Vector n a
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector Struct (Repr n a)
a) (Struct (Repr n b) -> Vector n b
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector Struct (Repr n b)
b)

instance (Vector n a, Vector n b, Vector n c) => Vector n (a,b,c) where
   packVector :: Vector n (a, b, c) -> VectorStruct n (a, b, c)
packVector Vector n (a, b, c)
x =
      case Vector n (a, b, c) -> (Vector n a, Vector n b, Vector n c)
forall (f :: * -> *) a b c.
Functor f =>
f (a, b, c) -> (f a, f b, f c)
FuncHT.unzip3 Vector n (a, b, c)
x of
         (Vector n a
a,Vector n b
b,Vector n c
c) -> Struct (Repr n a)
-> Struct (Repr n b)
-> Struct (Repr n c)
-> Struct
     (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
forall f. (ConsStruct f, ConsResult f ~ PartialStruct f) => f
LLVM.consStruct (Vector n a -> Struct (Repr n a)
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector Vector n a
a) (Vector n b -> Struct (Repr n b)
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector Vector n b
b) (Vector n c -> Struct (Repr n c)
forall n a. Vector n a => Vector n a -> VectorStruct n a
packVector Vector n c
c)
   unpackVector :: VectorStruct n (a, b, c) -> Vector n (a, b, c)
unpackVector = Curried
  (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
  (Vector n (a, b, c))
-> Struct
     (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
-> Vector n (a, b, c)
forall a b. CurryStruct a => Curried a b -> Struct a -> b
LLVM.uncurryStruct (Curried
   (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
   (Vector n (a, b, c))
 -> Struct
      (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
 -> Vector n (a, b, c))
-> Curried
     (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
     (Vector n (a, b, c))
-> Struct
     (Struct (Repr n a), (Struct (Repr n b), (Struct (Repr n c), ())))
-> Vector n (a, b, c)
forall a b. (a -> b) -> a -> b
$ \Struct (Repr n a)
a Struct (Repr n b)
b Struct (Repr n c)
c ->
      (a -> b -> c -> (a, b, c))
-> Vector n a -> Vector n b -> Vector n c -> Vector n (a, b, c)
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 (,,) (Struct (Repr n a) -> Vector n a
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector Struct (Repr n a)
a) (Struct (Repr n b) -> Vector n b
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector Struct (Repr n b)
b) (Struct (Repr n c) -> Vector n c
forall n a. Vector n a => VectorStruct n a -> Vector n a
unpackVector Struct (Repr n c)
c)


with :: (C a) => a -> (LLVM.Ptr (Struct a) -> IO b) -> IO b
with :: forall a b. C a => a -> (Ptr (Struct a) -> IO b) -> IO b
with a
a Ptr (Struct (Repr a)) -> IO b
act = (Ptr (Struct (Repr a)) -> IO b) -> IO b
forall a b. IsType a => (Ptr a -> IO b) -> IO b
EE.alloca ((Ptr (Struct (Repr a)) -> IO b) -> IO b)
-> (Ptr (Struct (Repr a)) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr (Struct (Repr a))
ptr -> Ptr (Struct (Repr a)) -> a -> IO ()
forall a struct.
(C a, Struct a ~ struct, Marshal struct) =>
Ptr struct -> a -> IO ()
poke Ptr (Struct (Repr a))
ptr a
a IO () -> IO b -> IO b
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr (Struct (Repr a)) -> IO b
act Ptr (Struct (Repr a))
ptr