-- |
-- Module      : Foreign.CUDA.BLAS.Internal.C2HS
-- Copyright   : [2014..2017] Trevor L. McDonell
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Foreign.CUDA.BLAS.Internal.C2HS
  where

-- system
import Foreign
import Foreign.C
import Control.Monad                            ( liftM )


-- Conversions -----------------------------------------------------------------
--

-- | Integral conversion
--
{-# INLINE cIntConv #-}
cIntConv :: (Integral a, Integral b) => a -> b
cIntConv :: a -> b
cIntConv  = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | Floating conversion
--
{-# INLINE [1] cFloatConv #-}
cFloatConv :: (RealFloat a, RealFloat b) => a -> b
cFloatConv :: a -> b
cFloatConv  = a -> b
forall a b. (Real a, Fractional b) => a -> b
realToFrac
-- As this conversion by default goes via `Rational', it can be very slow...
{-# RULES
  "cFloatConv/Float->Float"    forall (x::Float).  cFloatConv x = x;
  "cFloatConv/Double->Double"  forall (x::Double). cFloatConv x = x;
  "cFloatConv/Float->CFloat"   forall (x::Float).  cFloatConv x = CFloat x;
  "cFloatConv/CFloat->Float"   forall (x::Float).  cFloatConv CFloat x = x;
  "cFloatConv/Double->CDouble" forall (x::Double). cFloatConv x = CDouble x;
  "cFloatConv/CDouble->Double" forall (x::Double). cFloatConv CDouble x = x
 #-}

-- | Obtain C value from Haskell 'Bool'.
--
{-# INLINE cFromBool #-}
cFromBool :: Num a => Bool -> a
cFromBool :: Bool -> a
cFromBool  = Bool -> a
forall a. Num a => Bool -> a
fromBool

-- | Obtain Haskell 'Bool' from C value.
--
{-# INLINE cToBool #-}
cToBool :: (Eq a, Num a) => a -> Bool
cToBool :: a -> Bool
cToBool  = a -> Bool
forall a. (Eq a, Num a) => a -> Bool
toBool

-- | Convert a C enumeration to Haskell.
--
{-# INLINE cToEnum #-}
cToEnum :: (Integral i, Enum e) => i -> e
cToEnum :: i -> e
cToEnum  = Int -> e
forall a. Enum a => Int -> a
toEnum (Int -> e) -> (i -> Int) -> i -> e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Int
forall a b. (Integral a, Integral b) => a -> b
cIntConv

-- | Convert a Haskell enumeration to C.
--
{-# INLINE cFromEnum #-}
cFromEnum :: (Enum e, Integral i) => e -> i
cFromEnum :: e -> i
cFromEnum  = Int -> i
forall a b. (Integral a, Integral b) => a -> b
cIntConv (Int -> i) -> (e -> Int) -> e -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Int
forall a. Enum a => a -> Int
fromEnum

-- | Peek a C value into a Haskell enumeration
--
{-# INLINE peekEnum #-}
peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a
peekEnum :: Ptr b -> IO a
peekEnum = (b -> a) -> IO b -> IO a
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM b -> a
forall i e. (Integral i, Enum e) => i -> e
cToEnum (IO b -> IO a) -> (Ptr b -> IO b) -> Ptr b -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr b -> IO b
forall a. Storable a => Ptr a -> IO a
peek